feat(cupang): 출고방식 파렛트, 상태/문서번호 폼 제거, 폼·상세 레이아웃 개편
- 출고방식 선택지에 "파렛트" 추가 - 신규/수정 폼에서 상태·문서번호 입력 제거 (status는 작성중 기본 + 취소처리로만 변경) - document_no DB 컬럼 제거: init.sql 반영 + 기존 DB용 002 드롭 마이그레이션(승인 후 실행) - 폼: 공통 헤더(좌) / 품목 라인(우) 2열 배치 - 상세: 엑셀·상태변경 버튼 삭제, ◀◀ 달력(검정) 좌측, 수정 우측 정렬, 문서번호 표시 제거 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -323,14 +323,13 @@ class CupangDBStore:
|
||||
row = conn.execute(
|
||||
"""
|
||||
INSERT INTO cupang_shipments
|
||||
(document_no, created_by, document_date, ship_date,
|
||||
(created_by, document_date, ship_date,
|
||||
center_arrival_date, center_id, center_name_snapshot,
|
||||
ship_method, outbound_summary, worker, status, memo)
|
||||
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
|
||||
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
|
||||
RETURNING *
|
||||
""",
|
||||
(
|
||||
h["document_no"] or None,
|
||||
created_by.lower().strip(),
|
||||
h["document_date"],
|
||||
h["ship_date"],
|
||||
@@ -360,7 +359,7 @@ class CupangDBStore:
|
||||
row = conn.execute(
|
||||
"""
|
||||
UPDATE cupang_shipments
|
||||
SET document_no = %s, document_date = %s, ship_date = %s,
|
||||
SET document_date = %s, ship_date = %s,
|
||||
center_arrival_date = %s, center_id = %s,
|
||||
center_name_snapshot = %s, ship_method = %s,
|
||||
outbound_summary = %s, worker = %s, memo = %s
|
||||
@@ -368,7 +367,6 @@ class CupangDBStore:
|
||||
RETURNING *
|
||||
""",
|
||||
(
|
||||
h["document_no"] or None,
|
||||
h["document_date"],
|
||||
h["ship_date"],
|
||||
h["center_arrival_date"],
|
||||
@@ -526,7 +524,6 @@ class CupangDBStore:
|
||||
center_id = None
|
||||
|
||||
return {
|
||||
"document_no": str(header.get("document_no") or "").strip(),
|
||||
"document_date": document_date,
|
||||
"ship_date": ship_date,
|
||||
"center_arrival_date": center_arrival_date,
|
||||
|
||||
@@ -248,7 +248,6 @@ async def new_form(request: Request) -> HTMLResponse:
|
||||
async def create(
|
||||
request: Request,
|
||||
lines_json: str = Form("[]"),
|
||||
document_no: str = Form(""),
|
||||
document_date: str = Form(...),
|
||||
ship_date: str = Form(...),
|
||||
center_arrival_date: str = Form(...),
|
||||
@@ -257,7 +256,6 @@ async def create(
|
||||
ship_method: str = Form("택배"),
|
||||
outbound_summary: str = Form(""),
|
||||
worker: str = Form(""),
|
||||
status: str = Form("작성중"),
|
||||
memo: str = Form(""),
|
||||
user: dict[str, Any] = Depends(_require_user),
|
||||
) -> RedirectResponse:
|
||||
@@ -265,7 +263,6 @@ async def create(
|
||||
if store is None:
|
||||
raise HTTPException(status_code=503, detail="cupang_db 미설정")
|
||||
header = {
|
||||
"document_no": document_no,
|
||||
"document_date": document_date,
|
||||
"ship_date": ship_date,
|
||||
"center_arrival_date": center_arrival_date,
|
||||
@@ -274,7 +271,6 @@ async def create(
|
||||
"ship_method": ship_method,
|
||||
"outbound_summary": outbound_summary,
|
||||
"worker": worker,
|
||||
"status": status,
|
||||
"memo": memo,
|
||||
}
|
||||
try:
|
||||
@@ -351,7 +347,6 @@ async def update(
|
||||
request: Request,
|
||||
shipment_id: int,
|
||||
lines_json: str = Form("[]"),
|
||||
document_no: str = Form(""),
|
||||
document_date: str = Form(...),
|
||||
ship_date: str = Form(...),
|
||||
center_arrival_date: str = Form(...),
|
||||
@@ -367,7 +362,6 @@ async def update(
|
||||
if store is None:
|
||||
raise HTTPException(status_code=503, detail="cupang_db 미설정")
|
||||
header = {
|
||||
"document_no": document_no,
|
||||
"document_date": document_date,
|
||||
"ship_date": ship_date,
|
||||
"center_arrival_date": center_arrival_date,
|
||||
|
||||
@@ -21,7 +21,7 @@ STATUSES: tuple[str, ...] = (
|
||||
)
|
||||
|
||||
# 출고방식 기본 후보 (자유 입력 허용, 아래는 select 기본값)
|
||||
SHIP_METHODS: tuple[str, ...] = ("택배", "직접배송", "화물", "기타")
|
||||
SHIP_METHODS: tuple[str, ...] = ("택배", "직접배송", "화물", "파렛트", "기타")
|
||||
|
||||
# 엑셀/시트 컬럼 순서 — 기존 구글시트와 동일하게 유지
|
||||
SHEET_COLUMNS: tuple[str, ...] = (
|
||||
|
||||
@@ -6,18 +6,7 @@
|
||||
<section class="cpg">
|
||||
|
||||
<div class="erp-page-actions cpg-actions">
|
||||
<a class="erp-btn erp-btn-primary" href="/cupang/{{ shipment.id }}/edit">수정</a>
|
||||
<a class="erp-btn erp-btn-outline" href="/cupang/{{ shipment.id }}/export">엑셀</a>
|
||||
<a class="erp-btn erp-btn-outline" href="/cupang/?date={{ shipment.ship_date }}">달력으로</a>
|
||||
|
||||
<form method="post" action="/cupang/{{ shipment.id }}/status" class="cpg-inline-form">
|
||||
<select class="erp-select" name="status">
|
||||
{% for s in statuses %}
|
||||
<option value="{{ s }}" {% if shipment.status == s %}selected{% endif %}>{{ s }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="submit" class="erp-btn erp-btn-outline">상태 변경</button>
|
||||
</form>
|
||||
<a class="erp-btn erp-btn-primary" href="/cupang/?date={{ shipment.ship_date }}">◀◀ 달력</a>
|
||||
|
||||
<form method="post" action="/cupang/{{ shipment.id }}/delete" class="cpg-inline-form"
|
||||
onsubmit="return confirm('이 출고 묶음을 취소 처리합니다(상태=취소). 계속할까요?');">
|
||||
@@ -28,6 +17,8 @@
|
||||
onsubmit="return confirm('이 출고를 완전 삭제합니다(복구 불가, 품목 포함). 계속할까요?');">
|
||||
<button type="submit" class="erp-btn erp-btn-danger">삭제</button>
|
||||
</form>
|
||||
|
||||
<a class="erp-btn erp-btn-primary cpg-push-right" href="/cupang/{{ shipment.id }}/edit">수정</a>
|
||||
</div>
|
||||
|
||||
<!-- 헤더 -->
|
||||
@@ -48,7 +39,6 @@
|
||||
<div><dt>입고센터</dt><dd>{{ shipment.center_name_snapshot or '—' }}</dd></div>
|
||||
<div><dt>출고방식</dt><dd>{{ shipment.ship_method }}</dd></div>
|
||||
<div><dt>작업자</dt><dd>{{ shipment.worker or '—' }}</dd></div>
|
||||
<div><dt>문서번호</dt><dd>{{ shipment.document_no or '—' }}</dd></div>
|
||||
<div class="cpg-full"><dt>출고/박스 요약</dt><dd>{{ shipment.outbound_summary or '—' }}</dd></div>
|
||||
<div class="cpg-full"><dt>메모</dt><dd>{{ shipment.memo or '—' }}</dd></div>
|
||||
</dl>
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
<form id="cpg-form" method="post" action="{{ action }}">
|
||||
<input type="hidden" name="lines_json" id="cpg-lines-json" value="[]" />
|
||||
|
||||
<!-- ── 공통 헤더 ── -->
|
||||
<div class="erp-card cpg-form-card">
|
||||
<div class="cpg-form-2col">
|
||||
|
||||
<!-- ── 공통 헤더 (왼쪽) ── -->
|
||||
<div class="erp-card cpg-form-card cpg-form-head">
|
||||
<div class="cpg-card-head"><h2>공통 헤더</h2></div>
|
||||
<div class="cpg-header-grid">
|
||||
<label class="erp-field"><span>작성일 *</span>
|
||||
@@ -45,17 +47,6 @@
|
||||
<label class="erp-field"><span>작업자</span>
|
||||
<input class="erp-input" type="text" name="worker"
|
||||
value="{{ shipment.worker if shipment else '' }}" /></label>
|
||||
|
||||
{% if mode == 'new' %}
|
||||
<label class="erp-field"><span>상태</span>
|
||||
<select class="erp-select" name="status">
|
||||
{% for s in statuses %}<option value="{{ s }}">{{ s }}</option>{% endfor %}
|
||||
</select></label>
|
||||
{% endif %}
|
||||
|
||||
<label class="erp-field"><span>문서번호(선택)</span>
|
||||
<input class="erp-input" type="text" name="document_no"
|
||||
value="{{ shipment.document_no or '' if shipment else '' }}" /></label>
|
||||
</div>
|
||||
|
||||
<label class="erp-field cpg-full"><span>출고/박스 요약 (수동 보정 메모)</span>
|
||||
@@ -66,8 +57,8 @@
|
||||
<textarea class="erp-input" name="memo" rows="2">{{ shipment.memo if shipment else '' }}</textarea></label>
|
||||
</div>
|
||||
|
||||
<!-- ── 품목 라인 ── -->
|
||||
<div class="erp-card cpg-form-card">
|
||||
<!-- ── 품목 라인 (오른쪽) ── -->
|
||||
<div class="erp-card cpg-form-card cpg-form-lines">
|
||||
<div class="cpg-card-head">
|
||||
<h2>품목 라인</h2>
|
||||
<span class="erp-muted">
|
||||
@@ -90,6 +81,8 @@
|
||||
<button type="button" class="erp-btn erp-btn-outline" id="cpg-add-line">+ 라인 추가</button>
|
||||
</div>
|
||||
|
||||
</div><!-- /cpg-form-2col -->
|
||||
|
||||
<div class="erp-page-actions">
|
||||
<button type="submit" class="erp-btn erp-btn-primary">저장</button>
|
||||
{% if mode == 'edit' %}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
.cpg { display: flex; flex-direction: column; gap: 16px; }
|
||||
.cpg-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
||||
/* 맨 오른쪽으로 밀기 (수정 버튼) */
|
||||
.cpg-push-right { margin-left: auto; }
|
||||
|
||||
/* ── 레이아웃: 왼쪽 큰 달력 + 오른쪽 리스트 ── */
|
||||
.cpg-layout {
|
||||
@@ -68,6 +70,16 @@
|
||||
|
||||
/* ── 폼 ── */
|
||||
.cpg-form-card { padding: 16px; margin-bottom: 16px; }
|
||||
|
||||
/* 공통 헤더(좌) + 품목 라인(우) 2열 */
|
||||
.cpg-form-2col {
|
||||
display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start;
|
||||
}
|
||||
.cpg-form-head { flex: 1 1 380px; min-width: 0; margin-bottom: 0; }
|
||||
.cpg-form-lines { flex: 1 1 520px; min-width: 0; margin-bottom: 0; }
|
||||
@media (max-width: 900px) {
|
||||
.cpg-form-head, .cpg-form-lines { flex-basis: 100%; }
|
||||
}
|
||||
.cpg-card-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
|
||||
.cpg-card-head h2 { font-size: 16px; font-weight: 600; margin: 0; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user