feat(cupang): 쿠팡 밀크런 모듈 추가 (출고 달력/박스계산/입고센터)
- app/modules/cupang: router/db/store/itemcode + 템플릿 5종 - cupang_db 전용(JSON 폴백 없음). CUPANG_DB_URL 미설정 시 안내 페이지 - 월간 달력 + 출고 묶음(헤더+라인), 박스 입수량 자동계산(서버 재계산) - 입고센터 관리(사용중 soft delete), 박스규칙 upsert, 엑셀 내보내기 - 상품 검색은 itemcode_db 읽기 전용(미설정 시 수동 입력) - MODULE_KEYS/메뉴/아이콘/라벨 동기화, scripts/sql/cupang_db_init.sql(멱등) - app/data/ gitignore 추가(PII) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<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>
|
||||
|
||||
<form method="post" action="/cupang/{{ shipment.id }}/delete" class="cpg-inline-form"
|
||||
onsubmit="return confirm('이 출고 묶음을 취소 처리합니다. 계속할까요?');">
|
||||
<button type="submit" class="erp-btn erp-btn-danger">취소 처리</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 헤더 -->
|
||||
<div class="erp-card cpg-form-card">
|
||||
<div class="cpg-card-head">
|
||||
<h2>출고 #{{ shipment.id }}
|
||||
{% set badge = 'erp-badge-neutral' %}
|
||||
{% if shipment.status == '출고완료' %}{% set badge = 'erp-badge-inverse' %}
|
||||
{% elif shipment.status == '센터입고완료' %}{% set badge = 'erp-badge-success' %}
|
||||
{% elif shipment.status == '취소' %}{% set badge = 'erp-badge-danger' %}{% endif %}
|
||||
<span class="erp-badge {{ badge }}">{{ shipment.status }}</span>
|
||||
</h2>
|
||||
</div>
|
||||
<dl class="cpg-detail-grid">
|
||||
<div><dt>작성일</dt><dd>{{ shipment.document_date }}</dd></div>
|
||||
<div><dt>출고일</dt><dd>{{ shipment.ship_date }}</dd></div>
|
||||
<div><dt>센터입고일</dt><dd>{{ shipment.center_arrival_date }}</dd></div>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- 라인 -->
|
||||
<div class="erp-card cpg-form-card">
|
||||
<div class="cpg-card-head"><h2>품목 ({{ shipment.lines|length }})</h2></div>
|
||||
<div class="erp-table-wrap">
|
||||
<table class="erp-table">
|
||||
<thead>
|
||||
<tr><th>#</th><th>제품코드</th><th>제품명</th><th>수량</th>
|
||||
<th>입수량</th><th>필요박스</th><th>잔량</th><th>수동보정</th><th>메모</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ln in shipment.lines %}
|
||||
<tr>
|
||||
<td>{{ ln.line_no }}</td>
|
||||
<td>{{ ln.product_code }}</td>
|
||||
<td>{{ ln.product_name_snapshot }}</td>
|
||||
<td>{{ ln.quantity }}</td>
|
||||
<td>{{ ln.units_per_box if ln.units_per_box else '미설정' }}</td>
|
||||
<td>{{ ln.calculated_boxes if ln.calculated_boxes is not none else '—' }}</td>
|
||||
<td>{{ ln.remainder_units if ln.remainder_units is not none else '—' }}</td>
|
||||
<td>{{ ln.manual_box_text or '—' }}</td>
|
||||
<td>{{ ln.memo or '—' }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user