Browse Source

update

master
CANCERYS\kw093 2 weeks ago
parent
commit
8e64686a40
5 changed files with 176 additions and 25 deletions
  1. +1
    -0
      src/app/api/jo/actions.ts
  2. +31
    -15
      src/components/JoSearch/JoCreateFormModal.tsx
  3. +137
    -8
      src/components/PickOrderSearch/LotTable.tsx
  4. +2
    -2
      src/components/ProductionProcess/ProductionProcessJobOrderDetail.tsx
  5. +5
    -0
      src/i18n/zh/common.json

+ 1
- 0
src/app/api/jo/actions.ts View File

@@ -211,6 +211,7 @@ export interface ProductProcessWithLinesResponse {
jobOrderId?: number;
jobOrderCode: string;
jobOrderStatus: string;
jobType: string;
isDark: string;
isDense: number;
isFloat: string;


+ 31
- 15
src/components/JoSearch/JoCreateFormModal.tsx View File

@@ -56,6 +56,7 @@ const JoCreateFormModal: React.FC<Props> = ({
const dateDayjs = dateStringToDayjs(data.planStart)
data.planStart = dayjsToDateTimeString(dateDayjs.startOf('day'))
}
data.jobTypeId = Number(data.jobTypeId);
const response = await manualCreateJo(data)
if (response) {
onSearch();
@@ -168,21 +169,36 @@ const JoCreateFormModal: React.FC<Props> = ({
/>
</Grid>
<Grid item xs={12} sm={12} md={6}>
<FormControl fullWidth>
<InputLabel>{t("Job Type")}</InputLabel>
<Select
label={t("Job Type")}
defaultValue=""
>
<MenuItem value="1">{t("FG")}</MenuItem>
<MenuItem value="2">{t("WIP")}</MenuItem>
<MenuItem value="3">{t("R&D")}</MenuItem>
<MenuItem value="4">{t("STF")}</MenuItem>
<MenuItem value="5">{t("Other")}</MenuItem>
</Select>
</FormControl>

</Grid>
<Controller
control={control}
name="jobTypeId"
rules={{ required: t("Job Type required!") as string }}
render={({ field, fieldState: { error } }) => (
<FormControl fullWidth error={Boolean(error)}>
<InputLabel>{t("Job Type")}</InputLabel>
<Select
{...field}
label={t("Job Type")}
value={field.value?.toString() ?? ""}
onChange={(event) => {
const value = event.target.value;
field.onChange(value === "" ? undefined : Number(value));
}}
>
<MenuItem value="">
<em>{t("Please select")}</em>
</MenuItem>
<MenuItem value="1">{t("FG")}</MenuItem>
<MenuItem value="2">{t("WIP")}</MenuItem>
<MenuItem value="3">{t("R&D")}</MenuItem>
<MenuItem value="4">{t("STF")}</MenuItem>
<MenuItem value="5">{t("Other")}</MenuItem>
</Select>
{/*{error && <FormHelperText>{error.message}</FormHelperText>}*/}
</FormControl>
)}
/>
</Grid>
<Grid item xs={12} sm={12} md={6}>
<Controller
control={control}


+ 137
- 8
src/components/PickOrderSearch/LotTable.tsx View File

@@ -429,7 +429,21 @@ const LotTable: React.FC<LotTableProps> = ({
return t("Please finish QR code scan and pick order.");
}
}, [t]);

const handleOpenQrModal = useCallback((lot: LotPickData) => {
setSelectedLotForQr(lot);
setManualQrInput(lot.lotNo ?? "");
setValidationErrors({});
setQrModalOpen(true);
resetScan();
startScan();
}, [startScan, resetScan]);
const handleCloseQrModal = useCallback(() => {
setQrModalOpen(false);
setSelectedLotForQr(null);
stopScan();
resetScan();
}, [stopScan, resetScan]);
const prepareLotTableData = useMemo(() => {
return lotData.map((lot) => ({
...lot,
@@ -477,9 +491,55 @@ const LotTable: React.FC<LotTableProps> = ({
}, [calculateRemainingAvailableQty, calculateRemainingRequiredQty, t]);

const handleQrCodeSubmit = useCallback(async (lotNo: string) => {
// ... 保持你原本的 QR 提交邏輯 ...
}, [selectedLotForQr, selectedRowId, onPickQtyChange, onLotDataRefresh]);

if (selectedLotForQr && selectedLotForQr.lotNo === lotNo) {
console.log(` QR Code verified for lot: ${lotNo}`);
if (!selectedLotForQr.stockOutLineId) {
console.error("No stock out line ID found for this lot");
alert("No stock out line found for this lot. Please contact administrator.");
return;
}
// Store the required quantity before creating stock out line
const requiredQty = selectedLotForQr.requiredQty;
const lotId = selectedLotForQr.lotId;
try {
// Update stock out line status to 'checked' (QR scan completed)
const stockOutLineUpdate = await updateStockOutLineStatus({
id: selectedLotForQr.stockOutLineId,
status: 'checked',
qty: selectedLotForQr.stockOutLineQty || 0
});
console.log(" Stock out line updated to 'checked':", stockOutLineUpdate);
// Close modal
setQrModalOpen(false);
setSelectedLotForQr(null);
if (onLotDataRefresh) {
await onLotDataRefresh();
}
// Set pick quantity AFTER stock out line update is complete
if (selectedRowId) {
// Add a small delay to ensure the data refresh is complete
setTimeout(() => {
onPickQtyChange(selectedRowId, lotId ?? 0, requiredQty);
console.log(` Auto-set pick quantity to ${requiredQty} for lot ${lotNo}`);
}, 500); // 500ms delay to ensure refresh is complete
}
// Show success message
console.log("Stock out line updated successfully!");
} catch (error) {
console.error("❌ Error updating stock out line status:", error);
alert("Failed to update lot status. Please try again.");
}
} else {
// Handle case where lot numbers don't match
console.error("QR scan mismatch:", { scanned: lotNo, expected: selectedLotForQr?.lotNo });
alert(`QR scan mismatch! Expected: ${selectedLotForQr?.lotNo}, Scanned: ${lotNo}`);
}
}, [selectedLotForQr, selectedRowId, onPickQtyChange]);
// PickExecutionForm 狀態與提交(保持原本邏輯)
const [pickExecutionFormOpen, setPickExecutionFormOpen] = useState(false);
const [selectedLotForExecutionForm, setSelectedLotForExecutionForm] = useState<LotPickData | null>(null);
@@ -606,9 +666,73 @@ const LotTable: React.FC<LotTableProps> = ({
})()}
</TableCell>
<TableCell align="center">
{/* 已掃碼後的實際數量 + Issue 按鈕(保持原有邏輯,略) */}
{/* 對 noLot 行而言這裡通常保持為 0/禁用 */}
</TableCell>
{lot.stockOutLineStatus?.toLowerCase() === 'pending' ? (
<Button
variant="outlined"
size="small"
startIcon={<QrCodeIcon />}
onClick={() => handleOpenQrModal(lot)}
disabled={
lot.lotAvailability === 'expired' ||
lot.lotAvailability === 'status_unavailable' ||
lot.lotAvailability === 'rejected' ||
selectedLotRowId !== `row_${index}`
}
sx={{ fontSize: '0.7rem', minHeight: 40, minWidth: 100 }}
title={
selectedLotRowId !== `row_${index}`
? t("Please select this lot first to enable QR scanning")
: t("Click to scan QR code")
}
>
{t("Scan")}
</Button>
) : (
<Stack direction="row" spacing={1} alignItems="center" justifyContent="center">
<TextField
type="number"
size="small"
value={
selectedRowId && lot.lotId != null
? pickQtyData[selectedRowId]?.[lot.lotId] ?? ''
: ''
}
onChange={(e) => {
if (selectedRowId && lot.lotId != null) {
onPickQtyChange(selectedRowId, lot.lotId, Number(e.target.value) || 0);
}
}}
disabled={
lot.lotAvailability === 'expired' ||
lot.lotAvailability === 'status_unavailable' ||
lot.lotAvailability === 'rejected' ||
selectedLotRowId !== `row_${index}` ||
lot.stockOutLineStatus === 'completed'
}
error={!!validationErrors[`lot_${lot.lotId}`]}
helperText={validationErrors[`lot_${lot.lotId}`]}
inputProps={{ min: 0, max: calculateRemainingRequiredQty(lot) }}
sx={{ width: 70 }}
placeholder="0"
/>
<Button
variant="outlined"
size="small"
onClick={() => handlePickExecutionForm(lot)}
disabled={
lot.lotAvailability === 'expired' ||
lot.lotAvailability === 'status_unavailable' ||
lot.lotAvailability === 'rejected' ||
selectedLotRowId !== `row_${index}`
}
sx={{ fontSize: '0.7rem', minWidth: 70, borderColor: 'warning.main', color: 'warning.main' }}
title={t("Report missing or bad items")}
>
{t("Issue")}
</Button>
</Stack>
)}
</TableCell>
<TableCell align="right">
{calculateRemainingAvailableQty(lot).toLocaleString()}
</TableCell>
@@ -680,7 +804,12 @@ const LotTable: React.FC<LotTableProps> = ({
</TableContainer>

{/* Status message & pagination & modals 保持原有程式不變(略) */}

<QrCodeModal
open={qrModalOpen}
onClose={handleCloseQrModal}
lot={selectedLotForQr}
onQrCodeSubmit={handleQrCodeSubmit}
/>
{pickExecutionFormOpen && selectedLotForExecutionForm && selectedRow && (
<PickExecutionForm
open={pickExecutionFormOpen}


+ 2
- 2
src/components/ProductionProcess/ProductionProcessJobOrderDetail.tsx View File

@@ -204,8 +204,8 @@ const handleRelease = useCallback(async ( jobOrderId: number) => {
label={t("Job Type")}
fullWidth
disabled={true}
// value={processData?.jobType || ""}
value={t("N/A")}
value={t(processData?.jobType) || t("N/A")}
//value={t("N/A")}
/>
</Grid>
<Grid item xs={6}>


+ 5
- 0
src/i18n/zh/common.json View File

@@ -12,6 +12,11 @@
"code": "編號",
"Name": "名稱",
"Type": "類型",

"WIP": "半成品",
"R&D": "研發",
"STF": "樣品",
"Other": "其他",
"Add some entries!": "添加條目",
"Add Record": "新增",
"Clean Record": "重置",


Loading…
Cancel
Save