修复一些错误

This commit is contained in:
liu
2026-08-14 21:28:55 +08:00
parent 398bb98356
commit 228212f8e3
20 changed files with 489 additions and 100 deletions
+209
View File
@@ -0,0 +1,209 @@
<?php
namespace Tests\Feature;
use App\Models\BillModel;
use App\Models\CustomerLevelModel;
use App\Models\PaymentModel;
use App\Models\ProductModel;
use App\Models\ProductPriceModel;
use App\Models\PurchaseOrderModel;
use App\Models\StoreModel;
use App\Models\StoreOrderModel;
use App\Models\UserModel;
/**
* 账单链路与支付:订单状态随业务链自动推进(采购单完成→配送中、生成账单→已完成);
* 账单支付后累加门店总采购金额(只统计商品金额,手动收款与支付审核双入口)
*/
class BillPaymentTest extends ProcurementTestCase
{
/**
* 完整业务链造账单:下单 → 接单 → 生成采购单 → 完成采购单 → 生成账单
* (商品 5.00 × 4 = 商品金额 20.00,配送费/筐/托盘均 0)
*
* @return array{0: StoreModel, 1: StoreOrderModel, 2: BillModel}
*/
private function makeBillViaChain(): array
{
$level = CustomerLevelModel::factory()->create();
$store = StoreModel::factory()->create(['level_id' => $level->id]);
$product = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON]);
ProductPriceModel::factory()->create([
'product_id' => $product->id,
'level_id' => $level->id,
'price' => '5.00',
]);
$user = UserModel::factory()->forStore($store->id)->create();
$this->actingAsMiniUser($user);
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 4]]])
->assertJsonPath('success', true);
$order = StoreOrderModel::where('store_id', $store->id)->first();
$this->actingAsSysUser();
// 接单
$this->putJson("/order/store/{$order->id}/status", ['status' => StoreOrderModel::STATUS_SUMMARIZED])
->assertJsonPath('success', true);
// 生成采购单 → 采购中
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertJsonPath('success', true);
$purchase = PurchaseOrderModel::first();
// 完成采购单 → 配送中
$this->putJson("/purchase/order/{$purchase->id}/finish")->assertJsonPath('success', true);
// 生成账单 → 已完成
$this->postJson("/purchase/order/{$purchase->id}/bill", [
'stores' => [['store_id' => $store->id, 'delivery_fee' => 0, 'box_num' => 0, 'tray_num' => 0]],
])->assertJsonPath('success', true);
return [$store, $order->fresh(), BillModel::where('store_id', $store->id)->first()];
}
/** 造一张指定商品金额的未支付账单(总额=商品金额) */
private function makeBill(StoreModel $store, string $productAmount, array $attributes = []): BillModel
{
return BillModel::create(array_merge([
'bill_no' => 'ZD' . random_int(100000000000, 999999999999),
'purchase_id' => PurchaseOrderModel::factory()->create()->id,
'store_id' => $store->id,
'bill_date' => '2026-08-10',
'product_amount' => $productAmount,
'delivery_fee' => '0.00',
'box_num' => 0,
'tray_num' => 0,
'box_price' => '0.00',
'tray_price' => '0.00',
'added_amount' => '0.00',
'total_amount' => $productAmount,
'status' => BillModel::STATUS_UNPAID,
], $attributes));
}
/** 订单状态随业务链自动推进:接单→采购中→配送中→(生成账单)已完成 */
public function test_order_status_progresses_via_business_chain(): void
{
$level = CustomerLevelModel::factory()->create();
$store = StoreModel::factory()->create(['level_id' => $level->id]);
$product = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON]);
ProductPriceModel::factory()->create(['product_id' => $product->id, 'level_id' => $level->id, 'price' => '5.00']);
$user = UserModel::factory()->forStore($store->id)->create();
$this->actingAsMiniUser($user);
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 4]]])
->assertJsonPath('success', true);
$order = StoreOrderModel::where('store_id', $store->id)->first();
$this->assertSame(StoreOrderModel::STATUS_PENDING, $order->status);
$this->actingAsSysUser();
// 接单 → 已接单
$this->putJson("/order/store/{$order->id}/status", ['status' => StoreOrderModel::STATUS_SUMMARIZED])
->assertJsonPath('success', true);
$this->assertSame(StoreOrderModel::STATUS_SUMMARIZED, $order->fresh()->status);
// 生成采购单 → 采购中
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertJsonPath('success', true);
$purchase = PurchaseOrderModel::first();
$order->refresh();
$this->assertSame(StoreOrderModel::STATUS_DELIVERING, $order->status);
$this->assertSame($purchase->id, $order->purchase_id);
// 完成采购单 → 配送中
$this->putJson("/purchase/order/{$purchase->id}/finish")->assertJsonPath('success', true);
$this->assertSame(StoreOrderModel::STATUS_DISTRIBUTION, $order->fresh()->status);
// 生成账单 → 已完成 + 回写 bill_id
$this->postJson("/purchase/order/{$purchase->id}/bill", [
'stores' => [['store_id' => $store->id, 'delivery_fee' => 0, 'box_num' => 0, 'tray_num' => 0]],
])->assertJsonPath('success', true);
$order->refresh();
$bill = BillModel::where('store_id', $store->id)->first();
$this->assertNotNull($bill);
$this->assertSame(StoreOrderModel::STATUS_COMPLETED, $order->status);
$this->assertSame($bill->id, $order->bill_id);
$this->assertSame('20.00', (string) $bill->product_amount, '5.00 × 4');
}
/** 后台手动确认收款:累加门店总采购金额(只统计商品金额),重复收款拒绝不重复累加 */
public function test_manual_pay_accumulates_store_total_purchase_amount(): void
{
[$store, , $bill] = $this->makeBillViaChain();
$this->actingAsSysUser();
$this->putJson("/recon/bill/{$bill->id}/pay", ['pay_remark' => '线下现金'])
->assertJsonPath('success', true);
$store->refresh();
$this->assertSame('20.00', (string) $store->total_purchase_amount, '只累加商品金额 20.00');
// 第二笔账单收款后继续累加
$bill2 = $this->makeBill($store, '100.00');
$this->putJson("/recon/bill/{$bill2->id}/pay")->assertJsonPath('success', true);
$this->assertSame('120.00', (string) $store->fresh()->total_purchase_amount);
// 重复收款拒绝,金额不重复累加
$this->putJson("/recon/bill/{$bill->id}/pay")->assertJsonPath('success', false);
$this->assertSame('120.00', (string) $store->fresh()->total_purchase_amount);
}
/** 支付审核通过:关联账单置已支付并累加门店总采购金额 */
public function test_payment_audit_pass_accumulates_store_total_purchase_amount(): void
{
$store = StoreModel::factory()->create();
$user = UserModel::factory()->forStore($store->id)->create();
$payment = PaymentModel::create([
'payment_no' => 'ZF202608140001',
'store_id' => $store->id,
'user_id' => $user->id,
'amount' => '150.00',
'pay_method' => PaymentModel::METHOD_BANK,
'voucher_ids' => '',
'status' => PaymentModel::STATUS_PENDING,
]);
$bill1 = $this->makeBill($store, '100.00', ['payment_id' => $payment->id]);
$bill2 = $this->makeBill($store, '50.00', ['payment_id' => $payment->id]);
$this->actingAsSysUser();
$this->putJson("/recon/payment/{$payment->id}/audit", ['result' => 'pass'])
->assertJsonPath('success', true);
$this->assertSame(BillModel::STATUS_PAID, $bill1->fresh()->status);
$this->assertSame(BillModel::STATUS_PAID, $bill2->fresh()->status);
$this->assertSame('150.00', (string) $store->fresh()->total_purchase_amount);
// 重复审核拒绝,不重复累加
$this->putJson("/recon/payment/{$payment->id}/audit", ['result' => 'pass'])
->assertJsonPath('success', false);
$this->assertSame('150.00', (string) $store->fresh()->total_purchase_amount);
}
/** 审核拒绝:账单释放回待支付,不累加门店总采购金额 */
public function test_payment_audit_reject_does_not_accumulate(): void
{
$store = StoreModel::factory()->create();
$user = UserModel::factory()->forStore($store->id)->create();
$payment = PaymentModel::create([
'payment_no' => 'ZF202608140002',
'store_id' => $store->id,
'user_id' => $user->id,
'amount' => '100.00',
'pay_method' => PaymentModel::METHOD_WECHAT,
'voucher_ids' => '',
'status' => PaymentModel::STATUS_PENDING,
]);
$bill = $this->makeBill($store, '100.00', ['payment_id' => $payment->id]);
$this->actingAsSysUser();
$this->putJson("/recon/payment/{$payment->id}/audit", [
'result' => 'reject',
'audit_remark' => '凭证不清晰',
])->assertJsonPath('success', true);
$bill->refresh();
$this->assertSame(BillModel::STATUS_UNPAID, $bill->status);
$this->assertSame(0, $bill->payment_id, '账单释放可重新付款');
$this->assertSame('0.00', (string) $store->fresh()->total_purchase_amount);
}
}