feat(sales): 現金支付面額明細(收各面額張數+找零)回傳並於銷售紀錄顯示
- orders 新增 cash_detail JSON 欄(migration) - Order model fillable/casts + cash_received_summary accessor (顯示「收:總額(只列有收到幣別明細) 找:x」) - TransactionService create/transition 兩處寫入 cash_detail - 銷售列表 blade 桌機/手機各加一列現金明細 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
dc9421e482
commit
be73e7c7a0
@ -60,6 +60,7 @@ class Order extends Model
|
|||||||
'discount_amount',
|
'discount_amount',
|
||||||
'pay_amount',
|
'pay_amount',
|
||||||
'change_amount',
|
'change_amount',
|
||||||
|
'cash_detail',
|
||||||
'points_used',
|
'points_used',
|
||||||
'original_amount',
|
'original_amount',
|
||||||
'payment_status',
|
'payment_status',
|
||||||
@ -82,6 +83,7 @@ class Order extends Model
|
|||||||
'discount_amount' => 'decimal:2',
|
'discount_amount' => 'decimal:2',
|
||||||
'pay_amount' => 'decimal:2',
|
'pay_amount' => 'decimal:2',
|
||||||
'change_amount' => 'decimal:2',
|
'change_amount' => 'decimal:2',
|
||||||
|
'cash_detail' => 'array',
|
||||||
'original_amount' => 'decimal:2',
|
'original_amount' => 'decimal:2',
|
||||||
'payment_at' => 'datetime',
|
'payment_at' => 'datetime',
|
||||||
'machine_time' => 'datetime',
|
'machine_time' => 'datetime',
|
||||||
@ -90,6 +92,42 @@ class Order extends Model
|
|||||||
'delivery_status' => 'integer',
|
'delivery_status' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 現金收款摘要字串:「收:{總收金額}(只列有收到的面額明細) 找:{找零}」。
|
||||||
|
* 例:收:120(佰:1、10:2) 找:30。無 cash_detail(非現金或舊資料)或全為 0 時回 null。
|
||||||
|
* 總收金額由各面額張數加總得出,與括號內明細一致。
|
||||||
|
*/
|
||||||
|
public function getCashReceivedSummaryAttribute(): ?string
|
||||||
|
{
|
||||||
|
$cd = $this->cash_detail;
|
||||||
|
if (empty($cd)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 面額顯示標籤 + 幣值(依大到小)
|
||||||
|
$denoms = [
|
||||||
|
'b1000' => ['label' => '仟', 'unit' => 1000],
|
||||||
|
'b500' => ['label' => '伍佰', 'unit' => 500],
|
||||||
|
'b100' => ['label' => '佰', 'unit' => 100],
|
||||||
|
'c50' => ['label' => '50', 'unit' => 50],
|
||||||
|
'c10' => ['label' => '10', 'unit' => 10],
|
||||||
|
'c5' => ['label' => '5', 'unit' => 5],
|
||||||
|
'c1' => ['label' => '1', 'unit' => 1],
|
||||||
|
];
|
||||||
|
$received = 0;
|
||||||
|
$parts = [];
|
||||||
|
foreach ($denoms as $key => $d) {
|
||||||
|
$n = (int) ($cd[$key] ?? 0);
|
||||||
|
if ($n > 0) {
|
||||||
|
$parts[] = $d['label'] . ':' . $n; // 只列有收到的幣別
|
||||||
|
$received += $n * $d['unit'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($parts)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return '收:' . $received . '(' . implode('、', $parts) . ') 找:' . number_format($this->change_amount, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取得所有支付類型的對照標籤
|
* 取得所有支付類型的對照標籤
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -71,6 +71,8 @@ class TransactionService
|
|||||||
'discount_amount' => $data['discount_amount'] ?? 0,
|
'discount_amount' => $data['discount_amount'] ?? 0,
|
||||||
'pay_amount' => $data['pay_amount'],
|
'pay_amount' => $data['pay_amount'],
|
||||||
'change_amount' => $data['change_amount'] ?? 0,
|
'change_amount' => $data['change_amount'] ?? 0,
|
||||||
|
// 現金面額明細(僅現金 payment_type=9 會帶;其餘為 null)
|
||||||
|
'cash_detail' => $data['cash_detail'] ?? null,
|
||||||
'points_used' => $data['points_used'] ?? 0,
|
'points_used' => $data['points_used'] ?? 0,
|
||||||
'original_amount' => $data['original_amount'] ?? $data['total_amount'],
|
'original_amount' => $data['original_amount'] ?? $data['total_amount'],
|
||||||
'payment_type' => (int) ($data['payment_type'] ?? 0),
|
'payment_type' => (int) ($data['payment_type'] ?? 0),
|
||||||
@ -124,6 +126,8 @@ class TransactionService
|
|||||||
'original_amount' => $data['original_amount'] ?? $order->original_amount,
|
'original_amount' => $data['original_amount'] ?? $order->original_amount,
|
||||||
'discount_amount' => $data['discount_amount'] ?? $order->discount_amount,
|
'discount_amount' => $data['discount_amount'] ?? $order->discount_amount,
|
||||||
'change_amount' => $data['change_amount'] ?? $order->change_amount,
|
'change_amount' => $data['change_amount'] ?? $order->change_amount,
|
||||||
|
// 現金面額明細:completed finalize 才帶(pending 階段無投幣結果)
|
||||||
|
'cash_detail' => $data['cash_detail'] ?? $order->cash_detail,
|
||||||
'points_used' => $data['points_used'] ?? $order->points_used,
|
'points_used' => $data['points_used'] ?? $order->points_used,
|
||||||
'invoice_info' => $data['invoice_info'] ?? $order->invoice_info,
|
'invoice_info' => $data['invoice_info'] ?? $order->invoice_info,
|
||||||
'delivery_status' => isset($data['delivery_status'])
|
'delivery_status' => isset($data['delivery_status'])
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 現金支付面額明細:orders 增加 cash_detail JSON 欄位。
|
||||||
|
* 記錄本筆現金交易「收」進的各面額張數(仟/伍佰/佰/50/10/5/1),
|
||||||
|
* 供銷售紀錄在支付金額下方顯示「收:仟:x、伍佰:x… 找:x」。
|
||||||
|
* 找零金額沿用既有 change_amount,不另存。
|
||||||
|
* 僅現金(payment_type=9)交易會帶此欄,其餘交易為 null,不影響既有行為。
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('orders', function (Blueprint $table) {
|
||||||
|
if (!Schema::hasColumn('orders', 'cash_detail')) {
|
||||||
|
$table->json('cash_detail')->nullable()
|
||||||
|
->comment('現金收款面額明細 {b1000,b500,b100,c50,c10,c5,c1}')
|
||||||
|
->after('change_amount');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('orders', function (Blueprint $table) {
|
||||||
|
if (Schema::hasColumn('orders', 'cash_detail')) {
|
||||||
|
$table->dropColumn('cash_detail');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -285,6 +285,11 @@
|
|||||||
{{ __('Discounted') }} ${{ number_format($order->discount_amount, 0) }}
|
{{ __('Discounted') }} ${{ number_format($order->discount_amount, 0) }}
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
|
@if($order->cash_received_summary)
|
||||||
|
<span class="text-[10px] text-emerald-600 dark:text-emerald-400 font-bold mt-1 tracking-tight leading-relaxed">
|
||||||
|
{{ $order->cash_received_summary }}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
@if((int) $order->payment_type === 6 && !empty($order->member_barcode))
|
@if((int) $order->payment_type === 6 && !empty($order->member_barcode))
|
||||||
{{-- 取貨碼交易:於支付金額欄換行加註取貨碼序號 --}}
|
{{-- 取貨碼交易:於支付金額欄換行加註取貨碼序號 --}}
|
||||||
<span class="text-[10px] font-black text-cyan-600 dark:text-cyan-400 mt-1.5 flex items-center gap-1">
|
<span class="text-[10px] font-black text-cyan-600 dark:text-cyan-400 mt-1.5 flex items-center gap-1">
|
||||||
@ -468,6 +473,11 @@
|
|||||||
<span class="text-[10px] px-1.5 py-0.5 rounded bg-slate-100 dark:bg-slate-800/50 text-slate-500">{{
|
<span class="text-[10px] px-1.5 py-0.5 rounded bg-slate-100 dark:bg-slate-800/50 text-slate-500">{{
|
||||||
$paymentTypes[$order->payment_type] ?? '??' }}</span>
|
$paymentTypes[$order->payment_type] ?? '??' }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
@if($order->cash_received_summary)
|
||||||
|
<div class="text-[10px] text-emerald-600 dark:text-emerald-400 font-bold mt-1 leading-relaxed">
|
||||||
|
{{ $order->cash_received_summary }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
@if($order->payment_type == 41 && $order->staffCardLog && $order->staffCardLog->staffCard)
|
@if($order->payment_type == 41 && $order->staffCardLog && $order->staffCardLog->staffCard)
|
||||||
<div class="text-[10px] text-cyan-600 dark:text-cyan-400 font-extrabold mt-1 flex items-center gap-1">
|
<div class="text-[10px] text-cyan-600 dark:text-cyan-400 font-extrabold mt-1 flex items-center gap-1">
|
||||||
<svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
<svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user