- scripts/sql/cupang_db_006_sales.sql: cupang_sales(발주 라인) / cupang_sales_weekly(광고비·할인·장려금) 생성
- scripts/sql/cupang_sales_seed.sql: 구글 시트 초기 데이터 2,218행 + 주차비용 100건
(공급가 합계가 시트 2024/2025 총계와 일치)
- /cupang/sales: 기간·센터·발주유형·검색 조회, 합계 KPI(공급가/원가/물류비/마진/순마진),
행 추가·수정·삭제, 시트(xlsx·csv) 업로드 일괄 등록, 조회 조건 그대로 엑셀 다운로드
- 달력 상단에 "쿠팡 로켓 매출" 버튼 추가
- sales_import.py: 병합 머리글 3행 건너뛰고 라인/주차 소계 분리, 월계·총계는 저장하지 않음
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
주 수(5주/6주)에 따라 1fr 로 나뉘던 행 높이를 고정값(--mcal-row)으로 바꿔
두 달의 칸 크기와 세로 간격을 동일하게 맞춘다. 화면 높이에 따라 84/72/62px.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 상단 바: ← 제목 → 을 가운데 정렬, 화살표는 테두리 없는 큰 글리프
- "오늘" 버튼을 두 달 사이 상단 중앙으로 이동
- 달 머리글 가운데 정렬, 출고 건수 배지는 오른쪽에 겹쳐 배치
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- holidays.py 를 이름까지 담도록 확장(holiday_name), is_holiday 는 이름 유무로 판정
- 대체공휴일은 원래 명칭 대신 "대체공휴일"로 표기, 겹치는 날은 "어린이날·부처님오신날"
- 달력 칸에 날짜 아래 빨강 소형 라벨 + title 툴팁, 칸 최소 높이 62→70px
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 혼합 상자 채움률 60% 이하면 "상자 변경 필요"(오렌지) 도장 + 업로드/날짜 전환 시 안내 팝업
- ① 직접 입력 표와 계산/제품 추가/초기화 버튼·이벤트 제거. 품목은 업로드(또는 임시 저장 불러오기)로만
- 상단 출고일 탭 바를 없애고 ① 카드 안 세로 목록으로 이동 (날짜·센터수·상자수·수량)
- 임시 저장에 ship_date 를 함께 담아 불러올 때 출고일 유지
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 출고일자 선택 대화상자 제거. 확정 시 활성 출고일(업로드 F13−1일, 없으면 오늘)로 바로 저장
- 저장 중 스피너 모달 표시 → 응답 오면 닫고 달력으로 이동(여러 날짜면 다음 날짜로 이어감)
- 실패 시 모달 닫고 사유를 상단 메시지로 표시, 버튼 재활성화
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- /cupang/centers GET/POST, 수정·삭제 라우트와 centers.html 삭제
- 달력 상단 "입고센터 관리" 버튼 제거, 상자 계산의 안내 문구 정리
- 센터 관리 화면 전용 CSS 제거(공용 .cpg-icon-btn/.cpg-btn-sm 은 유지)
- 센터 데이터(cupang_centers)와 db 계층은 그대로 — 출고 확정·발주 업로드에서 계속 사용
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 엑셀 다운로드 버튼 배경 #217346
- 표 머리글은 말줄임 없이 전체 표시(상자번호 열 74px)
- 행 클릭 시 상자 단위로 체크 색 토글 + 체크 개수 표시(세는 용도)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- ② 상자 목록: 카드 대신 표. 한 상자에 여러 제품이면 상자번호 칸 rowspan 병합
- GET /cupang/{id}/boxes.xlsx — 같은 표를 xlsx 로 (export.build_box_list_workbook)
- box_list 항목에 product_code 포함
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 달력 월 이름/연도 글자 크기 2배·굵게
- 출고 상세 ② 상자 요약 → ② 상자 목록: 전체 상자에 1번부터 번호를 붙이고
상자마다 담긴 제품·수량을 표시. box_plan 스냅샷 우선, 없으면 계산 결과로 대체
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
카드 높이는 grid 행(1fr)으로 화면에 맞춰져 있으므로 카드에 overflow-y:auto
를 걸면 안쪽 구조와 무관하게 스크롤된다. 목록은 자연 높이로 두고 헤더는
sticky. JS 높이 계산 대상에서 ③ 제외(①② 만 유지).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
진단 결과 1열로 접힌 상태에서 .cpg-calc3 가 704px 를 세 카드가 나눠
가져(224px씩) 내용이 잘렸고, JS 가 준 높이(561px)는 카드보다 커서
무용지물이었다.
- 1501px 이상: 카드 안쪽만 스크롤. 높이는 "카드 아래끝 − 영역 top" 으로 계산
- 1500px 이하: 카드/영역 높이 제한 해제, .cpg 를 flex:0 0 auto 로 두어
내용만큼 늘고 페이지(.erp-page)가 스크롤
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
원인: .cpg-calc3 의 행 높이가 auto 라 카드가 화면 아래로 넘치도록 늘어났고,
페이지 스크롤도 없어서 아래쪽(마지막 상자, [+ 새 혼합 상자])이 잘렸다.
- grid-template-rows: minmax(0,1fr) 로 행을 컨테이너 높이에 고정
- 카드 overflow:hidden, ①표/②목록/③센터목록만 내부 스크롤
- 그동안 덧댄 !important 패치와 JS 높이 강제 지정 제거(충돌 정리)
- 2열/1열로 접히면 행이 여러 개라 카드 max-height(76vh)로 처리
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
앞선 커밋의 .cpg-page-grow(페이지가 늘어나는 방식)를 되돌리고,
③ 카드는 overflow:hidden + 목록만 스크롤로 복구.
JS 높이 계산 대상에 ③ 목록을 다시 포함(창높이-요소top, 260 이하면 60vh).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
.cpg 가 flex:1 1 auto + min-height:0 이라 남은 높이에 맞춰 눌리기만 해서
③ 이 늘어나도 페이지 높이가 그대로였다(=스크롤 안 됨).
이 화면에만 .cpg-page-grow 를 붙여 flex:0 0 auto 로 두고,
페이지 스크롤 시 ①② 내부 스크롤 높이를 다시 계산한다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
혼합 상자를 추가하면 칸이 아래로 늘어나야 하는데 카드/목록에 걸어둔
max-height + overflow:hidden 이 잘라내고 있었다. ③ 은 높이 제한과
클리핑을 없애고 넘치면 페이지가 스크롤되게 한다.
①(입력 표) ②(요약 목록) 의 내부 스크롤은 그대로 유지.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CSS 우선순위나 flex 높이 계산에 밀리지 않도록
#cpg-dist-list / 표 / 요약 목록에 !important 최대 높이를 주고,
JS 도 setProperty(..., "important") 로 지정한다(data-fit 로 확인 가능).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
카드에 max-height(82vh)를 주고 ③ 카드는 overflow-y:auto 로 바꿔,
안쪽 목록 스크롤이 동작하지 않는 상황에서도 카드가 스크롤되게 한다.
스크롤바는 gutter 고정 + webkit 스크롤바 폭 지정으로 보이게.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- mixPut/moveUnits 에서 용량 제한 제거. 이동 목록도 "가득"이어도 선택 가능
(채움률이 100% 를 넘으면 빨간색으로 표시만)
- 부모 flex 높이 계산에 기대던 스크롤을 max-height 로 직접 지정
(③ 72vh, ① 표 64vh, ② 목록 64vh)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- "미배치로 빼기" 옵션과 미배치 풀 UI/상태 삭제
- [−] 는 자리가 있는 다른 상자로 1개 이동(없으면 새 상자 자동 생성),
[+] 는 같은 제품이 있는 다른 상자에서 1개 가져오기 → 총량 항상 보존
- 혼합 상자 ✕ 는 내용물을 다른 상자로 옮긴 뒤 상자를 없앤다
- 3열이 2열/1열로 접히는 폭에서 카드 max-height 를 줘서 ③ 목록이
카드 안에서 스크롤되도록 수정(편집으로 줄이 늘어나도 페이지가 안 밀림)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- ③ 센터 분배의 혼합 상자 트리에서 항목마다 [−] n [+] 와 이동 드롭다운
(다른 혼합 상자 / 새 상자 / 미배치로 빼기). 용량(부피 합)을 넘지 않게 제한
- 센터마다 "미배치 자투리" 풀 + [자동 담기], [+ 새 혼합 상자] 버튼
- 혼합 상자 ✕ 는 내용물을 미배치로 옮기고 상자를 없앤다
- 상자가 비면 자동 제거, 채움률은 헤더에 실시간 표시
- 확정 조건에 "미배치 자투리 0" 추가
- 혼합 상자 키를 위치 index → 상자별 고유 id 로 바꿔 추가/삭제에도 배분 유지
- 미배치 풀은 출고일 탭 전환 시에도 함께 보관
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 마이그레이션 005: cupang_shipments.box_plan JSONB (확정 당시 박스 구성)
확정 payload 에서 제품별/혼합 상자와 내용물·상자 종류를 받아 저장
- 달력 오른쪽 목록을 ③ 센터 분배 카드 형식으로 변경 — 혼합 상자는
내용물 트리까지 표시. box_plan 이 없는 예전 출고는 기존 합계 표시로 폴백
- 출고 보기(view.html) ③ 목록도 동일하게 box_plan 기준
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- detail.html / form.html 삭제, GET·POST /{id}/edit 라우트와
_form_context / _parse_lines 헬퍼 제거
- GET /{id} → view.html: ① 품목 / ② 박스 요약(서버 재계산) / ③ 센터
(박스 계산 화면과 같은 3열 구성, 편집 불가)
- 박스 계산 로직을 _compute_boxes 로 분리해 API 와 보기 화면이 공유
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- [쿠팡 발주파일 업로드] 라벨 버튼, 파일 선택 즉시 자동 분석(분석 버튼 제거)
- 안내 문구와 분석 결과 상세 표시 제거 — 경고만 남김
- ①②③ 카드가 각자 스크롤: 문서 전체는 스크롤되지 않음
· ① 표 머리글 sticky, 행 높이 축소로 품목 더 많이 표시
· ② KPI 요약까지 고정, 아래 목록만 스크롤
· ③ 헤더/센터 선택 고정, 센터 목록만 스크롤
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
박스 요약 카드에서 쿠팡상자 / 3호상자 / 6호상자 중 하나를 고른다.
고른 종류는 카드 제목·박스 그림·③ 센터 분배 라벨에 반영되고,
출고일 탭 전환과 임시 저장/불러오기에도 함께 보관된다.
드롭다운 조작 시에는 드래그·담기 대화상자가 열리지 않게 예외 처리.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 업로드 API가 (출고일, 센터, 제품)으로 합산해 groups[] 로 반환
- 화면 상단에 출고일 탭 — 날짜마다 ①직접입력 / ②박스요약 / ③센터분배 상태를
따로 보관하고 탭으로 전환 (박스 계산은 날짜 × 센터 단위로 실행)
- 확정은 현재 날짜만 대상. 남은 날짜가 있으면 달력으로 나가지 않고 다음 탭으로 이동
- 업로드 결과 카드에 출고일별 센터 수·수량 요약 추가
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- ① 카드를 "쿠팡 발주 업로드"로 개편, xlsx 다중 선택 업로드
- POST /cupang/api/box-calc/upload (openpyxl): F13 입고예정일 −1일 = 출고일,
22행부터 B=쿠팡상품코드 / F=센터명 / G=수량을 읽어 파일들을 합산
- 쿠팡상품코드 → cupang_products.coupang_item_code 로 제품 매칭,
센터명 → cupang_centers.name 매칭. 미매칭 코드/센터/박스규칙은 경고로 표시
- 박스는 센터 단위로 포장되므로 센터마다 박스 계산을 돌려 ② 요약에 합치고
③ 센터에 자동 배분(자투리 혼합 박스는 소속 센터를 라벨에 표시)
- 확정 대화상자 기본 출고일도 업로드한 발주서 날짜로 채움
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 요일 행 높이 고정(34px) — grid-template-rows: auto 로 주 행만 균등 분할
- 요일 11→22px, 일자 13→20px, 둘 다 bold
- 날짜 셀 1px 테두리 + hover 강조, 타월은 회색 배경으로 구분
- 오늘 원 24→32px, 출고 태그 12px
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- index 라우터가 두 달치 출고를 합쳐(중복 id 제거) 달 별 격자 2개를 생성
- 상단 바: ‹ › 이동 + 기간 제목 + [오늘], 달마다 머리글/월 출고 합계 배지
- 셀 UI 정리: 오늘=검은 원, 선택=링, 출고일=건수/센터수 태그, 타월은 흐리게
- 범례 추가, 1200px 이하에서는 두 달을 세로로 배치
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
셀 box-sizing: border-box 로 지정 폭에 padding 포함(기존엔 열마다 20px 씩
초과해 표가 카드보다 넓어짐). 카드 폭 600→680, 줄바꿈 브레이크포인트 1240px,
erp-table-wrap overflow-x: hidden.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- cupang_products.coupang_item_code 컬럼 추가 (마이그레이션 004, init.sql 동기화)
- 설정 화면: 쿠팡상품코드 열 표시/정렬, 수기 추가 폼 입력란 추가
- 선택 등록 시 바로 등록하지 않고 쿠팡상품코드 입력 팝업을 먼저 표시
- 상태 배지를 클릭 토글로 변경 (POST /cupang/api/products/{id}/toggle)
- 빈 쿠팡상품코드는 "미입력"으로 처리해 기존 값을 덮어쓰지 않음
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
분배 확정으로 만든 출고를 지우려면 상세 페이지까지 들어가야 했다. 달력에서
날짜를 고른 뒤 오른쪽 카드에서 바로 지울 수 있게 한다. 센터가 여러 건일 때를
위해 목록 헤더에 "이 날짜 전체 삭제" 도 둔다. 둘 다 가운데 확인 팝업을 거친다.
삭제는 기존 정책대로 status='취소' soft delete 이고, 대신 달력·목록에서
취소 건을 걸러내 사용자에게는 삭제로 보이게 했다(기록은 DB 에 남는다).
- router: /{id}/delete 에 next 폼값(내부 경로만 허용) 추가, POST /cupang/day-delete 신설
- index.html: 카드 헤더에 삭제 버튼, 앵커 안에 버튼이 들어가지 않게 구조 정리
출고 묶음을 만드는 길이 둘(신규 등록 폼 / 박스 계산 분배 확정)이라 헷갈렸다.
폼 경로를 없애고 [+ 신규 등록] 이 박스 계산을 열게 한다. 중복이던 오른쪽
[박스 계산] 버튼은 제거. /cupang/new 는 북마크가 깨지지 않게 박스 계산으로
리다이렉트하고 POST /new(생성)는 삭제했다. 기존 묶음 수정은 그대로 동작한다.
달력 칸은 작성/출고/입고 세 배지를 늘어놓아 읽기 어려웠다. 출고 기준으로
"출고 N건 · 센터 M곳"만 남긴다. 오른쪽 상세도 같은 기준(출고일)으로 맞추고
센터별 출고방식·총 박스/개수와 상품별 수량·박스를 카드 안에 펼친다. 품목이
바로 보이므로 hover 툴팁은 제거.
임시 저장 기본 제목은 "2026.08.31(월) 오후 04시 50분" 형식으로.
③ 센터 분배 헤더에 [분배 확정] 을 두고, 조건이 갖춰질 때만 활성화한다.
조건은 두 가지다. 남은 박스가 0 이어야 하고, 담긴 센터마다 출고방식
(택배/파렛트)이 골라져 있어야 한다. 비활성일 때는 버튼 툴팁에 막힌 사유를
적는다(남은 박스 수, 출고방식 미선택 센터명).
확정을 누르면 달력이 바로 뜨는 팝업에서 출고일자를 고르고, 확인 시 센터마다
출고 묶음 1건(status=출고준비)을 만들어 쿠팡 달력의 그 날짜로 이동한다.
혼합 박스는 내용물 제품으로 풀어 담고 같은 제품끼리 합산한다. 박스 수는
화면 값을 믿지 않고 저장 시 서버가 수량·입수량으로 다시 계산한다.
- router: POST /cupang/api/box-calc/confirm
- box_calc.html: 센터 헤더 출고방식 select(미선택은 빨간 배경), 확정 팝업 달력
- 임시 저장 스냅샷에 출고방식 포함
- 센터입고일은 출고일과 같게 저장(상세에서 수정)
계산 중 화면 상태를 서버에 이름 붙여 저장하고 다시 불러온다. 다른 PC 에서도
이어서 작업할 수 있어야 해서 localStorage 대신 DB 에 둔다.
저장 대상은 화면 스냅샷(입력 품목·열어둔 센터·분배 내역·도장 상태)뿐이고,
박스 수는 불러온 뒤 기존 계산 API 로 서버에서 다시 구한다. 저장값을 그대로
믿지 않으므로 입수량 규칙이 바뀌어도 어긋나지 않고, 계산 결과에서 사라진
항목은 제외한 건수를 알려준다. 같은 제목으로 저장하면 덮어써 목록이 무한히
늘어나지 않는다.
- scripts/sql/cupang_db_003_box_calc_drafts.sql (신규 테이블 + 권한, 멱등)
- db.py: list/get/save/delete_box_calc_draft
- router: GET·POST /cupang/api/box-calc/drafts, GET·DELETE /{id}
- box_calc.html: [임시 저장]·[불러오기] 버튼 + 목록 대화상자
센터 이름과 담긴 품목이 같은 평면에 있어 경계가 흐렸다. 헤더를 바로 만들어
분리하고(담긴 센터는 검정 바 + 흰 배지) 품목은 패널 안쪽에서 구분선으로
나눈다.
박스 수량은 세 자리를 넘지 않으므로 입력란을 62px → 46px 로 줄이고,
자리만 차지하던 number 스피너를 숨겼다. 고정폭 글꼴로 자릿수 정렬,
max=999·inputmode=numeric 추가.
브라우저 기본 alert/confirm 은 상단에 붙고 URL 이 그대로 보여 어수선했다.
기존 .cpg-modal 스타일을 재사용해 화면 가운데 팝업으로 바꾸고, 삭제 확인도
같은 팝업(빨간 확인 버튼)으로 통일했다. ESC·배경 클릭으로 닫힘.
목록은 헤더와 항목이 같은 평면에 있어 구분이 약했다. 그룹을 테두리 있는
패널로 만들고 헤더에 회색 바 + 카운트 배지 + 접기 캐럿을 뒀다. 센터명은
고정폭 글꼴로 정렬감을 주고, 비활성은 취소선으로 표시.
추가 시 같은 이름이 있으면 조용히 재활성되던 동작(ON CONFLICT DO UPDATE)
때문에 사용자가 중복을 알 수 없었다. 등록 전에 먼저 조회해서 이미 있으면
만들지 않고 알림(활성/비활성 구분)을 띄운다.
목록은 29개가 가로 4열로 흩어져 훑기 어려웠다. 센터명 앞 지역 접두사로
묶고(인천14 → "인천") CSS 멀티컬럼으로 한 열을 위→아래로 읽게 바꿨다.
숫자는 자연 정렬(인천4 < 인천14). 행 액션은 hover/focus 시에만 노출해
이름이 먼저 눈에 들어오게 했다.
- 라우터: _center_group / _center_sort_key / _group_centers 추가
- 검색은 그룹 단위로 접히고 결과 0건이면 안내 표시
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>