All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 1m4s
1. 將 B005 (廣告同步) 從 POST 改為 GET,符合 RESTful 規範。
2. 完善 B009 (庫存回報) 回應規格,加入業務代碼 (200 OK)。
3. API 文件 UI 優化:新增 Method Badge (方法標籤),並修正 JSON 中文/斜線轉義問題。
4. 機台管理介面優化:實作「唯讀庫存與效期」面板,並將日誌圖示改為「👁️」。
5. 標準化 ID 識別邏輯:資料表全面移除對 sku 的依賴,改以 id 為主、barcode 為輔。
6. 新增 Migration:正式移除 sku 欄位並同步 barcode 指向。
7. 更新多語系支援 (zh_TW, en, ja)。
121 lines
4.4 KiB
PHP
121 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Transaction;
|
|
|
|
use App\Models\Transaction\Order;
|
|
use App\Models\Transaction\OrderItem;
|
|
use App\Models\Transaction\Invoice;
|
|
use App\Models\Transaction\DispenseRecord;
|
|
use Illuminate\Support\Facades\DB;
|
|
use App\Models\Machine\Machine;
|
|
|
|
class TransactionService
|
|
{
|
|
/**
|
|
* Process a new transaction (B600).
|
|
*/
|
|
public function processTransaction(array $data): Order
|
|
{
|
|
return DB::transaction(function () use ($data) {
|
|
$machine = Machine::where('serial_no', $data['serial_no'])->firstOrFail();
|
|
|
|
// Create Order
|
|
$order = Order::create([
|
|
'company_id' => $machine->company_id,
|
|
'flow_id' => $data['flow_id'] ?? null,
|
|
'order_no' => $data['order_no'] ?? $this->generateOrderNo(),
|
|
'machine_id' => $machine->id,
|
|
'member_id' => $data['member_id'] ?? null,
|
|
'total_amount' => $data['total_amount'],
|
|
'discount_amount' => $data['discount_amount'] ?? 0,
|
|
'pay_amount' => $data['pay_amount'],
|
|
'payment_type' => $data['payment_type'] ?? 0,
|
|
'payment_status' => $data['payment_status'] ?? 1,
|
|
'payment_at' => now(),
|
|
'status' => 'completed',
|
|
'metadata' => $data['metadata'] ?? null,
|
|
]);
|
|
|
|
// Create Order Items
|
|
if (!empty($data['items'])) {
|
|
foreach ($data['items'] as $item) {
|
|
$order->items()->create([
|
|
'product_id' => $item['product_id'],
|
|
'product_name' => $item['product_name'] ?? 'Unknown',
|
|
'barcode' => $item['barcode'] ?? null,
|
|
'price' => $item['price'],
|
|
'quantity' => $item['quantity'],
|
|
'subtotal' => $item['price'] * $item['quantity'],
|
|
]);
|
|
}
|
|
}
|
|
|
|
return $order;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Generate a unique order number.
|
|
*/
|
|
protected function generateOrderNo(): string
|
|
{
|
|
return 'ORD-' . now()->format('YmdHis') . '-' . strtoupper(bin2hex(random_bytes(3)));
|
|
}
|
|
|
|
/**
|
|
* Record Invoice (B601).
|
|
*/
|
|
public function recordInvoice(array $data): Invoice
|
|
{
|
|
return DB::transaction(function () use ($data) {
|
|
$machine = Machine::where('serial_no', $data['serial_no'])->firstOrFail();
|
|
|
|
$order = null;
|
|
if (!empty($data['flow_id'])) {
|
|
$order = Order::where('flow_id', $data['flow_id'])->first();
|
|
}
|
|
|
|
return Invoice::create([
|
|
'company_id' => $machine->company_id,
|
|
'order_id' => $order?->id ?? ($data['order_id'] ?? null),
|
|
'machine_id' => $machine->id,
|
|
'flow_id' => $data['flow_id'] ?? null,
|
|
'invoice_no' => $data['invoice_no'] ?? null,
|
|
'amount' => $data['amount'] ?? 0,
|
|
'carrier_id' => $data['carrier_id'] ?? null,
|
|
'invoice_date' => $data['invoice_date'] ?? null,
|
|
'random_number' => $data['random_no'] ?? null,
|
|
'love_code' => $data['love_code'] ?? null,
|
|
'metadata' => $data['metadata'] ?? null,
|
|
]);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Record dispense result (B602).
|
|
*/
|
|
public function recordDispense(array $data): DispenseRecord
|
|
{
|
|
return DB::transaction(function () use ($data) {
|
|
$machine = Machine::where('serial_no', $data['serial_no'])->firstOrFail();
|
|
|
|
$order = null;
|
|
if (!empty($data['flow_id'])) {
|
|
$order = Order::where('flow_id', $data['flow_id'])->first();
|
|
}
|
|
|
|
return DispenseRecord::create([
|
|
'company_id' => $machine->company_id,
|
|
'order_id' => $order?->id ?? ($data['order_id'] ?? null),
|
|
'flow_id' => $data['flow_id'] ?? null,
|
|
'machine_id' => $machine->id,
|
|
'slot_no' => $data['slot_no'] ?? 'unknown',
|
|
'product_id' => $data['product_id'] ?? null,
|
|
'amount' => $data['amount'] ?? 0,
|
|
'dispense_status' => $data['dispense_status'] ?? 0,
|
|
'machine_time' => $data['machine_time'] ?? now(),
|
|
]);
|
|
});
|
|
}
|
|
}
|