Merge branch 'feature-product' into development
WMS API/ECOMMERCE/pipeline/head There was a failure building this commit
Details
WMS API/ECOMMERCE/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
95d0b6cdd6
|
|
@ -32,6 +32,7 @@ class AddressController extends Controller
|
|||
'postal_code' => $address->postal_code,
|
||||
'latitude' => $address->latitude,
|
||||
'longitude' => $address->longitude,
|
||||
'phone' => $address->phone,
|
||||
];
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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,11 +94,13 @@ class CheckoutController extends Controller
|
|||
$request->merge(['location_id' => $location_id]);
|
||||
$carts = $memberCartRepository->getList($request);
|
||||
|
||||
|
||||
try{
|
||||
$shipping_list = collect($shippingRepository->getList([
|
||||
"location_id" => $location_id,
|
||||
"address_id" => $address_id,
|
||||
"items" => $carts,
|
||||
])['pricing'])->map(function($row){
|
||||
])['pricing'] ?? [])->map(function($row){
|
||||
return [
|
||||
'courier' => $row['courier_code'],
|
||||
'service' => $row['courier_service_code'],
|
||||
|
|
@ -106,6 +110,17 @@ class CheckoutController extends Controller
|
|||
];
|
||||
});
|
||||
|
||||
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,
|
||||
'subtotal' => $subtotal,
|
||||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ class ShippingRepository
|
|||
});
|
||||
|
||||
if ($hasLatLong){
|
||||
try{
|
||||
$list = $biteship->rateByLatLong([
|
||||
"origin_latitude" => $location->latitude,
|
||||
"origin_longitude" => $location->longitude,
|
||||
|
|
@ -103,6 +104,13 @@ class ShippingRepository
|
|||
"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([
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@
|
|||
<td class="py-3 ps-0">
|
||||
<div class="d-flex align-items-center">
|
||||
<a class="flex-shrink-0"
|
||||
href="{{ route('product.detail', $cart->itemVariant->item->slug) }}">
|
||||
href="{{ $cart->itemVariant->item->slug != null ? route('product.detail', $cart->itemVariant->item->slug) : '#' }}">
|
||||
<img src="{{ $cart->itemReference->item->image_url ?? '' }}"
|
||||
width="80" alt="{{ $cart->name ?? 'Product' }}">
|
||||
</a>
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
<div class="w-100 min-w-0 ps-2 ps-xl-3">
|
||||
<h5 class="d-flex animate-underline mb-2">
|
||||
<a class="d-block fs-sm fw-medium text-truncate animate-target"
|
||||
href="{{ $cart->itemVariant->item->slug != null ? route('product.detail', [$cart->item->slug]) : '#' }}">{{ $cart->itemVariant->display_name ?? ($cart->itemVariant->description ?? 'Product Name') }}</a>
|
||||
href="{{ $cart->itemVariant->item->slug != null ? route('product.detail', [$cart->itemVariant->item->slug]) : '#' }}">{{ $cart->itemVariant->display_name ?? ($cart->itemVariant->description ?? 'Product Name') }}</a>
|
||||
</h5>
|
||||
{{-- <ul class="list-unstyled gap-1 fs-xs mb-0">
|
||||
<li><span class="text-body-secondary">Color:</span> <span
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
<aside class="col-lg-4 offset-xl-1" style="margin-top: -100px">
|
||||
<div class="position-sticky top-0" style="padding-top: 100px">
|
||||
<x-checkout.order-summary :subtotal="$subtotal" :total="$total" :savings="0" :tax="0"
|
||||
:showEdit="true" :editUrl="route('second', ['checkout', 'v1-cart'])" />
|
||||
:showEdit="true" :editUrl="route('cart.index')" />
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
<span
|
||||
class="badge bg-primary ms-2">{{ __('checkout.primary') }}</span>
|
||||
class="badge bg-primary ms-2">({{ __('checkout.primary') }})</span>
|
||||
@endif
|
||||
</option>
|
||||
@endforeach
|
||||
|
|
@ -100,7 +101,12 @@
|
|||
|
||||
<!-- Shipping Address (shown automatically) -->
|
||||
<div id="shippingAddress" class="shipping-address mt-4" style="display: block;">
|
||||
<div class="d-flex justify-content-between">
|
||||
|
||||
<h6 class="mb-3">{{ __('checkout.shipping_address') }}</h6>
|
||||
<a type="button" href="{{ route('addresses') }}"
|
||||
class="btn btn-outline-primary btn-sm">Edit</a>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label for="firstName"
|
||||
|
|
@ -108,11 +114,17 @@
|
|||
<input type="text" class="form-control" id="firstName" readonly
|
||||
style="border: none; background-color: #f8f9fa;">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{{-- <div class="col-md-6">
|
||||
<label for="lastName"
|
||||
class="form-label">{{ __('checkout.last_name') }}</label>
|
||||
<input type="text" class="form-control" id="lastName" readonly
|
||||
style="border: none; background-color: #f8f9fa;">
|
||||
</div> --}}
|
||||
<div class="col-12">
|
||||
<label for="phone"
|
||||
class="form-label">{{ __('checkout.phone') }}</label>
|
||||
<input type="tel" class="form-control" id="phone" readonly
|
||||
style="border: none; background-color: #f8f9fa;">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="address"
|
||||
|
|
@ -138,12 +150,19 @@
|
|||
<input type="text" class="form-control" id="zip" readonly
|
||||
style="border: none; background-color: #f8f9fa;">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="phone"
|
||||
class="form-label">{{ __('checkout.phone') }}</label>
|
||||
<input type="tel" class="form-control" id="phone" readonly
|
||||
<div class="col-md-6">
|
||||
<label for="latitude"
|
||||
class="form-label">Latitude</label>
|
||||
<input type="text" class="form-control" id="latitude" readonly
|
||||
style="border: none; background-color: #f8f9fa;">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="longitude"
|
||||
class="form-label">Longitude</label>
|
||||
<input type="text" class="form-control" id="longitude" readonly
|
||||
style="border: none; background-color: #f8f9fa;">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -170,8 +189,10 @@
|
|||
<div class="mt-4">
|
||||
<form action="{{ route('checkout.delivery.process') }}" method="post">
|
||||
@csrf
|
||||
<input type="hidden" name="delivery_method" id="deliveryMethodInput" value="shipping">
|
||||
<input type="hidden" name="address_id" id="addressIdInput" value="{{ $address_list->first()->id }}">
|
||||
<input type="hidden" name="delivery_method" id="deliveryMethodInput"
|
||||
value="shipping">
|
||||
<input type="hidden" name="address_id" id="addressIdInput"
|
||||
value="{{ $address_list->first()->id }}">
|
||||
<button type="submit" class="btn btn-lg btn-primary w-100"
|
||||
id="continueButton">
|
||||
<span
|
||||
|
|
@ -203,14 +224,14 @@
|
|||
<aside class="col-lg-4 offset-xl-1" style="margin-top: -100px">
|
||||
<div class="position-sticky top-0" style="padding-top: 100px">
|
||||
<x-checkout.order-summary :subtotal="$subtotal" :total="$total" :savings="0" :tax="0"
|
||||
:showEdit="true" :editUrl="route('second', ['checkout', 'v1-cart'])" />
|
||||
:showEdit="true" :editUrl="route('cart.index')" />
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue