- 所有账户页签在「店铺」右侧新增「总账备注」下拉:按(平台+账单项目)翻译成账单项目集合过滤,页面/列设置/导出同口径;淘系支付宝、淘系微信同页签混多平台时按店铺名前缀细分 - 每日账单脚本:胜算超出同步导出上限(url=null+taskId)时自动从「异步导出下载管理」取回本次任务全部分片并合并成一份 CSV,导入前按页面笔数核对(不一致则跳过导入) - 实测:京东 7 月异步导出两片 219158+235846=455004 笔 / 收入 17695094.84 / 支出 8035128.21,与已导入口径一致
145 lines
6.6 KiB
PHP
145 lines
6.6 KiB
PHP
<?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(
|
||
['记录编码', '店铺', '总账备注', '类型', '二次备注', '销售订单号', '订单结算时间', '订单日期(按订单号)', '含税金额', '收入金额', '支出金额'],
|
||
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);
|
||
|
||
$this->loginAs()
|
||
->getJson(route('ecommerce-finance.account-bills.filter-options', ['bill_type' => 'vipshop-jx']))
|
||
->assertOk()
|
||
->assertExactJson([
|
||
'shops' => ['唯品会JITX_测试店'],
|
||
'bill_items' => ['客退', '销售'],
|
||
'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();
|
||
|
||
$this->loginAs()
|
||
->getJson(route('ecommerce-finance.account-bills.filter-options', ['bill_type' => 'vipshop-jx']))
|
||
->assertOk()
|
||
->assertExactJson([
|
||
'shops' => ['唯品会JITX_测试店'],
|
||
'bill_items' => ['客退', '销售'],
|
||
'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);
|
||
}
|
||
|
||
private function bill(string $billType, string $orderNo, string $item, string $occurredAt, float $income, float $expense): 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' => '订单', 'settle_period' => '2026-07'],
|
||
]);
|
||
}
|
||
|
||
private function allowPage(): void
|
||
{
|
||
$this->user->attachPermission(
|
||
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
||
);
|
||
}
|
||
}
|