fix: Update error handling and warehouse code rendering in inventory and outbound pages
- Enhanced error handling in the OutboundPage component to capture and display error messages from API responses, improving user feedback during operations. - Updated the InventoryStatusPage to render warehouse names instead of codes, providing clearer information to users. - These changes aim to enhance the user experience by ensuring better error visibility and more informative data representation across multiple company implementations.
This commit is contained in:
@@ -164,7 +164,7 @@ export default function InventoryStatusPage() {
|
|||||||
}
|
}
|
||||||
// item_info 단위 카테고리
|
// item_info 단위 카테고리
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
const res = await apiClient.get("/table-categories/item_info/unit/values?filterCompanyCode=COMPANY_10");
|
||||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||||
} catch { /* skip */ }
|
} catch { /* skip */ }
|
||||||
setCategoryOptions(optMap);
|
setCategoryOptions(optMap);
|
||||||
@@ -214,7 +214,6 @@ export default function InventoryStatusPage() {
|
|||||||
...r,
|
...r,
|
||||||
item_name: itemInfo?.name || "",
|
item_name: itemInfo?.name || "",
|
||||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
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 || "",
|
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||||
status: resolve("status", r.status),
|
status: resolve("status", r.status),
|
||||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||||
@@ -350,6 +349,12 @@ export default function InventoryStatusPage() {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (col.key === "warehouse_code") {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
if (col.key === "safety_qty") {
|
if (col.key === "safety_qty") {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
import { apiClient } from "@/lib/api/client";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -326,7 +327,7 @@ export default function OutboundPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_10`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
@@ -371,7 +372,7 @@ export default function OutboundPage() {
|
|||||||
}
|
}
|
||||||
const res = await getOutboundList(params);
|
const res = await getOutboundList(params);
|
||||||
if (res.success) setData(res.data);
|
if (res.success) setData(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -388,7 +389,7 @@ export default function OutboundPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await getOutboundWarehouses();
|
const res = await getOutboundWarehouses();
|
||||||
if (res.success) setWarehouses(res.data);
|
if (res.success) setWarehouses(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -564,7 +565,7 @@ export default function OutboundPage() {
|
|||||||
const res = await getItemSources(keyword || undefined);
|
const res = await getItemSources(keyword || undefined);
|
||||||
if (res.success) setItems(res.data);
|
if (res.success) setItems(res.data);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setSourceLoading(false);
|
setSourceLoading(false);
|
||||||
@@ -596,7 +597,7 @@ export default function OutboundPage() {
|
|||||||
loadSourceData(defaultType),
|
loadSourceData(defaultType),
|
||||||
]);
|
]);
|
||||||
if (numRes.success) setModalOutboundNo(numRes.data);
|
if (numRes.success) setModalOutboundNo(numRes.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
setModalOutboundNo("");
|
setModalOutboundNo("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -899,8 +900,8 @@ export default function OutboundPage() {
|
|||||||
fetchList();
|
fetchList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
toast.error(editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
const msg = err?.response?.data?.message || (editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다."); toast.error(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ export default function ReceivingPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_10`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export default function InventoryStatusPage() {
|
|||||||
}
|
}
|
||||||
// item_info 단위 카테고리
|
// item_info 단위 카테고리
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
const res = await apiClient.get("/table-categories/item_info/unit/values?filterCompanyCode=COMPANY_16");
|
||||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||||
} catch { /* skip */ }
|
} catch { /* skip */ }
|
||||||
setCategoryOptions(optMap);
|
setCategoryOptions(optMap);
|
||||||
@@ -214,7 +214,6 @@ export default function InventoryStatusPage() {
|
|||||||
...r,
|
...r,
|
||||||
item_name: itemInfo?.name || "",
|
item_name: itemInfo?.name || "",
|
||||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
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 || "",
|
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||||
status: resolve("status", r.status),
|
status: resolve("status", r.status),
|
||||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||||
@@ -350,6 +349,12 @@ export default function InventoryStatusPage() {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (col.key === "warehouse_code") {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
if (col.key === "safety_qty") {
|
if (col.key === "safety_qty") {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
import { apiClient } from "@/lib/api/client";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -326,17 +327,22 @@ export default function OutboundPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_16`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
} catch { /* skip */ }
|
} catch (e: any) { console.error("[outbound] cat load error:", col, e?.message, e?.response?.status, e?.response?.data); }
|
||||||
})
|
})
|
||||||
).then(() => setCatMap(map));
|
).then(() => {
|
||||||
|
console.log("[outbound] catMap loaded:", JSON.stringify(map).slice(0, 200));
|
||||||
|
setCatMap(map);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
const resolveCat = useCallback((col: string, code: string) => {
|
const resolveCat = useCallback((col: string, code: string) => {
|
||||||
if (!code) return "";
|
if (!code) return "";
|
||||||
return catMap[col]?.[code] || code;
|
const result = catMap[col]?.[code] || code;
|
||||||
|
if (code.startsWith("CAT_")) console.log("[outbound] resolveCat:", col, code, "->", result, "catMap keys:", Object.keys(catMap));
|
||||||
|
return result;
|
||||||
}, [catMap]);
|
}, [catMap]);
|
||||||
|
|
||||||
// 소스 데이터
|
// 소스 데이터
|
||||||
@@ -371,7 +377,7 @@ export default function OutboundPage() {
|
|||||||
}
|
}
|
||||||
const res = await getOutboundList(params);
|
const res = await getOutboundList(params);
|
||||||
if (res.success) setData(res.data);
|
if (res.success) setData(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -388,7 +394,7 @@ export default function OutboundPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await getOutboundWarehouses();
|
const res = await getOutboundWarehouses();
|
||||||
if (res.success) setWarehouses(res.data);
|
if (res.success) setWarehouses(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -564,7 +570,7 @@ export default function OutboundPage() {
|
|||||||
const res = await getItemSources(keyword || undefined);
|
const res = await getItemSources(keyword || undefined);
|
||||||
if (res.success) setItems(res.data);
|
if (res.success) setItems(res.data);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setSourceLoading(false);
|
setSourceLoading(false);
|
||||||
@@ -596,7 +602,7 @@ export default function OutboundPage() {
|
|||||||
loadSourceData(defaultType),
|
loadSourceData(defaultType),
|
||||||
]);
|
]);
|
||||||
if (numRes.success) setModalOutboundNo(numRes.data);
|
if (numRes.success) setModalOutboundNo(numRes.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
setModalOutboundNo("");
|
setModalOutboundNo("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -899,8 +905,8 @@ export default function OutboundPage() {
|
|||||||
fetchList();
|
fetchList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
toast.error(editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
const msg = err?.response?.data?.message || (editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다."); toast.error(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ export default function ReceivingPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_16`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export default function InventoryStatusPage() {
|
|||||||
}
|
}
|
||||||
// item_info 단위 카테고리
|
// item_info 단위 카테고리
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
const res = await apiClient.get("/table-categories/item_info/unit/values?filterCompanyCode=COMPANY_29");
|
||||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||||
} catch { /* skip */ }
|
} catch { /* skip */ }
|
||||||
setCategoryOptions(optMap);
|
setCategoryOptions(optMap);
|
||||||
@@ -214,7 +214,6 @@ export default function InventoryStatusPage() {
|
|||||||
...r,
|
...r,
|
||||||
item_name: itemInfo?.name || "",
|
item_name: itemInfo?.name || "",
|
||||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
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 || "",
|
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||||
status: resolve("status", r.status),
|
status: resolve("status", r.status),
|
||||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||||
@@ -350,6 +349,12 @@ export default function InventoryStatusPage() {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (col.key === "warehouse_code") {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
if (col.key === "safety_qty") {
|
if (col.key === "safety_qty") {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
import { apiClient } from "@/lib/api/client";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -326,7 +327,7 @@ export default function OutboundPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_29`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
@@ -371,7 +372,7 @@ export default function OutboundPage() {
|
|||||||
}
|
}
|
||||||
const res = await getOutboundList(params);
|
const res = await getOutboundList(params);
|
||||||
if (res.success) setData(res.data);
|
if (res.success) setData(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -388,7 +389,7 @@ export default function OutboundPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await getOutboundWarehouses();
|
const res = await getOutboundWarehouses();
|
||||||
if (res.success) setWarehouses(res.data);
|
if (res.success) setWarehouses(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -564,7 +565,7 @@ export default function OutboundPage() {
|
|||||||
const res = await getItemSources(keyword || undefined);
|
const res = await getItemSources(keyword || undefined);
|
||||||
if (res.success) setItems(res.data);
|
if (res.success) setItems(res.data);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setSourceLoading(false);
|
setSourceLoading(false);
|
||||||
@@ -596,7 +597,7 @@ export default function OutboundPage() {
|
|||||||
loadSourceData(defaultType),
|
loadSourceData(defaultType),
|
||||||
]);
|
]);
|
||||||
if (numRes.success) setModalOutboundNo(numRes.data);
|
if (numRes.success) setModalOutboundNo(numRes.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
setModalOutboundNo("");
|
setModalOutboundNo("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -899,8 +900,8 @@ export default function OutboundPage() {
|
|||||||
fetchList();
|
fetchList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
toast.error(editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
const msg = err?.response?.data?.message || (editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다."); toast.error(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ export default function ReceivingPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_29`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export default function InventoryStatusPage() {
|
|||||||
}
|
}
|
||||||
// item_info 단위 카테고리
|
// item_info 단위 카테고리
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
const res = await apiClient.get("/table-categories/item_info/unit/values?filterCompanyCode=COMPANY_30");
|
||||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||||
} catch { /* skip */ }
|
} catch { /* skip */ }
|
||||||
setCategoryOptions(optMap);
|
setCategoryOptions(optMap);
|
||||||
@@ -214,7 +214,6 @@ export default function InventoryStatusPage() {
|
|||||||
...r,
|
...r,
|
||||||
item_name: itemInfo?.name || "",
|
item_name: itemInfo?.name || "",
|
||||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
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 || "",
|
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||||
status: resolve("status", r.status),
|
status: resolve("status", r.status),
|
||||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||||
@@ -350,6 +349,12 @@ export default function InventoryStatusPage() {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (col.key === "warehouse_code") {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
if (col.key === "safety_qty") {
|
if (col.key === "safety_qty") {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
import { apiClient } from "@/lib/api/client";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -326,7 +327,7 @@ export default function OutboundPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_30`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
@@ -371,7 +372,7 @@ export default function OutboundPage() {
|
|||||||
}
|
}
|
||||||
const res = await getOutboundList(params);
|
const res = await getOutboundList(params);
|
||||||
if (res.success) setData(res.data);
|
if (res.success) setData(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -388,7 +389,7 @@ export default function OutboundPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await getOutboundWarehouses();
|
const res = await getOutboundWarehouses();
|
||||||
if (res.success) setWarehouses(res.data);
|
if (res.success) setWarehouses(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -564,7 +565,7 @@ export default function OutboundPage() {
|
|||||||
const res = await getItemSources(keyword || undefined);
|
const res = await getItemSources(keyword || undefined);
|
||||||
if (res.success) setItems(res.data);
|
if (res.success) setItems(res.data);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setSourceLoading(false);
|
setSourceLoading(false);
|
||||||
@@ -596,7 +597,7 @@ export default function OutboundPage() {
|
|||||||
loadSourceData(defaultType),
|
loadSourceData(defaultType),
|
||||||
]);
|
]);
|
||||||
if (numRes.success) setModalOutboundNo(numRes.data);
|
if (numRes.success) setModalOutboundNo(numRes.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
setModalOutboundNo("");
|
setModalOutboundNo("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -899,8 +900,8 @@ export default function OutboundPage() {
|
|||||||
fetchList();
|
fetchList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
toast.error(editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
const msg = err?.response?.data?.message || (editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다."); toast.error(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ export default function ReceivingPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_30`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export default function InventoryStatusPage() {
|
|||||||
}
|
}
|
||||||
// item_info 단위 카테고리
|
// item_info 단위 카테고리
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
const res = await apiClient.get("/table-categories/item_info/unit/values?filterCompanyCode=COMPANY_7");
|
||||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||||
} catch { /* skip */ }
|
} catch { /* skip */ }
|
||||||
setCategoryOptions(optMap);
|
setCategoryOptions(optMap);
|
||||||
@@ -214,7 +214,6 @@ export default function InventoryStatusPage() {
|
|||||||
...r,
|
...r,
|
||||||
item_name: itemInfo?.name || "",
|
item_name: itemInfo?.name || "",
|
||||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
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 || "",
|
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||||
status: resolve("status", r.status),
|
status: resolve("status", r.status),
|
||||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||||
@@ -350,6 +349,12 @@ export default function InventoryStatusPage() {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (col.key === "warehouse_code") {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
if (col.key === "safety_qty") {
|
if (col.key === "safety_qty") {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
import { apiClient } from "@/lib/api/client";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -326,7 +327,7 @@ export default function OutboundPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_7`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
@@ -899,8 +900,9 @@ export default function OutboundPage() {
|
|||||||
fetchList();
|
fetchList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
toast.error(editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
const msg = err?.response?.data?.message || (editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
||||||
|
toast.error(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ export default function ReceivingPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_7`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export default function InventoryStatusPage() {
|
|||||||
}
|
}
|
||||||
// item_info 단위 카테고리
|
// item_info 단위 카테고리
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
const res = await apiClient.get("/table-categories/item_info/unit/values?filterCompanyCode=COMPANY_8");
|
||||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||||
} catch { /* skip */ }
|
} catch { /* skip */ }
|
||||||
setCategoryOptions(optMap);
|
setCategoryOptions(optMap);
|
||||||
@@ -214,7 +214,6 @@ export default function InventoryStatusPage() {
|
|||||||
...r,
|
...r,
|
||||||
item_name: itemInfo?.name || "",
|
item_name: itemInfo?.name || "",
|
||||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
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 || "",
|
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||||
status: resolve("status", r.status),
|
status: resolve("status", r.status),
|
||||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||||
@@ -350,6 +349,12 @@ export default function InventoryStatusPage() {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (col.key === "warehouse_code") {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
if (col.key === "safety_qty") {
|
if (col.key === "safety_qty") {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
import { apiClient } from "@/lib/api/client";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -326,7 +327,7 @@ export default function OutboundPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_8`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
@@ -371,7 +372,7 @@ export default function OutboundPage() {
|
|||||||
}
|
}
|
||||||
const res = await getOutboundList(params);
|
const res = await getOutboundList(params);
|
||||||
if (res.success) setData(res.data);
|
if (res.success) setData(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -388,7 +389,7 @@ export default function OutboundPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await getOutboundWarehouses();
|
const res = await getOutboundWarehouses();
|
||||||
if (res.success) setWarehouses(res.data);
|
if (res.success) setWarehouses(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -564,7 +565,7 @@ export default function OutboundPage() {
|
|||||||
const res = await getItemSources(keyword || undefined);
|
const res = await getItemSources(keyword || undefined);
|
||||||
if (res.success) setItems(res.data);
|
if (res.success) setItems(res.data);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setSourceLoading(false);
|
setSourceLoading(false);
|
||||||
@@ -596,7 +597,7 @@ export default function OutboundPage() {
|
|||||||
loadSourceData(defaultType),
|
loadSourceData(defaultType),
|
||||||
]);
|
]);
|
||||||
if (numRes.success) setModalOutboundNo(numRes.data);
|
if (numRes.success) setModalOutboundNo(numRes.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
setModalOutboundNo("");
|
setModalOutboundNo("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -899,8 +900,8 @@ export default function OutboundPage() {
|
|||||||
fetchList();
|
fetchList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
toast.error(editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
const msg = err?.response?.data?.message || (editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다."); toast.error(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ export default function ReceivingPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_8`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export default function InventoryStatusPage() {
|
|||||||
}
|
}
|
||||||
// item_info 단위 카테고리
|
// item_info 단위 카테고리
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get("/table-categories/item_info/unit/values");
|
const res = await apiClient.get("/table-categories/item_info/unit/values?filterCompanyCode=COMPANY_9");
|
||||||
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
|
||||||
} catch { /* skip */ }
|
} catch { /* skip */ }
|
||||||
setCategoryOptions(optMap);
|
setCategoryOptions(optMap);
|
||||||
@@ -214,7 +214,6 @@ export default function InventoryStatusPage() {
|
|||||||
...r,
|
...r,
|
||||||
item_name: itemInfo?.name || "",
|
item_name: itemInfo?.name || "",
|
||||||
unit: resolve("item_unit", rawUnit) || rawUnit,
|
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 || "",
|
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
|
||||||
status: resolve("status", r.status),
|
status: resolve("status", r.status),
|
||||||
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
|
||||||
@@ -350,6 +349,12 @@ export default function InventoryStatusPage() {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (col.key === "warehouse_code") {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
if (col.key === "safety_qty") {
|
if (col.key === "safety_qty") {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
import { apiClient } from "@/lib/api/client";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -326,7 +327,7 @@ export default function OutboundPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_9`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
@@ -371,7 +372,7 @@ export default function OutboundPage() {
|
|||||||
}
|
}
|
||||||
const res = await getOutboundList(params);
|
const res = await getOutboundList(params);
|
||||||
if (res.success) setData(res.data);
|
if (res.success) setData(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -388,7 +389,7 @@ export default function OutboundPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await getOutboundWarehouses();
|
const res = await getOutboundWarehouses();
|
||||||
if (res.success) setWarehouses(res.data);
|
if (res.success) setWarehouses(res.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -564,7 +565,7 @@ export default function OutboundPage() {
|
|||||||
const res = await getItemSources(keyword || undefined);
|
const res = await getItemSources(keyword || undefined);
|
||||||
if (res.success) setItems(res.data);
|
if (res.success) setItems(res.data);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// ignore
|
// ignore
|
||||||
} finally {
|
} finally {
|
||||||
setSourceLoading(false);
|
setSourceLoading(false);
|
||||||
@@ -596,7 +597,7 @@ export default function OutboundPage() {
|
|||||||
loadSourceData(defaultType),
|
loadSourceData(defaultType),
|
||||||
]);
|
]);
|
||||||
if (numRes.success) setModalOutboundNo(numRes.data);
|
if (numRes.success) setModalOutboundNo(numRes.data);
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
setModalOutboundNo("");
|
setModalOutboundNo("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -899,8 +900,8 @@ export default function OutboundPage() {
|
|||||||
fetchList();
|
fetchList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
toast.error(editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다.");
|
const msg = err?.response?.data?.message || (editMode ? "수정에 실패했어요" : "출고 등록 중 오류가 발생했습니다."); toast.error(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ export default function ReceivingPage() {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
["material", "unit"].map(async (col) => {
|
["material", "unit"].map(async (col) => {
|
||||||
try {
|
try {
|
||||||
const res = await apiClient.get(`/table-categories/item_info/${col}/values`);
|
const res = await apiClient.get(`/table-categories/item_info/${col}/values?filterCompanyCode=COMPANY_9`);
|
||||||
const items = flatten(res.data?.data || []);
|
const items = flatten(res.data?.data || []);
|
||||||
map[col] = {};
|
map[col] = {};
|
||||||
for (const item of items) map[col][item.code] = item.label;
|
for (const item of items) map[col][item.code] = item.label;
|
||||||
|
|||||||
Reference in New Issue
Block a user