feat(cupang): 출고리스트 서식 보강 (요일·머리글색·파렛트 강조)

- 시트명 20260903(목) 형식, 작성일/출고일/센터입고일에 요일 표기
- 머리글 행 배경 #DBE9F7 + 굵게
- 출고방식이 파렛트인 센터 블록 행 배경 #FAE2D5
- A열 너비 10
xlsx·구글시트 양쪽에 동일 적용(google_sheets.write_table 에
header_bg / row_highlights 인자 추가).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-01 15:24:55 +09:00
parent 042d5f8574
commit ebf1710982
3 changed files with 83 additions and 18 deletions
+45 -10
View File
@@ -28,7 +28,10 @@ COL_FIRST = 2
COL_LAST = 12
# 센터 단위로 병합되는 열
MERGE_COLS = (3, 4, 5, 6, 7, 11, 12)
WIDTHS = {2: 6, 3: 12, 4: 12, 5: 12, 6: 11, 7: 10, 8: 12, 9: 26, 10: 8, 11: 12, 12: 11}
WIDTHS = {1: 10, 2: 6, 3: 12, 4: 12, 5: 12, 6: 11, 7: 10, 8: 12, 9: 26, 10: 8, 11: 12, 12: 11}
HEADER_BG = "DBE9F7" # 머리글 행 배경
PALLET_BG = "FAE2D5" # 출고방식이 파렛트인 센터 블록 배경
PALLET_METHOD = "파렛트"
TITLE_ROW = 2
COMPANY_ROW = 4
@@ -36,9 +39,20 @@ HEADER_ROW = 5
FIRST_DATA_ROW = 6
def with_dow(value: str) -> str:
"""YYYY-MM-DD → "YYYY-MM-DD(요일)". 날짜가 아니면 원문 그대로."""
text = (value or "").strip()
try:
d = _date.fromisoformat(text)
except ValueError:
return text
return f"{text}({DOW[d.weekday()]})"
def sheet_title(ship_date: str) -> str:
"""시트명 = 출고일 YYYYMMDD."""
return _date.fromisoformat(ship_date).strftime("%Y%m%d")
"""시트명 = 출고일 YYYYMMDD(요일)."""
d = _date.fromisoformat(ship_date)
return f"{d.strftime('%Y%m%d')}({DOW[d.weekday()]})"
def build_table(ship_date: str, shipments: list[dict[str, Any]]) -> dict[str, Any]:
@@ -53,6 +67,7 @@ def build_table(ship_date: str, shipments: list[dict[str, Any]]) -> dict[str, An
d = _date.fromisoformat(ship_date)
tag = d.strftime("%Y%m%d")
title = f"{tag}({DOW[d.weekday()]}) 쿠팡로켓 밀크런 출고리스트"
pallet_ranges: list[tuple[int, int]] = []
cells: dict[tuple[int, int], Any] = {(TITLE_ROW, COL_FIRST): title,
(COMPANY_ROW, COL_FIRST): COMPANY}
@@ -77,12 +92,17 @@ def build_table(ship_date: str, shipments: list[dict[str, Any]]) -> dict[str, An
row += 1
end = row - 1
method = sh.get("ship_method") or ""
if method == PALLET_METHOD:
pallet_ranges.append((start, end))
block = {
3: str(sh.get("document_date") or ""),
4: str(sh.get("ship_date") or ""),
5: str(sh.get("center_arrival_date") or ""),
# 날짜는 요일까지 표기 — 2026-09-03(목)
3: with_dow(str(sh.get("document_date") or "")),
4: with_dow(str(sh.get("ship_date") or "")),
5: with_dow(str(sh.get("center_arrival_date") or "")),
6: sh.get("center_name_snapshot") or "",
7: sh.get("ship_method") or "",
7: method,
11: sh.get("outbound_summary") or "",
12: WORKER,
}
@@ -91,13 +111,19 @@ def build_table(ship_date: str, shipments: list[dict[str, Any]]) -> dict[str, An
if end > start:
merges.append((start, col, end, col))
return {"title": title, "cells": cells, "merges": merges, "last_row": row - 1}
return {
"title": title,
"cells": cells,
"merges": merges,
"last_row": row - 1,
"pallet_ranges": pallet_ranges,
}
def build_workbook(ship_date: str, shipments: list[dict[str, Any]]) -> Any:
"""xlsx 워크북(openpyxl). 시트명 = YYYYMMDD."""
"""xlsx 워크북(openpyxl). 시트명 = YYYYMMDD(요일)."""
from openpyxl import Workbook
from openpyxl.styles import Alignment, Border, Font, Side
from openpyxl.styles import Alignment, Border, Font, PatternFill, Side
from openpyxl.utils import get_column_letter
table = build_table(ship_date, shipments)
@@ -121,11 +147,13 @@ def build_workbook(ship_date: str, shipments: list[dict[str, Any]]) -> Any:
title_cell.font = Font(size=16, bold=True)
title_cell.alignment = center_align
header_fill = PatternFill("solid", fgColor=HEADER_BG)
for col in range(COL_FIRST, COL_LAST + 1):
head = ws.cell(row=HEADER_ROW, column=col)
head.font = Font(bold=True)
head.alignment = center_align
head.border = box
head.fill = header_fill
for row in range(FIRST_DATA_ROW, table["last_row"] + 1):
for col in range(COL_FIRST, COL_LAST + 1):
@@ -133,6 +161,13 @@ def build_workbook(ship_date: str, shipments: list[dict[str, Any]]) -> Any:
cell.border = box
cell.alignment = left_align if col == 9 else center_align
# 파렛트 출고 블록은 배경색으로 구분
pallet_fill = PatternFill("solid", fgColor=PALLET_BG)
for (r1, r2) in table["pallet_ranges"]:
for row in range(r1, r2 + 1):
for col in range(COL_FIRST, COL_LAST + 1):
ws.cell(row=row, column=col).fill = pallet_fill
for col, width in WIDTHS.items():
ws.column_dimensions[get_column_letter(col)].width = width
ws.row_dimensions[TITLE_ROW].height = 28