CaiWuXiTong/tests/Feature/Business/OnlineDaifaPricePageTest.php
limeng 29547fbd4d feat(线上代发价格): 新增实际发货商品编码与聚水潭标记|多标签两列
按店铺交易单号(钉钉行)/内部单号(采购单行)批量关联聚水潭订单
(ops_jst_orders + 淘系 ops_jst_qmcust_orders),补充:
- 实际发货商品编码:组合装拆开后的子商品编码×数量;优先取本行商品编码
  拆出的子商品,普通商品取自身,对不上时列整单;忽略被拆分/合并/作废原单
- 聚水潭标记|多标签:订单 labels
只按当前页/导出批次的单号做索引等值查询;页面与 CSV 导出同步加列。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AvVQFrueqWakFKTdSyu5q
2026-10-28 14:09:04 +08:00

295 lines
14 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 Mockery;
use Modules\EcommerceFinance\Repositories\DingOnlineDaifaPriceMirrorRepository;
use Tests\Feature\FeatureTestCase;
class OnlineDaifaPricePageTest extends FeatureTestCase
{
public function test_online_daifa_price_page_renders_matched_product_and_amounts(): void
{
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$repository = Mockery::mock(DingOnlineDaifaPriceMirrorRepository::class);
$repository->shouldReceive('paginate')->once()->andReturn([
'data' => [[
'process_instance_id' => 'DEMO-6927049845766979458',
'detail_index' => 0,
'product_id' => '3821829253650055444',
'daifa_trade_no' => '6927049845766979458',
'shop_trade_no' => '6927049845766979458',
'shop_name' => '抖音-HX旗舰店101',
'payee_name' => '宁波顾家望业家居有限公司',
'tag' => '刘萧代发',
'supplier_name' => '',
'material_no' => '',
'ship_qty' => 1,
'paid_amount' => 616.61,
'daifa_amount' => 375.0,
'price_diff' => 241.61,
'workflow' => [
'businessId' => '20260901001',
'title' => '线上代发业务报销',
'status' => 'COMPLETED',
'result' => 'agree',
'originatorUserName' => '扬灵',
'createAt' => '2026-09-01 10:00:00',
],
'scheme' => [['name' => '商品ID', 'value' => '3821829253650055444']],
'tasks' => [],
'status_key' => 'COMPLETED',
'status_label' => '已完成',
'matched_product' => ['matched' => true, 'name' => '演示商品', 'sku_id' => null, 'i_id' => null],
'workflow_created_at' => '2026-09-01 10:00:00',
]],
'total' => 1,
'status' => 'succeeded',
'last_synced_at' => '2026-09-08 00:00:05',
'summary' => [
'count' => 1,
'matched_count' => 1,
'daifa_amount' => 375.0,
'paid_amount' => 616.61,
'price_diff' => 241.61,
],
]);
$this->app->instance(DingOnlineDaifaPriceMirrorRepository::class, $repository);
$this->loginAs()->get(route('business.pages.show', [
'section' => 'product-inventory',
'page' => 'online-daifa-price',
]))->assertOk()
->assertSee('线上代发价格')
->assertSee('数据来源:钉钉线上代发审批、聚水潭采购单管理(已确认/已完成)')
->assertDontSee('固定收款人:')
->assertSee('宁波顾家望业家居有限公司')
->assertSee('镜像状态:succeeded')
->assertSee('3821829253650055444')
->assertSee('演示商品')
->assertSee('抖音-HX旗舰店101')
->assertSee('6927049845766979458')
->assertSee('已完成')
->assertSee('扬灵')
->assertSee('标签')
->assertSee('刘萧代发')
->assertSee('已匹配商品目录')
->assertDontSee('原始表单')
->assertDontSee('展开表单');
}
public function test_online_daifa_price_page_places_purchase_fields_in_existing_columns(): void
{
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$repository = Mockery::mock(DingOnlineDaifaPriceMirrorRepository::class);
$repository->shouldReceive('paginate')->once()->andReturn([
'data' => [[
'source_type' => 'purchase',
'process_instance_id' => '907329',
'detail_index' => 1,
'product_id' => '',
'daifa_trade_no' => '',
'shop_trade_no' => '110212448119316609',
'shop_name' => '得物-米客米家家居旗舰店',
'payee_name' => '',
'tag' => '采购单管理',
'supplier_name' => '霸州市亚锦五金制品厂',
'material_no' => 'DF-C1ZDY000202',
'ship_qty' => 1,
'paid_amount' => null,
'daifa_amount' => 19.3,
'price_diff' => null,
'workflow' => ['businessId' => '907329', 'title' => '采购单管理'],
'status_label' => '已确认',
'matched_product' => ['matched' => false, 'name' => null],
'order_matched' => true,
'workflow_created_at' => '2026-09-22 16:30:03',
]],
'total' => 1,
'status' => 'available',
'last_synced_at' => '2026-09-22 17:35:11',
'summary' => ['count' => 1, 'purchase_count' => 1, 'matchable_count' => 0],
'source_statuses' => [
'purchase' => ['label' => '聚水潭采购单管理', 'ready' => true, 'status' => 'succeeded'],
],
]);
$this->app->instance(DingOnlineDaifaPriceMirrorRepository::class, $repository);
$this->loginAs()->get(route('business.pages.show', [
'section' => 'product-inventory',
'page' => 'online-daifa-price',
]))->assertOk()
->assertSee('110212448119316609')
->assertSee('得物-米客米家家居旗舰店')
->assertSee('霸州市亚锦五金制品厂')
->assertSee('DF-C1ZDY000202')
->assertSee('19.30')
->assertSee('采购单管理')
->assertSee('已确认')
->assertDontSee('(未匹配)');
}
public function test_online_daifa_price_page_keeps_an_unavailable_mirror_readable(): void
{
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$repository = Mockery::mock(DingOnlineDaifaPriceMirrorRepository::class);
$repository->shouldReceive('paginate')->andThrow(new \RuntimeException('not ready'));
$this->app->instance(DingOnlineDaifaPriceMirrorRepository::class, $repository);
$this->loginAs()->get(route('business.pages.show', [
'section' => 'product-inventory',
'page' => 'online-daifa-price',
]))->assertOk()
->assertSee('线上代发价格镜像尚未完成同步,请稍后重试。')
->assertSee('镜像读取失败,请稍后重试。');
}
public function test_online_daifa_price_page_passes_filters_to_repository(): void
{
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$repository = Mockery::mock(DingOnlineDaifaPriceMirrorRepository::class);
$repository->shouldReceive('paginate')->once()->with(
[
'keyword' => '6927049845766979458',
'product_id' => '3821829253650055444',
'shop_name' => '抖音-HX旗舰店101',
'supplier_name' => '新北供应商',
'material_no' => 'MAT-001',
'status' => '',
'created_from' => '2026-09-01',
'created_to' => '2026-09-07',
],
1,
Mockery::type('int'),
)->andReturn([
'data' => [],
'total' => 0,
'status' => 'succeeded',
'last_synced_at' => '2026-09-08 00:00:05',
'summary' => [],
]);
$this->app->instance(DingOnlineDaifaPriceMirrorRepository::class, $repository);
$this->loginAs()->get(route('business.pages.show', [
'section' => 'product-inventory',
'page' => 'online-daifa-price',
'keyword' => '6927049845766979458',
'product_id' => '3821829253650055444',
'shop_name' => '抖音-HX旗舰店101',
'supplier_name' => '新北供应商',
'material_no' => 'MAT-001',
'created_from' => '2026-09-01',
'created_to' => '2026-09-07',
]))->assertOk()
->assertSee('商品ID')
->assertSee('店铺名称')
->assertSee('供应商名称')
->assertSee('新北供应商')
->assertSee('商品编码')
->assertSee('MAT-001')
->assertSee('2026-09-01')
->assertSee('2026-09-07');
}
public function test_online_daifa_price_export_streams_all_currently_filtered_rows(): void
{
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$filters = [
'keyword' => 'DAIFA-001',
'product_id' => 'PRODUCT-001',
'shop_name' => '抖音旗舰店',
'supplier_name' => '新北供应商',
'material_no' => 'MAT-001',
'status' => 'COMPLETED',
'created_from' => '2026-09-01',
'created_to' => '2026-09-07',
];
$repository = Mockery::mock(DingOnlineDaifaPriceMirrorRepository::class);
$repository->shouldReceive('ready')->once()->andReturnTrue();
$repository->shouldReceive('exportRows')->once()->with($filters)->andReturn((static function (): \Generator {
yield [
'process_instance_id' => 'PROCESS-001',
'product_id' => '3821829253650055444',
'daifa_trade_no' => '6927049845766979458',
'shop_trade_no' => '6927049845766979459',
'shop_name' => '抖音旗舰店',
'payee_name' => '宁波顾家望业家居有限公司',
'tag' => '刘萧代发',
'supplier_name' => '@新北供应商',
'material_no' => 'MAT-001',
'ship_qty' => 2,
'paid_amount' => 616.61,
'daifa_amount' => 375.0,
'price_diff' => 241.61,
'workflow' => [
'businessId' => '=APPROVAL-001',
'title' => '线上代发业务报销',
'originatorUserName' => '+扬灵',
],
'status_label' => '已完成',
'matched_product' => ['matched' => true, 'name' => '演示商品'],
'ship_skus' => 'VTYZ010102×1, GDYRB020102×1',
'jst_labels' => '京东供销订单,京喜',
'workflow_created_at' => '2026-09-01 10:00:00',
];
})());
$this->app->instance(DingOnlineDaifaPriceMirrorRepository::class, $repository);
$response = $this->loginAs()->get(route('business.product-inventory.online-daifa-price.export', $filters));
$response->assertOk();
$this->assertStringContainsString('attachment;', (string) $response->headers->get('content-disposition'));
$this->assertStringContainsString('text/csv', (string) $response->headers->get('content-type'));
$content = $response->streamedContent();
$this->assertStringStartsWith(chr(0xEF) . chr(0xBB) . chr(0xBF), $content);
$this->assertStringContainsString('供应商名称', $content);
$this->assertStringContainsString('商品编码', $content);
$this->assertStringContainsString('标签', $content);
$this->assertStringContainsString('刘萧代发', $content);
$this->assertStringContainsString("'=APPROVAL-001", $content);
$this->assertStringContainsString("'+扬灵", $content);
$this->assertStringContainsString("'@新北供应商", $content);
$this->assertStringContainsString("'3821829253650055444", $content);
$this->assertStringContainsString("'6927049845766979458", $content);
$this->assertStringContainsString("'6927049845766979459", $content);
$this->assertStringContainsString('MAT-001', $content);
$this->assertStringContainsString('实际发货商品编码', $content);
$this->assertStringContainsString('聚水潭标记|多标签', $content);
$this->assertStringContainsString('VTYZ010102×1, GDYRB020102×1', $content);
$this->assertStringContainsString('京东供销订单,京喜', $content);
}
public function test_online_daifa_price_export_requires_a_ready_mirror(): void
{
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$repository = Mockery::mock(DingOnlineDaifaPriceMirrorRepository::class);
$repository->shouldReceive('ready')->once()->andReturnFalse();
$repository->shouldNotReceive('exportRows');
$this->app->instance(DingOnlineDaifaPriceMirrorRepository::class, $repository);
$this->withExceptionHandling()
->loginAs()
->get(route('business.product-inventory.online-daifa-price.export'))
->assertServiceUnavailable();
}
public function test_online_daifa_price_export_rejects_users_without_sidebar_permission(): void
{
$subject = 'user_' . $this->user->id;
$this->user->roles()->sync([\App\Models\Auth\Role::where('name', 'admin')->firstOrFail()->id]);
setting()->set('system.sidebar_permissions', json_encode([
'configured' => [$subject],
'subjects' => [
$subject => ['company-management/basic-information'],
],
], JSON_UNESCAPED_UNICODE));
$this->withExceptionHandling()
->loginAs()
->get(route('business.product-inventory.online-daifa-price.export'))
->assertForbidden();
}
}