diff --git a/app/Models/Order.php b/app/Models/Order.php index 4515d72..a70f23b 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -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', diff --git a/app/Services/CourierService.php b/app/Services/CourierService.php index 4ad6ffb..0825dc0 100644 --- a/app/Services/CourierService.php +++ b/app/Services/CourierService.php @@ -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 */ diff --git a/database/migrations/2026_01_02_000003_split_shipping_address_into_components.php b/database/migrations/2026_01_02_000003_split_shipping_address_into_components.php new file mode 100644 index 0000000..8ef4288 --- /dev/null +++ b/database/migrations/2026_01_02_000003_split_shipping_address_into_components.php @@ -0,0 +1,43 @@ +string('shipping_street_address')->nullable()->after('shipping_address'); + $table->string('shipping_local_area')->nullable()->after('shipping_street_address'); + $table->string('shipping_city')->nullable()->after('shipping_local_area'); + $table->string('shipping_zone')->nullable()->after('shipping_city'); + $table->string('shipping_country')->default('ZA')->after('shipping_zone'); + $table->string('shipping_postcode')->nullable()->after('shipping_country'); + $table->enum('shipping_type', ['residential', 'business'])->default('residential')->after('shipping_postcode'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('orders', function (Blueprint $table) { + $table->dropColumn([ + 'shipping_street_address', + 'shipping_local_area', + 'shipping_city', + 'shipping_zone', + 'shipping_country', + 'shipping_postcode', + 'shipping_type', + ]); + }); + } +}; diff --git a/storage/framework/views/adc4c4a369b2bee1705d8da3a6247c45.php b/storage/framework/views/adc4c4a369b2bee1705d8da3a6247c45.php new file mode 100644 index 0000000..f1db8d5 --- /dev/null +++ b/storage/framework/views/adc4c4a369b2bee1705d8da3a6247c45.php @@ -0,0 +1,793 @@ +startSection('title', 'Request Custom Design - Additional Design'); ?> + +startSection('styles'); ?> + +stopSection(); ?> + +startSection('content'); ?> +
Create a custom wallpaper, mural, or fabric design tailored to your needs
+Estimated Total:
+