QueenFruits/Backend/app/Services/CheckoutService.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;
});
}
}