CaiWuXiTong/tests/Unit/EcommerceFinance/SupplierManagementMirrorRepositoryTest.php

180 lines
9.6 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\EcommerceFinance\Repositories\GenericBusinessMirrorRepository;
use Modules\EcommerceFinance\Repositories\SupplierManagementMirrorRepository;
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
use Modules\EcommerceFinance\Services\BusinessMirrorSchemaManager;
use Tests\TestCase;
class SupplierManagementMirrorRepositoryTest extends TestCase
{
private SupplierManagementMirrorRepository $repository;
protected function setUp(): void
{
parent::setUp();
config(['database.connections.business_mirror' => ['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '']]);
DB::purge('business_mirror');
Schema::connection('business_mirror')->create('business_mirror_table_states', function (Blueprint $table): void {
$table->string('dataset_key')->primary();
$table->dateTime('initial_completed_at')->nullable();
});
$registry = new BusinessMirrorDatasetRegistry();
foreach ([SupplierManagementMirrorRepository::DATASET, ...array_values(SupplierManagementMirrorRepository::RELATED)] as $key) {
Schema::connection('business_mirror')->create($registry->get($key)->targetTable(), function (Blueprint $table) use ($registry, $key): void {
foreach ($registry->columnSelection($key) as $column) {
if (strtolower($column) === 'id') $table->integer($column)->primary();
else $table->string($column)->nullable();
}
});
}
$this->repository = new SupplierManagementMirrorRepository($registry, new GenericBusinessMirrorRepository(app('db')));
}
public function test_filters_treat_wildcards_literally_and_pages_are_stable(): void
{
$this->ready(SupplierManagementMirrorRepository::DATASET);
$this->table('js_supplier_management')->insert([
['Id' => 1, 'scmname' => 'A%_供应商', 'buyer' => '采购甲', 'coopersgn' => 1],
['Id' => 2, 'scmname' => 'A%_供应商', 'buyer' => '采购甲', 'coopersgn' => 1],
['Id' => 3, 'scmname' => 'A普通供应商', 'buyer' => '采购乙', 'coopersgn' => 2],
]);
$filters = ['supplier_name' => '%_', 'buyer' => '采购甲', 'cooperation_status' => '1'];
$this->assertSame(2, $this->repository->paginate($filters, 1, 1)['total']);
$this->assertSame(2, $this->repository->paginate($filters, 2, 1)['rows'][0]->Id);
$this->assertSame([1, 2], array_map(fn ($row) => $row->Id, iterator_to_array($this->repository->exportRows($filters))));
}
public function test_right_hand_supplier_fields_survive_pagination_and_export(): void
{
$this->ready(SupplierManagementMirrorRepository::DATASET);
$fields = ['handlePerson' => '测试经办人', 'paycyclesgn' => '月结',
'endTimeB' => '2026-12-31', 'finishTimeA' => '2026-10-01',
'undefined2' => '第三方', 'linkerprovience' => '江苏省', 'linkeradd' => '测试地址',
'craftType' => '板式', 'capacity' => '120', 'region' => '苏北', 'sindou' => '双日'];
$this->table('js_supplier_management')->insert(['Id' => 9, 'scmname' => '完整资料测试'] + $fields);
$page = $this->repository->paginate([], 1, 20);
$export = iterator_to_array($this->repository->exportRows([]));
foreach ($fields as $column => $value) {
$this->assertSame($value, $page['rows'][0]->{$column});
$this->assertSame($value, $export[0]->{$column});
$this->assertArrayHasKey($column, SupplierManagementMirrorRepository::COLUMNS);
}
$columns = (new BusinessMirrorDatasetRegistry())->columnSelection(SupplierManagementMirrorRepository::DATASET);
$this->assertCount(52, $columns);
$this->assertSame([], array_values(array_diff(array_keys(SupplierManagementMirrorRepository::COLUMNS), $columns)));
}
public function test_related_mirror_indexes_can_be_built_from_the_50_character_source_fields(): void
{
$registry = new BusinessMirrorDatasetRegistry();
foreach (SupplierManagementMirrorRepository::RELATED as $key) {
$dataset = $registry->get($key);
foreach ($registry->columnSelection($key) as $position => $name) {
DB::table('upstream_schema_columns')->insert([
'source_key' => 'jiansun', 'schema_name' => 'dbo', 'object_name' => $dataset->sourceObject(),
'object_type' => 'VIEW', 'column_name' => $name, 'ordinal_position' => $position + 1,
'data_type' => strtolower($name) === 'id' ? 'int' : 'varchar', 'max_length' => 50,
'is_nullable' => true, 'synchronized_at' => now(),
'created_at' => now(), 'updated_at' => now(),
]);
}
(new BusinessMirrorSchemaManager())->ensure($dataset);
$indexes = collect(Schema::connection('business_mirror')->getIndexes($dataset->targetTable()))
->pluck('columns')->all();
foreach ($dataset->indexDefinitions() as $columns) $this->assertContains($columns, $indexes);
}
}
public function test_details_do_not_mix_suppliers_or_contract_signing_companies(): void
{
foreach (SupplierManagementMirrorRepository::RELATED as $key) $this->ready($key);
$supplier = (object) ['scmname' => '甲供应商', 'tradebody' => '甲主体', 'company' => '签订公司甲'];
$this->table('js_supplier_contracts')->insert([
['id' => 1, 'tradebody' => '甲主体', 'company' => '签订公司甲', 'title' => '正确合同'],
['id' => 2, 'tradebody' => '甲主体', 'company' => '签订公司乙', 'title' => '其他公司合同'],
]);
foreach (['js_supplier_contacts', 'js_supplier_payment_accounts'] as $table) {
$this->table($table)->insert([['Id' => 1, 'scmname' => '甲供应商'], ['Id' => 2, 'scmname' => '乙供应商']]);
}
foreach (['contracts', 'contacts', 'payments'] as $tab) {
$this->assertSame(1, $this->repository->details($supplier, $tab, 1, 20)['total']);
}
$supplier->company = '';
$this->assertSame(0, $this->repository->details($supplier, 'contracts', 1, 20)['total']);
$supplier->scmname = '';
$this->assertSame(0, $this->repository->details($supplier, 'payments', 1, 20)['total']);
$this->assertFalse($this->repository->details($supplier, 'logs', 1, 20)['ready']);
}
public function test_partial_initial_sync_is_not_presented_as_complete(): void
{
$this->table('js_supplier_management')->insert(['Id' => 1]);
$this->assertFalse($this->repository->ready());
$this->assertSame([], $this->repository->signingOptions());
$this->assertNull($this->repository->signingSupplier(1));
$this->expectException(\RuntimeException::class);
$this->repository->paginate([], 1, 20);
}
public function test_signing_accounts_use_the_account_field_and_keep_real_names_separate(): void
{
$this->ready(SupplierManagementMirrorRepository::DATASET);
$this->table('js_supplier_management')->insert([
['Id' => 7, 'scmname' => '测试供应商', 'scmcode' => 'T007', 'tradebody' => '测试供应商有限公司',
'accountbankno' => '13800138000', 'handlePerson' => '张经理'],
['Id' => 8, 'scmname' => '缺账号供应商', 'scmcode' => 'T008', 'tradebody' => '',
'accountbankno' => null, 'handlePerson' => '李经理'],
]);
$options = collect($this->repository->signingOptions())->keyBy('id');
$this->assertSame('13800138000', $options[7]['account']);
$this->assertSame('张经理', $options[7]['operator']);
$this->assertSame('', $options[8]['account']);
$this->assertSame('13800138000', $this->repository->signingSupplier(7)->accountbankno);
$this->assertNull($this->repository->signingSupplier(999));
}
public function test_supplier_lookup_uses_supplier_codes_for_local_supplements(): void
{
$this->ready(SupplierManagementMirrorRepository::DATASET);
$this->table('js_supplier_management')->insert([
['Id' => 9, 'scmcode' => 'N901', 'scmname' => '一泰'],
['Id' => 11, 'scmcode' => 'Y411', 'scmname' => '七彩'],
]);
$rows = $this->repository->suppliersByCodes(['N901', 'Y411', 'UNKNOWN']);
$this->assertSame([9, 11], array_map(static fn (object $row): int => (int) $row->Id, $rows));
$this->assertSame('一泰', $this->repository->supplierById(9)->scmname);
$this->assertNull($this->repository->supplierById(999));
}
public function test_supplier_lookup_by_exact_names_supports_portal_roster_mapping(): void
{
$this->ready(SupplierManagementMirrorRepository::DATASET);
$this->table('js_supplier_management')->insert([
['Id' => 9, 'scmcode' => 'N901', 'scmname' => '一泰'],
['Id' => 11, 'scmcode' => 'Y411', 'scmname' => '七彩'],
]);
$rows = $this->repository->suppliersByNames(['一泰', '不存在']);
$this->assertCount(1, $rows);
$this->assertSame('N901', $rows[0]->scmcode);
}
private function ready(string $key): void
{
$this->table('business_mirror_table_states')->insert(['dataset_key' => $key, 'initial_completed_at' => '2026-10-11 00:00:00']);
}
private function table(string $name): \Illuminate\Database\Query\Builder
{
return DB::connection('business_mirror')->table($name);
}
}