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(), '第二次生成应被拒绝,不产生新采购单'); } }