user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $this->createQuote(); $this->loginAs() ->get(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => 'quote-management', 'quote_view' => 'warehouse', ])) ->assertOk() ->assertSeeText('快递报价') ->assertSeeText('仓储报价') ->assertSeeText('录入新报价') ->assertSeeText('南昌樵舍仓') ->assertSeeText('入库管理费(元/吨)') ->assertSeeText('出库费(元/单)') ->assertSeeText('每托折算件数(件/托)') ->assertSeeText('每托占地面积(㎡/托)') ->assertSeeText('仓储面积单价(元/㎡·月)') ->assertSeeText('Σ(普通商品资料重量kg ÷ 1000 ×(加工进仓+加工出仓+采购进仓+采购退货+其它退货+销售退货+盘点+调拨入))× 入库管理费单价') ->assertSeeText('Σ(销售出仓 + 其它出库 + 调拨出)× 出库费单价') ->assertSeeText('系统数据为唯一核算来源,不读取仓库提供、核对或差异列') ->assertSeeText($this->user->name) ->assertSee('data-quote-panel="warehouse"', false) ->assertDontSee('wire:click="calculateStorageFee"', false) ->assertDontSee('warehouse-settle-period', false); } public function test_warehouse_quote_store_creates_a_new_effective_version(): void { $this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $this->loginAs(); $existing = $this->createQuote(); Livewire::test(WarehouseQuoteComponent::class) ->set('warehouseName', '南昌樵舍仓') ->set('inboundRatePerTon', '22.5') ->set('outboundRatePerOrder', '0.9') ->set('piecesPerPallet', '24') ->set('palletAreaSqm', '3.2') ->set('storageRatePerSqmMonth', '11') ->set('effectiveAt', '2026-09-01') ->set('remark', '九月新报价') ->call('save') ->assertHasNoErrors() ->assertSet('message', '仓储报价已保存,新报价不会覆盖历史版本。'); $this->assertDatabaseCount('business_third_party_warehouse_quotes', 2); $this->assertDatabaseHas('business_third_party_warehouse_quotes', [ 'company_id' => company_id(), 'warehouse_name' => '南昌樵舍仓', 'inbound_rate_per_ton' => 22.5, 'outbound_rate_per_order' => 0.9, 'pieces_per_pallet' => 24, 'pallet_area_sqm' => 3.2, 'storage_rate_per_sqm_month' => 11, 'effective_at' => '2026-09-01', 'status' => ThirdPartyWarehouseQuote::STATUS_ACTIVE, 'created_by' => user_id(), ]); $this->assertSame('20.0000', (string) $existing->fresh()->inbound_rate_per_ton); } public function test_warehouse_quote_validation_rejects_zero_divisors(): void { $this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $this->loginAs(); Livewire::test(WarehouseQuoteComponent::class) ->set('piecesPerPallet', '0') ->set('palletAreaSqm', '0') ->call('save') ->assertHasErrors(['piecesPerPallet' => 'gt', 'palletAreaSqm' => 'gt']); } public function test_warehouse_quote_validation_rejects_a_blank_warehouse_name(): void { $this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $this->loginAs(); Livewire::test(WarehouseQuoteComponent::class) ->set('warehouseName', ' ') ->call('save') ->assertHasErrors(['warehouseName' => 'required']); $this->assertDatabaseCount('business_third_party_warehouse_quotes', 0); } public function test_quote_status_action_is_company_scoped(): void { $this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $quote = ThirdPartyWarehouseQuote::withoutGlobalScopes()->create([ 'company_id' => company_id() + 999, 'warehouse_name' => '其他公司仓库', 'inbound_rate_per_ton' => 20, 'outbound_rate_per_order' => 0.85, 'pieces_per_pallet' => 23, 'pallet_area_sqm' => 3, 'storage_rate_per_sqm_month' => 10.5, 'effective_at' => '2026-08-01', 'status' => ThirdPartyWarehouseQuote::STATUS_ACTIVE, ]); $this->loginAs(); $this->expectException(ModelNotFoundException::class); Livewire::test(WarehouseQuoteComponent::class) ->call('setStatus', $quote->id, ThirdPartyWarehouseQuote::STATUS_INACTIVE); } private function createQuote(): ThirdPartyWarehouseQuote { return ThirdPartyWarehouseQuote::query()->create([ 'company_id' => company_id(), 'warehouse_name' => '南昌樵舍仓', 'inbound_rate_per_ton' => 20, 'outbound_rate_per_order' => 0.85, 'pieces_per_pallet' => 23, 'pallet_area_sqm' => 3, 'storage_rate_per_sqm_month' => 10.5, 'effective_at' => '2026-08-01', 'status' => ThirdPartyWarehouseQuote::STATUS_ACTIVE, 'remark' => '八月合同报价', 'created_by' => $this->user->id, 'updated_by' => $this->user->id, ]); } }