CaiWuXiTong/tests/Feature/Business/VipshopJxReceivingBillsTest.php
qiuxiang 217b953a03 唯品会JX账户:科目映射与总账备注按行内「账单项目」匹配
- AccountLedgerRemarkMap:JX 页签取 payload.second_remark 作为映射的账单项目,
  与「科目映射表」里按账单项目(处罚款/客服特殊退款-仅退款/盘盈盘亏…)维护的规则对齐
- AccountBills:总账备注筛选对 JX 改为按行内账单项目过滤,其余页签不变
- 测试同步(总账备注筛选按账单项目命中)
2026-10-09 16:57:28 +08:00

148 lines
7.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Tests\Feature\Business;
use App\Models\Auth\Permission;
use Illuminate\Support\Facades\DB;
use Modules\EcommerceFinance\Services\AccountLedgerRemarkMap;
use Modules\EcommerceFinance\Models\AccountBill;
use Tests\Feature\FeatureTestCase;
/**
* 店铺收款账户账单 › 唯品会JX账户(bill_type = vipshop-jx,读取 ec_account_bills)。
*/
class VipshopJxReceivingBillsTest extends FeatureTestCase
{
public function test_vipshop_jx_tab_reads_only_its_own_bill_type(): void
{
$this->allowPage();
$this->bill('vipshop-jx', '26060921475309', '销售', '2026-06-09 00:00:00', 82.48, 0);
$this->bill('vipshop-jx', '26070393670736', '客退', '2026-07-03 00:00:00', 0, 68.60);
$this->bill('vipshop', '26060100000001', '订单退款', '2026-06-01 00:00:00', 0, 999.00);
$response = $this->loginAs()
->getJson(route('ecommerce-finance.account-bills.index', [
'bill_type' => 'vipshop-jx',
'limit' => 20,
]))
->assertOk()
->assertJsonPath('columns.title', '唯品会JX账户')
->assertJsonPath('total', 2)
->assertJsonPath('summary.count', 2)
->assertJsonPath('summary.income', 82.48)
->assertJsonPath('summary.expense', 68.60)
// 该页签没有账户余额列,汇总口径为收支净额。
->assertJsonPath('summary.balance', 13.88)
// 日期按 Y-m-d H:i:s 返回,前端直接展示,不再出现 ISO8601(UTC)。
->assertJsonPath('data.0.occurred_at', '2026-07-03 00:00:00')
->assertJsonPath('data.1.occurred_at', '2026-06-09 00:00:00')
// 订单结算时间来自账单结算期间(现系统内全部为 2026-07)
->assertJsonPath('data.0.payload.settle_period', '2026-07')
->assertJsonPath('data.1.payload.settle_period', '2026-07');
$this->assertSame(
['记录编码', '店铺', '明细类型', '账单项目', '总账备注', '订单号/SO', '账单期间', '订单日期(按订单号)', '收入金额', '支出金额', '合计金额'],
array_column($response->json('columns.columns'), 'label'),
);
}
public function test_vipshop_jx_filter_options_and_export_stay_inside_the_tab(): void
{
$this->allowPage();
$this->bill('vipshop-jx', '26060921475309', '销售', '2026-06-09 00:00:00', 82.48, 0, '处罚款');
$this->bill('vipshop-jx', '26070393670736', '客退', '2026-07-03 00:00:00', 0, 68.60, '客服特殊退款-仅退款');
$this->bill('vipshop', '26060100000001', '订单退款', '2026-06-01 00:00:00', 0, 999.00);
$options = $this->loginAs()
->getJson(route('ecommerce-finance.account-bills.filter-options', ['bill_type' => 'vipshop-jx']))
->assertOk()
->json();
$this->assertSame(['唯品会JITX_测试店'], $options['shops']);
// 唯品会JX 的「账单项目」筛选取行内业务备注(与页面「账单项目」列同源)
$billItems = $options['bill_items'];
sort($billItems);
$this->assertSame(['处罚款', '客服特殊退款-仅退款'], $billItems);
$this->assertSame([], $options['ledger_remarks']);
$export = $this->loginAs()->get(route('ecommerce-finance.account-bills.export', [
'bill_type' => 'vipshop-jx',
'bill_item' => '处罚款',
]));
$export->assertOk()->assertDownload('vipshop-jx_account_bills.csv');
$csv = $export->streamedContent();
$this->assertStringContainsString('26060921475309', $csv);
$this->assertStringContainsString('账单项目', $csv);
$this->assertStringContainsString('2026-07', $csv);
$this->assertStringNotContainsString('26070393670736', $csv);
$this->assertStringNotContainsString('999.00', $csv);
}
public function test_ledger_remark_filter_uses_mapped_bill_items_on_page_and_export(): void
{
$this->allowPage();
$this->bill('vipshop-jx', '26060921475309', '销售', '2026-06-09 00:00:00', 82.48, 0, '处罚款');
$this->bill('vipshop-jx', '26070393670736', '客退', '2026-07-03 00:00:00', 0, 68.60, '客服特殊退款-仅退款/补寄应收费用-配件');
$this->bill('vipshop', '26060100000001', '订单退款', '2026-06-01 00:00:00', 0, 999.00);
$now = now();
DB::table('ec_account_ledger_remarks')->insert([
['platform' => '唯品会jx', 'bill_item' => '处罚款', 'ledger_remark' => '营业外支出', 'created_at' => $now, 'updated_at' => $now],
['platform' => '唯品会jx', 'bill_item' => '客服特殊退款-仅退款/补寄应收费用-配件', 'ledger_remark' => '销售费用/售后补偿', 'created_at' => $now, 'updated_at' => $now],
]);
app(AccountLedgerRemarkMap::class)->forget();
$options = $this->loginAs()
->getJson(route('ecommerce-finance.account-bills.filter-options', ['bill_type' => 'vipshop-jx']))
->assertOk()
->json();
$this->assertSame(['唯品会JITX_测试店'], $options['shops']);
$this->assertSame(['营业外支出', '销售费用/售后补偿'], $options['ledger_remarks']);
$page = $this->loginAs()->getJson(route('ecommerce-finance.account-bills.index', [
'bill_type' => 'vipshop-jx',
'ledger_remark' => '营业外支出',
'limit' => 20,
]))->assertOk();
$this->assertSame(1, $page->json('total'));
$this->assertSame('销售', $page->json('data.0.bill_item'));
$this->assertSame(82.48, (float) $page->json('data.0.income'));
$export = $this->loginAs()->get(route('ecommerce-finance.account-bills.export', [
'bill_type' => 'vipshop-jx',
'ledger_remark' => '营业外支出',
]));
$export->assertOk()->assertDownload('vipshop-jx_account_bills.csv');
$csv = $export->streamedContent();
$this->assertStringContainsString('26060921475309', $csv);
$this->assertStringNotContainsString('26070393670736', $csv);
}
/**
* @param string $billItemRemark 页面「账单项目」列取值(payload.second_remark),JX 页签的账单项目筛选按它过滤
*/
private function bill(string $billType, string $orderNo, string $item, string $occurredAt, float $income, float $expense, string $billItemRemark = '订单'): void
{
AccountBill::create([
'company_id' => $this->company->id,
'bill_type' => $billType,
'record_code' => $orderNo . '-' . $item,
'store_name' => $billType === 'vipshop-jx' ? '唯品会JITX_测试店' : '唯品会MP-测试店',
'order_no' => $orderNo,
'amount' => $income - $expense,
'bill_item' => $item,
'occurred_at' => $occurredAt,
'income' => $income,
'expense' => $expense,
'payload' => ['second_remark' => $billItemRemark, 'settle_period' => '2026-07'],
]);
}
private function allowPage(): void
{
$this->user->attachPermission(
Permission::where('name', 'read-admin-panel')->firstOrFail()
);
}
}