Browse Source

add qc category to item master, update inventory

master
cyril.tsui 1 week ago
parent
commit
d2789b064f
9 changed files with 109 additions and 35 deletions
  1. +12
    -0
      src/app/api/settings/qcCategory/index.ts
  2. +20
    -0
      src/app/api/shop/index.ts
  3. +4
    -1
      src/components/CreateItem/CreateItem.tsx
  4. +5
    -0
      src/components/CreateItem/CreateItemWrapper.tsx
  5. +36
    -4
      src/components/CreateItem/ProductDetails.tsx
  6. +14
    -14
      src/components/InventorySearch/InventoryLotLineTable.tsx
  7. +14
    -14
      src/components/InventorySearch/InventoryTable.tsx
  8. +3
    -2
      src/i18n/zh/inventory.json
  9. +1
    -0
      src/i18n/zh/items.json

+ 12
- 0
src/app/api/settings/qcCategory/index.ts View File

@@ -9,6 +9,12 @@ export interface QcCategoryResult {
name: string;
}

export interface QcCategoryCombo {
id: number;
value: number;
label: string;
}

export const preloadQcCategory = () => {
fetchQcCategories();
};
@@ -18,3 +24,9 @@ export const fetchQcCategories = cache(async () => {
next: { tags: ["qcCategories"] },
});
});

export const fetchQcCategoryCombo = cache(async () => {
return serverFetchJson<QcCategoryCombo[]>(`${BASE_API_URL}/qcCategories/combo`, {
next: { tags: ["qcCategoryCombo"] },
});
});

+ 20
- 0
src/app/api/shop/index.ts View File

@@ -0,0 +1,20 @@
"server only"
import { BASE_API_URL } from '@/config/api';
import { serverFetchJson } from '@/app/utils/fetchUtil';
import { cache } from "react";

export interface ShopCombo {
id: number;
value: number; // id
label: string;
}

export const fetchSupplierCombo = cache(async() => {
return serverFetchJson<ShopCombo[]>(`${BASE_API_URL}/shop/combo/supplier`, {
method: "GET",
headers: { "Content-Type": "application/json"},
next: {
tags: ["supplierCombo"]
}
})
})

+ 4
- 1
src/components/CreateItem/CreateItem.tsx View File

@@ -29,12 +29,14 @@ import QcDetails from "./QcDetails";
import { ItemQc } from "@/app/api/settings/item";
import { saveItemQcChecks } from "@/app/api/settings/qcCheck/actions";
import { useGridApiRef } from "@mui/x-data-grid";
import { QcCategoryCombo } from "@/app/api/settings/qcCategory";

type Props = {
isEditMode: boolean;
// type: TypeEnum;
defaultValues: Partial<CreateItemInputs> | undefined;
qcChecks: ItemQc[];
qcCategoryCombo: QcCategoryCombo[]
};

const CreateItem: React.FC<Props> = ({
@@ -42,6 +44,7 @@ const CreateItem: React.FC<Props> = ({
// type,
defaultValues,
qcChecks,
qcCategoryCombo,
}) => {
// console.log(type)
const apiRef = useGridApiRef();
@@ -192,7 +195,7 @@ const CreateItem: React.FC<Props> = ({
{serverError}
</Typography>
)}
{tabIndex === 0 && <ProductDetails isEditMode={isEditMode} />}
{tabIndex === 0 && <ProductDetails isEditMode={isEditMode} qcCategoryCombo={qcCategoryCombo}/>}
{tabIndex === 1 && <QcDetails apiRef={apiRef} />}
{/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */}
{/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */}


+ 5
- 0
src/components/CreateItem/CreateItemWrapper.tsx View File

@@ -5,6 +5,7 @@ import { CreateItemInputs } from "@/app/api/settings/item/actions";
import { notFound } from "next/navigation";
import { fetchItem } from "@/app/api/settings/item";
import { fetchQcItems } from "@/app/api/settings/qcItem";
import { fetchQcCategoryCombo } from "@/app/api/settings/qcCategory";
interface SubComponents {
Loading: typeof CreateItemLoading;
}
@@ -37,14 +38,18 @@ const CreateItemWrapper: React.FC<Props> & SubComponents = async ({ id }) => {
maxQty: item?.maxQty,
qcChecks: qcChecks,
qcChecks_active: activeRows,
qcCategoryId: item.qcCategory?.id
};
}

const qcCategoryCombo = await fetchQcCategoryCombo();

return (
<CreateItem
isEditMode={Boolean(id)}
defaultValues={defaultValues}
qcChecks={qcChecks || []}
qcCategoryCombo={qcCategoryCombo}
/>
);
};


+ 36
- 4
src/components/CreateItem/ProductDetails.tsx View File

@@ -1,5 +1,6 @@
"use client";
import {
Autocomplete,
Box,
Button,
Card,
@@ -10,11 +11,11 @@ import {
Typography,
} from "@mui/material";
import { Check, Close, EditNote } from "@mui/icons-material";
import { useFormContext } from "react-hook-form";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import InputDataGrid from "../InputDataGrid";

import { useCallback, useMemo, useState } from "react";
import { SyntheticEvent, useCallback, useMemo, useState } from "react";
import { GridColDef, GridRowModel } from "@mui/x-data-grid";
import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid";
import { TypeEnum } from "@/app/utils/typeEnum";
@@ -22,6 +23,7 @@ import { NumberInputProps } from "./NumberInputProps";
import { CreateItemInputs } from "@/app/api/settings/item/actions";
import { RestartAlt } from "@mui/icons-material";
import { ItemQc } from "@/app/api/settings/item";
import { QcCategoryCombo } from "@/app/api/settings/qcCategory";
type Props = {
// isEditMode: boolean;
// type: TypeEnum;
@@ -29,9 +31,10 @@ type Props = {
// type: TypeEnum;
defaultValues?: Partial<CreateItemInputs> | undefined;
qcChecks?: ItemQc[];
qcCategoryCombo: QcCategoryCombo[];
};

const ProductDetails: React.FC<Props> = ({ isEditMode }) => {
const ProductDetails: React.FC<Props> = ({ isEditMode, qcCategoryCombo }) => {
const {
t,
i18n: { language },
@@ -104,6 +107,11 @@ const ProductDetails: React.FC<Props> = ({ isEditMode }) => {
// router.replace(`/settings/product`);
console.log("cancel");
};

const handleAutoCompleteChange = useCallback((event: SyntheticEvent<Element, Event>, value: QcCategoryCombo, onChange: (...event: any[]) => void) => {
onChange(value.id)
}, [])

return (
<Card sx={{ display: "block" }}>
<CardContent component={Stack} spacing={4}>
@@ -202,7 +210,31 @@ const ProductDetails: React.FC<Props> = ({ isEditMode }) => {
helperText={errors.maxQty?.message}
/>
</Grid>
<Grid item xs={0}>
<Grid item xs={6}>
<Controller
control={control}
name="qcCategoryId"
render={({ field }) => (
<Autocomplete
disableClearable
options={qcCategoryCombo}
defaultValue={qcCategoryCombo.find(qc => qc.id === field.value)}
onChange={(event, value) => {
handleAutoCompleteChange(event, value, field.onChange)
}}
onBlur={field.onBlur}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
label={t("Qc Category")}
/>
)}
/>
)}
/>
</Grid>
<Grid item xs={12}>
<Stack
direction="row"
justifyContent="flex-end"


+ 14
- 14
src/components/InventorySearch/InventoryLotLineTable.tsx View File

@@ -82,23 +82,23 @@ const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingContr
},
{
name: "uom",
label: t("Sales UoM"),
align: "left",
headerAlign: "left",
},
{
name: "qtyPerSmallestUnit",
label: t("Available Qty Per Smallest Unit"),
align: "right",
headerAlign: "right",
type: "integer",
},
{
name: "baseUom",
label: t("Base UoM"),
label: t("Stock UoM"),
align: "left",
headerAlign: "left",
},
// {
// name: "qtyPerSmallestUnit",
// label: t("Available Qty Per Smallest Unit"),
// align: "right",
// headerAlign: "right",
// type: "integer",
// },
// {
// name: "baseUom",
// label: t("Base UoM"),
// align: "left",
// headerAlign: "left",
// },
{
name: "expiryDate",
label: t("Expiry Date"),


+ 14
- 14
src/components/InventorySearch/InventoryTable.tsx View File

@@ -41,25 +41,25 @@ const InventoryTable: React.FC<Props> = ({ inventories, pagingController, setPag
},
{
name: "uomUdfudesc",
label: t("Sales UoM"),
align: "left",
headerAlign: "left",
},
{
name: "qtyPerSmallestUnit",
label: t("Available Qty Per Smallest Unit"),
align: "right",
headerAlign: "right",
type: "integer",
},
{
name: "baseUom",
label: t("Base UoM"),
label: t("Stock UoM"),
align: "left",
headerAlign: "left",
},
// {
// name: "qtyPerSmallestUnit",
// label: t("Available Qty Per Smallest Unit"),
// align: "right",
// headerAlign: "right",
// type: "integer",
// },
// {
// name: "baseUom",
// label: t("Base UoM"),
// align: "left",
// headerAlign: "left",
// },
// {
// name: "qtyPerSmallestUnit",
// label: t("Qty Per Smallest Unit"),
// align: "right",
// headerAlign: "right",


+ 3
- 2
src/i18n/zh/inventory.json View File

@@ -8,12 +8,13 @@
"UoM": "單位",
"mat": "物料",
"fg": "成品",
"Available Qty": "可用數量 (銷售單位)",
"Available Qty": "可用數量 (倉存單位)",
"Sales UoM": "銷售單位",
"Stock UoM": "倉存單位",
"Available Qty Per Smallest Unit": "可用數量 (基本單位)",
"Base UoM": "基本單位",
"Lot No": "批號",
"Expiry Date": "到期日",
"No items are selected yet.": "未選擇項目",
"Item selected": "已選擇項目"
}
}

+ 1
- 0
src/i18n/zh/items.json View File

@@ -10,6 +10,7 @@
"Product / Material": "產品 / 材料",
"Product / Material Details": "產品 / 材料詳情",
"Qc items": "QC 項目",
"Qc Category": "質檢模板",
"Name": "名稱",
"name": "名稱",
"description": "描述",


Loading…
Cancel
Save