feat: Enhance inventory and outbound pages with category mapping and user information
- Implemented user mapping to display user names instead of IDs in the inventory and receiving pages. - Added category mapping for materials and units in the outbound page, improving data representation. - Updated API calls to fetch user and category data, ensuring accurate and user-friendly displays. - These enhancements aim to improve the overall user experience by providing clearer information and better data management across multiple company implementations.
This commit is contained in:
@@ -140,31 +140,47 @@ export default function InventoryStatusPage() {
|
||||
Record<string, { code: string; label: string }[]>
|
||||
>({});
|
||||
|
||||
// 카테고리 로드
|
||||
// 사용자 맵 (writer → 이름)
|
||||
const [userMap, setUserMap] = useState<Record<string, string>>({});
|
||||
|
||||
// 카테고리 + 사용자 로드
|
||||
useEffect(() => {
|
||||
const load = async () => {
|
||||
const optMap: Record<string, { code: string; label: string }[]> = {};
|
||||
const flatten = (vals: any[]): { code: string; label: string }[] => {
|
||||
const result: { code: string; label: string }[] = [];
|
||||
for (const v of vals) {
|
||||
result.push({ code: v.valueCode, label: v.valueLabel });
|
||||
result.push({ code: v.valueCode || v.value_code || v.code, label: v.valueLabel || v.value_label || v.label });
|
||||
if (v.children?.length) result.push(...flatten(v.children));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
for (const col of ["status", "unit"]) {
|
||||
// inventory_stock 카테고리
|
||||
for (const col of ["status"]) {
|
||||
try {
|
||||
const res = await apiClient.get(
|
||||
`/table-categories/${STOCK_TABLE}/${col}/values`
|
||||
);
|
||||
const res = await apiClient.get(`/table-categories/${STOCK_TABLE}/${col}/values`);
|
||||
if (res.data?.success) optMap[col] = flatten(res.data.data || []);
|
||||
} catch {
|
||||
/* skip */
|
||||
}
|
||||
} catch { /* skip */ }
|
||||
}
|
||||
// item_info 단위 카테고리
|
||||
try {
|
||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||
} catch { /* skip */ }
|
||||
setCategoryOptions(optMap);
|
||||
};
|
||||
load();
|
||||
// 사용자 목록 로드
|
||||
apiClient.get("/admin/users").then((res) => {
|
||||
const users = res.data?.data || res.data || [];
|
||||
const map: Record<string, string> = {};
|
||||
for (const u of users) {
|
||||
const id = u.user_id || u.id;
|
||||
const name = u.user_name || u.name || id;
|
||||
if (id) map[id] = name;
|
||||
}
|
||||
setUserMap(map);
|
||||
}).catch(() => {});
|
||||
}, []);
|
||||
|
||||
// 재고 목록 조회
|
||||
@@ -193,10 +209,12 @@ export default function InventoryStatusPage() {
|
||||
};
|
||||
const data = raw.map((r: any) => {
|
||||
const itemInfo = itemMap.get(r.item_code) as any;
|
||||
const rawUnit = itemInfo?.unit || r.unit || "";
|
||||
return {
|
||||
...r,
|
||||
item_name: itemInfo?.name || "",
|
||||
unit: itemInfo?.unit || resolve("unit", r.unit),
|
||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
||||
warehouse_code: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||
status: resolve("status", r.status),
|
||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||
@@ -613,7 +631,7 @@ export default function InventoryStatusPage() {
|
||||
<TableCell className="truncate max-w-[150px]">
|
||||
{h.remark || h.reason || ""}
|
||||
</TableCell>
|
||||
<TableCell>{h.writer || h.created_by || ""}</TableCell>
|
||||
<TableCell>{userMap[h.writer] || userMap[h.created_by] || h.writer || h.created_by || ""}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
|
||||
Reference in New Issue
Block a user