新增「账单流水数据 › 种菜明细表」页面:汇总卡(笔数/财务打款金额/财务售价/扣款/京喜差价)+ 筛选(日期区间/店铺/负责人/类型/标签/关键词)+ 分页 + 按筛选全量导出,样式沿用 upstream-data 黑金令牌。新增 planting_details 表(20 列与源表一一对应,金额保留 4 位小数)、PlantingDetail 模型、PlantingDetailImporter(xlsx/xls/csv,兼容 Excel 序列号日期与千分位金额)与 planting-details:import 命令。补 PlantingDetailsPageTest 覆盖导入、序列号日期、页面渲染、筛选与导出。
140 lines
5.9 KiB
PHP
140 lines
5.9 KiB
PHP
<?php
|
||
|
||
namespace Tests\Feature\Business;
|
||
|
||
use App\Business\PlantingDetailImporter;
|
||
use App\Models\Auth\Permission;
|
||
use App\Models\Business\PlantingDetail;
|
||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||
use Tests\Feature\FeatureTestCase;
|
||
|
||
/**
|
||
* 账单流水数据 › 种菜明细表(导入 + 页面 + 筛选 + 导出)。
|
||
*/
|
||
class PlantingDetailsPageTest extends FeatureTestCase
|
||
{
|
||
private array $files = [];
|
||
|
||
protected function tearDown(): void
|
||
{
|
||
foreach ($this->files as $file) {
|
||
if (is_file($file)) {
|
||
unlink($file);
|
||
}
|
||
}
|
||
|
||
parent::tearDown();
|
||
}
|
||
|
||
public function test_import_then_page_filter_and_export(): void
|
||
{
|
||
$this->allowPage();
|
||
$result = app(PlantingDetailImporter::class)->import($this->csvFixture(), $this->company->id, true, null, 'test-import');
|
||
|
||
$this->assertSame(2, $result['inserted']);
|
||
$this->assertSame('2665.3600', $result['selling_price']);
|
||
$this->assertSame('2665.8600', $result['payment_amount']);
|
||
$this->assertSame('2026-06-01', $result['date_min']);
|
||
$this->assertSame('2026-07-15', $result['date_max']);
|
||
|
||
$page = $this->loginAs()->get(route('business.pages.show', [
|
||
'section' => 'billing-transactions',
|
||
'page' => 'planting-details',
|
||
]));
|
||
|
||
$page->assertOk()
|
||
->assertSee('种菜明细表')
|
||
->assertSee('3306215028042824171')
|
||
->assertSee('260529-659019537933390')
|
||
->assertSee('2,665.35')
|
||
->assertSee('阿里巴巴-常州乐畅家居有限公司');
|
||
|
||
// 按店铺 + 日期筛选
|
||
$filtered = $this->loginAs()->get(route('business.pages.show', [
|
||
'section' => 'billing-transactions',
|
||
'page' => 'planting-details',
|
||
'store' => '拼多多-亿家达实木家具官方旗舰店',
|
||
'date_from' => '2026-07-01',
|
||
]));
|
||
|
||
$filtered->assertOk()
|
||
->assertSee('260529-659019537933390')
|
||
->assertDontSee('3306215028042824171');
|
||
|
||
// 导出:表头 + 行数与页面筛选一致
|
||
$export = $this->loginAs()->get(route('business.billing-transactions.planting-details.export', [
|
||
'store' => '拼多多-亿家达实木家具官方旗舰店',
|
||
]));
|
||
|
||
$export->assertOk()->assertDownload();
|
||
$csv = $export->streamedContent();
|
||
$this->assertStringContainsString('日期,订单编号,财务售价', explode("\n", $csv)[0]);
|
||
$this->assertStringContainsString('260529-659019537933390', $csv);
|
||
$this->assertStringNotContainsString('3306215028042824171', $csv);
|
||
$this->assertStringContainsString('2026-07-15', $csv);
|
||
}
|
||
|
||
public function test_importer_handles_excel_serial_dates_and_grouped_amounts(): void
|
||
{
|
||
$path = $this->writeFile('planting.xlsx');
|
||
$book = new Spreadsheet();
|
||
$sheet = $book->getActiveSheet();
|
||
$sheet->fromArray([
|
||
['日期', '订单编号', '财务售价', '财务运费', '财务佣金', '京喜差价', '扣款', '财务空包费', '财务打款金额', '笔数', '备注', '正确店铺', '负责人', '账户', '类型', '创建人', '标签', '所属利润中心', '负责平台', 'ID'],
|
||
[46174, 'ORDER-1', '1,234.56', 0, '0.5', 0, 0, 0, '1,235.06', 2, '', '天猫-亿家达旗舰店', '仝孟欣', '', 'CCDD', '齐静春', 'CCDD', '运营中心A', '', 'ID-1'],
|
||
// 无效日期(空)+ 无效订单号 → 跳过
|
||
['', '', 10, 0, 0, 0, 0, 0, 10, 1, '', '天猫-亿家达旗舰店', '', '', '', '', '', '', '', ''],
|
||
]);
|
||
(new Xlsx($book))->save($path);
|
||
$book->disconnectWorksheets();
|
||
|
||
$result = app(PlantingDetailImporter::class)->import($path, $this->company->id, true, null, 'test-xlsx');
|
||
|
||
$this->assertSame(1, $result['inserted']);
|
||
$this->assertSame(1, $result['skipped']);
|
||
$this->assertSame('2026-06-01', $result['date_min']);
|
||
|
||
$record = PlantingDetail::query()->where('company_id', $this->company->id)->firstOrFail();
|
||
$this->assertSame('2026-06-01', $record->bill_date->toDateString());
|
||
$this->assertSame('1234.5600', $record->finance_selling_price);
|
||
$this->assertSame('1235.0600', $record->finance_payment_amount);
|
||
$this->assertSame(2, $record->pieces);
|
||
$this->assertSame('CCDD', $record->type);
|
||
$this->assertSame('运营中心A', $record->profit_center);
|
||
}
|
||
|
||
private function csvFixture(): string
|
||
{
|
||
$path = $this->writeFile('planting.csv');
|
||
$rows = [
|
||
['日期', '订单编号', '财务售价', '财务运费', '财务佣金', '京喜差价', '扣款', '财务空包费', '财务打款金额', '笔数', '备注', '正确店铺', '负责人', '账户', '类型', '创建人', '标签', '所属利润中心', '负责平台', 'ID'],
|
||
['2026-06-01', '3306215028042824171', '2665.35', '0', '0', '0', '0', '0', '2665.35', '1', '', '阿里巴巴-常州乐畅家居有限公司', '叶颖龙', '6222031202029761854', '', '勇武', 'AABB', '运营中心B', '', '1056008452997'],
|
||
['2026-07-15', '260529-659019537933390', '0.01', '0', '0.5', '0', '0', '0', '0.51', '1', '', '拼多多-亿家达实木家具官方旗舰店', '屠锦超', '6222031211003375839', 'SSDD', '玄鸟', 'SSDD', '运营中心G', '', '959767499187'],
|
||
];
|
||
|
||
$handle = fopen($path, 'wb');
|
||
foreach ($rows as $row) {
|
||
fputcsv($handle, $row);
|
||
}
|
||
fclose($handle);
|
||
|
||
return $path;
|
||
}
|
||
|
||
private function writeFile(string $name): string
|
||
{
|
||
$path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('planting-', true) . '-' . $name;
|
||
$this->files[] = $path;
|
||
|
||
return $path;
|
||
}
|
||
|
||
private function allowPage(): void
|
||
{
|
||
$this->user->attachPermission(
|
||
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
||
);
|
||
}
|
||
}
|