CaiWuXiTong/tests/Feature/Console/ImportTaobaoAlipayBillsTest.php
chenxi 1751d8e062 接入淘系支付宝账单副本库全量数据 (#208)
使用经营分析副本库作为全量分页、筛选、汇总与导出主数据源;演示表仅按记录编码补充源表缺失字段。验证:47 项 PHP 测试、435 assertions;6 项账户账单脚本测试;真实页面全量及日期筛选验收通过。
2026-09-19 01:52:45 +08:00

115 lines
4.9 KiB
PHP

<?php
namespace Tests\Feature\Console;
use Modules\EcommerceFinance\Models\AlipayBill;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Tests\TestCase;
class ImportTaobaoAlipayBillsTest extends TestCase
{
private array $files = [];
protected function tearDown(): void
{
foreach ($this->files as $file) {
@unlink($file);
}
parent::tearDown();
}
public function testItImportsExactIdentifiersAndIsIdempotent(): void
{
$file = $this->workbook();
$this->artisan('business:import-taobao-alipay-bills', ['file' => $file, '--company' => 1])
->expectsOutputToContain('新增 1 条,更新 0 条')
->assertSuccessful();
$bill = AlipayBill::query()->where('company_id', 1)->firstOrFail();
$this->assertSame('2000000001141269665', $bill->record_code);
$this->assertSame('2026071323001146201449637707', $bill->business_serial_no);
$this->assertSame('2026-07-15 23:59:12', $bill->occurred_at->format('Y-m-d H:i:s'));
$this->assertSame('100.250000', $bill->income);
$this->assertSame('attachment-import', $bill->created_from);
$this->assertSame('2026-07-16 06:31:02', $bill->created_at->format('Y-m-d H:i:s'));
$this->assertSame('2026-07-16 06:35:03', $bill->updated_at->format('Y-m-d H:i:s'));
$this->artisan('business:import-taobao-alipay-bills', ['file' => $file, '--company' => 1])
->expectsOutputToContain('新增 0 条,更新 1 条')
->assertSuccessful();
$this->assertSame(1, AlipayBill::query()->where('company_id', 1)->count());
}
public function testItRejectsAnUnexpectedHeader(): void
{
$file = $this->workbook('错误表头');
$this->artisan('business:import-taobao-alipay-bills', ['file' => $file, '--company' => 1])
->expectsOutputToContain('表头与淘系支付宝账户模板不一致')
->assertFailed();
$this->assertSame(0, AlipayBill::query()->count());
}
public function testItRejectsAnUnexpectedSheetName(): void
{
$file = $this->workbook(null, '其他工作表');
$this->artisan('business:import-taobao-alipay-bills', ['file' => $file, '--company' => 1])
->expectsOutputToContain('未找到工作表“淘系支付宝账户”')
->assertFailed();
}
public function testReplaceValidatesFirstAndAtomicallyRemovesOldRows(): void
{
$old = AlipayBill::query()->create([
'company_id' => 1, 'record_code' => 'OLD-ROW', 'store_name' => '旧店铺',
'bill_item' => '旧账单', 'business_type' => '', 'alipay_account' => '',
'counterparty_account' => '', 'account_order_no' => '', 'business_serial_no' => '',
'goods_name' => '', 'income' => 0, 'expense' => 0, 'balance' => 0,
'platform' => 'taobao', 'created_from' => 'old-data',
]);
$this->artisan('business:import-taobao-alipay-bills', [
'file' => $this->workbook('错误表头'), '--company' => 1, '--replace' => true,
])->assertFailed();
$this->assertDatabaseHas('ec_alipay_bills', ['id' => $old->id, 'record_code' => 'OLD-ROW']);
$this->artisan('business:import-taobao-alipay-bills', [
'file' => $this->workbook(), '--company' => 1, '--replace' => true,
])->expectsOutputToContain('替换旧数据 1 条')->assertSuccessful();
$this->assertSame(1, AlipayBill::query()->where('company_id', 1)->count());
$this->assertDatabaseMissing('ec_alipay_bills', ['record_code' => 'OLD-ROW']);
$this->assertDatabaseHas('ec_alipay_bills', ['record_code' => '2000000001141269665']);
}
private function workbook(?string $firstHeader = null, string $sheetName = '淘系支付宝账户'): string
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle($sheetName);
$headers = \App\Business\TaobaoAlipayBillSpreadsheetImporter::HEADERS;
$headers[0] = $firstHeader ?? $headers[0];
$sheet->fromArray($headers, null, 'A1');
$sheet->fromArray([
'2000000001141269665', '淘宝_测试店铺', '', '交易收款', '2088480341979438',
'1570808064092446200', '2026071323001146201449637707', 'T200P3312548005778060954',
'', '', 'buyer@example.test', '2026-07-15 23:59:12', '100.25', '0.00',
'456.78', '交易付款', '', '12345678901234567890', '淘宝_测试店铺', '测试业务',
'支付宝', 'BIZ12345678901234567890', '2026/7/16 6:31:02', '2026/7/16 6:35:03', '测试人',
], null, 'A2');
$file = tempnam(sys_get_temp_dir(), 'alipay-import-') . '.xlsx';
(new Xlsx($spreadsheet))->save($file);
$spreadsheet->disconnectWorksheets();
$this->files[] = $file;
return $file;
}
}