| @@ -28,7 +28,7 @@ import { fetchPickOrderClient, autoAssignAndReleasePickOrder } from "@/app/api/p | |||||
| import Jobcreatitem from "./Jobcreatitem"; | import Jobcreatitem from "./Jobcreatitem"; | ||||
| import { useSession } from "next-auth/react"; | import { useSession } from "next-auth/react"; | ||||
| import { SessionWithTokens } from "@/config/authConfig"; | import { SessionWithTokens } from "@/config/authConfig"; | ||||
| import PickExecutionDetail from "./GoodPickExecutiondetail"; | |||||
| interface Props { | interface Props { | ||||
| pickOrders: PickOrderResult[]; | pickOrders: PickOrderResult[]; | ||||
| } | } | ||||
| @@ -276,27 +276,22 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => { | |||||
| p: 2, | p: 2, | ||||
| borderBottom: '1px solid #e0e0e0' | borderBottom: '1px solid #e0e0e0' | ||||
| }}> | }}> | ||||
| <Stack rowGap={2}> | |||||
| <Grid container> | |||||
| <Stack rowGap={2}> | |||||
| <Grid container alignItems="center"> | |||||
| <Grid item xs={8}> | <Grid item xs={8}> | ||||
| <Typography variant="h4" marginInlineEnd={2}> | <Typography variant="h4" marginInlineEnd={2}> | ||||
| {t("Finished Good Order")} | {t("Finished Good Order")} | ||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| {/* | |||||
| <Grid item xs={4} display="flex" justifyContent="end" alignItems="end"> | |||||
| <Button onClick={openCreateModal}> | |||||
| {t("create")} | |||||
| <Grid item xs={4} display="flex" justifyContent="end" alignItems="center"> | |||||
| <Button | |||||
| variant="contained" | |||||
| onClick={handleManualAssign} | |||||
| disabled={isAssigning} | |||||
| > | |||||
| {isAssigning ? t("Assigning pick order...") : t("Assign & Release")} | |||||
| </Button> | </Button> | ||||
| {isOpenCreateModal && | |||||
| <CreatePickOrderModal | |||||
| open={isOpenCreateModal} | |||||
| onClose={closeCreateModal} | |||||
| items={items} | |||||
| /> | |||||
| } | |||||
| </Grid> | </Grid> | ||||
| */} | |||||
| </Grid> | </Grid> | ||||
| </Stack> | </Stack> | ||||
| </Box> | </Box> | ||||
| @@ -306,26 +301,10 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => { | |||||
| borderBottom: '1px solid #e0e0e0' | borderBottom: '1px solid #e0e0e0' | ||||
| }}> | }}> | ||||
| <Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | <Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | ||||
| <Tab | |||||
| label={t("Pick Execution")} | |||||
| iconPosition="end" | |||||
| onClick={handleManualAssign} | |||||
| sx={{ | |||||
| cursor: 'pointer', | |||||
| '&:hover': { | |||||
| color: 'primary.main', | |||||
| } | |||||
| }} | |||||
| title={t("Click to assign a new pick order")} | |||||
| /> | |||||
| <Tab label={t("Pick Execution")} iconPosition="end" /> | |||||
| <Tab label={t("Pick Execution Detail")} iconPosition="end" /> | |||||
| </Tabs> | </Tabs> | ||||
| {isAssigning && ( | |||||
| <Box sx={{ p: 1, textAlign: 'center' }}> | |||||
| <Typography variant="caption" color="primary"> | |||||
| {t("Assigning pick order...")} | |||||
| </Typography> | |||||
| </Box> | |||||
| )} | |||||
| </Box> | </Box> | ||||
| {/* Content section - NO overflow: 'auto' here */} | {/* Content section - NO overflow: 'auto' here */} | ||||
| @@ -333,6 +312,7 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => { | |||||
| p: 2 | p: 2 | ||||
| }}> | }}> | ||||
| {tabIndex === 0 && <PickExecution filterArgs={filterArgs} />} | {tabIndex === 0 && <PickExecution filterArgs={filterArgs} />} | ||||
| {tabIndex === 1 && <PickExecutionDetail filterArgs={filterArgs} />} | |||||
| </Box> | </Box> | ||||
| </Box> | </Box> | ||||
| ); | ); | ||||
| @@ -934,17 +934,10 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| return ( | return ( | ||||
| <FormProvider {...formProps}> | <FormProvider {...formProps}> | ||||
| <Stack spacing={2}> | |||||
| {/* Search Box */} | {/* Search Box */} | ||||
| <Box> | <Box> | ||||
| {/* | |||||
| <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}> | |||||
| <Typography variant="h6" gutterBottom sx={{ mb: 0 }}> | |||||
| {t("FG Pick Orders")} | |||||
| </Typography> | |||||
| </Box> | |||||
| */} | |||||
| {fgPickOrdersLoading ? ( | {fgPickOrdersLoading ? ( | ||||
| <Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}> | <Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}> | ||||
| <CircularProgress /> | <CircularProgress /> | ||||
| @@ -972,9 +965,8 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| {/* | |||||
| {/* Combined Lot Table */} | |||||
| <Box> | <Box> | ||||
| <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}> | <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}> | ||||
| <Typography variant="h6" gutterBottom sx={{ mb: 0 }}> | <Typography variant="h6" gutterBottom sx={{ mb: 0 }}> | ||||
| @@ -992,12 +984,11 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| <TableCell>{t("Route")}</TableCell> | <TableCell>{t("Route")}</TableCell> | ||||
| <TableCell>{t("Item Name")}</TableCell> | <TableCell>{t("Item Name")}</TableCell> | ||||
| <TableCell>{t("Lot#")}</TableCell> | <TableCell>{t("Lot#")}</TableCell> | ||||
| <TableCell>{t("Target Date")}</TableCell> | |||||
| {/* <TableCell>{t("Lot Location")}</TableCell> */} | |||||
| <TableCell align="right">{t("Lot Required Pick Qty")}</TableCell> | <TableCell align="right">{t("Lot Required Pick Qty")}</TableCell> | ||||
| <TableCell align="right">{t("Original Available Qty")}</TableCell> | |||||
| <TableCell align="center">{t("Lot Actual Pick Qty")}</TableCell> | <TableCell align="center">{t("Lot Actual Pick Qty")}</TableCell> | ||||
| {/* <TableCell align="right">{t("Remaining Available Qty")}</TableCell> */} | |||||
| <TableCell align="center">{t("Action")}</TableCell> | <TableCell align="center">{t("Action")}</TableCell> | ||||
| </TableRow> | </TableRow> | ||||
| </TableHead> | </TableHead> | ||||
| @@ -1045,9 +1036,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| </Typography> | </Typography> | ||||
| </Box> | </Box> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell>{lot.pickOrderTargetDate}</TableCell> | |||||
| {/* <TableCell>{lot.location}</TableCell> */} | |||||
| <TableCell align="right">{calculateRemainingRequiredQty(lot).toLocaleString()}</TableCell> | |||||
| <TableCell align="right"> | <TableCell align="right"> | ||||
| {(() => { | {(() => { | ||||
| const inQty = lot.inQty || 0; | const inQty = lot.inQty || 0; | ||||
| @@ -1057,7 +1046,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| })()} | })()} | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | <TableCell align="center"> | ||||
| {/* ✅ QR Scan Button if not scanned, otherwise show TextField + Issue button */} | |||||
| {!lot.stockOutLineId ? ( | {!lot.stockOutLineId ? ( | ||||
| <Button | <Button | ||||
| variant="outlined" | variant="outlined" | ||||
| @@ -1106,12 +1095,13 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| max: calculateRemainingRequiredQty(lot), | max: calculateRemainingRequiredQty(lot), | ||||
| step: 0.01 | step: 0.01 | ||||
| }} | }} | ||||
| sx={{ | |||||
| width: '80px', | |||||
| sx={{ | |||||
| width: '60px', | |||||
| height: '28px', | |||||
| '& .MuiInputBase-input': { | '& .MuiInputBase-input': { | ||||
| fontSize: '0.75rem', | |||||
| fontSize: '0.7rem', | |||||
| textAlign: 'center', | textAlign: 'center', | ||||
| padding: '8px 4px' | |||||
| padding: '6px 8px' | |||||
| } | } | ||||
| }} | }} | ||||
| placeholder="0" | placeholder="0" | ||||
| @@ -1136,14 +1126,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| </Stack> | </Stack> | ||||
| )} | )} | ||||
| </TableCell> | </TableCell> | ||||
| {/* <TableCell align="right"> | |||||
| {(() => { | |||||
| const inQty = lot.inQty || 0; | |||||
| const outQty = lot.outQty || 0; | |||||
| const result = inQty - outQty; | |||||
| return result.toLocaleString(); | |||||
| })()} | |||||
| </TableCell> */} | |||||
| <TableCell align="center"> | <TableCell align="center"> | ||||
| <Stack direction="column" spacing={1} alignItems="center"> | <Stack direction="column" spacing={1} alignItems="center"> | ||||
| <Button | <Button | ||||
| @@ -1168,14 +1151,17 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| {t("Submit")} | {t("Submit")} | ||||
| </Button> | </Button> | ||||
| </Stack> | </Stack> | ||||
| </TableCell> | |||||
| </TableCell> | |||||
| </TableRow> | </TableRow> | ||||
| )) | )) | ||||
| )} | )} | ||||
| </TableBody> | </TableBody> | ||||
| </Table> | </Table> | ||||
| </TableContainer> | </TableContainer> | ||||
| */} | |||||
| {/* | |||||
| <TablePagination | <TablePagination | ||||
| component="div" | component="div" | ||||
| count={combinedLotData.length} | count={combinedLotData.length} | ||||
| @@ -1192,7 +1178,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| </Box> | </Box> | ||||
| </Stack> | </Stack> | ||||
| {/* ✅ QR Code Modal */} | |||||
| <QrCodeModal | <QrCodeModal | ||||
| open={qrModalOpen} | open={qrModalOpen} | ||||
| onClose={() => { | onClose={() => { | ||||
| @@ -1206,7 +1192,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| onQrCodeSubmit={handleQrCodeSubmitFromModal} | onQrCodeSubmit={handleQrCodeSubmitFromModal} | ||||
| /> | /> | ||||
| {/* ✅ Good Pick Execution Form Modal */} | |||||
| {pickExecutionFormOpen && selectedLotForExecutionForm && ( | {pickExecutionFormOpen && selectedLotForExecutionForm && ( | ||||
| <GoodPickExecutionForm | <GoodPickExecutionForm | ||||
| open={pickExecutionFormOpen} | open={pickExecutionFormOpen} | ||||
| @@ -1234,6 +1220,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => { | |||||
| pickOrderCreateDate={new Date()} | pickOrderCreateDate={new Date()} | ||||
| /> | /> | ||||
| )} | )} | ||||
| */} | |||||
| </FormProvider> | </FormProvider> | ||||
| ); | ); | ||||
| }; | }; | ||||
| @@ -250,34 +250,34 @@ const calculateRequiredQty = useCallback((lot: LotPickData) => { | |||||
| <Grid item xs={6}> | <Grid item xs={6}> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| label={t('requiredQty')} | |||||
| label={t('Required Qty')} | |||||
| value={requiredQty || 0} | value={requiredQty || 0} | ||||
| disabled | disabled | ||||
| variant="outlined" | variant="outlined" | ||||
| helperText={t('Still need to pick')} | |||||
| // helperText={t('Still need to pick')} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6}> | <Grid item xs={6}> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| label={t('remainingAvailableQty')} | |||||
| label={t('Remaining Available Qty')} | |||||
| value={remainingAvailableQty} | value={remainingAvailableQty} | ||||
| disabled | disabled | ||||
| variant="outlined" | variant="outlined" | ||||
| helperText={t('Available in warehouse')} | |||||
| // helperText={t('Available in warehouse')} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| label={t('actualPickQty')} | |||||
| label={t('Actual Pick Qty')} | |||||
| type="number" | type="number" | ||||
| value={formData.actualPickQty || 0} | value={formData.actualPickQty || 0} | ||||
| onChange={(e) => handleInputChange('actualPickQty', parseFloat(e.target.value) || 0)} | onChange={(e) => handleInputChange('actualPickQty', parseFloat(e.target.value) || 0)} | ||||
| error={!!errors.actualPickQty} | error={!!errors.actualPickQty} | ||||
| helperText={errors.actualPickQty || t('Enter the quantity actually picked')} | |||||
| // helperText={errors.actualPickQty || t('Enter the quantity actually picked')} | |||||
| variant="outlined" | variant="outlined" | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| @@ -285,12 +285,12 @@ const calculateRequiredQty = useCallback((lot: LotPickData) => { | |||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| label={t('missQty')} | |||||
| label={t('Missing item Qty')} | |||||
| type="number" | type="number" | ||||
| value={formData.missQty || 0} | value={formData.missQty || 0} | ||||
| onChange={(e) => handleInputChange('missQty', parseFloat(e.target.value) || 0)} | onChange={(e) => handleInputChange('missQty', parseFloat(e.target.value) || 0)} | ||||
| error={!!errors.missQty} | error={!!errors.missQty} | ||||
| helperText={errors.missQty || t('Enter missing quantity (required if no bad items)')} | |||||
| // helperText={errors.missQty || t('Enter missing quantity (required if no bad items)')} | |||||
| variant="outlined" | variant="outlined" | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| @@ -298,31 +298,31 @@ const calculateRequiredQty = useCallback((lot: LotPickData) => { | |||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| label={t('badItemQty')} | |||||
| label={t('Bad Item Qty')} | |||||
| type="number" | type="number" | ||||
| value={formData.badItemQty || 0} | value={formData.badItemQty || 0} | ||||
| onChange={(e) => handleInputChange('badItemQty', parseFloat(e.target.value) || 0)} | onChange={(e) => handleInputChange('badItemQty', parseFloat(e.target.value) || 0)} | ||||
| error={!!errors.badItemQty} | error={!!errors.badItemQty} | ||||
| helperText={errors.badItemQty || t('Enter bad item quantity (required if no missing items)')} | |||||
| // helperText={errors.badItemQty || t('Enter bad item quantity (required if no missing items)')} | |||||
| variant="outlined" | variant="outlined" | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/* ✅ Show issue description and handler fields when bad items > 0 */} | {/* ✅ Show issue description and handler fields when bad items > 0 */} | ||||
| {(formData.badItemQty && formData.badItemQty > 0) && ( | |||||
| {(formData.badItemQty && formData.badItemQty > 0) ? ( | |||||
| <> | <> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| id="issueRemark" | id="issueRemark" | ||||
| label={t('issueRemark')} | |||||
| label={t('Issue Remark')} | |||||
| multiline | multiline | ||||
| rows={4} | rows={4} | ||||
| value={formData.issueRemark || ''} | value={formData.issueRemark || ''} | ||||
| onChange={(e) => handleInputChange('issueRemark', e.target.value)} | onChange={(e) => handleInputChange('issueRemark', e.target.value)} | ||||
| error={!!errors.issueRemark} | error={!!errors.issueRemark} | ||||
| helperText={errors.issueRemark} | helperText={errors.issueRemark} | ||||
| placeholder={t('Describe the issue with bad items')} | |||||
| //placeholder={t('Describe the issue with bad items')} | |||||
| variant="outlined" | variant="outlined" | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| @@ -349,7 +349,7 @@ const calculateRequiredQty = useCallback((lot: LotPickData) => { | |||||
| </FormControl> | </FormControl> | ||||
| </Grid> | </Grid> | ||||
| </> | </> | ||||
| )} | |||||
| ) : (<></>)} | |||||
| </Grid> | </Grid> | ||||
| </Box> | </Box> | ||||
| </DialogContent> | </DialogContent> | ||||
| @@ -718,56 +718,56 @@ const LotTable: React.FC<LotTableProps> = ({ | |||||
| <Stack direction="row" spacing={1} alignItems="center"> | <Stack direction="row" spacing={1} alignItems="center"> | ||||
| {/* ✅ 恢复 TextField 用于正常数量输入 */} | {/* ✅ 恢复 TextField 用于正常数量输入 */} | ||||
| <TextField | <TextField | ||||
| type="number" | |||||
| size="small" | |||||
| value={pickQtyData[selectedRowId!]?.[lot.lotId] || ''} | |||||
| onChange={(e) => { | |||||
| if (selectedRowId) { | |||||
| const inputValue = parseFloat(e.target.value) || 0; | |||||
| const maxAllowed = Math.min(calculateRemainingAvailableQty(lot), calculateRemainingRequiredQty(lot)); | |||||
| {/* | |||||
| // ✅ Validate input | |||||
| if (inputValue > maxAllowed) { | |||||
| // Set validation error for this lot | |||||
| setValidationErrors(prev => ({ ...prev, [`lot_${lot.lotId}`]: `${t('Input quantity cannot exceed')} ${maxAllowed}` })); | |||||
| return; | |||||
| } else { | |||||
| // Clear validation error if valid | |||||
| setValidationErrors(prev => { | |||||
| const newErrors = { ...prev }; | |||||
| delete newErrors[`lot_${lot.lotId}`]; | |||||
| return newErrors; | |||||
| }); | |||||
| */} | |||||
| onPickQtyChange(selectedRowId, lot.lotId, inputValue); | |||||
| } | |||||
| }} | |||||
| disabled={ | |||||
| (lot.lotAvailability === 'expired' || | |||||
| lot.lotAvailability === 'status_unavailable' || | |||||
| lot.lotAvailability === 'rejected') || | |||||
| selectedLotRowId !== `row_${index}` || | |||||
| lot.stockOutLineStatus === 'completed' | |||||
| } | |||||
| error={!!validationErrors[`lot_${lot.lotId}`]} // ✅ Show red border when error | |||||
| helperText={validationErrors[`lot_${lot.lotId}`]} // ✅ Show red error text below | |||||
| inputProps={{ | |||||
| min: 0, | |||||
| max: calculateRemainingRequiredQty(lot), | |||||
| step: 0.01 | |||||
| }} | |||||
| sx={{ | |||||
| width: '60px', | |||||
| height: '28px', | |||||
| '& .MuiInputBase-input': { | |||||
| fontSize: '0.7rem', | |||||
| textAlign: 'center', | |||||
| padding: '6px 8px' | |||||
| } | |||||
| }} | |||||
| placeholder="0" | |||||
| type="number" | |||||
| size="small" | |||||
| value={pickQtyData[selectedRowId!]?.[lot.lotId] || ''} | |||||
| onChange={(e) => { | |||||
| if (selectedRowId) { | |||||
| const inputValue = parseFloat(e.target.value) || 0; | |||||
| const maxAllowed = Math.min(calculateRemainingAvailableQty(lot), calculateRemainingRequiredQty(lot)); | |||||
| {/* | |||||
| // ✅ Validate input | |||||
| if (inputValue > maxAllowed) { | |||||
| // Set validation error for this lot | |||||
| setValidationErrors(prev => ({ ...prev, [`lot_${lot.lotId}`]: `${t('Input quantity cannot exceed')} ${maxAllowed}` })); | |||||
| return; | |||||
| } else { | |||||
| // Clear validation error if valid | |||||
| setValidationErrors(prev => { | |||||
| const newErrors = { ...prev }; | |||||
| delete newErrors[`lot_${lot.lotId}`]; | |||||
| return newErrors; | |||||
| }); | |||||
| */} | |||||
| onPickQtyChange(selectedRowId, lot.lotId, inputValue); | |||||
| } | |||||
| }} | |||||
| disabled={ | |||||
| (lot.lotAvailability === 'expired' || | |||||
| lot.lotAvailability === 'status_unavailable' || | |||||
| lot.lotAvailability === 'rejected') || | |||||
| selectedLotRowId !== `row_${index}` || | |||||
| lot.stockOutLineStatus === 'completed' | |||||
| } | |||||
| error={!!validationErrors[`lot_${lot.lotId}`]} // ✅ Show red border when error | |||||
| helperText={validationErrors[`lot_${lot.lotId}`]} // ✅ Show red error text below | |||||
| inputProps={{ | |||||
| min: 0, | |||||
| max: calculateRemainingRequiredQty(lot), | |||||
| step: 0.01 | |||||
| }} | |||||
| sx={{ | |||||
| width: '60px', | |||||
| height: '28px', | |||||
| '& .MuiInputBase-input': { | |||||
| fontSize: '0.7rem', | |||||
| textAlign: 'center', | |||||
| padding: '6px 8px' | |||||
| } | |||||
| }} | |||||
| placeholder="0" | |||||
| /> | /> | ||||
| {/* ✅ 添加 Pick Form 按钮用于问题情况 */} | {/* ✅ 添加 Pick Form 按钮用于问题情况 */} | ||||
| @@ -775,6 +775,12 @@ const LotTable: React.FC<LotTableProps> = ({ | |||||
| variant="outlined" | variant="outlined" | ||||
| size="small" | size="small" | ||||
| onClick={() => handlePickExecutionForm(lot)} | onClick={() => handlePickExecutionForm(lot)} | ||||
| disabled={ | |||||
| (lot.lotAvailability === 'expired' || | |||||
| lot.lotAvailability === 'status_unavailable' || | |||||
| lot.lotAvailability === 'rejected') || | |||||
| selectedLotRowId !== `row_${index}` | |||||
| } | |||||
| sx={{ | sx={{ | ||||
| fontSize: '0.7rem', | fontSize: '0.7rem', | ||||
| py: 0.5, | py: 0.5, | ||||
| @@ -301,9 +301,9 @@ const calculateRequiredQty = useCallback((lot: LotPickData) => { | |||||
| variant="outlined" | variant="outlined" | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/* ✅ Show issue description and handler fields when bad items > 0 */} | {/* ✅ Show issue description and handler fields when bad items > 0 */} | ||||
| {(formData.badItemQty && formData.badItemQty > 0) && ( | |||||
| {(formData.badItemQty && formData.badItemQty > 0) ? ( | |||||
| <> | <> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <TextField | <TextField | ||||
| @@ -343,8 +343,9 @@ const calculateRequiredQty = useCallback((lot: LotPickData) => { | |||||
| </FormControl> | </FormControl> | ||||
| </Grid> | </Grid> | ||||
| </> | </> | ||||
| )} | |||||
| </Grid> | |||||
| ) : (<></>)} | |||||
| </Grid> | |||||
| </Box> | </Box> | ||||
| </DialogContent> | </DialogContent> | ||||
| <DialogActions> | <DialogActions> | ||||
| @@ -227,6 +227,8 @@ | |||||
| "This form is for reporting issues only. You must report either missing items or bad items.":"此表單僅用於報告問題。您必須報告缺少的貨品或不良貨品。", | "This form is for reporting issues only. You must report either missing items or bad items.":"此表單僅用於報告問題。您必須報告缺少的貨品或不良貨品。", | ||||
| "Bad item Qty":"不良貨品數量", | "Bad item Qty":"不良貨品數量", | ||||
| "Missing item Qty":"缺少貨品數量", | "Missing item Qty":"缺少貨品數量", | ||||
| "Bad Item Qty":"不良貨品數量", | |||||
| "Missing Item Qty":"缺少貨品數量", | |||||
| "Actual Pick Qty":"實際提料數量", | "Actual Pick Qty":"實際提料數量", | ||||
| "Required Qty":"所需數量", | "Required Qty":"所需數量", | ||||
| "Issue Remark":"問題描述", | "Issue Remark":"問題描述", | ||||
| @@ -234,5 +236,11 @@ | |||||
| "Qty is required":"必需輸入數量", | "Qty is required":"必需輸入數量", | ||||
| "Qty is not allowed to be greater than remaining available qty":"輸入數量不能大於剩餘可用數量", | "Qty is not allowed to be greater than remaining available qty":"輸入數量不能大於剩餘可用數量", | ||||
| "Qty is not allowed to be greater than required qty":"輸入數量不能大於所需數量", | "Qty is not allowed to be greater than required qty":"輸入數量不能大於所需數量", | ||||
| "At least one issue must be reported":"至少需要報告一個問題" | |||||
| "At least one issue must be reported":"至少需要報告一個問題", | |||||
| "issueRemark":"問題描述是必需的", | |||||
| "handler":"處理者", | |||||
| "Max":"最大值", | |||||
| "Route":"路線", | |||||
| "Index":"編號", | |||||
| "No FG pick orders found":"沒有成品提料單" | |||||
| } | } | ||||