feat: 판매대장 크기 필터를 봉투/음식물/폐기물 카테고리별 그룹으로

- 크기 드롭다운을 카테고리별 optgroup(봉투(일반용)/음식물/폐기물 등)으로 묶음
- 선택값을 '카테고리|크기'(예: general|3L)로 바꿔 카테고리+크기 조합 필터링
- 엑셀저장에도 size 파라미터 반영(기존 누락 수정)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
taekyoungc
2026-06-25 14:41:55 +09:00
parent d366661b4b
commit bdeef2c69d
2 changed files with 58 additions and 15 deletions

View File

@@ -87,24 +87,59 @@ class SalesReport extends BaseController
}
return '';
};
// 현재(카테고리 필터까지 적용된) 결과에서 선택 가능한 크기 목록 구성
$sizeOptions = [];
// 봉투(일반용)/음식물/폐기물 등 카테고리별로 선택 가능한 크기 목록 구성한다.
// (카테고리 필터까지 적용된 현재 결과 기준)
$sizeCatLabels = [
'general' => '봉투(일반용)',
'food' => '음식물',
'waste' => '폐기물',
'sticker' => '스티커',
'reuse' => '재사용',
'apt' => '공동주택용',
'public_use' => '공공용',
'container' => '용기',
];
$sizeCatOrder = ['general', 'food', 'waste', 'sticker', 'reuse', 'apt', 'public_use', 'container'];
$sizeByCat = []; // catKey => [size => true]
foreach ($filtered as $row) {
$sz = $sizeOf((string) ($row->bs_bag_name ?? ''));
if ($sz !== '') {
$sizeOptions[$sz] = true;
if ($sz === '') {
continue;
}
$ck = $this->classifyLedgerProductCategory(
(string) ($row->bs_bag_name ?? ''),
(string) ($row->bs_bag_code ?? '')
);
$sizeByCat[$ck][$sz] = true;
}
$sizeGroups = [];
foreach ($sizeCatOrder as $ck) {
if (empty($sizeByCat[$ck])) {
continue;
}
$sizes = array_keys($sizeByCat[$ck]);
usort($sizes, static function (string $a, string $b): int {
return (int) preg_replace('/\D/', '', $a) <=> (int) preg_replace('/\D/', '', $b);
});
$sizeGroups[] = ['key' => $ck, 'label' => $sizeCatLabels[$ck] ?? $ck, 'sizes' => $sizes];
}
$sizeOptions = array_keys($sizeOptions);
usort($sizeOptions, static function (string $a, string $b): int {
$na = (int) preg_replace('/\D/', '', $a);
$nb = (int) preg_replace('/\D/', '', $b);
return $na <=> $nb;
});
// 선택값은 "카테고리|크기" 형식(예: general|10L). 구버전(크기만) 값도 호환.
$size = trim((string) ($this->request->getGet('size') ?? ''));
if ($size !== '') {
$filtered = array_values(array_filter($filtered, static fn ($row): bool => $sizeOf((string) ($row->bs_bag_name ?? '')) === $size));
if (strpos($size, '|') !== false) {
[$selCat, $selSize] = array_pad(explode('|', $size, 2), 2, '');
$filtered = array_values(array_filter($filtered, function ($row) use ($sizeOf, $selCat, $selSize): bool {
$ck = $this->classifyLedgerProductCategory(
(string) ($row->bs_bag_name ?? ''),
(string) ($row->bs_bag_code ?? '')
);
return $ck === $selCat && $sizeOf((string) ($row->bs_bag_name ?? '')) === $selSize;
}));
} else {
$filtered = array_values(array_filter($filtered, static fn ($row): bool => $sizeOf((string) ($row->bs_bag_name ?? '')) === $size));
}
}
if ($mode === 'daily') {
@@ -199,7 +234,7 @@ class SalesReport extends BaseController
'dsIdx' => $dsIdx,
'saIdx' => $saIdx,
'cats' => $cats,
'sizeOptions' => $sizeOptions,
'sizeGroups' => $sizeGroups,
'size' => $size,
'shops' => $shops,
'agencies' => $agencies,