user->attachPermission( Permission::where('name', 'read-admin-panel')->firstOrFail() ); Storage::fake('uploads'); } public function test_final_workspace_places_both_summary_pages_after_courier_payables_report(): void { $response = $this->loginAs()->get(route('business.pages.show', [ 'section' => 'courier-payables-final', ])); $response->assertOk()->assertSeeInOrder([ route('business.pages.show', ['section' => 'courier-payables', 'page' => 'courier-payables-report']), route('business.pages.show', ['section' => 'courier-payables', 'page' => 'freight-difference']), route('business.pages.show', ['section' => 'courier-payables', 'page' => 'other-surcharge-summary']), ], false); } public function test_summary_pages_render_import_and_export_buttons(): void { foreach (CourierPayableSummaryStore::PAGES as $page => $title) { $this->loginAs()->get(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => $page, ])) ->assertOk() ->assertSee("data-courier-payable-summary=\"{$page}\"", false) ->assertSeeText($title) ->assertSeeText('导入') ->assertSeeText('导出') ->assertSeeText('暂无数据,请先点击“导入”上传汇总表。'); } } public function test_freight_difference_import_dialog_downloads_the_supplied_xlsx_template(): void { $pageResponse = $this->loginAs()->get(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => 'freight-difference', ])); $pageResponse ->assertOk() ->assertSee('data-courier-summary-import-dialog', false) ->assertSeeText('下载模板') ->assertSee(route('business.courier-payable-summaries.template', [ 'summaryPage' => 'freight-difference', ]), false); $templateResponse = $this->loginAs()->get(route('business.courier-payable-summaries.template', [ 'summaryPage' => 'freight-difference', ])); $templateResponse ->assertOk() ->assertDownload('freight_difference_import_template.xlsx') ->assertHeader('content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); $this->assertStringContainsString( "filename*=utf-8''" . rawurlencode('运费差导入模板.xlsx'), (string) $templateResponse->headers->get('Content-Disposition'), ); $spreadsheet = IOFactory::load(resource_path('templates/courier-payables/freight-difference-import-template.xlsx')); $worksheet = $spreadsheet->getActiveSheet(); $this->assertSame([ '负责人', '快递公司', '快递单号', '店铺', 'id', '条码', '交易单号', '差异(结算运费-提供成本运费)', '是否配件', '配件成品条码', ], $worksheet->rangeToArray('A1:J1', null, false, false)[0]); $this->assertSame('FFFFC000', $worksheet->getStyle('D1')->getFill()->getStartColor()->getARGB()); $this->assertSame('FFFFC000', $worksheet->getStyle('E1')->getFill()->getStartColor()->getARGB()); $this->assertSame('FFFFC000', $worksheet->getStyle('G1')->getFill()->getStartColor()->getARGB()); $this->assertSame('@', $worksheet->getStyle('E2')->getNumberFormat()->getFormatCode()); $this->assertSame('@', $worksheet->getStyle('G2')->getNumberFormat()->getFormatCode()); $this->assertSame('', (string) $worksheet->getCell('A2')->getValue()); $spreadsheet->disconnectWorksheets(); } public function test_other_surcharge_page_does_not_offer_the_freight_difference_template(): void { $this->loginAs()->get(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => 'other-surcharge-summary', ])) ->assertOk() ->assertDontSeeText('下载模板') ->assertDontSee('data-courier-summary-import-dialog', false); } public function test_completed_freight_difference_template_preserves_long_identifiers_on_import(): void { $spreadsheet = IOFactory::load(resource_path('templates/courier-payables/freight-difference-import-template.xlsx')); $worksheet = $spreadsheet->getActiveSheet(); $worksheet->fromArray([ '苏木', '测试快递', 'YT7632543323146', '测试店铺', '855226246304', 'DNZ0117123N1210V01', '3312228147193110069', 0.1827, '成品', '', ], null, 'A2'); $worksheet->getCell('E2')->setValueExplicit('855226246304', DataType::TYPE_STRING); $worksheet->getCell('G2')->setValueExplicit('3312228147193110069', DataType::TYPE_STRING); $path = tempnam(sys_get_temp_dir(), 'freight-template-'); $this->assertNotFalse($path); $xlsxPath = $path . '.xlsx'; try { IOFactory::createWriter($spreadsheet, 'Xlsx')->save($xlsxPath); $spreadsheet->disconnectWorksheets(); $file = new UploadedFile( $xlsxPath, '运费差导入模板.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', null, true, ); $this->loginAs()->post(route('business.courier-payable-summaries.import', [ 'summaryPage' => 'freight-difference', ]), ['import' => $file]) ->assertRedirect(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => 'freight-difference', ])) ->assertSessionHas('success', '导入完成:1 条数据,10 个字段。'); $snapshot = app(CourierPayableSummaryStore::class)->snapshot( (int) $this->company->id, 'freight-difference', ); $this->assertSame('855226246304', $snapshot['rows'][0][4]); $this->assertSame('3312228147193110069', $snapshot['rows'][0][6]); $this->assertSame('0.1827', $snapshot['rows'][0][7]); } finally { if (isset($spreadsheet)) { $spreadsheet->disconnectWorksheets(); } if ($path !== false && is_file($path)) { unlink($path); } if (isset($xlsxPath) && is_file($xlsxPath)) { unlink($xlsxPath); } } } public function test_import_replaces_the_page_snapshot_and_export_returns_all_rows(): void { $file = UploadedFile::fake()->createWithContent( '运费差.csv', "快递公司,结算月份,运费差,备注\n测试快递,2026-08,-18.50,复核\n第二快递,2026-08,20,=待确认\n", ); $this->loginAs()->post(route('business.courier-payable-summaries.import', [ 'summaryPage' => 'freight-difference', ]), ['import' => $file]) ->assertRedirect(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => 'freight-difference', ])) ->assertSessionHas('success', '导入完成:2 条数据,4 个字段。'); Storage::disk('uploads')->assertExists( app(CourierPayableSummaryStore::class)->path((int) $this->company->id, 'freight-difference') ); $this->loginAs()->get(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => 'freight-difference', ])) ->assertOk() ->assertSeeText('导入完成:2 条数据,4 个字段。') ->assertSeeText('测试快递') ->assertSeeText('-18.50') ->assertSeeText('第二快递'); $response = $this->loginAs()->get(route('business.courier-payable-summaries.export', [ 'summaryPage' => 'freight-difference', ])); $content = $response->streamedContent(); $response->assertOk()->assertHeader('content-type', 'text/csv; charset=UTF-8'); $this->assertStringContainsString('快递公司,结算月份,运费差,备注', $content); $this->assertStringContainsString('测试快递,2026-08,-18.50,复核', $content); $this->assertStringContainsString("\t=待确认", $content); } public function test_summary_actions_require_the_matching_page_permission(): void { $this->withExceptionHandling(); $this->user->roles()->sync([ \App\Models\Auth\Role::where('name', 'admin')->firstOrFail()->id, ]); setting()->set('system.sidebar_permissions', [ 'configured' => ['user_' . $this->user->id], 'subjects' => ['user_' . $this->user->id => ['courier-payables/courier-information']], ]); $this->loginAs()->get(route('business.courier-payable-summaries.export', [ 'summaryPage' => 'freight-difference', ]))->assertForbidden(); $this->loginAs()->get(route('business.courier-payable-summaries.template', [ 'summaryPage' => 'freight-difference', ]))->assertForbidden(); } }