@@ -1,3 +1,4 @@ | |||||
import { fetchPrinterCombo } from "@/app/api/settings/printer"; | |||||
import { fetchEscalationCombo } from "@/app/api/user"; | import { fetchEscalationCombo } from "@/app/api/user"; | ||||
import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
@@ -25,6 +26,7 @@ const PoEdit: React.FC<Props> = async ({ searchParams }) => { | |||||
} | } | ||||
fetchEscalationCombo() | fetchEscalationCombo() | ||||
fetchPrinterCombo() | |||||
return ( | return ( | ||||
<> | <> | ||||
@@ -6,10 +6,11 @@ import { revalidateTag } from "next/cache"; | |||||
import { cache } from "react"; | import { cache } from "react"; | ||||
import { PoResult, StockInLine } from "."; | import { PoResult, StockInLine } from "."; | ||||
//import { serverFetchJson } from "@/app/utils/fetchUtil"; | //import { serverFetchJson } from "@/app/utils/fetchUtil"; | ||||
import { serverFetchJson } from "../../utils/fetchUtil"; | |||||
import { serverFetchJson, serverFetchWithNoContent } from "../../utils/fetchUtil"; | |||||
import { QcItemResult } from "../settings/qcItem"; | import { QcItemResult } from "../settings/qcItem"; | ||||
import { RecordsRes } from "../utils"; | import { RecordsRes } from "../utils"; | ||||
import { Uom } from "../settings/uom"; | import { Uom } from "../settings/uom"; | ||||
import { convertObjToURLSearchParams } from "@/app/utils/commonUtil"; | |||||
// import { BASE_API_URL } from "@/config/api"; | // import { BASE_API_URL } from "@/config/api"; | ||||
export interface PostStockInLineResponse<T> { | export interface PostStockInLineResponse<T> { | ||||
@@ -81,26 +82,34 @@ export interface EscalationInput { | |||||
acceptedQty?: number; // this is the qty to be escalated | acceptedQty?: number; // this is the qty to be escalated | ||||
// escalationQty: number | // escalationQty: number | ||||
} | } | ||||
export interface PutawayLine { | |||||
export interface PutAwayLine { | |||||
id?: number | id?: number | ||||
qty: number | qty: number | ||||
warehouseId: number; | warehouseId: number; | ||||
warehouse: string; | warehouse: string; | ||||
printQty: number | |||||
printQty: number; | |||||
_isNew?: boolean; | |||||
printQty?: number; | |||||
} | } | ||||
export interface PutawayInput { | |||||
export interface PutAwayInput { | |||||
status: string; | status: string; | ||||
acceptedQty: number; | acceptedQty: number; | ||||
warehouseId: number; | warehouseId: number; | ||||
putawayLine: PutawayLine[] | |||||
putAwayLines: PutAwayLine[] | |||||
} | } | ||||
export type ModalFormInput = Partial< | export type ModalFormInput = Partial< | ||||
PurchaseQCInput & StockInInput & PutawayInput | |||||
PurchaseQCInput & StockInInput & PutAwayInput | |||||
> & { | > & { | ||||
escalationLog? : Partial<EscalationInput> | escalationLog? : Partial<EscalationInput> | ||||
}; | }; | ||||
export interface PrintQrCodeForSilRequest { | |||||
stockInLineId: number; | |||||
printerId: number; | |||||
printQty?: number; | |||||
} | |||||
export const testFetch = cache(async (id: number) => { | export const testFetch = cache(async (id: number) => { | ||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | ||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
@@ -217,3 +226,16 @@ export const testing = cache(async (queryParams?: Record<string, any>) => { | |||||
); | ); | ||||
} | } | ||||
}); | }); | ||||
export const printQrCodeForSil = cache(async(data: PrintQrCodeForSilRequest) => { | |||||
const params = convertObjToURLSearchParams(data) | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/stockInLine/printQrCode?${params}`, | |||||
{ | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["printQrCodeForSil"], | |||||
}, | |||||
}, | |||||
) | |||||
}) |
@@ -6,6 +6,7 @@ import { serverFetchJson } from "../../utils/fetchUtil"; | |||||
import { BASE_API_URL } from "../../../config/api"; | import { BASE_API_URL } from "../../../config/api"; | ||||
import { Uom } from "../settings/uom"; | import { Uom } from "../settings/uom"; | ||||
import { RecordsRes } from "../utils"; | import { RecordsRes } from "../utils"; | ||||
import { PutAwayLine } from "./actions"; | |||||
export interface PoResult { | export interface PoResult { | ||||
id: number; | id: number; | ||||
@@ -82,6 +83,7 @@ export interface StockInLine { | |||||
dnDate?: number[]; | dnDate?: number[]; | ||||
stockQty?: number; | stockQty?: number; | ||||
handlerId?: number; | handlerId?: number; | ||||
putAwayLines?: PutAwayLine[]; | |||||
} | } | ||||
export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | ||||
@@ -0,0 +1,21 @@ | |||||
import { serverFetchJson } from '@/app/utils/fetchUtil'; | |||||
import { BASE_API_URL } from '@/config/api'; | |||||
import { cache } from "react"; | |||||
import "server-only"; | |||||
export interface PrinterCombo { | |||||
id: number; | |||||
value: number; | |||||
label?: string; | |||||
code?: string; | |||||
name?: string; | |||||
description?: string; | |||||
ip?: string; | |||||
port?: number; | |||||
} | |||||
export const fetchPrinterCombo = cache(async () => { | |||||
return serverFetchJson<PrinterCombo[]>(`${BASE_API_URL}/printers/combo`, { | |||||
next: { tags: ["qcItems"] }, | |||||
}) | |||||
}) |
@@ -10,8 +10,20 @@ export interface WarehouseResult { | |||||
description: string; | description: string; | ||||
} | } | ||||
export interface WarehouseCombo { | |||||
id: number; | |||||
value: number; | |||||
label: string; | |||||
} | |||||
export const fetchWarehouseList = cache(async () => { | export const fetchWarehouseList = cache(async () => { | ||||
return serverFetchJson<WarehouseResult[]>(`${BASE_API_URL}/warehouse`, { | return serverFetchJson<WarehouseResult[]>(`${BASE_API_URL}/warehouse`, { | ||||
next: { tags: ["warehouse"] }, | next: { tags: ["warehouse"] }, | ||||
}); | }); | ||||
}); | }); | ||||
export const fetchWarehouseCombo = cache(async () => { | |||||
return serverFetchJson<WarehouseCombo[]>(`${BASE_API_URL}/warehouse/combo`, { | |||||
next: { tags: ["warehouseCombo"] }, | |||||
}); | |||||
}); |
@@ -74,6 +74,7 @@ export interface InputDataGridProps<T, V, E> { | |||||
validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | ||||
needAdd?: boolean; | needAdd?: boolean; | ||||
showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
addRowDefaultValue?: Partial<V>; | |||||
} | } | ||||
export interface SelectionInputDataGridProps<T, V, E> { | export interface SelectionInputDataGridProps<T, V, E> { | ||||
@@ -85,6 +86,7 @@ export interface SelectionInputDataGridProps<T, V, E> { | |||||
validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | ||||
needAdd?: boolean; | needAdd?: boolean; | ||||
showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
addRowDefaultValue?: Partial<V>; | |||||
} | } | ||||
export type Props<T, V, E> = | export type Props<T, V, E> = | ||||
@@ -112,6 +114,7 @@ function InputDataGrid<T, V, E>({ | |||||
validateRow, | validateRow, | ||||
needAdd, | needAdd, | ||||
showRemoveBtn = true, | showRemoveBtn = true, | ||||
addRowDefaultValue = {}, | |||||
}: Props<T, V, E>) { | }: Props<T, V, E>) { | ||||
const { | const { | ||||
t, | t, | ||||
@@ -126,13 +129,13 @@ function InputDataGrid<T, V, E>({ | |||||
[], | [], | ||||
); | ); | ||||
const list: TableRow<V, E>[] = getValues(formKey); | const list: TableRow<V, E>[] = getValues(formKey); | ||||
console.log(list) | |||||
// console.log(list) | |||||
const [rows, setRows] = useState<TableRow<V, E>[]>(() => { | const [rows, setRows] = useState<TableRow<V, E>[]>(() => { | ||||
const list: TableRow<V, E>[] = getValues(formKey); | const list: TableRow<V, E>[] = getValues(formKey); | ||||
console.log(list) | |||||
// console.log(list) | |||||
return list && list.length > 0 ? list : []; | return list && list.length > 0 ? list : []; | ||||
}); | }); | ||||
console.log(rows) | |||||
// console.log(rows) | |||||
// const originalRows = list && list.length > 0 ? list : []; | // const originalRows = list && list.length > 0 ? list : []; | ||||
const originalRows = useMemo(() => ( | const originalRows = useMemo(() => ( | ||||
list && list.length > 0 ? list : [] | list && list.length > 0 ? list : [] | ||||
@@ -145,7 +148,7 @@ function InputDataGrid<T, V, E>({ | |||||
const rowModel: GridRowSelectionModel = getValues( | const rowModel: GridRowSelectionModel = getValues( | ||||
`${formKey}_active`, | `${formKey}_active`, | ||||
) as GridRowSelectionModel; | ) as GridRowSelectionModel; | ||||
console.log(rowModel); | |||||
// console.log(rowModel); | |||||
return rowModel; | return rowModel; | ||||
}); | }); | ||||
@@ -162,7 +165,7 @@ function InputDataGrid<T, V, E>({ | |||||
(updateError: ProcessRowUpdateError<T, E>) => { | (updateError: ProcessRowUpdateError<T, E>) => { | ||||
const errors = updateError.errors; | const errors = updateError.errors; | ||||
const row = updateError.row; | const row = updateError.row; | ||||
console.log(errors); | |||||
// console.log(errors); | |||||
apiRef.current.updateRows([{ ...row, _error: errors }]); | apiRef.current.updateRows([{ ...row, _error: errors }]); | ||||
}, | }, | ||||
[apiRef], | [apiRef], | ||||
@@ -176,7 +179,7 @@ function InputDataGrid<T, V, E>({ | |||||
///////////////// | ///////////////// | ||||
// validation here | // validation here | ||||
const errors = validateRow(newRow); | const errors = validateRow(newRow); | ||||
console.log(newRow); | |||||
// console.log(newRow); | |||||
if (errors) { | if (errors) { | ||||
throw new ProcessRowUpdateError( | throw new ProcessRowUpdateError( | ||||
originalRow, | originalRow, | ||||
@@ -189,7 +192,6 @@ function InputDataGrid<T, V, E>({ | |||||
const rowToSave = { | const rowToSave = { | ||||
...updatedRow, | ...updatedRow, | ||||
} as TableRow<V, E>; /// test | } as TableRow<V, E>; /// test | ||||
console.log(rowToSave); | |||||
setRows((rw) => | setRows((rw) => | ||||
rw.map((r) => (getRowId(r) === getRowId(originalRow) ? rowToSave : r)), | rw.map((r) => (getRowId(r) === getRowId(originalRow) ? rowToSave : r)), | ||||
); | ); | ||||
@@ -198,8 +200,8 @@ function InputDataGrid<T, V, E>({ | |||||
[validateRow, getRowId], | [validateRow, getRowId], | ||||
); | ); | ||||
const addRow = useCallback(() => { | |||||
const newEntry = { id: Date.now(), _isNew: true } as TableRow<V, E>; | |||||
const addRow = useCallback((addRowDefaultValue: Partial<V>) => { | |||||
const newEntry = { ...addRowDefaultValue, id: Date.now(), _isNew: true } as TableRow<V, E>; | |||||
setRows((prev) => [...prev, newEntry]); | setRows((prev) => [...prev, newEntry]); | ||||
setRowModesModel((model) => ({ | setRowModesModel((model) => ({ | ||||
...model, | ...model, | ||||
@@ -290,7 +292,6 @@ function InputDataGrid<T, V, E>({ | |||||
// sync useForm | // sync useForm | ||||
useEffect(() => { | useEffect(() => { | ||||
// console.log(formKey) | // console.log(formKey) | ||||
// console.log(rows) | |||||
setValue(formKey, rows); | setValue(formKey, rows); | ||||
}, [formKey, rows, setValue]); | }, [formKey, rows, setValue]); | ||||
@@ -300,7 +301,7 @@ function InputDataGrid<T, V, E>({ | |||||
disableRipple | disableRipple | ||||
variant="outlined" | variant="outlined" | ||||
startIcon={<Add />} | startIcon={<Add />} | ||||
onClick={addRow} | |||||
onClick={() => addRow(addRowDefaultValue)} | |||||
size="small" | size="small" | ||||
> | > | ||||
新增 | 新增 | ||||
@@ -1,6 +1,6 @@ | |||||
"use client"; | "use client"; | ||||
import { PurchaseQcResult, PutawayInput, PutawayLine } from "@/app/api/po/actions"; | |||||
import { PurchaseQcResult, PutAwayInput, PutAwayLine } from "@/app/api/po/actions"; | |||||
import { | import { | ||||
Autocomplete, | Autocomplete, | ||||
Box, | Box, | ||||
@@ -61,11 +61,11 @@ interface Props { | |||||
} | } | ||||
type EntryError = | type EntryError = | ||||
| { | | { | ||||
[field in keyof PutawayLine]?: string; | |||||
[field in keyof PutAwayLine]?: string; | |||||
} | } | ||||
| undefined; | | undefined; | ||||
type PutawayRow = TableRow<Partial<PutawayLine>, EntryError>; | |||||
type PutawayRow = TableRow<Partial<PutAwayLine>, EntryError>; | |||||
const style = { | const style = { | ||||
position: "absolute", | position: "absolute", | ||||
@@ -93,7 +93,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
resetField, | resetField, | ||||
setError, | setError, | ||||
clearErrors, | clearErrors, | ||||
} = useFormContext<PutawayInput>(); | |||||
} = useFormContext<PutAwayInput>(); | |||||
console.log(itemDetail); | console.log(itemDetail); | ||||
// const [recordQty, setRecordQty] = useState(0); | // const [recordQty, setRecordQty] = useState(0); | ||||
const [warehouseId, setWarehouseId] = useState(itemDetail.defaultWarehouseId); | const [warehouseId, setWarehouseId] = useState(itemDetail.defaultWarehouseId); | ||||
@@ -143,7 +143,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
}, | }, | ||||
[], | [], | ||||
); | ); | ||||
console.log(watch("putawayLine")) | |||||
console.log(watch("putAwayLines")) | |||||
// const accQty = watch("acceptedQty"); | // const accQty = watch("acceptedQty"); | ||||
// const validateForm = useCallback(() => { | // const validateForm = useCallback(() => { | ||||
// console.log(accQty); | // console.log(accQty); | ||||
@@ -492,10 +492,10 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
style={{ display: "flex", justifyContent: "center" }} | style={{ display: "flex", justifyContent: "center" }} | ||||
> | > | ||||
{/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | ||||
<InputDataGrid<PutawayInput, PutawayLine, EntryError> | |||||
<InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | |||||
apiRef={apiRef} | apiRef={apiRef} | ||||
checkboxSelection={false} | checkboxSelection={false} | ||||
_formKey={"putawayLine"} | |||||
_formKey={"putAwayLines"} | |||||
columns={columns} | columns={columns} | ||||
validateRow={validation} | validateRow={validation} | ||||
needAdd={true} | needAdd={true} | ||||
@@ -1,4 +1,4 @@ | |||||
import { PutawayLine } from "@/app/api/po/actions" | |||||
import { PutAwayLine } from "@/app/api/po/actions" | |||||
export interface QcData { | export interface QcData { | ||||
id: number, | id: number, | ||||
@@ -67,7 +67,7 @@ export const dummyEscalationHistory: EscalationData[] = [ | |||||
}, | }, | ||||
] | ] | ||||
export const dummyPutawayLine: PutawayLine[] = [ | |||||
export const dummyPutawayLine: PutAwayLine[] = [ | |||||
{ | { | ||||
id: 1, | id: 1, | ||||
qty: 100, | qty: 100, | ||||
@@ -80,7 +80,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
const formProps = useForm<any>({ | const formProps = useForm<any>({ | ||||
defaultValues: { | defaultValues: { | ||||
...itemDetail, | ...itemDetail, | ||||
putawayLine: dummyPutawayLine, | |||||
putAwayLine: dummyPutawayLine, | |||||
// receiptDate: itemDetail.receiptDate || dayjs().add(-1, "month").format(INPUT_DATE_FORMAT), | // receiptDate: itemDetail.receiptDate || dayjs().add(-1, "month").format(INPUT_DATE_FORMAT), | ||||
// warehouseId: itemDetail.defaultWarehouseId || 0 | // warehouseId: itemDetail.defaultWarehouseId || 0 | ||||
}, | }, | ||||
@@ -79,6 +79,7 @@ import { DatePicker, LocalizationProvider, zhHK } from "@mui/x-date-pickers"; | |||||
import { debounce } from "lodash"; | import { debounce } from "lodash"; | ||||
import LoadingComponent from "../General/LoadingComponent"; | import LoadingComponent from "../General/LoadingComponent"; | ||||
import { getMailTemplateForStockInLine } from "@/app/api/mailTemplate/actions"; | import { getMailTemplateForStockInLine } from "@/app/api/mailTemplate/actions"; | ||||
import { PrinterCombo } from "@/app/api/settings/printer"; | |||||
//import { useRouter } from "next/navigation"; | //import { useRouter } from "next/navigation"; | ||||
@@ -86,6 +87,7 @@ type Props = { | |||||
po: PoResult; | po: PoResult; | ||||
qc: QcItemWithChecks[]; | qc: QcItemWithChecks[]; | ||||
warehouse: WarehouseResult[]; | warehouse: WarehouseResult[]; | ||||
printerCombo: PrinterCombo[]; | |||||
}; | }; | ||||
type EntryError = | type EntryError = | ||||
@@ -188,7 +190,7 @@ interface PolInputResult { | |||||
dnQty: number, | dnQty: number, | ||||
} | } | ||||
const PoDetail: React.FC<Props> = ({ po, qc, warehouse }) => { | |||||
const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo }) => { | |||||
const cameras = useContext(CameraContext); | const cameras = useContext(CameraContext); | ||||
// console.log(cameras); | // console.log(cameras); | ||||
const { t } = useTranslation("purchaseOrder"); | const { t } = useTranslation("purchaseOrder"); | ||||
@@ -858,6 +860,7 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse }) => { | |||||
warehouse={warehouse} | warehouse={warehouse} | ||||
fetchPoDetail={fetchPoDetail} | fetchPoDetail={fetchPoDetail} | ||||
handleMailTemplateForStockInLine={handleMailTemplateForStockInLine} | handleMailTemplateForStockInLine={handleMailTemplateForStockInLine} | ||||
printerCombo={printerCombo} | |||||
/> | /> | ||||
</Box> | </Box> | ||||
</TableCell> | </TableCell> | ||||
@@ -11,6 +11,7 @@ import { QcItemWithChecks } from "@/app/api/qc"; | |||||
import { fetchWarehouseList } from "@/app/api/warehouse"; | import { fetchWarehouseList } from "@/app/api/warehouse"; | ||||
import { fetchQcItemCheck } from "@/app/api/qc/actions"; | import { fetchQcItemCheck } from "@/app/api/qc/actions"; | ||||
import { fetchEscalationCombo } from "@/app/api/user"; | import { fetchEscalationCombo } from "@/app/api/user"; | ||||
import { fetchPrinterCombo } from "@/app/api/settings/printer"; | |||||
interface SubComponents { | interface SubComponents { | ||||
Loading: typeof PoDetailLoading; | Loading: typeof PoDetailLoading; | ||||
@@ -25,16 +26,18 @@ const PoDetailWrapper: React.FC<Props> & SubComponents = async ({ id }) => { | |||||
poWithStockInLine, | poWithStockInLine, | ||||
warehouse, | warehouse, | ||||
qc, | qc, | ||||
escalationCombo | |||||
escalationCombo, | |||||
printerCombo, | |||||
] = await Promise.all([ | ] = await Promise.all([ | ||||
fetchPoWithStockInLines(id), | fetchPoWithStockInLines(id), | ||||
fetchWarehouseList(), | fetchWarehouseList(), | ||||
fetchQcItemCheck(), | fetchQcItemCheck(), | ||||
fetchEscalationCombo(), | fetchEscalationCombo(), | ||||
fetchPrinterCombo() | |||||
]); | ]); | ||||
// const poWithStockInLine = await fetchPoWithStockInLines(id) | // const poWithStockInLine = await fetchPoWithStockInLines(id) | ||||
return <PoDetail po={poWithStockInLine} qc={qc} warehouse={warehouse} />; | |||||
return <PoDetail po={poWithStockInLine} qc={qc} warehouse={warehouse} printerCombo={printerCombo} />; | |||||
}; | }; | ||||
PoDetailWrapper.Loading = PoDetailLoading; | PoDetailWrapper.Loading = PoDetailLoading; | ||||
@@ -62,6 +62,7 @@ import { useSession } from "next-auth/react"; | |||||
// import { SessionWithTokens } from "src/config/authConfig"; | // import { SessionWithTokens } from "src/config/authConfig"; | ||||
import PoQcStockInModalVer2 from "./QcStockInModalVer2"; | import PoQcStockInModalVer2 from "./QcStockInModalVer2"; | ||||
import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | ||||
import { PrinterCombo } from "@/app/api/settings/printer"; | |||||
import { EscalationResult } from "@/app/api/escalation"; | import { EscalationResult } from "@/app/api/escalation"; | ||||
import { fetchEscalationLogsByStockInLines } from "@/app/api/escalation/actions"; | import { fetchEscalationLogsByStockInLines } from "@/app/api/escalation/actions"; | ||||
import { SessionWithTokens } from "@/config/authConfig"; | import { SessionWithTokens } from "@/config/authConfig"; | ||||
@@ -80,6 +81,7 @@ interface Props { | |||||
warehouse: WarehouseResult[]; | warehouse: WarehouseResult[]; | ||||
fetchPoDetail: (poId: string) => void; | fetchPoDetail: (poId: string) => void; | ||||
handleMailTemplateForStockInLine: (stockInLineId: number) => void; | handleMailTemplateForStockInLine: (stockInLineId: number) => void; | ||||
printerCombo: PrinterCombo[]; | |||||
} | } | ||||
export type StockInLineEntryError = { | export type StockInLineEntryError = { | ||||
@@ -119,7 +121,8 @@ function PoInputGrid({ | |||||
stockInLine, | stockInLine, | ||||
warehouse, | warehouse, | ||||
fetchPoDetail, | fetchPoDetail, | ||||
handleMailTemplateForStockInLine | |||||
handleMailTemplateForStockInLine, | |||||
printerCombo | |||||
}: Props) { | }: Props) { | ||||
console.log(itemDetail); | console.log(itemDetail); | ||||
const { t } = useTranslation("purchaseOrder"); | const { t } = useTranslation("purchaseOrder"); | ||||
@@ -301,7 +304,7 @@ const closeNewModal = useCallback(() => { | |||||
const handleNewQC = useCallback( | const handleNewQC = useCallback( | ||||
(id: GridRowId, params: any) => async() => { | (id: GridRowId, params: any) => async() => { | ||||
// console.log(id) | // console.log(id) | ||||
// console.log(params) | |||||
console.log("params", params.row) | |||||
// setBtnIsLoading(true); | // setBtnIsLoading(true); | ||||
setRowModesModel((prev) => ({ | setRowModesModel((prev) => ({ | ||||
...prev, | ...prev, | ||||
@@ -939,6 +942,7 @@ const closeNewModal = useCallback(() => { | |||||
onClose={closeNewModal} | onClose={closeNewModal} | ||||
itemDetail={modalInfo} | itemDetail={modalInfo} | ||||
handleMailTemplateForStockInLine={handleMailTemplateForStockInLine} | handleMailTemplateForStockInLine={handleMailTemplateForStockInLine} | ||||
printerCombo={printerCombo} | |||||
/> | /> | ||||
</> | </> | ||||
) | ) | ||||
@@ -28,7 +28,7 @@ import { useSearchParams } from "next/navigation"; | |||||
import { StockInLineRow } from "./PoInputGrid"; | import { StockInLineRow } from "./PoInputGrid"; | ||||
import EscalationForm from "./EscalationForm"; | import EscalationForm from "./EscalationForm"; | ||||
import StockInForm from "./StockInForm"; | import StockInForm from "./StockInForm"; | ||||
import PutawayForm from "./PutawayForm"; | |||||
import PutAwayForm from "./PutAwayForm"; | |||||
import { | import { | ||||
INPUT_DATE_FORMAT, | INPUT_DATE_FORMAT, | ||||
stockInLineStatusMap, | stockInLineStatusMap, | ||||
@@ -437,7 +437,7 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||||
/> | /> | ||||
)} | )} | ||||
{itemDetail !== undefined && type === "putaway" && ( | {itemDetail !== undefined && type === "putaway" && ( | ||||
<PutawayForm | |||||
<PutAwayForm | |||||
itemDetail={itemDetail} | itemDetail={itemDetail} | ||||
warehouse={warehouse!} | warehouse={warehouse!} | ||||
disabled={!renderSubmitButton} | disabled={!renderSubmitButton} | ||||
@@ -1,6 +1,6 @@ | |||||
"use client"; | "use client"; | ||||
import { PurchaseQcResult, PutawayInput, PutawayLine } from "@/app/api/po/actions"; | |||||
import { PurchaseQcResult, PutAwayInput, PutAwayLine } from "@/app/api/po/actions"; | |||||
import { | import { | ||||
Autocomplete, | Autocomplete, | ||||
Box, | Box, | ||||
@@ -50,7 +50,8 @@ import { QrCodeInfo } from "@/app/api/qrcode"; | |||||
import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | ||||
import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
import arraySupport from "dayjs/plugin/arraySupport"; | import arraySupport from "dayjs/plugin/arraySupport"; | ||||
import { dummyPutawayLine } from "./dummyQcTemplate"; | |||||
import { dummyPutAwayLine } from "./dummyQcTemplate"; | |||||
import { PrinterCombo } from "@/app/api/settings/printer"; | |||||
dayjs.extend(arraySupport); | dayjs.extend(arraySupport); | ||||
interface Props { | interface Props { | ||||
@@ -58,14 +59,15 @@ interface Props { | |||||
warehouse: WarehouseResult[]; | warehouse: WarehouseResult[]; | ||||
disabled: boolean; | disabled: boolean; | ||||
// qc: QcItemWithChecks[]; | // qc: QcItemWithChecks[]; | ||||
printerCombo: PrinterCombo[]; | |||||
} | } | ||||
type EntryError = | type EntryError = | ||||
| { | | { | ||||
[field in keyof PutawayLine]?: string; | |||||
[field in keyof PutAwayLine]?: string; | |||||
} | } | ||||
| undefined; | | undefined; | ||||
type PutawayRow = TableRow<Partial<PutawayLine>, EntryError>; | |||||
type PutAwayRow = TableRow<Partial<PutAwayLine>, EntryError>; | |||||
const style = { | const style = { | ||||
position: "absolute", | position: "absolute", | ||||
@@ -79,7 +81,7 @@ const style = { | |||||
width: "auto", | width: "auto", | ||||
}; | }; | ||||
const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, printerCombo }) => { | |||||
const { t } = useTranslation("purchaseOrder"); | const { t } = useTranslation("purchaseOrder"); | ||||
const apiRef = useGridApiRef(); | const apiRef = useGridApiRef(); | ||||
const { | const { | ||||
@@ -93,7 +95,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
resetField, | resetField, | ||||
setError, | setError, | ||||
clearErrors, | clearErrors, | ||||
} = useFormContext<PutawayInput>(); | |||||
} = useFormContext<PutAwayInput>(); | |||||
console.log(itemDetail); | console.log(itemDetail); | ||||
// const [recordQty, setRecordQty] = useState(0); | // const [recordQty, setRecordQty] = useState(0); | ||||
const [warehouseId, setWarehouseId] = useState(itemDetail.defaultWarehouseId); | const [warehouseId, setWarehouseId] = useState(itemDetail.defaultWarehouseId); | ||||
@@ -143,7 +145,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
}, | }, | ||||
[], | [], | ||||
); | ); | ||||
console.log(watch("putawayLine")) | |||||
console.log(watch("putAwayLines")) | |||||
// const accQty = watch("acceptedQty"); | // const accQty = watch("acceptedQty"); | ||||
// const validateForm = useCallback(() => { | // const validateForm = useCallback(() => { | ||||
// console.log(accQty); | // console.log(accQty); | ||||
@@ -274,6 +276,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
field: "qty", | field: "qty", | ||||
headerName: t("qty"), | headerName: t("qty"), | ||||
flex: 1, | flex: 1, | ||||
editable: true, | |||||
// renderCell(params) { | // renderCell(params) { | ||||
// return <>100</> | // return <>100</> | ||||
// }, | // }, | ||||
@@ -282,6 +285,33 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
field: "warehouse", | field: "warehouse", | ||||
headerName: t("warehouse"), | headerName: t("warehouse"), | ||||
flex: 1, | flex: 1, | ||||
editable: true, | |||||
renderEditCell: (params) => { | |||||
const index = params.api.getRowIndexRelativeToVisibleRows(params.row.id) | |||||
// console.log(index) | |||||
// console.log(watch(`putAwayLines.${index}.warehouse`)) | |||||
return <Autocomplete | |||||
fullWidth | |||||
disableClearable | |||||
options={options} | |||||
// defaultValue={options.find((o) => o.value === itemDetail.defaultWarehouseId)} | |||||
// value={options.find((o) => o.value === watch(`putAwayLines.${index}.warehouseId`))} | |||||
defaultValue={options.find((o) => o.value === watch(`putAwayLines.${index}.warehouseId`))} | |||||
onChange={(event, value) => { | |||||
params.api.setEditCellValue({ id: params.id, field: params.field, value: options.find((o) => o.value === value.value)?.label ?? ""}) | |||||
params.api.setEditCellValue({ id: params.id, field: "warehouseId", value: value.value}) | |||||
// setValue(`putAwayLines.${index}.warehouseId`, value.value) | |||||
// setValue(`putAwayLines.${index}.warehouse`, options.find((o) => o.value === value.value)?.label ?? "") | |||||
}} | |||||
renderInput={(params) => ( | |||||
<TextField | |||||
{...params} | |||||
variant="outlined" | |||||
// label={t("Warehouse")} | |||||
/> | |||||
)} | |||||
/> | |||||
} | |||||
// renderCell(params) { | // renderCell(params) { | ||||
// return <>{filteredWarehouse[0].name}</> | // return <>{filteredWarehouse[0].name}</> | ||||
// }, | // }, | ||||
@@ -290,6 +320,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
field: "printQty", | field: "printQty", | ||||
headerName: t("printQty"), | headerName: t("printQty"), | ||||
flex: 1, | flex: 1, | ||||
editable: true, | |||||
// renderCell(params) { | // renderCell(params) { | ||||
// return <>100</> | // return <>100</> | ||||
// }, | // }, | ||||
@@ -297,7 +328,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
], []) | ], []) | ||||
const validation = useCallback( | const validation = useCallback( | ||||
(newRow: GridRowModel<PutawayRow>): EntryError => { | |||||
(newRow: GridRowModel<PutAwayRow>): EntryError => { | |||||
const error: EntryError = {}; | const error: EntryError = {}; | ||||
const { qty, warehouseId, printQty } = newRow; | const { qty, warehouseId, printQty } = newRow; | ||||
@@ -306,6 +337,13 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
[], | [], | ||||
); | ); | ||||
const addRowDefaultValue = useMemo(() => { | |||||
const defaultMaxQty = watch("acceptedQty") - watch("putAwayLines").reduce((acc, cur) => acc + cur.qty, 0) | |||||
const defaultWarehouseId = itemDetail.defaultWarehouseId ?? 1 | |||||
const defaultWarehouse = options.find((o) => o.value === defaultWarehouseId)?.label | |||||
return {qty: defaultMaxQty, warehouseId: defaultWarehouseId, warehouse: defaultWarehouse, printQty: 1 } as Partial<PutAwayLine> | |||||
}, []) | |||||
return ( | return ( | ||||
<Grid container justifyContent="flex-start" alignItems="flex-start"> | <Grid container justifyContent="flex-start" alignItems="flex-start"> | ||||
<Grid item xs={12}> | <Grid item xs={12}> | ||||
@@ -493,14 +531,15 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
style={{ display: "flex", justifyContent: "center" }} | style={{ display: "flex", justifyContent: "center" }} | ||||
> | > | ||||
{/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | ||||
<InputDataGrid<PutawayInput, PutawayLine, EntryError> | |||||
<InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | |||||
apiRef={apiRef} | apiRef={apiRef} | ||||
checkboxSelection={false} | checkboxSelection={false} | ||||
_formKey={"putawayLine"} | |||||
_formKey={"putAwayLines"} | |||||
columns={columns} | columns={columns} | ||||
validateRow={validation} | validateRow={validation} | ||||
needAdd={true} | needAdd={true} | ||||
showRemoveBtn={false} | showRemoveBtn={false} | ||||
addRowDefaultValue={addRowDefaultValue} | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
</Grid> | </Grid> | ||||
@@ -525,4 +564,4 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
</Grid> | </Grid> | ||||
); | ); | ||||
}; | }; | ||||
export default PutawayForm; | |||||
export default PutAwayForm; |
@@ -1,14 +1,16 @@ | |||||
"use client"; | "use client"; | ||||
import { StockInLine } from "@/app/api/po"; | import { StockInLine } from "@/app/api/po"; | ||||
import { ModalFormInput, PurchaseQcResult, StockInLineEntry, updateStockInLine, PurchaseQCInput } from "@/app/api/po/actions"; | |||||
import { ModalFormInput, PurchaseQcResult, StockInLineEntry, updateStockInLine, PurchaseQCInput, printQrCodeForSil, PrintQrCodeForSilRequest } from "@/app/api/po/actions"; | |||||
import { QcItemWithChecks, QcData } from "@/app/api/qc"; | import { QcItemWithChecks, QcData } from "@/app/api/qc"; | ||||
import { | import { | ||||
Autocomplete, | |||||
Box, | Box, | ||||
Button, | Button, | ||||
Grid, | Grid, | ||||
Modal, | Modal, | ||||
ModalProps, | ModalProps, | ||||
Stack, | Stack, | ||||
TextField, | |||||
Typography, | Typography, | ||||
} from "@mui/material"; | } from "@mui/material"; | ||||
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react"; | import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react"; | ||||
@@ -20,10 +22,16 @@ import StockInFormVer2 from "./StockInFormVer2"; | |||||
import PutawayForm from "./PutawayForm"; | import PutawayForm from "./PutawayForm"; | ||||
import QcComponent from "./QcComponent"; | import QcComponent from "./QcComponent"; | ||||
import { dummyPutawayLine, dummyQCData } from "./dummyQcTemplate"; | import { dummyPutawayLine, dummyQCData } from "./dummyQcTemplate"; | ||||
import QcFormVer2 from "./QcFormVer2"; | |||||
import PutAwayForm from "./PutAwayForm"; | |||||
import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate"; | |||||
import { useGridApiRef } from "@mui/x-data-grid"; | import { useGridApiRef } from "@mui/x-data-grid"; | ||||
import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | ||||
import { arrayToDateString, arrayToInputDateString, dayjsToInputDateString, INPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; | |||||
import { INPUT_DATE_FORMAT, arrayToDateString, arrayToInputDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; | |||||
import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
import { fetchPoQrcode } from "@/app/api/pdf/actions"; | |||||
import { downloadFile } from "@/app/utils/commonUtil"; | |||||
import { PrinterCombo } from "@/app/api/settings/printer"; | |||||
import { watch } from "fs"; | import { watch } from "fs"; | ||||
import { EscalationResult } from "@/app/api/escalation"; | import { EscalationResult } from "@/app/api/escalation"; | ||||
import { SessionWithTokens } from "@/config/authConfig"; | import { SessionWithTokens } from "@/config/authConfig"; | ||||
@@ -60,6 +68,7 @@ interface CommonProps extends Omit<ModalProps, "children"> { | |||||
warehouse?: any[]; | warehouse?: any[]; | ||||
// type: "qc" | "stockIn" | "escalation" | "putaway" | "reject"; | // type: "qc" | "stockIn" | "escalation" | "putaway" | "reject"; | ||||
handleMailTemplateForStockInLine: (stockInLineId: number) => void; | handleMailTemplateForStockInLine: (stockInLineId: number) => void; | ||||
printerCombo: PrinterCombo[]; | |||||
onClose: () => void; | onClose: () => void; | ||||
} | } | ||||
interface Props extends CommonProps { | interface Props extends CommonProps { | ||||
@@ -78,19 +87,25 @@ const PoQcStockInModalVer2: React.FC<Props> = ({ | |||||
qc, | qc, | ||||
warehouse, | warehouse, | ||||
handleMailTemplateForStockInLine, | handleMailTemplateForStockInLine, | ||||
printerCombo | |||||
}) => { | }) => { | ||||
const { | const { | ||||
t, | t, | ||||
i18n: { language }, | i18n: { language }, | ||||
} = useTranslation("purchaseOrder"); | } = useTranslation("purchaseOrder"); | ||||
// Select Printer | |||||
const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]) | |||||
const defaultNewValue = useMemo(() => { | const defaultNewValue = useMemo(() => { | ||||
return ( | return ( | ||||
{ | { | ||||
...itemDetail, | ...itemDetail, | ||||
status: itemDetail.status ?? "pending", | status: itemDetail.status ?? "pending", | ||||
dnDate: arrayToInputDateString(itemDetail.dnDate)?? dayjsToInputDateString(dayjs()), | dnDate: arrayToInputDateString(itemDetail.dnDate)?? dayjsToInputDateString(dayjs()), | ||||
putawayLine: dummyPutawayLine, | |||||
// putAwayLines: dummyPutAwayLine, | |||||
// putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [], | |||||
putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1})) ?? [], | |||||
qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData], | qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData], | ||||
escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [], | escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [], | ||||
receiptDate: itemDetail.receiptDate ?? dayjs().add(0, "month").format(INPUT_DATE_FORMAT), | receiptDate: itemDetail.receiptDate ?? dayjs().add(0, "month").format(INPUT_DATE_FORMAT), | ||||
@@ -123,6 +138,17 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
} else return false; | } else return false; | ||||
}; | }; | ||||
useEffect(() => { | |||||
formProps.reset({ | |||||
...itemDetail, | |||||
dnDate: dayjsToInputDateString(dayjs()), | |||||
// putAwayLines: dummyPutAwayLine, | |||||
putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1})) ?? [], | |||||
}) | |||||
setOpenPutaway(isPutaway); | |||||
}, [open, itemDetail]) | |||||
const [viewOnly, setViewOnly] = useState(false); | const [viewOnly, setViewOnly] = useState(false); | ||||
useEffect(() => { | useEffect(() => { | ||||
if (itemDetail && itemDetail.status) { | if (itemDetail && itemDetail.status) { | ||||
@@ -248,7 +274,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
if (validationErrors.length > 0) { | if (validationErrors.length > 0) { | ||||
console.error("QC Validation failed:", validationErrors); | console.error("QC Validation failed:", validationErrors); | ||||
alert(`未完成品檢: ${validationErrors}`); | |||||
alert(`未完成品檢: ${validationErrors}`); | |||||
return; | return; | ||||
} | } | ||||
@@ -275,7 +301,6 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
// const qcData = data; | // const qcData = data; | ||||
console.log("QC Data for submission:", qcData); | console.log("QC Data for submission:", qcData); | ||||
if (data.qcDecision == 3) { // Escalate | if (data.qcDecision == 3) { // Escalate | ||||
const escalationLog = { | const escalationLog = { | ||||
type : "qc", | type : "qc", | ||||
@@ -286,12 +311,10 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
} | } | ||||
console.log("ESCALATION RESULT", escalationLog); | console.log("ESCALATION RESULT", escalationLog); | ||||
await postStockInLine({...qcData, escalationLog}); | await postStockInLine({...qcData, escalationLog}); | ||||
} else { | } else { | ||||
await postStockInLine(qcData); | await postStockInLine(qcData); | ||||
} | } | ||||
if (qcData.qcAccept) { | if (qcData.qcAccept) { | ||||
// submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?", | // submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?", | ||||
// confirmButtonText: t("confirm putaway"), html: ""}); | // confirmButtonText: t("confirm putaway"), html: ""}); | ||||
@@ -312,7 +335,6 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
console.log("Submitting", submitData); | console.log("Submitting", submitData); | ||||
const res = await updateStockInLine(submitData); | const res = await updateStockInLine(submitData); | ||||
console.log("Result ", res); | |||||
return res; | return res; | ||||
},[itemDetail]) | },[itemDetail]) | ||||
@@ -357,13 +379,16 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
expiryDate : arrayToInputDateString(data.expiryDate), | expiryDate : arrayToInputDateString(data.expiryDate), | ||||
receiptDate : arrayToInputDateString(data.receiptDate), | receiptDate : arrayToInputDateString(data.receiptDate), | ||||
// for putaway data | |||||
inventoryLotLines: data.putAwayLines?.filter((line) => Boolean(line._isNew)) | |||||
// Add other putaway specific fields | // Add other putaway specific fields | ||||
} as ModalFormInput; | } as ModalFormInput; | ||||
console.log("Putaway Data:", putawayData); | console.log("Putaway Data:", putawayData); | ||||
// Handle putaway submission logic here | // Handle putaway submission logic here | ||||
const res = await postStockInLine(putawayData); | const res = await postStockInLine(putawayData); | ||||
console.log("Result ", res); | |||||
console.log("result ", res); | |||||
// Close modal after successful putaway | // Close modal after successful putaway | ||||
closeHandler({}, "backdropClick"); | closeHandler({}, "backdropClick"); | ||||
@@ -371,11 +396,32 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
[closeHandler], | [closeHandler], | ||||
); | ); | ||||
// Print handler | // Print handler | ||||
const onPrint = useCallback(() => { | |||||
console.log("Print putaway documents"); | |||||
const [isPrinting, setIsPrinting] = useState(false) | |||||
const handlePrint = useCallback(async () => { | |||||
// console.log("Print putaway documents"); | |||||
console.log("%c data", "background: white; color: red", formProps.watch("putAwayLines")); | |||||
// Handle print logic here | // Handle print logic here | ||||
window.print(); | |||||
}, []); | |||||
// window.print(); | |||||
// const postData = { stockInLineIds: [itemDetail.id]}; | |||||
// const response = await fetchPoQrcode(postData); | |||||
// if (response) { | |||||
// downloadFile(new Uint8Array(response.blobValue), response.filename) | |||||
// } | |||||
try { | |||||
setIsPrinting(() => true) | |||||
const data: PrintQrCodeForSilRequest = { | |||||
stockInLineId: itemDetail.id, | |||||
printerId: selectedPrinter.id, | |||||
printQty: formProps.watch("putAwayLines")?.reduce((acc, cur) => acc + cur.printQty, 0) | |||||
} | |||||
const response = await printQrCodeForSil(data); | |||||
if (response) { | |||||
console.log(response) | |||||
} | |||||
} finally { | |||||
setIsPrinting(() => false) | |||||
} | |||||
}, [itemDetail.id]); | |||||
const acceptQty = formProps.watch("acceptedQty") | const acceptQty = formProps.watch("acceptedQty") | ||||
@@ -395,7 +441,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
console.log(qcItems) | console.log(qcItems) | ||||
// checkQcIsPassed(qcItems) | // checkQcIsPassed(qcItems) | ||||
}, [qcItems, checkQcIsPassed]) | }, [qcItems, checkQcIsPassed]) | ||||
return ( | return ( | ||||
<> | <> | ||||
<FormProvider {...formProps}> | <FormProvider {...formProps}> | ||||
@@ -410,26 +456,44 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
marginRight: 3, | marginRight: 3, | ||||
}} | }} | ||||
> | > | ||||
{openPutaway ? ( | |||||
{openPutaway ? ( | |||||
<Box | <Box | ||||
component="form" | component="form" | ||||
onSubmit={formProps.handleSubmit(onSubmitPutaway)} | onSubmit={formProps.handleSubmit(onSubmitPutaway)} | ||||
> | > | ||||
<PutawayForm | |||||
<PutAwayForm | |||||
printerCombo={printerCombo} | |||||
itemDetail={itemDetail} | itemDetail={itemDetail} | ||||
warehouse={warehouse!} | warehouse={warehouse!} | ||||
disabled={viewOnly} | disabled={viewOnly} | ||||
/> | /> | ||||
<Stack direction="row" justifyContent="flex-end" gap={1}> | <Stack direction="row" justifyContent="flex-end" gap={1}> | ||||
<Autocomplete | |||||
disableClearable | |||||
options={printerCombo} | |||||
defaultValue={selectedPrinter} | |||||
onChange={(event, value) => { | |||||
setSelectedPrinter(value) | |||||
}} | |||||
renderInput={(params) => ( | |||||
<TextField | |||||
{...params} | |||||
variant="outlined" | |||||
label={t("Printer")} | |||||
sx={{ width: 300}} | |||||
/> | |||||
)} | |||||
/> | |||||
<Button | <Button | ||||
id="printButton" | id="printButton" | ||||
type="button" | type="button" | ||||
variant="contained" | variant="contained" | ||||
color="primary" | color="primary" | ||||
sx={{ mt: 1 }} | sx={{ mt: 1 }} | ||||
onClick={onPrint} | |||||
onClick={handlePrint} | |||||
disabled={isPrinting} | |||||
> | > | ||||
{t("print")} | |||||
{isPrinting ? t("Printing") : t("print")} | |||||
</Button> | </Button> | ||||
<Button | <Button | ||||
id="putawaySubmit" | id="putawaySubmit" | ||||
@@ -20,7 +20,7 @@ import { | |||||
StockInLineEntry, | StockInLineEntry, | ||||
updateStockInLine, | updateStockInLine, | ||||
} from "@/app/api/po/actions"; | } from "@/app/api/po/actions"; | ||||
import PutawayForm from "./PutawayForm"; | |||||
import PutAwayForm from "./PutAwayForm"; | |||||
import { StockInLine } from "@/app/api/po"; | import { StockInLine } from "@/app/api/po"; | ||||
import { WarehouseResult } from "@/app/api/warehouse"; | import { WarehouseResult } from "@/app/api/warehouse"; | ||||
import { QrCodeInfo } from "@/app/api/qrcode"; | import { QrCodeInfo } from "@/app/api/qrcode"; | ||||
@@ -204,7 +204,7 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||||
</Typography> | </Typography> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
<PutawayForm | |||||
<PutAwayForm | |||||
itemDetail={itemDetail} | itemDetail={itemDetail} | ||||
warehouse={warehouse} | warehouse={warehouse} | ||||
disabled={false} | disabled={false} | ||||
@@ -1,4 +1,4 @@ | |||||
import { PutawayLine } from "@/app/api/po/actions" | |||||
import { PutAwayLine } from "@/app/api/po/actions" | |||||
import { QcData } from "@/app/api/qc" | import { QcData } from "@/app/api/qc" | ||||
// export interface QcData { | // export interface QcData { | ||||
@@ -73,12 +73,12 @@ export const dummyEscalationHistory: EscalationData[] = [ | |||||
}, | }, | ||||
] | ] | ||||
export const dummyPutawayLine: PutawayLine[] = [ | |||||
export const dummyPutAwayLine: PutAwayLine[] = [ | |||||
{ | { | ||||
id: 1, | id: 1, | ||||
qty: 100, | qty: 100, | ||||
warehouseId: 1, | warehouseId: 1, | ||||
warehouse: "W001 - 憶兆 3樓A倉", | warehouse: "W001 - 憶兆 3樓A倉", | ||||
printQty: 100 | |||||
printQty: 1 | |||||
} | } | ||||
] | ] |
@@ -133,5 +133,7 @@ | |||||
"bind": "綁定", | "bind": "綁定", | ||||
"Search": "搜尋", | "Search": "搜尋", | ||||
"Found": "已找到", | "Found": "已找到", | ||||
"escalation processing": "處理上報記錄" | |||||
"escalation processing": "處理上報記錄", | |||||
"Printer": "列印機", | |||||
"Printing": "列印中" | |||||
} | } |