feat(财务台账): 法人筛选显示账户数量 #515

Merged
shanshi merged 2 commits from feature/shanshi-unretained-legal-count into main 2026-10-24 19:21:05 +08:00
2 changed files with 110 additions and 6 deletions

View File

@ -363,9 +363,22 @@ class FinanceLedger extends Controller
if (isset($textFilterColumns[$headerFilterColumn])) {
$query->where($textFilterColumns[$headerFilterColumn], 'like', '%' . $headerFilterValue . '%');
} elseif ($headerFilterColumn === 'legal_representative') {
$matchingCompanies = collect($legalRepresentatives)
->filter(static fn ($name): bool => str_contains((string) $name, $headerFilterValue))
->keys()
$legalFilterValue = trim((string) preg_replace('/[((]\d+[))]\s*$/u', '', $headerFilterValue));
$allCompanyNames = $headerOptionRows
->pluck('company_name')
->map(static fn ($name): string => trim((string) $name))
->filter()
->unique()
->values();
$matchingEmptyValues = in_array($legalFilterValue, ['__empty__', '未填写'], true);
$matchingCompanies = $allCompanyNames
->filter(static function ($companyName) use ($legalRepresentatives, $legalFilterValue, $matchingEmptyValues): bool {
$representative = trim((string) ($legalRepresentatives[$companyName] ?? ''));
return $matchingEmptyValues
? $representative === ''
: str_contains($representative, $legalFilterValue);
})
->all();
if ($matchingCompanies === []) {
$query->whereRaw('1 = 0');
@ -436,6 +449,12 @@ class FinanceLedger extends Controller
}
}
$legalRepresentativeCountSource = in_array($headerFilterColumn, ['', 'legal_representative'], true)
? $headerOptionRows->pluck('company_name')
: (clone $query)
->reorder()
->select('accounts.company_name')
->pluck('accounts.company_name');
$summaryQuery = clone $query;
$summary = [
'count' => (clone $query)->count(),
@ -541,12 +560,23 @@ class FinanceLedger extends Controller
};
$hasEmpty = static fn (string $column): bool => $headerOptionRows
->contains(static fn ($row): bool => trim((string) ($row->{$column} ?? '')) === '');
$legalRepresentativeCounts = $legalRepresentativeCountSource->countBy(
static fn ($companyName): string => trim((string) ($legalRepresentatives[trim((string) $companyName)] ?? '')),
);
$legalRepresentativeOptions = [];
if (($legalRepresentativeCounts[''] ?? 0) > 0) {
$legalRepresentativeOptions[] = '未填写(' . $legalRepresentativeCounts[''] . ')';
}
$legalRepresentativeCounts
->except([''])
->sortKeys(SORT_NATURAL | SORT_FLAG_CASE)
->each(static function ($count, $name) use (&$legalRepresentativeOptions): void {
$legalRepresentativeOptions[] = $name . '(' . $count . ')';
});
$keepHeaderOptions = [
'company_name' => $headerOptionValues($headerOptionRows->pluck('company_name'), $hasEmpty('company_name')),
'account_short' => $headerOptionValues($headerOptionRows->pluck('account_short'), $hasEmpty('account_short')),
'legal_representative' => $headerOptionValues(array_values($legalRepresentatives), $headerOptionRows->contains(
static fn ($row): bool => trim((string) ($legalRepresentatives[trim((string) $row->company_name)] ?? '')) === '',
)),
'legal_representative' => $legalRepresentativeOptions,
'account_type' => $headerOptionValues($typeOptions, true),
'account_status' => $headerOptionValues(array_values(FinanceLedgerAccountStatus::OPTIONS)),
'account_no' => $headerOptionValues($headerOptionRows->pluck('account_no'), $hasEmpty('account_no')),

View File

@ -303,6 +303,80 @@ class FinanceLedgerAccountKeepTodoTest extends FeatureTestCase
$this->assertSame(['排序账户甲', '排序账户乙'], $sort('current_progress', 'desc'));
}
public function test_legal_representative_filter_options_show_account_counts(): void
{
$connection = DB::connection('business_mirror');
$connection->table('fin_accounts')->insert([
[
'company_name' => '法人计数公司甲',
'account_short' => '法人计数甲一',
'account_type' => '网商银行',
'company_plan' => '保留',
'account_should_keep' => '否',
],
[
'company_name' => '法人计数公司甲',
'account_short' => '法人计数甲二',
'account_type' => '公户',
'company_plan' => '保留',
'account_should_keep' => '否',
],
[
'company_name' => '法人计数公司乙',
'account_short' => '法人计数乙',
'account_type' => '网商银行',
'company_plan' => '保留',
'account_should_keep' => '否',
],
]);
$connection->table('ops_fys_company_info')->insert([
'Id' => 31,
'businessLicenseName' => '法人计数公司甲',
'legalRepresentative' => '王法人',
]);
$optionsResponse = $this->loginAs()->get($this->keepTasksUrl())->assertOk();
preg_match(
'/<datalist id="ledger-header-options-keep-legal_representative">(.*?)<\/datalist>/su',
$optionsResponse->getContent(),
$legalRepresentativeOptions,
);
$legalRepresentativeOptions = $legalRepresentativeOptions[1] ?? '';
$this->assertStringContainsString('value="王法人(2)"', $legalRepresentativeOptions);
$this->assertStringContainsString('value="未填写(1)"', $legalRepresentativeOptions);
$this->assertStringNotContainsString('__empty__', $legalRepresentativeOptions);
$typeFilteredResponse = $this->loginAs()->get($this->keepTasksUrl([
'keep_filter_column' => 'account_type',
'keep_filter_value' => '网商银行',
]))->assertOk();
preg_match(
'/<datalist id="ledger-header-options-keep-legal_representative">(.*?)<\/datalist>/su',
$typeFilteredResponse->getContent(),
$typeFilteredLegalOptions,
);
$typeFilteredLegalOptions = $typeFilteredLegalOptions[1] ?? '';
$this->assertStringContainsString('value="王法人(1)"', $typeFilteredLegalOptions);
$this->assertStringContainsString('value="未填写(1)"', $typeFilteredLegalOptions);
$this->assertStringNotContainsString('王法人(2)', $typeFilteredLegalOptions);
$this->loginAs()->get($this->keepTasksUrl([
'keep_filter_column' => 'legal_representative',
'keep_filter_value' => '王法人(2)',
]))->assertOk()
->assertSee('data-keep-account="法人计数甲一"', false)
->assertSee('data-keep-account="法人计数甲二"', false)
->assertDontSee('data-keep-account="法人计数乙"', false);
$this->loginAs()->get($this->keepTasksUrl([
'keep_filter_column' => 'legal_representative',
'keep_filter_value' => '未填写(1)',
]))->assertOk()
->assertSee('data-keep-account="法人计数乙"', false)
->assertDontSee('data-keep-account="法人计数甲一"', false)
->assertDontSee('data-keep-account="法人计数甲二"', false);
}
public function test_keep_tasks_header_filters_apply_with_typeahead_options(): void
{
$connection = DB::connection('business_mirror');