feat(cupang): 발주 업로드 결과를 출고일별로 분리
- 업로드 API가 (출고일, 센터, 제품)으로 합산해 groups[] 로 반환 - 화면 상단에 출고일 탭 — 날짜마다 ①직접입력 / ②박스요약 / ③센터분배 상태를 따로 보관하고 탭으로 전환 (박스 계산은 날짜 × 센터 단위로 실행) - 확정은 현재 날짜만 대상. 남은 날짜가 있으면 달력으로 나가지 않고 다음 탭으로 이동 - 업로드 결과 카드에 출고일별 센터 수·수량 요약 추가 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -769,8 +769,8 @@ async def box_calc_upload(
|
||||
warnings: list[str] = []
|
||||
file_infos: list[dict[str, Any]] = []
|
||||
ship_dates: list[str] = []
|
||||
# (센터명, 제품코드) → 수량
|
||||
agg: dict[tuple[str, str], dict[str, Any]] = {}
|
||||
# (출고일, 센터명, 제품코드) → 수량
|
||||
agg: dict[tuple[str, str, str], dict[str, Any]] = {}
|
||||
unknown_codes: set[str] = set()
|
||||
unknown_centers: set[str] = set()
|
||||
no_rule: set[str] = set()
|
||||
@@ -793,6 +793,7 @@ async def box_calc_upload(
|
||||
else:
|
||||
warnings.append(f"{name}: F13 입고예정일을 읽지 못했습니다.")
|
||||
|
||||
ship_iso = ship.isoformat() if ship else ""
|
||||
used = 0
|
||||
for row in parsed["rows"]:
|
||||
prod = by_coupang.get(row["coupang_item_code"])
|
||||
@@ -805,10 +806,11 @@ async def box_calc_upload(
|
||||
code = prod["product_code"]
|
||||
if code not in rules:
|
||||
no_rule.add(f'{prod["product_name"]}({code})')
|
||||
key = (cname, code)
|
||||
key = (ship_iso, cname, code)
|
||||
cell = agg.setdefault(
|
||||
key,
|
||||
{
|
||||
"ship_date": ship_iso,
|
||||
"center_name": cname,
|
||||
"product_code": code,
|
||||
"product_name": prod["product_name"],
|
||||
@@ -823,7 +825,7 @@ async def box_calc_upload(
|
||||
{
|
||||
"filename": name,
|
||||
"arrival_date": arrival.isoformat() if arrival else "",
|
||||
"ship_date": ship.isoformat() if ship else "",
|
||||
"ship_date": ship_iso,
|
||||
"rows": len(parsed["rows"]),
|
||||
"quantity": used,
|
||||
}
|
||||
@@ -841,12 +843,12 @@ async def box_calc_upload(
|
||||
warnings.append("박스 입수량 미설정: " + ", ".join(sorted(no_rule)))
|
||||
|
||||
uniq_dates = sorted(set(ship_dates))
|
||||
if len(uniq_dates) > 1:
|
||||
warnings.append("파일마다 출고일이 다릅니다: " + ", ".join(uniq_dates))
|
||||
|
||||
grouped: dict[str, dict[str, Any]] = {}
|
||||
for (cname, _code), cell in agg.items():
|
||||
g = grouped.setdefault(
|
||||
# 출고일 → 센터 → 품목. 업로드한 파일의 출고일이 다르면 날짜별로 나뉜다.
|
||||
by_date: dict[str, dict[str, dict[str, Any]]] = {}
|
||||
for (ship_iso, cname, _code), cell in agg.items():
|
||||
centers_of_date = by_date.setdefault(ship_iso, {})
|
||||
g = centers_of_date.setdefault(
|
||||
cname,
|
||||
{
|
||||
"center_name": cname,
|
||||
@@ -862,8 +864,24 @@ async def box_calc_upload(
|
||||
"quantity": cell["quantity"],
|
||||
}
|
||||
)
|
||||
for g in grouped.values():
|
||||
g["items"].sort(key=lambda it: it["product_code"])
|
||||
|
||||
groups: list[dict[str, Any]] = []
|
||||
for ship_iso in sorted(by_date):
|
||||
centers_of_date = by_date[ship_iso]
|
||||
for g in centers_of_date.values():
|
||||
g["items"].sort(key=lambda it: it["product_code"])
|
||||
groups.append(
|
||||
{
|
||||
"ship_date": ship_iso,
|
||||
"centers": sorted(centers_of_date.values(), key=lambda g: g["center_name"]),
|
||||
"files": [f for f in file_infos if f["ship_date"] == ship_iso],
|
||||
"quantity": sum(
|
||||
it["quantity"]
|
||||
for g in centers_of_date.values()
|
||||
for it in g["items"]
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
return JSONResponse(
|
||||
{
|
||||
@@ -871,7 +889,7 @@ async def box_calc_upload(
|
||||
"ship_date": uniq_dates[0] if uniq_dates else "",
|
||||
"ship_dates": uniq_dates,
|
||||
"files": file_infos,
|
||||
"centers": sorted(grouped.values(), key=lambda g: g["center_name"]),
|
||||
"groups": groups,
|
||||
"warnings": warnings,
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user