109 lines
4.3 KiB
PHP
109 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Order;
|
|
use App\Models\OrderItem;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class CheckoutService
|
|
{
|
|
private function generateOrderNumber()
|
|
{
|
|
$businessCode = config('app.current_tenant_code');
|
|
|
|
$now = Carbon::now();
|
|
|
|
$dateCode = $now->format('ymd'); // Format: 260406
|
|
|
|
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
|
|
$randomPart = '';
|
|
for ($i = 0; $i < 3; $i++) {
|
|
$randomPart .= $chars[rand(0, strlen($chars) - 1)];
|
|
}
|
|
|
|
$prefix = "INVC-$businessCode-$dateCode-";
|
|
|
|
$lastOrder = Order::where('order_number', 'like', $prefix . '%')
|
|
->orderBy('order_number', 'desc')
|
|
->first();
|
|
|
|
$nextSequence = 1;
|
|
|
|
if ($lastOrder) {
|
|
$parts = explode('-', $lastOrder->order_number);
|
|
$lastPart = end($parts);
|
|
|
|
if (strlen($lastPart) >= 5) {
|
|
$lastSeqStr = substr($lastPart, -5);
|
|
$nextSequence = (int)$lastSeqStr + 1;
|
|
}
|
|
}
|
|
|
|
$finalSequence = $randomPart . str_pad($nextSequence, 5, '0', STR_PAD_LEFT);
|
|
|
|
return $prefix . $finalSequence;
|
|
}
|
|
|
|
public function execute(array $data, $file)
|
|
{
|
|
return DB::transaction(function () use ($data, $file) {
|
|
$tenantId = config('app.current_tenant_id');
|
|
|
|
$businessCode = config('app.current_tenant_code');
|
|
|
|
$paymentProof = null;
|
|
if ($file) {
|
|
$filename = (string) Carbon::now()->getPreciseTimestamp(3). '.' . $file->getClientOriginalExtension();
|
|
$paymentProof = $file->storeAs("{$businessCode}/payment_proof_orders", $filename, 'public');
|
|
}
|
|
|
|
$order = Order::create([
|
|
'uuid' => Str::uuid7(),
|
|
'tenant_id' => $tenantId,
|
|
'order_number' => $this->generateOrderNumber(),
|
|
'outlet_id' => $data['outlet_id'],
|
|
'outlet_name_snapshot' => $data['outlet_name_snapshot'],
|
|
'outlet_phone_number_snapshot' => $data['outlet_phone_number_snapshot'],
|
|
'outlet_address_snapshot' => $data['outlet_address_snapshot'],
|
|
'customer_id' => $data['customer_id'],
|
|
'customer_name_snapshot' => $data['customer_name_snapshot'],
|
|
'customer_email_snapshot' => $data['customer_email_snapshot'] ?? null,
|
|
'customer_phone_number_snapshot' => $data['customer_phone_number_snapshot'],
|
|
'customer_address_snapshot' => $data['customer_address_snapshot'] ?? null,
|
|
'source' => 'online',
|
|
'already_read' => false,
|
|
'order_status' => $data['order_status'],
|
|
'delivery_type' => $data['delivery_type'],
|
|
'delivery_preference' => $data['delivery_preference'],
|
|
'delivery_fee_type' => $data['delivery_fee_type'],
|
|
'delivery_fee' => $data['delivery_fee'],
|
|
'total_delivery_fee' => $data['total_delivery_fee'],
|
|
'total_order' => $data['total_order'],
|
|
'total_amount' => $data['total_amount'],
|
|
'notes' => $data['notes'],
|
|
'payment_proof_url' => $paymentProof ? "{$businessCode}/payment_proof_orders/{$filename}" : null,
|
|
'payment_method' => $data['payment_method'],
|
|
]);
|
|
|
|
foreach ($data['items'] as $item) {
|
|
OrderItem::create([
|
|
'uuid' => Str::uuid7(),
|
|
'tenant_id' => $tenantId,
|
|
'order_id' => $order->uuid,
|
|
'product_variant_id' => $item['product_variant_id'],
|
|
'quantity' => $item['quantity'],
|
|
'product_image_url_snapshot' => $item['product_image_url_snapshot'] ?? null,
|
|
'product_name_snapshot' => $item['product_name_snapshot'],
|
|
'product_variant_name_snapshot' => $item['product_variant_name_snapshot'] ?? null,
|
|
'selling_price_snapshot' => $item['selling_price_snapshot'],
|
|
'subtotal' => $item['quantity'] * $item['selling_price_snapshot'],
|
|
]);
|
|
}
|
|
|
|
return $order;
|
|
});
|
|
}
|
|
} |