429 lines
17 KiB
PHP
429 lines
17 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Business;
|
|
|
|
use App\Models\Auth\Permission;
|
|
use Modules\EcommerceFinance\Models\AlipayBill;
|
|
use Modules\EcommerceFinance\Repositories\NonJingxiRefundMirrorRepository;
|
|
use Tests\Feature\FeatureTestCase;
|
|
|
|
class PagesTest extends FeatureTestCase
|
|
{
|
|
public function testTaobaoAlipayBillsEndpointIsAvailableToWorkspaceUsers()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
AlipayBill::create([
|
|
'company_id' => $this->company->id,
|
|
'record_code' => 'time-format-test',
|
|
'store_name' => '测试店铺',
|
|
'bill_item' => '交易收款',
|
|
'business_type' => '交易付款',
|
|
'alipay_account' => '2088000000000000',
|
|
'counterparty_account' => '测试账号',
|
|
'account_order_no' => 'account-order-test',
|
|
'business_serial_no' => 'business-serial-test',
|
|
'goods_name' => '测试商品',
|
|
'income' => 1,
|
|
'expense' => 0,
|
|
'balance' => 1,
|
|
'occurred_at' => '2026-07-15 23:59:12',
|
|
]);
|
|
|
|
$this->loginAs()
|
|
->withHeader('X-Requested-With', 'XMLHttpRequest')
|
|
->get(route('ecommerce-finance.alipay-bills.index'))
|
|
->assertOk()
|
|
->assertJsonStructure([
|
|
'current_page',
|
|
'data',
|
|
'total',
|
|
'summary' => ['income', 'expense', 'count', 'balance'],
|
|
])
|
|
->assertJsonPath('data.0.occurred_at', '2026-07-15 23:59:12');
|
|
}
|
|
|
|
public function testTaobaoAlipayBillsPageProvidesTheVueMountPoint()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'billing-transactions',
|
|
'page' => 'store-receiving-bills',
|
|
'tab' => 'taobao-alipay',
|
|
]))
|
|
->assertOk()
|
|
->assertSee('class="biz-card mt-6 business-blank-page"', false)
|
|
->assertSee('public/js/business/pages.min.js', false);
|
|
}
|
|
|
|
public function testSupplierPayablesPageRendersItsSpecificContent()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'supplier-payables',
|
|
'page' => 'payment-reconciliation',
|
|
]))
|
|
->assertOk()
|
|
->assertSee('id="goods-reconciliation-app"', false)
|
|
->assertSee('public/js/ecommerce-finance/goods-reconciliations.min.js', false)
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
}
|
|
|
|
public function testOrderDataTablesRenderAsRawDataPageTabs()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', ['section' => 'order-data']))
|
|
->assertRedirect(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
'tab' => 'after-sales-expenses',
|
|
]));
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
]))
|
|
->assertRedirect(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
'tab' => 'after-sales-expenses',
|
|
]));
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
'tab' => 'after-sales-expenses',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('订单售后费用明细')
|
|
->assertSee('aria-label="订单售后费用明细"', false)
|
|
->assertSeeText('内部订单号')
|
|
->assertSeeText('800503发空包/赠品费用')
|
|
->assertSeeText('暂无数据')
|
|
->assertSee('class="business-tab-bar"', false)
|
|
->assertSee(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
'tab' => 'after-sales-expenses',
|
|
]), false)
|
|
->assertSee(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
'tab' => 'promotion-expenses',
|
|
]), false)
|
|
->assertDontSee(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'after-sales-expenses',
|
|
]), false)
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
'tab' => 'promotion-expenses',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('商品推广费用明细')
|
|
->assertSee('aria-label="商品推广费用明细"', false)
|
|
->assertSeeText('店铺')
|
|
->assertSeeText('8001201直通车/钻展/快车等')
|
|
->assertSeeText('暂无数据')
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
}
|
|
|
|
public function testOrderDataIncludesTheConfiguredBillOffsetSubpage(): void
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$this->loginAs();
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'bill-offset',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeInOrder([
|
|
route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'raw-data',
|
|
'tab' => 'after-sales-expenses',
|
|
]),
|
|
route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'bill-offset',
|
|
]),
|
|
], false);
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'bill-offset',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('账单冲减')
|
|
->assertSeeText('该页面暂未配置数据表,敬请期待。');
|
|
|
|
$this->withExceptionHandling();
|
|
|
|
foreach (['national-subsidy', 'hundred-subsidy', 'consumption-coupon'] as $removedSlug) {
|
|
$this->withHeader('X-Requested-With', 'XMLHttpRequest')
|
|
->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => $removedSlug,
|
|
]))
|
|
->assertNotFound();
|
|
}
|
|
}
|
|
|
|
public function testRefundPagesUseTheGenericBusinessPageRoute()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$repository = \Mockery::mock(NonJingxiRefundMirrorRepository::class);
|
|
$repository->shouldReceive('available')->once()->andReturnFalse();
|
|
$repository->shouldNotReceive('states');
|
|
$repository->shouldNotReceive('syncStatus');
|
|
$repository->shouldNotReceive('ready');
|
|
$repository->shouldNotReceive('queryReady');
|
|
$repository->shouldNotReceive('paginate');
|
|
$this->app->instance(NonJingxiRefundMirrorRepository::class, $repository);
|
|
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'refunds',
|
|
]))
|
|
->assertRedirect(route('business.pages.show', [
|
|
'section' => 'refunds',
|
|
'page' => 'jingxi-refund-data',
|
|
]));
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'refunds',
|
|
'page' => 'jingxi-refund-data',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('京喜退款数据')
|
|
->assertSeeText('该页面暂未配置数据表,敬请期待。')
|
|
->assertSee('class="biz-empty"', false);
|
|
|
|
$response = $this->get(route('business.pages.show', [
|
|
'section' => 'refunds',
|
|
'page' => 'non-jingxi-refund-data',
|
|
]));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSeeText('售后(退货退款)')
|
|
->assertSee('aria-label="售后(退货退款)"', false)
|
|
->assertSee('aria-label="售后(退货退款)分页"', false)
|
|
->assertDontSeeText('非京喜退款数据')
|
|
->assertSeeText('共享业务镜像尚未建立')
|
|
->assertSeeText('数据暂时无法读取')
|
|
->assertSee('class="upstream-data-table refund-data-table refund-data-table--wide"', false)
|
|
->assertSee('data-header-row="labels"', false)
|
|
->assertSee('data-header-row="fields"', false)
|
|
->assertDontSee('class="biz-empty"', false);
|
|
|
|
$html = $response->getContent();
|
|
$headerRows = [];
|
|
preg_match_all(
|
|
'/<tr[^>]*data-header-row="(labels|fields)"[^>]*>(.*?)<\/tr>/s',
|
|
$html,
|
|
$headerRows,
|
|
PREG_SET_ORDER,
|
|
);
|
|
|
|
$headers = collect($headerRows)->mapWithKeys(function (array $row): array {
|
|
$cells = [];
|
|
preg_match_all('/<th[^>]*>(.*?)<\/th>/s', $row[2], $cells);
|
|
|
|
return [$row[1] => collect($cells[1])->map(
|
|
fn (string $cell): string => trim(html_entity_decode(strip_tags($cell)))
|
|
)->all()];
|
|
});
|
|
|
|
$this->assertSame([
|
|
'序号/主键ID', '退款日期', '售后单ID', '外部售后单号', '订单ID', '',
|
|
'子订单ID', '类型', '节点', '是否自营', '店铺名称', '平台', '责任部门',
|
|
'退款总金额', '原始邮编', '店铺商品ID', '店铺SKU编码', '商品ID', 'SKU编码',
|
|
'买家实付金额', '数量', '商品单位成本', '明细退款金额', '退款类型',
|
|
'退款数量', '退款商品成本', '退款回款金额', '售后金额', '创建时间', '状态',
|
|
'店铺状态', '创建记录/创建时间', '确认日期',
|
|
], $headers->get('labels'));
|
|
|
|
$this->assertSame([
|
|
'Id', 'refundDate', 'as_id', 'outer_as_id', 'o_id', '', 'so_id', 'type',
|
|
'node', 'isZC', 'shop_name', 'platform', 'responsibleDepartment',
|
|
'totalRefundMoney', 'originPostcode', 'shop_i_id', 'shop_sku_id', 'i_id',
|
|
'sku_id', 'buyer_paid_amount', 'qty', 'unitCostGoods', 'detailRefundMoney',
|
|
'refundType', 'refundQty', 'refundCostGoods', 'RefundMoneyIncome',
|
|
'AfSalesMoney', 'createTime', 'status', 'shop_status', 'created', 'confirm_date',
|
|
], $headers->get('fields'));
|
|
|
|
$this->withExceptionHandling()
|
|
->loginAs()
|
|
->withHeader('X-Requested-With', 'XMLHttpRequest')
|
|
->get(route('business.pages.show', [
|
|
'company_id' => $this->company->id,
|
|
'section' => 'refunds',
|
|
'page' => 'unknown-refund-page',
|
|
]))
|
|
->assertNotFound();
|
|
}
|
|
|
|
public function testPaperMaterialPagesRenderAsSeparateTables()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$pages = [
|
|
'paper-prices' => '价格类型',
|
|
'paper-details' => '压贴厂金额',
|
|
'penalty-details' => '违约金',
|
|
'paper-factory-payables' => '2026年公司应付纸厂6月份货款',
|
|
];
|
|
|
|
foreach ($pages as $page => $expectedHeader) {
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'paper-materials',
|
|
'page' => $page,
|
|
]))
|
|
->assertOk()
|
|
->assertSee($expectedHeader)
|
|
->assertSee('class="paper-material-table', false)
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
}
|
|
}
|
|
|
|
public function testEdgeBandingMaterialPagesRenderAsSeparateTables()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$pages = [
|
|
'edge-banding-prices' => '价格类型',
|
|
'details' => '封边条厂单价',
|
|
'compensation' => '最新出库日期',
|
|
'edge-banding-payables' => '2026年公司应付封边条厂6月份货款',
|
|
];
|
|
|
|
foreach ($pages as $page => $expectedHeader) {
|
|
$response = $this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'edge-banding-materials',
|
|
'page' => $page,
|
|
]))
|
|
->assertOk()
|
|
->assertSee($expectedHeader)
|
|
->assertSee('class="edge-banding-table', false)
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
|
|
if ($page !== 'compensation') {
|
|
$response->assertSeeText('该上游数据同步尚未启用,请联系管理员。');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function testLaminationFactoryPayablePagesRenderAsSeparateTables()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$pages = [
|
|
'lamination-prices' => '执行日期',
|
|
'finished-board-prices' => '最新价格',
|
|
'lamination-fees' => '单号类型',
|
|
'finished-board-freight' => '成品板规格',
|
|
'paper-stock-in' => '家具厂',
|
|
'paper-stock-out' => '压贴厂金额',
|
|
'factory-raw-boards' => '纸张合计',
|
|
'raw-board-freight' => '素板规格',
|
|
'invoice-tax-points' => '对账金额',
|
|
'factory-compensation' => '来源金额',
|
|
'factory-payables-details' => '成品板运费合计',
|
|
'factory-payables-report' => '2026年公司应付压贴厂5月份货款',
|
|
];
|
|
|
|
foreach ($pages as $page => $expectedHeader) {
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'lamination-factory-payables',
|
|
'page' => $page,
|
|
]))
|
|
->assertOk()
|
|
->assertSee($expectedHeader)
|
|
->assertSee('class="lamination-table', false)
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
}
|
|
}
|
|
|
|
public function testMergedFeaturePagesRenderTheirDedicatedContent()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$pages = [
|
|
['supplier-payables', 'product-prices', '数据读取失败,请稍后重试。'],
|
|
['courier-payables', 'freight-reconciliation', '快递单号'],
|
|
['courier-payables', 'bookkeeping-details', '暂无记账明细'],
|
|
['courier-payables', 'compensation-details', '暂无赔偿明细'],
|
|
['courier-payables', 'advance-details', '暂无借支明细'],
|
|
['courier-payables', 'other-adjustments', '暂无其他扣款补款明细'],
|
|
['raw-board-payables', 'board-prices', '价格类型'],
|
|
['raw-board-payables', 'board-reconciliation', '运费(包含分摊运费)'],
|
|
['raw-board-payables', 'compensation-details', '暂无素板赔付明细'],
|
|
['raw-board-payables', 'board-payables-report', '暂无素板应付汇总数据'],
|
|
];
|
|
|
|
foreach ($pages as [$section, $page, $expectedText]) {
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', compact('section', 'page')))
|
|
->assertOk()
|
|
->assertSeeText($expectedText)
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
}
|
|
}
|
|
|
|
public function testBoardInventoryDetailsRendersWorkbookColumnsAsItsOwnPage()
|
|
{
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'inventory-management',
|
|
'page' => 'board-inventory-details',
|
|
]))
|
|
->assertOk()
|
|
->assertSee('class="upstream-data-table upstream-data-table--inventory"', false)
|
|
->assertSeeText('加权平均单价')
|
|
->assertSeeText('上月剩余价值')
|
|
->assertSeeText('出库金额')
|
|
->assertDontSee('class="business-data-page"', false)
|
|
->assertDontSee('class="business-blank-page"', false);
|
|
}
|
|
}
|