修复BUG
This commit is contained in:
@@ -137,7 +137,7 @@ class ExportTest extends ProcurementTestCase
|
||||
return [PurchaseOrderModel::first(), $veg, $meat, $storeA, $storeB, $supplierA, $supplierB];
|
||||
}
|
||||
|
||||
/** 商品明细导出:含系统全部商品行(无订货数量 0)+ 行列合计 + 参考零售价列 */
|
||||
/** 商品明细导出:含系统全部商品行(无订货数量 0)+ 行列合计 + 单价列 */
|
||||
public function test_export_lists_all_catalog_products_with_totals_row(): void
|
||||
{
|
||||
[$purchase, $veg, $meat, $storeA, $storeB] = $this->buildPurchaseWithSuppliers();
|
||||
@@ -156,12 +156,12 @@ class ExportTest extends ProcurementTestCase
|
||||
if ($rows->count() !== 8) {
|
||||
return false;
|
||||
}
|
||||
// 列头含市场/参考零售价与门店列(市场列在供应商后,门店列从索引 12 起)
|
||||
// 列头含市场/单价与门店列(市场列在供应商后,门店列从索引 12 起)
|
||||
$header = $rows[3];
|
||||
if ($header[4] !== '市场' || $header[8] !== '参考零售价' || $header[12] !== $storeA->name || $header[13] !== $storeB->name) {
|
||||
if ($header[4] !== '市场' || $header[8] !== '单价' || $header[12] !== $storeA->name || $header[13] !== $storeB->name) {
|
||||
return false;
|
||||
}
|
||||
// 蔬菜行:市场 新发地、数量 2+3=5、金额 25、参考零售价 5÷10=0.50、门店列 2/3
|
||||
// 蔬菜行:市场 新发地、数量 2+3=5、金额 25、单价 5÷10=0.50、门店列 2/3
|
||||
$vegRow = $rows->firstWhere(2, $veg->name);
|
||||
if ($vegRow === null
|
||||
|| $vegRow[4] !== '新发地'
|
||||
@@ -170,7 +170,7 @@ class ExportTest extends ProcurementTestCase
|
||||
|| (float) $vegRow[12] !== 2.0 || (float) $vegRow[13] !== 3.0) {
|
||||
return false;
|
||||
}
|
||||
// 无订货商品行:数量 0、参考零售价留空、门店列 0
|
||||
// 无订货商品行:数量 0、单价留空、门店列 0
|
||||
$extraRow = $rows->firstWhere(2, $extra->name);
|
||||
if ($extraRow === null
|
||||
|| (float) $extraRow[9] !== 0.0 || $extraRow[8] !== ''
|
||||
@@ -277,10 +277,10 @@ class ExportTest extends ProcurementTestCase
|
||||
->assertJsonPath('msg', '该门店在此采购单中无采购商品');
|
||||
}
|
||||
|
||||
/** 供应商采购明细导出:多供应商合并一个 XLSX(工作表名=供应商名),按供应商聚合 */
|
||||
/** 供应商采购明细导出:按「供应商×市场」拆分工作表,模板列序=品名/汇总/市场/各门店明细 */
|
||||
public function test_export_suppliers_multi_sheet(): void
|
||||
{
|
||||
[$purchase, $veg, $meat, , , $supplierA, $supplierB] = $this->buildPurchaseWithSuppliers();
|
||||
[$purchase, $veg, $meat, $storeA, $storeB, $supplierA, $supplierB] = $this->buildPurchaseWithSuppliers();
|
||||
|
||||
Excel::fake();
|
||||
$this->actingAsSysUser();
|
||||
@@ -288,37 +288,103 @@ class ExportTest extends ProcurementTestCase
|
||||
|
||||
Excel::assertDownloaded(
|
||||
$purchase->purchase_no . '_供应商采购明细.xlsx',
|
||||
static function (PurchaseSupplierExport $export) use ($supplierA, $supplierB, $veg, $meat): bool {
|
||||
static function (PurchaseSupplierExport $export) use ($supplierA, $supplierB, $veg, $meat, $storeA, $storeB): bool {
|
||||
$sheets = $export->sheets();
|
||||
if (count($sheets) !== 2) {
|
||||
return false;
|
||||
}
|
||||
$titles = array_map(static fn ($sheet) => $sheet->title(), $sheets);
|
||||
if ($titles !== [$supplierA->name, $supplierB->name]) {
|
||||
if ($titles !== [$supplierA->name . '·新发地', $supplierB->name . '·岳各庄']) {
|
||||
return false;
|
||||
}
|
||||
// 供应商甲:蔬菜 2+3=5 件、金额 5×5=25(市场列在品名后)
|
||||
// 供应商甲·新发地:蔬菜 2+3=5 件;门店列=有该供应商明细的两家门店
|
||||
$rowsA = $sheets[0]->collection()->values();
|
||||
if ($rowsA[2] !== ['序号', '品名', '市场', '包规', '单位', '成本价', '数量', '重量(斤)', '金额']) {
|
||||
if ($rowsA[2] !== ['品名', '汇总', '市场', $storeA->name, $storeB->name]) {
|
||||
return false;
|
||||
}
|
||||
$vegRow = $rowsA->firstWhere(1, $veg->name);
|
||||
if ($vegRow === null || $vegRow[2] !== '新发地' || (int) $vegRow[6] !== 5 || (float) $vegRow[8] !== 25.0) {
|
||||
$vegRow = $rowsA->firstWhere(0, $veg->name);
|
||||
if ($vegRow === null || (int) $vegRow[1] !== 5 || $vegRow[2] !== '新发地'
|
||||
|| (int) $vegRow[3] !== 2 || (int) $vegRow[4] !== 3) {
|
||||
return false;
|
||||
}
|
||||
$totalA = $rowsA->last();
|
||||
if ($totalA[1] !== '合计' || (int) $totalA[6] !== 5 || (float) $totalA[8] !== 25.0) {
|
||||
if ($totalA[0] !== '合计' || (int) $totalA[1] !== 5 || (int) $totalA[3] !== 2 || (int) $totalA[4] !== 3) {
|
||||
return false;
|
||||
}
|
||||
// 供应商乙:肉 1 件、金额 20
|
||||
// 供应商乙·岳各庄:肉 1 件;门店列仅门店A
|
||||
$rowsB = $sheets[1]->collection()->values();
|
||||
$meatRow = $rowsB->firstWhere(1, $meat->name);
|
||||
return $meatRow !== null && $meatRow[2] === '岳各庄' && (int) $meatRow[6] === 1 && (float) $meatRow[8] === 20.0;
|
||||
if ($rowsB[2] !== ['品名', '汇总', '市场', $storeA->name]) {
|
||||
return false;
|
||||
}
|
||||
$meatRow = $rowsB->firstWhere(0, $meat->name);
|
||||
return $meatRow !== null && (int) $meatRow[1] === 1 && $meatRow[2] === '岳各庄' && (int) $meatRow[3] === 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 供应商采购明细导出:单供应商导出 + 无明细供应商拒绝 */
|
||||
/** 供应商采购明细导出:同一供应商多个市场拆分为多个工作表(空市场归入「未设置」) */
|
||||
public function test_export_suppliers_split_by_market(): void
|
||||
{
|
||||
$supplier = SupplierModel::factory()->create();
|
||||
$level = CustomerLevelModel::factory()->create();
|
||||
$store = StoreModel::factory()->create(['level_id' => $level->id]);
|
||||
$vegA = ProductModel::factory()->create([
|
||||
'status' => ProductModel::STATUS_ON, 'cost_price' => '5.00',
|
||||
'supplier_id' => $supplier->id, 'market' => '新发地',
|
||||
]);
|
||||
$vegB = ProductModel::factory()->create([
|
||||
'status' => ProductModel::STATUS_ON, 'cost_price' => '6.00',
|
||||
'supplier_id' => $supplier->id, 'market' => '岳各庄',
|
||||
]);
|
||||
$vegC = ProductModel::factory()->create([
|
||||
'status' => ProductModel::STATUS_ON, 'cost_price' => '7.00',
|
||||
'supplier_id' => $supplier->id, 'market' => '',
|
||||
]);
|
||||
|
||||
$this->actingAsMiniStore($store);
|
||||
$this->postJson('/mini/order', ['items' => [
|
||||
['product_id' => $vegA->id, 'quantity' => 1],
|
||||
['product_id' => $vegB->id, 'quantity' => 1],
|
||||
['product_id' => $vegC->id, 'quantity' => 1],
|
||||
]])->assertJsonPath('success', true);
|
||||
|
||||
StoreOrderModel::query()->update(['status' => StoreOrderModel::STATUS_SUMMARIZED]);
|
||||
$this->actingAsSysUser();
|
||||
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
|
||||
->assertJsonPath('success', true);
|
||||
$purchase = PurchaseOrderModel::first();
|
||||
|
||||
Excel::fake();
|
||||
$this->get("/purchase/order/{$purchase->id}/exportSuppliers?supplier_id={$supplier->id}")->assertOk();
|
||||
|
||||
Excel::assertDownloaded(
|
||||
$purchase->purchase_no . '_供应商采购明细_' . $supplier->name . '.xlsx',
|
||||
static function (PurchaseSupplierExport $export) use ($supplier, $vegA, $vegB, $vegC): bool {
|
||||
$sheets = $export->sheets();
|
||||
$titles = array_map(static fn ($sheet) => $sheet->title(), $sheets);
|
||||
sort($titles);
|
||||
if ($titles !== [$supplier->name . '·岳各庄', $supplier->name . '·新发地', $supplier->name . '·未设置']) {
|
||||
return false;
|
||||
}
|
||||
// 每个工作表仅含本市场商品
|
||||
foreach ($sheets as $sheet) {
|
||||
$rows = $sheet->collection()->values();
|
||||
$names = $rows->slice(3, -1)->map(static fn ($row) => $row[0])->values()->all();
|
||||
$expected = match (true) {
|
||||
str_ends_with($sheet->title(), '新发地') => [$vegA->name],
|
||||
str_ends_with($sheet->title(), '岳各庄') => [$vegB->name],
|
||||
default => [$vegC->name],
|
||||
};
|
||||
if ($names !== $expected) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 供应商采购明细导出:单供应商导出(工作表名=供应商·市场) + 无明细供应商拒绝 */
|
||||
public function test_export_suppliers_single(): void
|
||||
{
|
||||
[$purchase, , , , , , $supplierB] = $this->buildPurchaseWithSuppliers();
|
||||
@@ -331,7 +397,7 @@ class ExportTest extends ProcurementTestCase
|
||||
$purchase->purchase_no . '_供应商采购明细_' . $supplierB->name . '.xlsx',
|
||||
static function (PurchaseSupplierExport $export) use ($supplierB): bool {
|
||||
$sheets = $export->sheets();
|
||||
return count($sheets) === 1 && $sheets[0]->title() === $supplierB->name;
|
||||
return count($sheets) === 1 && $sheets[0]->title() === $supplierB->name . '·岳各庄';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user