feat(items): 제조사 필드/메뉴 제거 + 공급업체 검색 + 원가/단가 천단위 콤마
Deploy momo-erp / deploy (push) Failing after 1m31s
Deploy momo-erp / deploy (push) Failing after 1m31s
- 품목 폼/리스트/모바일 카드에서 제조사 컬럼·셀렉트 제거 (dead code 정리) - 공급업체 셀렉트 → SearchableSelect (결과내 검색 가능) - 단가/원가 인풋: type=number → text + 천단위 콤마 표시, 소수점 제거(반올림) - 운영 menu_info: '제조사 관리' (9000204) status='inactive' Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -3,14 +3,13 @@
|
||||
import { useEffect, useState, useRef, FormEvent } from "react";
|
||||
import { Plus, Search, Pencil, Trash2, Upload } from "lucide-react";
|
||||
import Swal from "sweetalert2";
|
||||
import { SearchableSelect } from "@/components/ui/searchable-select";
|
||||
|
||||
interface Item {
|
||||
OBJID: string;
|
||||
ITEM_CODE: string;
|
||||
ITEM_NAME: string;
|
||||
ITEM_DETAIL: string;
|
||||
MAKER_OBJID: string;
|
||||
MAKER_NAME: string;
|
||||
UNIT: string;
|
||||
UNIT_PRICE: number;
|
||||
COST_PRICE: number;
|
||||
@@ -27,7 +26,6 @@ interface Item {
|
||||
}
|
||||
interface Vendor { OBJID: string; VENDOR_NAME: string }
|
||||
|
||||
interface Maker { OBJID: string; MAKER_NAME: string }
|
||||
|
||||
interface ItemAttributes {
|
||||
expiry_date?: string; // 소비기한 (유통기한)
|
||||
@@ -42,7 +40,6 @@ const fmt = (n: number) => Number(n || 0).toLocaleString("ko-KR");
|
||||
|
||||
export default function AdminItemsPage() {
|
||||
const [items, setItems] = useState<Item[]>([]);
|
||||
const [makers, setMakers] = useState<Maker[]>([]);
|
||||
const [vendors, setVendors] = useState<Vendor[]>([]);
|
||||
const [keyword, setKeyword] = useState("");
|
||||
const [filterStatus, setFilterStatus] = useState("");
|
||||
@@ -60,15 +57,6 @@ export default function AdminItemsPage() {
|
||||
setItems((await res.json()).RESULTLIST ?? []);
|
||||
};
|
||||
|
||||
const loadMakers = async () => {
|
||||
const res = await fetch("/api/m/makers/list", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
setMakers((await res.json()).RESULTLIST ?? []);
|
||||
};
|
||||
|
||||
const loadVendors = async () => {
|
||||
const res = await fetch("/api/m/vendors/list", {
|
||||
method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({}),
|
||||
@@ -78,7 +66,6 @@ export default function AdminItemsPage() {
|
||||
|
||||
useEffect(() => {
|
||||
loadItems();
|
||||
loadMakers();
|
||||
loadVendors();
|
||||
}, []); // eslint-disable-line
|
||||
|
||||
@@ -106,7 +93,6 @@ export default function AdminItemsPage() {
|
||||
actionType: isNew ? "regist" : "update",
|
||||
itemName: editing.ITEM_NAME,
|
||||
itemDetail: editing.ITEM_DETAIL,
|
||||
makerObjid: editing.MAKER_OBJID,
|
||||
unit: editing.UNIT || "EA",
|
||||
unitPrice: editing.UNIT_PRICE,
|
||||
costPrice: editing.COST_PRICE,
|
||||
@@ -236,7 +222,7 @@ export default function AdminItemsPage() {
|
||||
{it.REQUIRES_DELIVERY === "Y" && <span className="px-1 py-0.5 rounded bg-orange-100 text-orange-700 text-[9px] font-bold">택배</span>}
|
||||
{it.MAX_ORDER_QTY != null && Number(it.MAX_ORDER_QTY) > 0 && <span className="px-1 py-0.5 rounded bg-sky-100 text-sky-700 text-[9px] font-bold">≤{it.MAX_ORDER_QTY}</span>}
|
||||
</div>
|
||||
<div className="text-[10px] text-slate-400 font-mono mt-0.5">{it.ITEM_CODE} · {it.MAKER_NAME || "제조사 없음"}</div>
|
||||
<div className="text-[10px] text-slate-400 font-mono mt-0.5">{it.ITEM_CODE}</div>
|
||||
<div className="flex items-center justify-between mt-1.5 text-[11px]">
|
||||
<div>
|
||||
<span className="text-slate-400">단가</span> <b className="tabular-nums">₩{fmt(it.UNIT_PRICE)}</b>
|
||||
@@ -261,7 +247,6 @@ export default function AdminItemsPage() {
|
||||
<th className="px-3 py-3 w-14"></th>
|
||||
<th className="text-left px-3 py-3">품목코드</th>
|
||||
<th className="text-left px-3 py-3">품목명</th>
|
||||
<th className="text-left px-3 py-3">제조사</th>
|
||||
<th className="text-center px-3 py-3">구분</th>
|
||||
<th className="text-right px-3 py-3">단가</th>
|
||||
<th className="text-right px-3 py-3">원가</th>
|
||||
@@ -273,7 +258,7 @@ export default function AdminItemsPage() {
|
||||
<tbody>
|
||||
{items.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan={10} className="text-center py-12 text-slate-400">
|
||||
<td colSpan={9} className="text-center py-12 text-slate-400">
|
||||
품목이 없습니다. 신규 등록 버튼을 눌러주세요.
|
||||
</td>
|
||||
</tr>
|
||||
@@ -291,7 +276,6 @@ export default function AdminItemsPage() {
|
||||
</td>
|
||||
<td className="px-3 py-2 font-mono text-xs text-slate-500">{it.ITEM_CODE}</td>
|
||||
<td className="px-3 py-2 font-semibold text-slate-800">{it.ITEM_NAME}</td>
|
||||
<td className="px-3 py-2 text-slate-600 text-xs">{it.MAKER_NAME || "-"}</td>
|
||||
<td className="px-3 py-2 text-center">
|
||||
{it.IS_TAX_FREE === "Y" ? (
|
||||
<span className="px-1.5 py-0.5 rounded bg-violet-100 text-violet-700 text-[10px] font-bold">면세</span>
|
||||
@@ -361,29 +345,13 @@ export default function AdminItemsPage() {
|
||||
className="w-full h-10 px-3 rounded-lg border border-slate-200 text-sm focus:border-emerald-500 outline-none"
|
||||
/>
|
||||
</Field>
|
||||
<Field label="제조사">
|
||||
<select
|
||||
value={editing.MAKER_OBJID ?? ""}
|
||||
onChange={(e) => setEditing({ ...editing, MAKER_OBJID: e.target.value })}
|
||||
className="w-full h-10 px-3 rounded-lg border border-slate-200 text-sm bg-white focus:border-emerald-500 outline-none"
|
||||
>
|
||||
<option value="">선택</option>
|
||||
{makers.map((m) => (
|
||||
<option key={m.OBJID} value={m.OBJID}>{m.MAKER_NAME}</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
<Field label="공급업체">
|
||||
<select
|
||||
<SearchableSelect
|
||||
options={vendors.map((v) => ({ value: v.OBJID, label: v.VENDOR_NAME }))}
|
||||
value={editing.VENDOR_OBJID ?? ""}
|
||||
onChange={(e) => setEditing({ ...editing, VENDOR_OBJID: e.target.value })}
|
||||
className="w-full h-10 px-3 rounded-lg border border-slate-200 text-sm bg-white focus:border-emerald-500 outline-none"
|
||||
>
|
||||
<option value="">선택</option>
|
||||
{vendors.map((v) => (
|
||||
<option key={v.OBJID} value={v.OBJID}>{v.VENDOR_NAME}</option>
|
||||
))}
|
||||
</select>
|
||||
onChange={(v) => setEditing({ ...editing, VENDOR_OBJID: v })}
|
||||
placeholder="공급업체 검색"
|
||||
/>
|
||||
</Field>
|
||||
<Field label="단위">
|
||||
<select
|
||||
@@ -420,18 +388,24 @@ export default function AdminItemsPage() {
|
||||
</Field>
|
||||
<Field label="단가 (VAT포함)">
|
||||
<input
|
||||
type="number" min={0}
|
||||
value={editing.UNIT_PRICE ?? 0}
|
||||
onChange={(e) => setEditing({ ...editing, UNIT_PRICE: Number(e.target.value) })}
|
||||
className="w-full h-10 px-3 rounded-lg border border-slate-200 text-sm focus:border-emerald-500 outline-none"
|
||||
type="text" inputMode="numeric"
|
||||
value={editing.UNIT_PRICE == null ? "" : Math.round(Number(editing.UNIT_PRICE)).toLocaleString("ko-KR")}
|
||||
onChange={(e) => {
|
||||
const n = Number(e.target.value.replace(/[^0-9]/g, ""));
|
||||
setEditing({ ...editing, UNIT_PRICE: Number.isFinite(n) ? n : 0 });
|
||||
}}
|
||||
className="w-full h-10 px-3 rounded-lg border border-slate-200 text-sm tabular-nums text-right focus:border-emerald-500 outline-none"
|
||||
/>
|
||||
</Field>
|
||||
<Field label="원가">
|
||||
<input
|
||||
type="number" min={0}
|
||||
value={editing.COST_PRICE ?? 0}
|
||||
onChange={(e) => setEditing({ ...editing, COST_PRICE: Number(e.target.value) })}
|
||||
className="w-full h-10 px-3 rounded-lg border border-slate-200 text-sm focus:border-emerald-500 outline-none"
|
||||
type="text" inputMode="numeric"
|
||||
value={editing.COST_PRICE == null ? "" : Math.round(Number(editing.COST_PRICE)).toLocaleString("ko-KR")}
|
||||
onChange={(e) => {
|
||||
const n = Number(e.target.value.replace(/[^0-9]/g, ""));
|
||||
setEditing({ ...editing, COST_PRICE: Number.isFinite(n) ? n : 0 });
|
||||
}}
|
||||
className="w-full h-10 px-3 rounded-lg border border-slate-200 text-sm tabular-nums text-right focus:border-emerald-500 outline-none"
|
||||
/>
|
||||
</Field>
|
||||
<Field label="상태">
|
||||
|
||||
Reference in New Issue
Block a user