diff --git a/app/Controllers/Admin/SalesReport.php b/app/Controllers/Admin/SalesReport.php index c7715f5..18e53ff 100644 --- a/app/Controllers/Admin/SalesReport.php +++ b/app/Controllers/Admin/SalesReport.php @@ -141,6 +141,10 @@ class SalesReport extends BaseController } } + // 하단 통계: 현재 필터(카테고리·크기)까지 적용된 결과 기준으로 + // ① 용량별(리터별) ② 품목별(봉투/음식물/폐기물) 집계 + [$sizeStats, $catStats] = $this->buildLedgerBottomStats($filtered, $sizeOf); + if ($mode === 'daily') { $built = $this->buildDailyLedgerPresentation($filtered, $hasBsFee); } else { @@ -235,6 +239,8 @@ class SalesReport extends BaseController 'cats' => $cats, 'sizeGroups' => $sizeGroups, 'size' => $size, + 'sizeStats' => $sizeStats, + 'catStats' => $catStats, 'shops' => $shops, 'agencies' => $agencies, 'lgName' => $lgName, @@ -286,6 +292,68 @@ class SalesReport extends BaseController return $builder->get()->getResult(); } + /** + * 판매대장 하단 통계: 용량별(리터별)·품목별(봉투/음식물/폐기물) 집계. + * + * @param list $rows 필터가 적용된 상세 판매행 + * @param callable $sizeOf 품목명 → 크기 토큰(예: '10L', '1000원', '') + * @return array{0: list, 1: list} + */ + private function buildLedgerBottomStats(array $rows, callable $sizeOf): array + { + $bySize = []; // 크기토큰 => [qty, amount] + $byCat = []; // '봉투'|'음식물'|'폐기물' => [qty, amount] + + foreach ($rows as $row) { + $name = (string) ($row->bs_bag_name ?? ''); + $qty = (int) ($row->line_qty ?? 0); + $amt = (float) ($row->line_amount ?? 0); + + // ① 용량별(리터별) — 크기 토큰이 없으면 '기타' + $sz = (string) $sizeOf($name); + if ($sz === '') { + $sz = '기타'; + } + $bySize[$sz]['qty'] = ($bySize[$sz]['qty'] ?? 0) + $qty; + $bySize[$sz]['amount'] = ($bySize[$sz]['amount'] ?? 0) + $amt; + + // ② 품목별 — 봉투/음식물/폐기물 3분류 + if (mb_strpos($name, '음식물') !== false) { + $cat = '음식물'; + } elseif (mb_strpos($name, '폐기물') !== false || mb_strpos($name, '대형') !== false) { + $cat = '폐기물'; + } else { + $cat = '봉투'; + } + $byCat[$cat]['qty'] = ($byCat[$cat]['qty'] ?? 0) + $qty; + $byCat[$cat]['amount'] = ($byCat[$cat]['amount'] ?? 0) + $amt; + } + + // 용량별: 숫자(리터/금액) 오름차순, '기타'는 맨 뒤 + $sizeStats = []; + foreach ($bySize as $label => $v) { + $sizeStats[] = ['label' => (string) $label, 'qty' => (int) $v['qty'], 'amount' => (int) round($v['amount'])]; + } + usort($sizeStats, static function (array $a, array $b): int { + $ao = $a['label'] === '기타' ? 1 : 0; + $bo = $b['label'] === '기타' ? 1 : 0; + if ($ao !== $bo) { + return $ao <=> $bo; + } + return (int) preg_replace('/\D/', '', $a['label']) <=> (int) preg_replace('/\D/', '', $b['label']); + }); + + // 품목별: 봉투 → 음식물 → 폐기물 고정 순서 + $catStats = []; + foreach (['봉투', '음식물', '폐기물'] as $c) { + if (isset($byCat[$c])) { + $catStats[] = ['label' => $c, 'qty' => (int) $byCat[$c]['qty'], 'amount' => (int) round($byCat[$c]['amount'])]; + } + } + + return [$sizeStats, $catStats]; + } + /** * @param list $cats 빈 배열이면 전체 */ diff --git a/app/Views/admin/sales_report/sales_ledger.php b/app/Views/admin/sales_report/sales_ledger.php index 8a77e5c..a31721f 100644 --- a/app/Views/admin/sales_report/sales_ledger.php +++ b/app/Views/admin/sales_report/sales_ledger.php @@ -250,6 +250,80 @@ $excelUrl = mgmt_url('reports/sales-ledger?' . http_build_query($exportParams));

판매건수(상세 행):

+ + (int) $r['qty'], $sizeStats)); + $sizeTotAmt = array_sum(array_map(static fn ($r) => (int) $r['amount'], $sizeStats)); + $catTotQty = array_sum(array_map(static fn ($r) => (int) $r['qty'], $catStats)); + $catTotAmt = array_sum(array_map(static fn ($r) => (int) $r['amount'], $catStats)); + ?> +
+ +
+
용량별(리터별) 통계
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
용량판매량(매)판매금액(원)
데이터 없음
합계
+
+ + +
+
품목별(봉투·음식물·폐기물) 통계
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
품목판매량(매)판매금액(원)
데이터 없음
합계
+
+