From 65367bd8dcff48aa8640d045d5ddc0409c096cc9 Mon Sep 17 00:00:00 2001 From: Bayu Lukman Yusuf Date: Thu, 26 Feb 2026 08:47:24 +0700 Subject: [PATCH] cart checkout --- .../Controllers/Auth/AddressController.php | 1 + app/Http/Controllers/CheckoutController.php | 45 +++++++---- .../Member/ShippingRepository.php | 22 ++++-- app/ThirdParty/Biteship/Rate.php | 29 +++++-- resources/views/checkout/v1-cart.blade.php | 4 +- .../checkout/v1-delivery-1-shipping.blade.php | 2 +- .../views/checkout/v1-delivery-1.blade.php | 75 +++++++++++++------ 7 files changed, 123 insertions(+), 55 deletions(-) diff --git a/app/Http/Controllers/Auth/AddressController.php b/app/Http/Controllers/Auth/AddressController.php index 00c3b46..b3f55ba 100644 --- a/app/Http/Controllers/Auth/AddressController.php +++ b/app/Http/Controllers/Auth/AddressController.php @@ -32,6 +32,7 @@ class AddressController extends Controller 'postal_code' => $address->postal_code, 'latitude' => $address->latitude, 'longitude' => $address->longitude, + 'phone' => $address->phone, ]; }); diff --git a/app/Http/Controllers/CheckoutController.php b/app/Http/Controllers/CheckoutController.php index c04ba45..065cdce 100644 --- a/app/Http/Controllers/CheckoutController.php +++ b/app/Http/Controllers/CheckoutController.php @@ -10,6 +10,8 @@ use App\Repositories\Member\Transaction\TransactionRepository; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; +use Illuminate\Validation\ValidationException; + class CheckoutController extends Controller { public function index(Request $request, MemberCartRepository $memberCartRepository) @@ -20,7 +22,7 @@ class CheckoutController extends Controller $subtotal = $memberCartRepository->getSubtotal($request->input('location_id')); - $address_list = Address::where('user_id', $request->user()->id)->orderBy('is_primary','desc')->get(); + $address_list = Address::where('user_id', auth()->user()->id)->orderBy('is_primary','desc')->get(); $total = $subtotal; @@ -92,19 +94,32 @@ class CheckoutController extends Controller $request->merge(['location_id' => $location_id]); $carts = $memberCartRepository->getList($request); - $shipping_list = collect($shippingRepository->getList([ - "location_id" => $location_id, - "address_id" => $address_id, - "items" => $carts, - ])['pricing'])->map(function($row){ - return [ - 'courier' => $row['courier_code'], - 'service' => $row['courier_service_code'], - 'title' => $row['courier_name']." - ".$row['courier_service_name'], - 'description' => $row['duration'], - 'cost' => $row['shipping_fee'], - ]; - }); + + try{ + $shipping_list = collect($shippingRepository->getList([ + "location_id" => $location_id, + "address_id" => $address_id, + "items" => $carts, + ])['pricing'] ?? [])->map(function($row){ + return [ + 'courier' => $row['courier_code'], + 'service' => $row['courier_service_code'], + 'title' => $row['courier_name']." - ".$row['courier_service_name'], + 'description' => $row['duration'], + 'cost' => $row['shipping_fee'], + ]; + }); + + if (count($shipping_list) == 0) { + throw ValidationException::withMessages([ + "message" => "Tidak dapat menghitung ongkir" + ]); + } + }catch(\Exception $e){ + throw ValidationException::withMessages([ + "message" => $e->getMessage() + ]); + } return view('checkout.v1-delivery-1-shipping', [ 'carts' => $request->user()->carts, @@ -117,7 +132,7 @@ class CheckoutController extends Controller ]); } catch (\Exception $e) { Log::info($e); - return redirect()->route('checkout.delivery')->with('error', 'Invalid checkout data'); + return redirect()->route('checkout.delivery')->with('error', $e->getMessage() ?? 'Invalid checkout data'); } } diff --git a/app/Repositories/Member/ShippingRepository.php b/app/Repositories/Member/ShippingRepository.php index 6b6d924..7791617 100644 --- a/app/Repositories/Member/ShippingRepository.php +++ b/app/Repositories/Member/ShippingRepository.php @@ -96,13 +96,21 @@ class ShippingRepository }); if ($hasLatLong){ - $list = $biteship->rateByLatLong([ - "origin_latitude" => $location->latitude, - "origin_longitude" => $location->longitude, - "destination_latitude" => $address->latitude, - "destination_longitude" => $address->longitude, - "items" => $items - ]); + try{ + $list = $biteship->rateByLatLong([ + "origin_latitude" => $location->latitude, + "origin_longitude" => $location->longitude, + "destination_latitude" => $address->latitude, + "destination_longitude" => $address->longitude, + "items" => $items + ]); + }catch(ValidationException $e){ + $list = $biteship->rateByPostal([ + "origin_postal_code" => $location->postal_code, + "destination_postal_code" => $address->postal_code, + "items" => $items + ]); + } }else{ $list = $biteship->rateByPostal([ diff --git a/app/ThirdParty/Biteship/Rate.php b/app/ThirdParty/Biteship/Rate.php index 25b5a52..7728286 100644 --- a/app/ThirdParty/Biteship/Rate.php +++ b/app/ThirdParty/Biteship/Rate.php @@ -5,6 +5,7 @@ namespace App\ThirdParty\Biteship; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Cache; +use Illuminate\Validation\ValidationException; class Rate { @@ -28,19 +29,29 @@ class Rate $items) { $url = env("BITESHIP_URL"); $key = env("BITESHIP_KEY"); - $res = Http::withHeaders([ - "authorization" => $key - ]) - ->withBody(json_encode([ + + $body = [ "origin_latitude" => $origin_latitude, "origin_longitude" => $origin_longitude, "destination_latitude" => $destination_latitude, "destination_longitude" => $destination_longitude, - "couriers" => env("BITESHIP_COURIER_ALL","grab,gojek,tiki,jnt,anteraja"), + "couriers" => env("BITESHIP_COURIER","grab,gojek,tiki,jnt,anteraja"), "items" => $items - ]), 'application/json') + ]; + $res = Http::withHeaders([ + "authorization" => $key + ]) + ->withBody(json_encode($body), 'application/json') ->post($url."/v1/rates/couriers"); + if ($res->status() != 200 && $res->json()['error'] != null) { + Log::info(json_encode($res->json())); + Log::info($body); + throw ValidationException::withMessages([ + "message" => $res->json()['error'] + ]); + } + if ($res->status() == 200) return $res->json(); @@ -73,6 +84,12 @@ class Rate ]), 'application/json') ->post($url."/v1/rates/couriers"); + if ($res->status() != 200 && $res->json()['error'] != null) { + throw ValidationException::withMessages([ + "message" => $res->json()['error'] + ]); + } + if ($res->status() == 200) return $res->json(); diff --git a/resources/views/checkout/v1-cart.blade.php b/resources/views/checkout/v1-cart.blade.php index e6b64e6..5ed2592 100644 --- a/resources/views/checkout/v1-cart.blade.php +++ b/resources/views/checkout/v1-cart.blade.php @@ -83,7 +83,7 @@
+ href="{{ $cart->itemVariant->item->slug != null ? route('product.detail', $cart->itemVariant->item->slug) : '#' }}"> {{ $cart->name ?? 'Product' }} @@ -92,7 +92,7 @@
{{ $cart->itemVariant->display_name ?? ($cart->itemVariant->description ?? 'Product Name') }} + href="{{ $cart->itemVariant->item->slug != null ? route('product.detail', [$cart->itemVariant->item->slug]) : '#' }}">{{ $cart->itemVariant->display_name ?? ($cart->itemVariant->description ?? 'Product Name') }}
{{--
  • Color:
    + :showEdit="true" :editUrl="route('cart.index')" />
diff --git a/resources/views/checkout/v1-delivery-1.blade.php b/resources/views/checkout/v1-delivery-1.blade.php index f0fe1a4..e8807d8 100644 --- a/resources/views/checkout/v1-delivery-1.blade.php +++ b/resources/views/checkout/v1-delivery-1.blade.php @@ -9,7 +9,7 @@
{{-- show error message --}} - @if(session('error')) + @if (session('error'))
{{ session('error') }}
@@ -84,13 +84,14 @@ data-state="{{ $address->province->name }}" data-postcode="{{ $address->postal_code }}" data-phone="{{ $address->phone }}" + data-latitude="{{ $address->latitude }}" + data-longitude="{{ $address->longitude }}" {{ $address->is_primary || $key === 0 ? 'selected' : '' }}> {{ $address->label }} - {{ $address->name }}, - {{ $address->address }}, {{ $address->city_name }}, - {{ $address->province_name }} {{ $address->postal_code }} + {{ $address->address }} @if ($address->is_primary) {{ __('checkout.primary') }} + class="badge bg-primary ms-2">({{ __('checkout.primary') }}) @endif @endforeach @@ -100,7 +101,12 @@
-
{{ __('checkout.shipping_address') }}
+
+ +
{{ __('checkout.shipping_address') }}
+ Edit +
-
+ {{--
+
--}} +
+ +
-
- - + +
+
+ + +
+
@@ -170,8 +189,10 @@
@csrf - - + +
- @include('layouts.partials/footer') + @include('layouts.partials/footer2') @endsection @section('scripts') @@ -231,7 +252,8 @@ pickupOptions.style.display = 'none'; resetPickupSelection(); // Update button text for delivery - document.getElementById('continueButtonText').textContent = '{{ __("checkout.continue_to_shipping") }}'; + document.getElementById('continueButtonText').textContent = + '{{ __('checkout.continue_to_shipping') }}'; // Update hidden input values document.getElementById('deliveryMethodInput').value = 'delivery'; // Update address ID from selected address @@ -309,13 +331,14 @@ if (selectedOption && selectedOption.value) { // Populate all shipping address form fields document.getElementById('firstName').value = selectedOption.dataset.firstName || ''; - document.getElementById('lastName').value = selectedOption.dataset.lastName || ''; + // document.getElementById('lastName').value = selectedOption.dataset.lastName || ''; document.getElementById('address').value = selectedOption.dataset.address || ''; document.getElementById('city').value = selectedOption.dataset.city || ''; document.getElementById('state').value = selectedOption.dataset.state || ''; document.getElementById('zip').value = selectedOption.dataset.postcode || ''; document.getElementById('phone').value = selectedOption.dataset.phone || ''; - document.getElementById('postcode').value = selectedOption.dataset.postcode || ''; + document.getElementById('latitude').value = selectedOption.dataset.latitude || ''; + document.getElementById('longitude').value = selectedOption.dataset.longitude || ''; // Update order summary with postcode if (selectedOption.dataset.postcode) { @@ -337,25 +360,29 @@ if (this.value === 'new' || this.value === '') { // Clear form fields for new address document.getElementById('firstName').value = ''; - document.getElementById('lastName').value = ''; + // document.getElementById('lastName').value = ''; document.getElementById('address').value = ''; document.getElementById('city').value = ''; document.getElementById('state').value = ''; document.getElementById('zip').value = ''; document.getElementById('phone').value = ''; - document.getElementById('postcode').value = ''; + document.getElementById('latitude').value = ''; + document.getElementById('longitude').value = ''; + document.getElementById('zip').value = ''; // Clear address ID input document.getElementById('addressIdInput').value = ''; } else { // Populate form fields with selected address document.getElementById('firstName').value = selectedOption.dataset.firstName || ''; - document.getElementById('lastName').value = selectedOption.dataset.lastName || ''; + // document.getElementById('lastName').value = selectedOption.dataset.lastName || ''; document.getElementById('address').value = selectedOption.dataset.address || ''; document.getElementById('city').value = selectedOption.dataset.city || ''; document.getElementById('state').value = selectedOption.dataset.state || ''; document.getElementById('zip').value = selectedOption.dataset.postcode || ''; document.getElementById('phone').value = selectedOption.dataset.phone || ''; - document.getElementById('postcode').value = selectedOption.dataset.postcode || ''; + document.getElementById('latitude').value = selectedOption.dataset.latitude || ''; + document.getElementById('longitude').value = selectedOption.dataset.longitude || ''; + document.getElementById('zip').value = selectedOption.dataset.postcode || ''; // Update address ID input document.getElementById('addressIdInput').value = this.value; @@ -368,7 +395,7 @@ } // Auto-update order summary when postcode changes - document.getElementById('postcode').addEventListener('input', function() { + document.getElementById('zip').addEventListener('input', function() { if (this.value) { updateOrderSummaryWithShipping(); } @@ -427,7 +454,7 @@ function updateOrderSummaryWithShipping() { // Simulate shipping cost calculation based on postcode - const shippingCost = calculateShippingCost(document.getElementById('postcode').value); + const shippingCost = calculateShippingCost(document.getElementById('zip').value); // Update order summary const subtotalElement = document.getElementById('cart-subtotal'); @@ -510,7 +537,7 @@ } function validateDeliveryForm() { - const postcode = document.getElementById('postcode').value; + const postcode = document.getElementById('zip').value; const firstName = document.getElementById('firstName').value; const address = document.getElementById('address').value; const city = document.getElementById('city').value;