사이트·관리자 봉투 물류 기능(수불·통계·레포트·재고·발주)과 DB·메뉴·E2E를 운영 반영한다.

통계 분석(전년대비·월별·계절별), 수급계획·LOT 수불, 지정판매소·실사·메뉴 링크 등을 포함한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
taekyoungc
2026-06-01 16:15:15 +09:00
parent 21e7b91871
commit 0f1d414f37
129 changed files with 18068 additions and 1585 deletions

View File

@@ -1,106 +1,140 @@
<?= view('components/print_header', ['printTitle' => '일계표']) ?>
<section class="border-b border-gray-300 p-2 shrink-0 bg-control-panel">
<?php
declare(strict_types=1);
/** @var list<array<string,mixed>> $tableRows */
/** @var string $date */
/** @var string $monthStart */
/** @var int $saIdx */
/** @var string $catFilter */
/** @var list<object> $agencies */
/** @var array<string,string> $catLabels */
/** @var bool $hasBsFee */
/** @var string $lgName */
/** @var string $agencyLabel */
/** @var string $catLabelFilter */
/** @var list<string> $printExtraLines */
$exportParams = array_filter([
'date' => $date ?? '',
'sa_idx' => (int) ($saIdx ?? 0),
'cat' => (string) ($catFilter ?? ''),
'export' => '1',
], static fn ($v): bool => $v !== '' && $v !== null);
$excelUrl = mgmt_url('reports/daily-summary?' . http_build_query($exportParams));
?>
<?= view('components/print_header', [
'printTitle' => '일계표',
'printExtraLines' => $printExtraLines ?? [],
]) ?>
<section class="border-b border-gray-300 p-2 shrink-0 bg-control-panel no-print">
<div class="flex flex-wrap items-center justify-between gap-y-2">
<span class="text-sm font-bold text-gray-700">일계표</span>
<button onclick="window.print()" class="no-print border border-btn-print-border text-gray-600 px-3 py-1 rounded-sm text-sm hover:bg-gray-50 transition">인쇄</button>
<div class="flex flex-wrap gap-2">
<button type="button" onclick="window.print()" class="border border-btn-print-border text-gray-600 px-3 py-1 rounded-sm text-sm hover:bg-gray-50 transition">인쇄</button>
<a href="<?= esc($excelUrl, 'attr') ?>" class="inline-flex items-center border border-green-600 text-green-700 px-3 py-1 rounded-sm text-sm hover:bg-green-50 transition">엑셀저장</a>
</div>
</div>
</section>
<section class="p-2 bg-white border-b border-gray-200">
<form method="GET" action="<?= mgmt_url('reports/daily-summary') ?>" class="flex flex-wrap items-center gap-2">
<label class="text-sm text-gray-600">조회일</label>
<input type="date" name="date" value="<?= esc($date ?? '') ?>" class="border border-gray-300 rounded px-2 py-1 text-sm"/>
<button type="submit" class="bg-btn-search text-white px-4 py-1 rounded-sm text-sm">조회</button>
<section class="p-3 bg-white border-b border-gray-200 no-print">
<form method="GET" action="<?= mgmt_url('reports/daily-summary') ?>" class="flex flex-wrap items-end gap-3 text-sm">
<div>
<label class="block text-gray-600 mb-0.5">조회일자</label>
<input type="date" name="date" value="<?= esc($date ?? '') ?>" class="border border-gray-300 rounded px-2 py-1 text-sm"/>
</div>
<div>
<label class="block text-gray-600 mb-0.5">대행소</label>
<select name="sa_idx" class="border border-gray-300 rounded px-2 py-1 text-sm min-w-[12rem] max-w-[20rem]">
<option value="0">전체</option>
<?php foreach ($agencies ?? [] as $agency): ?>
<?php $aid = (int) ($agency->sa_idx ?? 0); ?>
<option value="<?= esc((string) $aid) ?>" <?= (int) ($saIdx ?? 0) === $aid ? 'selected' : '' ?>>
<?= esc(trim((string) ($agency->sa_name ?? ''))) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label class="block text-gray-600 mb-0.5">구분</label>
<select name="cat" class="border border-gray-300 rounded px-2 py-1 text-sm min-w-[10rem]">
<option value="" <?= ($catFilter ?? '') === '' ? 'selected' : '' ?>>전체</option>
<?php foreach (($catLabels ?? []) as $ck => $lab): ?>
<option value="<?= esc($ck, 'attr') ?>" <?= ($catFilter ?? '') === $ck ? 'selected' : '' ?>><?= esc($lab) ?></option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" class="bg-btn-search text-white px-4 py-1.5 rounded-sm text-sm">조회</button>
</form>
</section>
<div class="flex gap-4 mt-2">
<!-- 당일 -->
<div class="flex-1 border border-gray-300 overflow-auto">
<div class="bg-gray-100 border-b border-gray-300 px-3 py-1.5">
<span class="text-sm font-bold text-gray-700">당일 (<?= esc($date ?? '') ?>)</span>
</div>
<table class="w-full data-table">
<thead>
<tr>
<th>봉투코드</th>
<th>봉투명</th>
<th>판매수량</th>
<th>판매금액</th>
</tr>
</thead>
<tbody class="text-right">
<?php
$dailySaleQtyTotal = 0;
$dailySaleAmountTotal = 0;
?>
<?php foreach ($daily as $row): ?>
<?php
$dailySaleQtyTotal += (int) $row->sale_qty;
$dailySaleAmountTotal += (int) $row->sale_amount;
?>
<tr>
<td class="text-center font-mono"><?= esc($row->bs_bag_code) ?></td>
<td class="text-left pl-2"><?= esc($row->bs_bag_name) ?></td>
<td><?= number_format((int) $row->sale_qty) ?></td>
<td><?= number_format((int) $row->sale_amount) ?></td>
</tr>
<?php endforeach; ?>
<?php if (empty($daily)): ?>
<tr><td colspan="4" class="text-center text-gray-400 py-4">조회된 데이터가 없습니다.</td></tr>
<?php endif; ?>
</tbody>
<tfoot class="bg-gray-50 font-bold text-right">
<tr>
<td colspan="2" class="text-center">합계</td>
<td><?= number_format($dailySaleQtyTotal) ?></td>
<td><?= number_format($dailySaleAmountTotal) ?></td>
</tr>
</tfoot>
</table>
<section class="p-3 bg-white">
<style>
@media print {
.daily-summary-screen-title { display: none !important; }
}
</style>
<div class="mb-2 text-center daily-summary-screen-title no-print">
<h1 class="text-lg font-bold m-0">일계표</h1>
<p class="text-sm text-gray-700 m-1"><?= esc(trim(($lgName ?? '') . ' · 조회일: ' . ($date ?? '') . ' · 대행소: ' . ($agencyLabel ?? '') . ' · 구분: ' . ($catLabelFilter ?? ''))) ?></p>
<p class="text-xs text-gray-500 m-0">누계(월): <?= esc(($monthStart ?? '') . ' ~ ' . ($date ?? '')) ?> · (단위: 매 / 원)</p>
</div>
<!-- 당월 누계 -->
<div class="flex-1 border border-gray-300 overflow-auto">
<div class="bg-gray-100 border-b border-gray-300 px-3 py-1.5">
<span class="text-sm font-bold text-gray-700">당월 누계 (<?= esc($monthStart ?? '') ?> ~ <?= esc($date ?? '') ?>)</span>
</div>
<table class="w-full data-table">
<div class="border border-gray-300 overflow-auto">
<table class="w-full data-table text-sm" id="daily-summary-table">
<thead>
<tr>
<th>봉투코드</th>
<th>봉투</th>
<th>판매수량</th>
<th>판매금액</th>
<th rowspan="2" class="align-middle">구분</th>
<th rowspan="2" class="align-middle">봉투종류</th>
<th colspan="4" class="text-center border-l border-gray-300">일계</th>
<th colspan="4" class="text-center border-l border-gray-300">누계(월)</th>
</tr>
<tr>
<th class="text-right border-l border-gray-300">수량</th>
<th class="text-right">판매금액</th>
<th class="text-right">수수료</th>
<th class="text-right">징수액</th>
<th class="text-right border-l border-gray-300">수량</th>
<th class="text-right">판매금액</th>
<th class="text-right">수수료</th>
<th class="text-right">징수액</th>
</tr>
</thead>
<tbody class="text-right">
<?php
$monthlySaleQtyTotal = 0;
$monthlySaleAmountTotal = 0;
?>
<?php foreach ($monthly as $row): ?>
<?php
$monthlySaleQtyTotal += (int) $row->sale_qty;
$monthlySaleAmountTotal += (int) $row->sale_amount;
?>
<tr>
<td class="text-center font-mono"><?= esc($row->bs_bag_code) ?></td>
<td class="text-left pl-2"><?= esc($row->bs_bag_name) ?></td>
<td><?= number_format((int) $row->sale_qty) ?></td>
<td><?= number_format((int) $row->sale_amount) ?></td>
</tr>
<?php foreach ($tableRows ?? [] as $r): ?>
<?php
$kind = (string) ($r['kind'] ?? 'data');
$trClass = $kind === 'subtotal' ? 'bg-gray-50 font-semibold' : ($kind === 'grand' ? 'bg-amber-50 font-bold' : '');
$fmtFee = static function (float $v) use ($hasBsFee): string {
if (! $hasBsFee) {
return '—';
}
return $v != 0.0 ? number_format((int) round($v)) : '';
};
?>
<tr class="<?= esc($trClass, 'attr') ?>">
<?php if ($kind === 'grand'): ?>
<td colspan="2" class="text-center"><?= esc((string) ($r['bag_name'] ?? '합 계')) ?></td>
<?php else: ?>
<td class="text-left pl-2"><?= esc((string) ($r['cat_label'] ?? '')) ?></td>
<td class="text-left pl-2"><?= esc((string) ($r['bag_name'] ?? '')) ?></td>
<?php endif; ?>
<td class="border-l border-gray-200 tabular-nums"><?= number_format((int) ($r['d_qty'] ?? 0)) ?></td>
<td class="tabular-nums"><?= number_format((int) round((float) ($r['d_amt'] ?? 0))) ?></td>
<td class="tabular-nums"><?= $fmtFee((float) ($r['d_fee'] ?? 0)) ?></td>
<td class="tabular-nums"><?= number_format((int) round((float) ($r['d_levy'] ?? 0))) ?></td>
<td class="border-l border-gray-200 tabular-nums"><?= number_format((int) ($r['m_qty'] ?? 0)) ?></td>
<td class="tabular-nums"><?= number_format((int) round((float) ($r['m_amt'] ?? 0))) ?></td>
<td class="tabular-nums"><?= $fmtFee((float) ($r['m_fee'] ?? 0)) ?></td>
<td class="tabular-nums"><?= number_format((int) round((float) ($r['m_levy'] ?? 0))) ?></td>
</tr>
<?php endforeach; ?>
<?php if (empty($monthly)): ?>
<tr><td colspan="4" class="text-center text-gray-400 py-4">조회된 데이터가 없습니다.</td></tr>
<?php if (($tableRows ?? []) === []): ?>
<tr>
<td colspan="10" class="text-center text-gray-400 py-6">조회된 데이터가 없습니다.</td>
</tr>
<?php endif; ?>
</tbody>
<tfoot class="bg-gray-50 font-bold text-right">
<tr>
<td colspan="2" class="text-center">합계</td>
<td><?= number_format($monthlySaleQtyTotal) ?></td>
<td><?= number_format($monthlySaleAmountTotal) ?></td>
</tr>
</tfoot>
</table>
</div>
</div>
</section>