refactor: Split shipping_address into component fields for ShipLogic API
- Create migration to add shipping_street_address, shipping_local_area, shipping_city, shipping_zone, shipping_country, shipping_postcode, shipping_type - Update Order model fillable array with new address component fields - Remove address parsing logic from CourierService - Use individual address fields directly in ShipLogic API payload - Fields match ShipLogic API requirements (street_address, local_area, city, zone, code, country, type) - Note: Custom orders address collection can be implemented later
This commit is contained in:
@@ -26,6 +26,13 @@ class Order extends Model
|
||||
'customer_email',
|
||||
'customer_phone',
|
||||
'shipping_address',
|
||||
'shipping_street_address',
|
||||
'shipping_local_area',
|
||||
'shipping_city',
|
||||
'shipping_zone',
|
||||
'shipping_country',
|
||||
'shipping_postcode',
|
||||
'shipping_type',
|
||||
'notes',
|
||||
'yoco_checkout_id',
|
||||
'yoco_redirect_url',
|
||||
|
||||
@@ -115,26 +115,70 @@ class CourierService
|
||||
}
|
||||
|
||||
try {
|
||||
// Fetch order to get customer and shipping details
|
||||
$order = Order::findOrFail($orderId);
|
||||
|
||||
// Validate required shipping info
|
||||
if (! $order->customer_name || ! $order->shipping_street_address) {
|
||||
throw new \Exception('Order missing required customer name or shipping address');
|
||||
}
|
||||
|
||||
if (! $order->customer_email && ! $order->customer_phone) {
|
||||
throw new \Exception('Order must have at least email or phone number');
|
||||
}
|
||||
|
||||
// Build shipment payload for Shiplogic
|
||||
$payload = [
|
||||
'parcel' => [
|
||||
'weight' => $weight,
|
||||
'height' => 10, // TODO: Update when height is captured separately
|
||||
'width' => $width,
|
||||
'length' => $length,
|
||||
'collection_address' => [
|
||||
'street' => 'Two Tales Designs', // TODO: Get from AppSetting
|
||||
'city' => 'Cape Town',
|
||||
'postcode' => '8000',
|
||||
'country' => 'ZA',
|
||||
],
|
||||
'destination' => [
|
||||
// TODO: Get from order's shipping address
|
||||
'collection_contact' => [
|
||||
'email' => config('mail.from.address'),
|
||||
'mobile_number' => '+27000000000', // TODO: Get from AppSetting
|
||||
],
|
||||
'reference' => $orderId,
|
||||
'delivery_address' => [
|
||||
'type' => $order->shipping_type ?? 'residential',
|
||||
'street_address' => $order->shipping_street_address,
|
||||
'local_area' => $order->shipping_local_area,
|
||||
'city' => $order->shipping_city,
|
||||
'zone' => $order->shipping_zone,
|
||||
'code' => $order->shipping_postcode,
|
||||
'country' => $order->shipping_country ?? 'ZA',
|
||||
],
|
||||
'delivery_contact' => [
|
||||
'name' => $order->customer_name,
|
||||
'email' => $order->customer_email,
|
||||
'mobile_number' => $order->customer_phone,
|
||||
],
|
||||
'parcels' => [
|
||||
[
|
||||
'weight' => $weight,
|
||||
'height' => 10, // TODO: Update when height is captured separately
|
||||
'width' => $width,
|
||||
'length' => $length,
|
||||
],
|
||||
],
|
||||
'service_level_id' => $this->getServiceLevelId(), // Standard delivery
|
||||
'customer_reference' => $order->order_number,
|
||||
'mute_notifications' => false,
|
||||
];
|
||||
|
||||
Log::info('Creating Shiplogic shipment', [
|
||||
'order_id' => $orderId,
|
||||
'order_number' => $order->order_number,
|
||||
'customer' => $order->customer_name,
|
||||
'delivery_address' => $street,
|
||||
]);
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => "Bearer {$this->apiKey}",
|
||||
])->post("{$this->baseUrl}/shipments", $payload);
|
||||
|
||||
if (! $response->successful()) {
|
||||
$errorMessage = $response->json('error.message', 'Unknown error');
|
||||
$errorMessage = $response->json('error.message', $response->json('message', 'Unknown error'));
|
||||
throw new \Exception("Courier API error: {$errorMessage}");
|
||||
}
|
||||
|
||||
@@ -155,6 +199,15 @@ class CourierService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service level ID for standard delivery
|
||||
* TODO: Move to AppSetting and make configurable
|
||||
*/
|
||||
private function getServiceLevelId(): int
|
||||
{
|
||||
return 1; // Standard service level
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate packing gate: order must be packed with dimensions
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user