619 lines
27 KiB
PHP
619 lines
27 KiB
PHP
<?php
|
||
|
||
namespace Tests\Unit\EcommerceFinance;
|
||
|
||
use App\Business\CompanyPlan\CompanyPlanCompanyRepository;
|
||
use App\Business\CompanyPlan\CompanyPlanRepository;
|
||
use App\Business\UpstreamBusinessInformation;
|
||
use Closure;
|
||
use Mockery;
|
||
use Modules\EcommerceFinance\Repositories\BusinessInformationMirrorRepository;
|
||
use Modules\EcommerceFinance\Repositories\StoreAccountMirrorRepository;
|
||
use Modules\EcommerceFinance\Repositories\StoreReportRepository;
|
||
use Modules\EcommerceFinance\Services\UpstreamQueryCache;
|
||
use Modules\EcommerceFinance\Services\UpstreamQueryCacheFactory;
|
||
use Tests\TestCase;
|
||
|
||
class UpstreamBusinessInformationTest extends TestCase
|
||
{
|
||
/**
|
||
* @dataProvider businessInformationPages
|
||
*/
|
||
public function test_local_direct_page_resolver_passes_pagination_to_its_fixed_snapshot(
|
||
string $section,
|
||
string $page,
|
||
string $scope,
|
||
): void {
|
||
config(['upstreams.local_configuration.enabled' => true]);
|
||
$cache = new class extends UpstreamQueryCache {
|
||
public array $calls = [];
|
||
|
||
public function __construct()
|
||
{
|
||
}
|
||
|
||
public function remember(string $scope, array $parameters, Closure $resolver): mixed
|
||
{
|
||
$this->calls[] = compact('scope', 'parameters');
|
||
|
||
return $resolver();
|
||
}
|
||
};
|
||
|
||
$caches = new class($cache) extends UpstreamQueryCacheFactory {
|
||
public function __construct(private readonly UpstreamQueryCache $cache)
|
||
{
|
||
}
|
||
|
||
public function forSource(string $source): UpstreamQueryCache
|
||
{
|
||
return $this->cache;
|
||
}
|
||
};
|
||
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->once()->with($scope)->andReturnFalse();
|
||
|
||
$information = new class($caches, $mirror) extends UpstreamBusinessInformation {
|
||
public array $snapshots = [];
|
||
|
||
public function snapshot(string $scope, array $parameters): array
|
||
{
|
||
$this->snapshots[] = compact('scope', 'parameters');
|
||
|
||
return ['data' => [], 'total' => 0];
|
||
}
|
||
};
|
||
|
||
$this->app['request']->merge(['page' => 3]);
|
||
|
||
$paginator = $information->paginate($section, $page, 25);
|
||
$expected = ['scope' => $scope, 'parameters' => ['page' => 3, 'perPage' => 25]];
|
||
|
||
$this->assertSame(3, $paginator->currentPage());
|
||
$this->assertSame($expected, $cache->calls[0]);
|
||
$this->assertSame($expected, $information->snapshots[0]);
|
||
}
|
||
|
||
/**
|
||
* @dataProvider paginatedBusinessInformationPages
|
||
*/
|
||
public function test_ready_business_mirror_is_used_without_registering_a_page_snapshot(
|
||
string $section,
|
||
string $page,
|
||
string $scope,
|
||
): void {
|
||
config(['operations_replica.enabled' => false, 'upstreams.stored_configuration.enabled' => false]);
|
||
$cache = new class extends UpstreamQueryCache {
|
||
public function __construct() {}
|
||
|
||
public function remember(string $scope, array $parameters, Closure $resolver): mixed
|
||
{
|
||
throw new \RuntimeException('镜像就绪后不应再读取分页快照。');
|
||
}
|
||
};
|
||
$caches = new class($cache) extends UpstreamQueryCacheFactory {
|
||
public function __construct(private readonly UpstreamQueryCache $cache) {}
|
||
|
||
public function forSource(string $source): UpstreamQueryCache { return $this->cache; }
|
||
};
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->once()->with($scope)->andReturnTrue();
|
||
$mirror->shouldReceive('paginate')->once()->with($scope, 2, 25, [])->andReturn([
|
||
'data' => [['id' => 10]],
|
||
'total' => 51,
|
||
]);
|
||
|
||
$this->app['request']->merge(['page' => 2]);
|
||
$paginator = (new UpstreamBusinessInformation($caches, $mirror))
|
||
->paginate($section, $page, 25);
|
||
|
||
$this->assertSame(2, $paginator->currentPage());
|
||
$this->assertSame(51, $paginator->total());
|
||
$this->assertSame(10, $paginator->items()[0]->id);
|
||
}
|
||
|
||
public function test_store_basic_information_uses_account_owner_and_department_head(): void
|
||
{
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->once()->with('store-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('allStores')->once()->with([])->andReturn([
|
||
[
|
||
'id' => 7,
|
||
'erp_store_name' => '拼多多_测试店铺',
|
||
'store_manager' => '旧店铺负责人',
|
||
'department_manager' => '旧部门负责人',
|
||
'store_status' => '0',
|
||
'platform' => '拼多多',
|
||
],
|
||
[
|
||
'id' => 8,
|
||
'erp_store_name' => '拼多多-其他店铺',
|
||
'store_manager' => '其他负责人',
|
||
'department_manager' => '其他部门负责人',
|
||
'store_status' => '6',
|
||
'platform' => '拼多多',
|
||
],
|
||
]);
|
||
$accounts = Mockery::mock(StoreAccountMirrorRepository::class);
|
||
$accounts->shouldReceive('ownershipByStoreName')->once()->andReturn([
|
||
StoreAccountMirrorRepository::storeNameKey('拼多多-测试店铺') => [
|
||
'operation_owner' => '正确店铺负责人',
|
||
'operation_department_head' => '正确部门负责人',
|
||
'operation_director' => '运营总监',
|
||
'profit_center' => '运营中心A',
|
||
],
|
||
]);
|
||
|
||
$this->app['request']->merge([
|
||
'store_manager' => '正确店铺负责人',
|
||
'department_manager' => '正确部门负责人',
|
||
]);
|
||
$paginator = (new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
null,
|
||
$accounts,
|
||
))->paginate('store-management', 'basic-information', 50);
|
||
|
||
$this->assertSame(1, $paginator->total());
|
||
$this->assertSame('正确店铺负责人', $paginator->items()[0]->store_manager);
|
||
$this->assertSame('正确部门负责人', $paginator->items()[0]->department_manager);
|
||
$this->assertNotSame('运营总监', $paginator->items()[0]->department_manager);
|
||
$this->assertSame('正常', $paginator->items()[0]->store_status);
|
||
$summaryCards = collect($this->app['request']->attributes->get('business-page-summary-cards'))->keyBy('label');
|
||
$this->assertSame([], $summaryCards->all());
|
||
}
|
||
|
||
public function test_trademark_classification_is_normalized_to_digits_only(): void
|
||
{
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->once()->with('trademark-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('paginate')->once()->with('trademark-information.read', 1, 50, [])->andReturn([
|
||
'data' => [
|
||
['id' => 1, 'trademark_type' => '第20'],
|
||
['id' => 2, 'trademark_type' => '第20类;第35类'],
|
||
['id' => 3, 'trademark_type' => null],
|
||
],
|
||
'total' => 3,
|
||
]);
|
||
|
||
$paginator = (new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
null,
|
||
))->paginate('trademark-management', 'information', 50);
|
||
|
||
$this->assertSame('20', $paginator->items()[0]->trademark_type);
|
||
$this->assertSame('20,35', $paginator->items()[1]->trademark_type);
|
||
$this->assertNull($paginator->items()[2]->trademark_type);
|
||
}
|
||
|
||
public function test_base_information_pages_do_not_render_summary_cards(): void
|
||
{
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->times(2)->andReturnUsing(
|
||
static fn (string $scope): bool => in_array($scope, ['company-information.read', 'trademark-information.read'], true),
|
||
);
|
||
$mirror->shouldReceive('paginate')->once()->with('company-information.read', 1, 50, [])->andReturn([
|
||
'data' => [],
|
||
'total' => 818,
|
||
'summary' => [
|
||
'total' => 818,
|
||
'normal' => 520,
|
||
'deregistered' => 298,
|
||
'general_taxpayer' => 123,
|
||
'small_taxpayer' => 606,
|
||
],
|
||
]);
|
||
$mirror->shouldReceive('paginate')->once()->with('trademark-information.read', 1, 50, [])->andReturn([
|
||
'data' => [],
|
||
'total' => 593,
|
||
'summary' => [
|
||
'total' => 593,
|
||
'enabled' => 548,
|
||
'disabled' => 45,
|
||
'holders' => 5,
|
||
'departments' => 6,
|
||
],
|
||
]);
|
||
|
||
$information = new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
null,
|
||
);
|
||
$information->paginate('company-management', 'basic-information', 50);
|
||
$companyCards = collect($this->app['request']->attributes->get('business-page-summary-cards'))->keyBy('label');
|
||
$this->assertSame([], $companyCards->all());
|
||
|
||
$information->paginate('trademark-management', 'information', 50);
|
||
$trademarkCards = collect($this->app['request']->attributes->get('business-page-summary-cards'))->keyBy('label');
|
||
$this->assertSame([], $trademarkCards->all());
|
||
}
|
||
|
||
public function test_company_registration_date_is_hidden_for_deregistered_and_invalid_pre_2000_values(): void
|
||
{
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->once()->with('company-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('paginate')->once()->with('company-information.read', 1, 50, [])->andReturn([
|
||
'data' => [
|
||
['id' => 1, 'company_status' => '1', 'establishment_date' => '2024-04-28'],
|
||
['id' => 2, 'company_status' => '已注销', 'establishment_date' => null],
|
||
['id' => 3, 'company_status' => '0', 'establishment_date' => '1900-01-01'],
|
||
['id' => 4, 'company_status' => '正常', 'establishment_date' => '1999-12-31'],
|
||
['id' => 5, 'company_status' => '0', 'establishment_date' => '2000-01-01'],
|
||
['id' => 6, 'company_status' => null, 'establishment_date' => null],
|
||
],
|
||
'total' => 6,
|
||
]);
|
||
|
||
$items = (new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
null,
|
||
))->paginate('company-management', 'basic-information', 50)->items();
|
||
|
||
$this->assertSame('已注销', $items[0]->company_status);
|
||
$this->assertSame('/', $items[0]->establishment_date);
|
||
$this->assertSame('/', $items[1]->establishment_date);
|
||
$this->assertSame('/', $items[2]->establishment_date);
|
||
$this->assertSame('/', $items[3]->establishment_date);
|
||
$this->assertSame('2000-01-01', $items[4]->establishment_date);
|
||
$this->assertNull($items[5]->establishment_date);
|
||
}
|
||
|
||
public function test_company_page_filters_and_overlays_shareholding_relations(): void
|
||
{
|
||
$path = sys_get_temp_dir() . '/caiwu-shareholding-' . bin2hex(random_bytes(6)) . '.sqlite';
|
||
config(['company_plan.database_path' => $path]);
|
||
$shareholder = '常州测试母体有限公司';
|
||
$relatedCompany = '常州测试子公司有限公司';
|
||
|
||
try {
|
||
$relations = app(CompanyPlanCompanyRepository::class);
|
||
$pdo = $relations->pdo();
|
||
$statement = $pdo->prepare(<<<'SQL'
|
||
INSERT INTO company_plan_company_relations (
|
||
company_id, shareholder_company_name, related_company_name,
|
||
related_unified_social_credit_code, share_ratio, shareholders_text,
|
||
source_sheet, created_at, updated_at
|
||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||
SQL);
|
||
$now = now()->toDateTimeString();
|
||
$statement->execute([
|
||
1,
|
||
$shareholder,
|
||
$relatedCompany,
|
||
'TEST-CHILD-UNIT',
|
||
'100.00',
|
||
$shareholder . ':100.00',
|
||
'主体明细',
|
||
$now,
|
||
$now,
|
||
]);
|
||
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')
|
||
->once()
|
||
->with('company-information.read')
|
||
->andReturnTrue();
|
||
$mirror->shouldReceive('paginate')
|
||
->once()
|
||
->withArgs(static fn (
|
||
string $scope,
|
||
int $page,
|
||
int $perPage,
|
||
array $filters,
|
||
): bool => $scope === 'company-information.read'
|
||
&& $page === 1
|
||
&& $perPage === 50
|
||
&& $filters['_company_names'] === [$relatedCompany])
|
||
->andReturn([
|
||
'data' => [[
|
||
'id' => 901,
|
||
'company_name' => $relatedCompany,
|
||
'company_status' => '0',
|
||
'taxpayer_category' => '小规模纳税人',
|
||
]],
|
||
'total' => 1,
|
||
]);
|
||
|
||
$this->app['request']->merge(['shareholder_company' => $shareholder]);
|
||
$paginator = (new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
null,
|
||
))->paginate('company-management', 'basic-information', 50);
|
||
|
||
$this->assertSame(1, $paginator->total());
|
||
$this->assertSame($relatedCompany, $paginator->items()[0]->company_name);
|
||
$this->assertSame($shareholder . ':100.00', $paginator->items()[0]->shareholders);
|
||
} finally {
|
||
@unlink($path);
|
||
@unlink($path . '-wal');
|
||
@unlink($path . '-shm');
|
||
}
|
||
}
|
||
|
||
public function test_company_tax_and_business_types_prefer_company_plan_by_name_or_credit_code(): void
|
||
{
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->once()->with('company-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('paginate')->once()->with('company-information.read', 1, 50, [])->andReturn([
|
||
'data' => [
|
||
[
|
||
'id' => 1,
|
||
'company_name' => '名称匹配公司',
|
||
'unified_social_credit_code' => 'CODE-1',
|
||
'taxpayer_category' => '旧税务类型',
|
||
'business_registration_type' => '/',
|
||
],
|
||
[
|
||
'id' => 2,
|
||
'company_name' => '未盘点公司',
|
||
'unified_social_credit_code' => 'CODE-2',
|
||
'taxpayer_category' => '一般纳税人',
|
||
'business_registration_type' => '个人独资企业',
|
||
],
|
||
[
|
||
'id' => 3,
|
||
'company_name' => '基础资料旧名称',
|
||
'unified_social_credit_code' => 'CODE-3',
|
||
'taxpayer_category' => '旧税务类型',
|
||
'business_registration_type' => '/',
|
||
],
|
||
],
|
||
'total' => 3,
|
||
]);
|
||
$companyPlans = Mockery::mock(CompanyPlanRepository::class);
|
||
$companyPlans->shouldReceive('classificationFilterOptions')
|
||
->once()
|
||
->with((int) (company_id() ?: 1))
|
||
->andReturn([
|
||
'taxpayer_type' => ['小规模纳税人', '一般纳税人'],
|
||
'business_registration_type' => ['核定', '有限责任公司'],
|
||
]);
|
||
$companyPlans->shouldReceive('classificationReferencesForCompanies')
|
||
->once()
|
||
->with(
|
||
(int) (company_id() ?: 1),
|
||
['名称匹配公司', '未盘点公司', '基础资料旧名称'],
|
||
['CODE-1', 'CODE-2', 'CODE-3'],
|
||
)
|
||
->andReturn([
|
||
[
|
||
'company_name' => '名称匹配公司',
|
||
'unified_social_credit_code' => 'CODE-1',
|
||
'taxpayer_type' => '小规模纳税人',
|
||
'business_registration_type' => '核定',
|
||
],
|
||
[
|
||
'company_name' => '盘点中的新名称',
|
||
'unified_social_credit_code' => 'CODE-3',
|
||
'taxpayer_type' => '一般纳税人',
|
||
'business_registration_type' => '有限责任公司',
|
||
],
|
||
]);
|
||
|
||
$items = (new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
null,
|
||
null,
|
||
null,
|
||
$companyPlans,
|
||
))->paginate('company-management', 'basic-information', 50)->items();
|
||
|
||
$this->assertSame('小规模纳税人', $items[0]->taxpayer_category);
|
||
$this->assertSame('核定', $items[0]->business_registration_type);
|
||
$this->assertSame('一般纳税人', $items[1]->taxpayer_category);
|
||
$this->assertSame('个人独资企业', $items[1]->business_registration_type);
|
||
$this->assertSame('一般纳税人', $items[2]->taxpayer_category);
|
||
$this->assertSame('有限责任公司', $items[2]->business_registration_type);
|
||
}
|
||
|
||
public function test_company_tax_filter_uses_company_plan_values(): void
|
||
{
|
||
$this->app['request']->merge([
|
||
'company_status' => '正常',
|
||
'taxpayer_type' => '一般纳税人',
|
||
]);
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('allCompaniesForClassification')
|
||
->once()
|
||
->with(['company_status' => '正常'])
|
||
->andReturn([
|
||
[
|
||
'id' => 2,
|
||
'company_name' => '旧口径为小规模',
|
||
'unified_social_credit_code' => 'CODE-1',
|
||
'taxpayer_category' => '小规模纳税人',
|
||
'business_registration_type' => '/',
|
||
],
|
||
[
|
||
'id' => 1,
|
||
'company_name' => '盘点为一般纳税人',
|
||
'unified_social_credit_code' => 'CODE-2',
|
||
'taxpayer_category' => '小规模纳税人',
|
||
'business_registration_type' => '/',
|
||
],
|
||
]);
|
||
$companyPlans = Mockery::mock(CompanyPlanRepository::class);
|
||
$companyPlans->shouldReceive('classificationFilterOptions')
|
||
->once()
|
||
->with((int) (company_id() ?: 1))
|
||
->andReturn([
|
||
'taxpayer_type' => ['小规模纳税人', '一般纳税人'],
|
||
'business_registration_type' => ['/'],
|
||
]);
|
||
$companyPlans->shouldReceive('allClassificationReferences')
|
||
->once()
|
||
->with((int) (company_id() ?: 1))
|
||
->andReturn([
|
||
[
|
||
'company_name' => '旧口径为小规模',
|
||
'unified_social_credit_code' => 'CODE-1',
|
||
'taxpayer_type' => '一般纳税人',
|
||
'business_registration_type' => '/',
|
||
],
|
||
[
|
||
'company_name' => '盘点为一般纳税人',
|
||
'unified_social_credit_code' => 'CODE-2',
|
||
'taxpayer_type' => '小规模纳税人',
|
||
'business_registration_type' => '/',
|
||
],
|
||
]);
|
||
|
||
$paginator = (new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
null,
|
||
null,
|
||
null,
|
||
$companyPlans,
|
||
))->paginate('company-management', 'basic-information', 50);
|
||
|
||
$this->assertSame(1, $paginator->total());
|
||
$this->assertSame('旧口径为小规模', $paginator->items()[0]->company_name);
|
||
$this->assertSame('一般纳税人', $paginator->items()[0]->taxpayer_category);
|
||
}
|
||
|
||
public function test_bootstrap_without_mirror_explains_shared_connection_instead_of_requesting_upstream_credentials(): void
|
||
{
|
||
config(['system_database.mode' => 'bootstrap', 'upstreams.local_configuration.enabled' => false]);
|
||
$caches = Mockery::mock(UpstreamQueryCacheFactory::class);
|
||
$caches->shouldNotReceive('forSource');
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->once()->with('store-information.read')->andReturnFalse();
|
||
$this->expectException(\Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException::class);
|
||
$this->expectExceptionMessage('无需另配上游 SQL Server');
|
||
(new UpstreamBusinessInformation($caches, $mirror))
|
||
->paginate('store-management', 'basic-information');
|
||
}
|
||
|
||
public function test_subject_operating_report_hides_income_months_without_data_by_default(): void
|
||
{
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->with('store-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('allStores')->andReturn([['erp_store_name' => '测试店铺']]);
|
||
$mirror->shouldReceive('ready')->with('company-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('companiesByNames')->andReturn([]);
|
||
$mirror->shouldReceive('companyClassificationsByNames')->andReturn([]);
|
||
|
||
$storeReports = Mockery::mock(StoreReportRepository::class);
|
||
$storeReports->shouldReceive('rows')->andReturn([[
|
||
'entity' => '测试主体',
|
||
'company_type' => '店铺-普通公司',
|
||
'rolling_12m_income' => 188.5,
|
||
'income_01' => null,
|
||
'income_02' => 88.5,
|
||
'income_03' => 0.0,
|
||
'income_04' => null,
|
||
'income_05' => null,
|
||
'income_06' => null,
|
||
'income_07' => null,
|
||
'income_08' => null,
|
||
'income_09' => null,
|
||
'income_10' => null,
|
||
'income_11' => null,
|
||
'income_12' => null,
|
||
]]);
|
||
$storeAccounts = Mockery::mock(StoreAccountMirrorRepository::class);
|
||
$storeAccounts->shouldReceive('ownershipByStoreName')->andReturn([]);
|
||
|
||
$information = new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
$storeReports,
|
||
$storeAccounts,
|
||
);
|
||
|
||
$paginator = $information->paginate('company-management', 'subject-operating-report', 50);
|
||
|
||
$this->assertSame(
|
||
['income_01', 'income_04', 'income_05', 'income_06', 'income_07', 'income_08', 'income_09', 'income_10', 'income_11', 'income_12'],
|
||
$this->app['request']->attributes->get('subject-operating-report.default_hidden_columns'),
|
||
);
|
||
$this->assertSame(1, $paginator->total());
|
||
$this->assertSame('测试主体', $paginator->items()[0]->entity);
|
||
}
|
||
|
||
public function test_subject_status_counts_use_all_rows_in_the_current_filter_result(): void
|
||
{
|
||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||
$mirror->shouldReceive('ready')->with('store-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('allStores')->once()->andReturn([['erp_store_name' => '测试店铺']]);
|
||
$mirror->shouldReceive('ready')->with('company-information.read')->andReturnTrue();
|
||
$mirror->shouldReceive('companiesByNames')->once()->andReturn([]);
|
||
$mirror->shouldReceive('companyClassificationsByNames')->once()->andReturn([
|
||
'主体甲' => [
|
||
'status' => '保留',
|
||
'tax_type' => '小规模纳税人',
|
||
'business_registration_type' => '个人独资企业',
|
||
],
|
||
'主体乙' => [
|
||
'status' => '待注销',
|
||
'tax_type' => '一般纳税人',
|
||
'business_registration_type' => '核定',
|
||
],
|
||
]);
|
||
|
||
$storeReports = Mockery::mock(StoreReportRepository::class);
|
||
$storeReports->shouldReceive('rows')->once()->andReturn([
|
||
[
|
||
'entity' => '主体甲',
|
||
'company_type' => '店铺-普通公司',
|
||
'rolling_12m_income' => 100,
|
||
],
|
||
[
|
||
'entity' => '主体乙',
|
||
'company_type' => '店铺-国标公司',
|
||
'rolling_12m_income' => 200,
|
||
],
|
||
]);
|
||
$storeAccounts = Mockery::mock(StoreAccountMirrorRepository::class);
|
||
$storeAccounts->shouldReceive('ownershipByStoreName')->once()->andReturn([]);
|
||
|
||
$information = new UpstreamBusinessInformation(
|
||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||
$mirror,
|
||
$storeReports,
|
||
$storeAccounts,
|
||
);
|
||
|
||
$paginator = $information->paginate('company-management', 'subject-operating-report', 1);
|
||
$counts = $this->app['request']->attributes->get('directory.status-counts');
|
||
$fields = collect($counts['fields'])->keyBy('name');
|
||
$valueCounts = static fn (string $field): array => collect($fields[$field]['values'])->pluck('count', 'value')->all();
|
||
|
||
$this->assertSame(2, $paginator->total());
|
||
$this->assertCount(1, $paginator->items());
|
||
$this->assertSame(2, $counts['total']);
|
||
$this->assertSame(1, $valueCounts('company_status')['正常']);
|
||
$this->assertSame(1, $valueCounts('company_status')['已注销']);
|
||
$this->assertSame(1, $valueCounts('company_type')['店铺-普通公司']);
|
||
$this->assertSame(1, $valueCounts('company_type')['店铺-国标公司']);
|
||
$this->assertSame(1, $valueCounts('tax_type')['小规模纳税人']);
|
||
$this->assertSame(1, $valueCounts('tax_type')['一般纳税人']);
|
||
$this->assertSame(2, $valueCounts('plan')['']);
|
||
}
|
||
|
||
public static function businessInformationPages(): array
|
||
{
|
||
return [
|
||
'company' => ['company-management', 'basic-information', 'company-information.read'],
|
||
'store' => ['store-management', 'basic-information', 'store-information.read'],
|
||
'trademark' => ['trademark-management', 'information', 'trademark-information.read'],
|
||
];
|
||
}
|
||
|
||
public static function paginatedBusinessInformationPages(): array
|
||
{
|
||
return [
|
||
'company' => ['company-management', 'basic-information', 'company-information.read'],
|
||
'trademark' => ['trademark-management', 'information', 'trademark-information.read'],
|
||
];
|
||
}
|
||
}
|