CaiWuXiTong/tests/Feature/Business/SupplierPayableFinalPagesTest.php
renshen 3e1d211d1b 应付款终版退货对账:新增「wms配货单号/创建人」列并去掉「快递名称」 (#352)
「备注」后插入 wms配货单号,末尾补创建人,删除快递名称列;导入模板/表格/导入/编辑/导出同一套字段,只作用于终版目录。
2026-10-16 21:23:25 +08:00

317 lines
15 KiB
PHP

<?php
namespace Tests\Feature\Business;
use App\Models\Auth\Permission;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Tests\Feature\FeatureTestCase;
class SupplierPayableFinalPagesTest extends FeatureTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->user->attachPermission(
Permission::where('name', 'read-admin-panel')->firstOrFail()
);
}
public function test_final_table_page_keeps_the_maintenance_toolbar_and_starts_empty(): void
{
$this->loginAs()
->get(route('business.pages.show', [
'section' => 'supplier-payables-final',
'page' => 'board-deductions',
]))
->assertOk()
->assertSeeText('导入')
->assertSeeText('导出')
->assertSeeText('查询')
->assertSeeText('重置')
->assertSeeText('编辑')
->assertSeeText('下载导入模板')
->assertSeeText('月份')
->assertSeeText('入库日期')
->assertSeeText('申领单号')
->assertSeeText('暂无数据,请点击“导入”上传本表数据。')
->assertSee('workspace/supplier-payables-final/actions/board-deductions/import', false)
->assertSee('workspace/supplier-payables-final/actions/board-deductions/template', false)
// 导入/编辑弹窗的行内脚本必须随页面输出,局部替换导航才不会出现“点了没反应”。
->assertSee('data-supplier-import-modal', false)
->assertSee('data-supplier-import-choose', false)
->assertSee('modal.dataset.ready', false)
->assertSee('data-supplier-maintenance-modal', false)
// 页签是局部替换导航,弹窗脚本要带 replay 标记,替换后才会重新执行并绑定。
->assertSee('data-caiwu-replay', false)
->assertDontSee('workspace/supplier-payables/actions/board-deductions/import', false);
}
public function test_final_template_downloads_the_same_columns(): void
{
$response = $this->loginAs()
->get(route('business.supplier-payables-final.board-deductions.template'))
->assertOk()
->assertHeader('content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$path = tempnam(sys_get_temp_dir(), 'caiwu-template') . '.xlsx';
try {
file_put_contents($path, $response->streamedContent());
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);
$header = $spreadsheet->getSheet(0)->rangeToArray('A1:C1')[0];
$notes = $spreadsheet->getSheet(1)->rangeToArray('A2:B2')[0];
$spreadsheet->disconnectWorksheets();
$this->assertSame(['记录标识', '月份', '入库日期'], $header);
$this->assertSame('记录标识', $notes[0]);
$this->assertStringContainsString('选填', (string) $notes[1]);
} finally {
@unlink($path);
}
}
public function test_final_payment_reconciliation_template_keeps_the_extra_columns_in_order(): void
{
$response = $this->loginAs()
->get(route('business.supplier-payables-final.payment-reconciliation.template'))
->assertOk()
->assertHeader('content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$path = tempnam(sys_get_temp_dir(), 'caiwu-template') . '.xlsx';
try {
file_put_contents($path, $response->streamedContent());
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);
$header = $spreadsheet->getSheet(0)->rangeToArray('A1:T1')[0];
$spreadsheet->disconnectWorksheets();
$this->assertSame([
'记录标识', '月份', '入库单号', '采购单号', '供应商', '货号', '商品编码', '规格名称', '数量', '单价',
'金额', '预估单价', '预估金额', '供应商商品编码', '备注', '仓库名称', '快递名称', '快递单号',
'未发出', '对账人',
], $header);
} finally {
@unlink($path);
}
}
public function test_final_payment_reconciliation_import_keeps_the_extra_columns(): void
{
$file = UploadedFile::fake()->createWithContent(
'payment-reconciliation.csv',
"\xEF\xBB\xBF月份,入库单号,采购单号,供应商,货号,商品编码,规格名称,数量,单价,金额,预估单价,预估金额,供应商商品编码,备注,仓库名称,快递名称,快递单号,未发出,对账人\n"
. "2026-09,RK-1,CG-1,终版供应商,X-1,P-1,规格甲,2,10,20,9,18,SC-1,备注甲,华东仓,顺丰,SF-1,未发出,对账人甲\n",
);
$this->loginAs()
->post(route('business.supplier-payables-final.payment-reconciliation.import'), ['import' => $file])
->assertStatus(302)
->assertSessionHas('success', '导入完成:新增 1 条,更新 0 条。');
$this->assertDatabaseHas('supplier_payable_overrides', [
'company_id' => $this->company->id,
'dataset' => 'final:supplier:payment-reconciliation',
]);
$this->loginAs()
->get(route('business.pages.show', [
'section' => 'supplier-payables-final',
'page' => 'payment-reconciliation',
]))
->assertOk()
->assertSeeText('入库单号')
->assertSeeText('采购单号')
->assertSeeText('对账人')
->assertSeeText('RK-1')
->assertSeeText('CG-1')
->assertSeeText('未发出')
->assertSeeText('对账人甲')
->assertSeeText('SF-1');
$export = $this->loginAs()->get(route('business.supplier-payables-final.payment-reconciliation.export'));
$export->assertOk();
$this->assertStringContainsString('快递单号,未发出,对账人', $export->streamedContent());
}
public function test_final_return_reconciliation_template_adds_wms_and_creator_columns(): void
{
$response = $this->loginAs()
->get(route('business.supplier-payables-final.return-reconciliation.template'))
->assertOk()
->assertHeader('content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$path = tempnam(sys_get_temp_dir(), 'caiwu-template') . '.xlsx';
try {
file_put_contents($path, $response->streamedContent());
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);
$header = $spreadsheet->getSheet(0)->rangeToArray('A1:T1')[0];
$spreadsheet->disconnectWorksheets();
$this->assertSame([
'记录标识', '月份', '发货时间', '明细供应商', '条形码', '商品名称', '发货量', '单价', '金额', '预估单价',
'预估金额', '供应商条码', '备注', 'wms配货单号', '标题', '仓库名称', '快递单号', '标记多标签', '对账人', '创建人',
], $header);
$this->assertNotContains('快递名称', $header);
} finally {
@unlink($path);
}
}
public function test_final_return_reconciliation_import_keeps_wms_and_creator_columns(): void
{
$file = UploadedFile::fake()->createWithContent(
'return-reconciliation.csv',
"\xEF\xBB\xBF月份,发货时间,明细供应商,条形码,商品名称,发货量,单价,金额,预估单价,预估金额,供应商条码,备注,wms配货单号,标题,仓库名称,快递单号,标记多标签,对账人,创建人\n"
. "2026-09,2026-09-01,退货供应商,BC-1,商品甲,3,10,30,9,27,SB-1,备注甲,WMS-1,标题甲,华南仓,SF-9,多标签,对账人乙,创建人甲\n",
);
$this->loginAs()
->post(route('business.supplier-payables-final.return-reconciliation.import'), ['import' => $file])
->assertStatus(302)
->assertSessionHas('success', '导入完成:新增 1 条,更新 0 条。');
$this->assertDatabaseHas('supplier_payable_overrides', [
'company_id' => $this->company->id,
'dataset' => 'final:supplier:return-reconciliation',
]);
$this->loginAs()
->get(route('business.pages.show', [
'section' => 'supplier-payables-final',
'page' => 'return-reconciliation',
]))
->assertOk()
->assertSeeText('wms配货单号')
->assertSeeText('创建人')
->assertSeeText('WMS-1')
->assertSeeText('创建人甲')
->assertDontSeeText('快递名称');
$export = $this->loginAs()->get(route('business.supplier-payables-final.return-reconciliation.export'));
$export->assertOk();
$this->assertStringContainsString('对账人,创建人', $export->streamedContent());
$this->assertStringNotContainsString('快递名称', $export->streamedContent());
}
public function test_product_price_final_page_reuses_the_price_template_columns(): void
{
$this->loginAs()
->get(route('business.pages.show', [
'section' => 'supplier-payables-final',
'page' => 'product-prices',
]))
->assertOk()
->assertSeeText('商品编码')
->assertSeeText('采购价')
->assertSeeText('京喜限价')
->assertSeeText('暂无数据,请点击“导入”上传本表数据。')
->assertSee('workspace/supplier-payables-final/actions/product-prices/template', false);
$this->loginAs()
->get(route('business.supplier-payables-final.product-prices.template'))
->assertOk()
->assertHeader('content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
}
public function test_import_writes_rows_into_the_final_dataset_only(): void
{
$file = UploadedFile::fake()->createWithContent(
'board-deductions.csv',
"\xEF\xBB\xBF月份,入库日期,出库日期,家具厂,压贴厂,类型,规格,原料名称,实收数量,单价,金额,单位,批次日期,出库单号,出库备注,申领单号,单号类型,送货单号\n"
. "2026-09,2026-09-01,2026-09-02,终版家具厂,终版压贴厂,类型A,规格A,原料A,3,12.5,37.5,张,2026-09-03,OUT-1,备注A,CLM-1,单号,DL-1\n",
);
$this->loginAs()
->post(route('business.supplier-payables-final.board-deductions.import'), ['import' => $file])
->assertStatus(302)
->assertSessionHas('success', '导入完成:新增 1 条,更新 0 条。');
$this->assertDatabaseHas('supplier_payable_overrides', [
'company_id' => $this->company->id,
'dataset' => 'final:supplier:board-deductions',
]);
$this->assertSame(0, DB::connection(config('database.supplier_payable_maintenance_connection'))
->table('supplier_payable_overrides')
->where('company_id', $this->company->id)
->where('dataset', 'board-deductions')
->count());
$this->loginAs()
->get(route('business.pages.show', [
'section' => 'supplier-payables-final',
'page' => 'board-deductions',
]))
->assertOk()
->assertSeeText('2026-09')
->assertSeeText('终版家具厂')
->assertSeeText('CLM-1')
->assertDontSeeText('暂无数据,请点击“导入”上传本表数据。');
}
public function test_final_export_and_edit_work_on_the_imported_rows(): void
{
$file = UploadedFile::fake()->createWithContent(
'board-deductions.csv',
"入库日期,出库日期,家具厂,压贴厂,类型,规格,原料名称,实收数量,单价,金额,单位,批次日期,出库单号,出库备注,申领单号,单号类型,送货单号\n"
. "2026-09-11,2026-09-12,导出家具厂,厂二,类型B,规格B,原料B,1,10,10,张,2026-09-13,OUT-2,备注B,CLM-2,单号,DL-2\n",
);
$this->loginAs()->post(route('business.supplier-payables-final.board-deductions.import'), ['import' => $file])
->assertStatus(302);
$connection = DB::connection(config('database.supplier_payable_maintenance_connection'));
$recordKey = (string) $connection->table('supplier_payable_overrides')
->where('company_id', $this->company->id)
->where('dataset', 'final:supplier:board-deductions')
->value('record_key');
$this->assertStringStartsWith('hash:', $recordKey);
$export = $this->loginAs()->get(route('business.supplier-payables-final.board-deductions.export'));
$export->assertOk();
$this->assertStringContainsString('导出家具厂', $export->streamedContent());
$this->loginAs()
->patch(route('business.supplier-payables-final.board-deductions.update', ['recordKey' => $recordKey]), [
'values' => ['furniture_factory' => '编辑后的家具厂'],
])
->assertStatus(302)
->assertSessionHas('success', '保存成功。');
$this->loginAs()
->get(route('business.pages.show', [
'section' => 'supplier-payables-final',
'page' => 'board-deductions',
]))
->assertOk()
->assertSeeText('编辑后的家具厂');
}
public function test_final_page_keyword_filter_narrows_the_rows(): void
{
$file = UploadedFile::fake()->createWithContent(
'board-deductions.csv',
"入库日期,出库日期,家具厂,压贴厂,类型,规格,原料名称,实收数量,单价,金额,单位,批次日期,出库单号,出库备注,申领单号,单号类型,送货单号\n"
. "2026-09-21,2026-09-22,筛选甲厂,厂二,类型C,规格C,原料C,1,1,1,张,2026-09-23,OUT-3,备注C,CLM-3,单号,DL-3\n"
. "2026-09-21,2026-09-22,筛选乙厂,厂二,类型D,规格D,原料D,1,1,1,张,2026-09-23,OUT-4,备注D,CLM-4,单号,DL-4\n",
);
$this->loginAs()->post(route('business.supplier-payables-final.board-deductions.import'), ['import' => $file])
->assertStatus(302);
$this->loginAs()
->get(route('business.pages.show', [
'section' => 'supplier-payables-final',
'page' => 'board-deductions',
'keyword' => '筛选甲厂',
]))
->assertOk()
->assertSeeText('筛选甲厂')
->assertDontSeeText('筛选乙厂')
->assertSeeText('共 1 条');
}
}