first version

This commit is contained in:
liu
2026-07-23 20:41:25 +08:00
parent 00a0938a1b
commit 10cff754a4
211 changed files with 11577 additions and 842 deletions
+102
View File
@@ -0,0 +1,102 @@
<?php
namespace Tests\Feature;
use App\Models\CustomerLevelModel;
use App\Models\ProductModel;
use App\Models\ProductPriceModel;
use App\Models\PurchaseOrderModel;
use App\Models\StoreModel;
use App\Models\StoreOrderModel;
use App\Models\UserModel;
/**
* C1 订单汇总生成采购单:多门店聚合、订单状态回写、无订单/重复生成防护
*/
class PurchaseGenerateTest extends ProcurementTestCase
{
/**
* 造当日待汇总订单:门店A 两单各 3 件 + 门店B 一单 4 件(同一商品)
* 商品设两个等级价 5.00 / 4.00,估算单价应取最低 4.00
*/
private function seedPendingOrders(): ProductModel
{
$level = CustomerLevelModel::factory()->create();
$levelLow = CustomerLevelModel::factory()->create();
$storeA = StoreModel::factory()->create(['level_id' => $level->id]);
$storeB = 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]);
ProductPriceModel::factory()->create(['product_id' => $product->id, 'level_id' => $levelLow->id, 'price' => 4.00]);
foreach ([[$storeA, 3], [$storeA, 3], [$storeB, 4]] as [$store, $qty]) {
$this->actingAsMiniUser(UserModel::factory()->forStore($store->id)->create());
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => $qty]]])
->assertJsonPath('success', true);
}
return $product;
}
/** 多门店多订单按商品聚合,估算单价取最低等级价 */
public function test_generate_aggregates_orders_by_product(): void
{
$this->seedPendingOrders();
$admin = $this->actingAsSysUser();
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertOk()
->assertJsonPath('success', true);
$purchase = PurchaseOrderModel::first();
$this->assertNotNull($purchase);
$this->assertStringStartsWith('PO', $purchase->purchase_no);
$this->assertSame(now()->toDateString(), $purchase->purchase_date->toDateString());
$this->assertSame($admin->id, $purchase->operator_id);
$this->assertSame(PurchaseOrderModel::STATUS_PENDING, $purchase->status);
$this->assertCount(1, $purchase->items, '单一商品应聚合为一行');
$item = $purchase->items->first();
$this->assertSame('10.00', (string) $item->quantity, '3+3+4');
$this->assertSame('4.00', (string) $item->price, '估算单价取最低等级价');
$this->assertSame('40.00', (string) $item->amount, '10 × 4.00');
$this->assertSame('40.00', (string) $purchase->estimate_amount);
}
/** 源订单状态回写为已汇总 */
public function test_generate_writes_back_order_status(): void
{
$this->seedPendingOrders();
$this->actingAsSysUser();
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertJsonPath('success', true);
$this->assertSame(0, StoreOrderModel::where('status', StoreOrderModel::STATUS_PENDING)->count());
$this->assertSame(3, StoreOrderModel::where('status', StoreOrderModel::STATUS_SUMMARIZED)->count());
}
/** 当日无待汇总订单 → 报错 */
public function test_generate_without_pending_orders_fails(): void
{
$this->actingAsSysUser();
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertJsonPath('success', false);
$this->assertSame(0, PurchaseOrderModel::count());
}
/** 幂等:已汇总订单不会被重复归集 */
public function test_generate_is_idempotent(): void
{
$this->seedPendingOrders();
$this->actingAsSysUser();
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertJsonPath('success', true);
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertJsonPath('success', false);
$this->assertSame(1, PurchaseOrderModel::count(), '第二次生成应被拒绝,不产生新采购单');
}
}