# Conflicts: # src/components/Jodetail/JobPickExecutionsecondscan.tsxMergeProblem1
| @@ -0,0 +1,181 @@ | |||
| "use client"; | |||
| import React, { useState, useEffect } from 'react'; | |||
| import { | |||
| Dialog, | |||
| DialogTitle, | |||
| DialogContent, | |||
| DialogActions, | |||
| Button, | |||
| Table, | |||
| TableBody, | |||
| TableCell, | |||
| TableContainer, | |||
| TableHead, | |||
| TableRow, | |||
| Paper, | |||
| Chip, | |||
| Typography, | |||
| } from '@mui/material'; | |||
| import PrintIcon from '@mui/icons-material/Print'; | |||
| import { | |||
| fetchSemiFGItemCodes, | |||
| fetchSemiFGItemCodesWithCategory, | |||
| generateSemiFGProductionAnalysisReport, | |||
| ItemCodeWithCategory, | |||
| } from './semiFGProductionAnalysisApi'; | |||
| interface SemiFGProductionAnalysisReportProps { | |||
| criteria: Record<string, string>; | |||
| requiredFieldLabels: string[]; | |||
| loading: boolean; | |||
| setLoading: (loading: boolean) => void; | |||
| reportTitle?: string; | |||
| } | |||
| export default function SemiFGProductionAnalysisReport({ | |||
| criteria, | |||
| requiredFieldLabels, | |||
| loading, | |||
| setLoading, | |||
| reportTitle = '成品/半成品生產分析報告', | |||
| }: SemiFGProductionAnalysisReportProps) { | |||
| const [showConfirmDialog, setShowConfirmDialog] = useState(false); | |||
| const [selectedItemCodesInfo, setSelectedItemCodesInfo] = useState<ItemCodeWithCategory[]>([]); | |||
| const [itemCodesWithCategory, setItemCodesWithCategory] = useState<Record<string, ItemCodeWithCategory>>({}); | |||
| // Fetch item codes with category when stockCategory changes | |||
| useEffect(() => { | |||
| const stockCategory = criteria.stockCategory || ''; | |||
| if (stockCategory) { | |||
| fetchSemiFGItemCodesWithCategory(stockCategory) | |||
| .then((items) => { | |||
| const categoryMap: Record<string, ItemCodeWithCategory> = {}; | |||
| items.forEach((item) => { | |||
| categoryMap[item.code] = item; | |||
| }); | |||
| setItemCodesWithCategory((prev) => ({ ...prev, ...categoryMap })); | |||
| }) | |||
| .catch((error) => { | |||
| console.error('Failed to fetch item codes with category:', error); | |||
| }); | |||
| } | |||
| }, [criteria.stockCategory]); | |||
| const handlePrintClick = async () => { | |||
| // Validate required fields | |||
| if (requiredFieldLabels.length > 0) { | |||
| alert(`缺少必填條件:\n- ${requiredFieldLabels.join('\n- ')}`); | |||
| return; | |||
| } | |||
| // If no itemCode is selected, print directly without confirmation | |||
| if (!criteria.itemCode) { | |||
| await executePrint(); | |||
| return; | |||
| } | |||
| // If itemCode is selected, show confirmation dialog | |||
| const selectedCodes = criteria.itemCode.split(',').filter((code) => code.trim()); | |||
| const itemCodesInfo: ItemCodeWithCategory[] = selectedCodes.map((code) => { | |||
| const codeTrimmed = code.trim(); | |||
| const categoryInfo = itemCodesWithCategory[codeTrimmed]; | |||
| return { | |||
| code: codeTrimmed, | |||
| category: categoryInfo?.category || 'Unknown', | |||
| name: categoryInfo?.name || '', | |||
| }; | |||
| }); | |||
| setSelectedItemCodesInfo(itemCodesInfo); | |||
| setShowConfirmDialog(true); | |||
| }; | |||
| const executePrint = async () => { | |||
| setLoading(true); | |||
| try { | |||
| await generateSemiFGProductionAnalysisReport(criteria, reportTitle); | |||
| setShowConfirmDialog(false); | |||
| } catch (error) { | |||
| console.error('Failed to generate report:', error); | |||
| alert('An error occurred while generating the report. Please try again.'); | |||
| } finally { | |||
| setLoading(false); | |||
| } | |||
| }; | |||
| return ( | |||
| <> | |||
| <Button | |||
| variant="contained" | |||
| size="large" | |||
| startIcon={<PrintIcon />} | |||
| onClick={handlePrintClick} | |||
| disabled={loading} | |||
| sx={{ px: 4 }} | |||
| > | |||
| {loading ? '生成報告...' : '列印報告'} | |||
| </Button> | |||
| {/* Confirmation Dialog for 成品/半成品生產分析報告 */} | |||
| <Dialog | |||
| open={showConfirmDialog} | |||
| onClose={() => setShowConfirmDialog(false)} | |||
| maxWidth="md" | |||
| fullWidth | |||
| > | |||
| <DialogTitle> | |||
| <Typography variant="h6" fontWeight="bold"> | |||
| 已選擇的物料編號以及列印成品/半成品生產分析報告 | |||
| </Typography> | |||
| </DialogTitle> | |||
| <DialogContent> | |||
| <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}> | |||
| 請確認以下已選擇的物料編號及其類別: | |||
| </Typography> | |||
| <TableContainer component={Paper} variant="outlined"> | |||
| <Table> | |||
| <TableHead> | |||
| <TableRow> | |||
| <TableCell> | |||
| <strong>物料編號及名稱</strong> | |||
| </TableCell> | |||
| <TableCell> | |||
| <strong>類別</strong> | |||
| </TableCell> | |||
| </TableRow> | |||
| </TableHead> | |||
| <TableBody> | |||
| {selectedItemCodesInfo.map((item, index) => { | |||
| const displayName = item.name ? `${item.code} ${item.name}` : item.code; | |||
| return ( | |||
| <TableRow key={index}> | |||
| <TableCell>{displayName}</TableCell> | |||
| <TableCell> | |||
| <Chip | |||
| label={item.category || 'Unknown'} | |||
| color={item.category === 'FG' ? 'primary' : item.category === 'WIP' ? 'secondary' : 'default'} | |||
| size="small" | |||
| /> | |||
| </TableCell> | |||
| </TableRow> | |||
| ); | |||
| })} | |||
| </TableBody> | |||
| </Table> | |||
| </TableContainer> | |||
| </DialogContent> | |||
| <DialogActions sx={{ p: 2 }}> | |||
| <Button onClick={() => setShowConfirmDialog(false)}>取消</Button> | |||
| <Button | |||
| variant="contained" | |||
| onClick={executePrint} | |||
| disabled={loading} | |||
| startIcon={<PrintIcon />} | |||
| > | |||
| {loading ? '生成報告...' : '確認列印報告'} | |||
| </Button> | |||
| </DialogActions> | |||
| </Dialog> | |||
| </> | |||
| ); | |||
| } | |||
| @@ -11,30 +11,17 @@ import { | |||
| Button, | |||
| Grid, | |||
| Divider, | |||
| Dialog, | |||
| DialogTitle, | |||
| DialogContent, | |||
| DialogActions, | |||
| Table, | |||
| TableBody, | |||
| TableCell, | |||
| TableContainer, | |||
| TableHead, | |||
| TableRow, | |||
| Paper, | |||
| Chip, | |||
| Autocomplete | |||
| } from '@mui/material'; | |||
| import PrintIcon from '@mui/icons-material/Print'; | |||
| import { REPORTS, ReportDefinition } from '@/config/reportConfig'; | |||
| import { getSession } from "next-auth/react"; | |||
| import { NEXT_PUBLIC_API_URL } from '@/config/api'; | |||
| interface ItemCodeWithCategory { | |||
| code: string; | |||
| category: string; | |||
| name?: string; | |||
| } | |||
| import SemiFGProductionAnalysisReport from './SemiFGProductionAnalysisReport'; | |||
| import { | |||
| fetchSemiFGItemCodes, | |||
| fetchSemiFGItemCodesWithCategory | |||
| } from './semiFGProductionAnalysisApi'; | |||
| interface ItemCodeWithName { | |||
| code: string; | |||
| @@ -46,9 +33,6 @@ export default function ReportPage() { | |||
| const [criteria, setCriteria] = useState<Record<string, string>>({}); | |||
| const [loading, setLoading] = useState(false); | |||
| const [dynamicOptions, setDynamicOptions] = useState<Record<string, { label: string; value: string }[]>>({}); | |||
| const [itemCodesWithCategory, setItemCodesWithCategory] = useState<Record<string, ItemCodeWithCategory>>({}); | |||
| const [showConfirmDialog, setShowConfirmDialog] = useState(false); | |||
| const [selectedItemCodesInfo, setSelectedItemCodesInfo] = useState<ItemCodeWithCategory[]>([]); | |||
| // Find the configuration for the currently selected report | |||
| const currentReport = useMemo(() => | |||
| @@ -77,6 +61,36 @@ export default function ReportPage() { | |||
| if (!field.dynamicOptionsEndpoint) return; | |||
| try { | |||
| // Use API service for SemiFG Production Analysis Report (rep-005) | |||
| if (currentReport?.id === 'rep-005' && field.name === 'itemCode') { | |||
| const itemCodesWithName = await fetchSemiFGItemCodes(paramValue); | |||
| const itemsWithCategory = await fetchSemiFGItemCodesWithCategory(paramValue); | |||
| const categoryMap: Record<string, { code: string; category: string; name?: string }> = {}; | |||
| itemsWithCategory.forEach(item => { | |||
| categoryMap[item.code] = item; | |||
| }); | |||
| // Create options with code and name format: "PP1162 瑞士汁(1磅/包)" | |||
| const options = itemCodesWithName.map(item => { | |||
| const code = item.code; | |||
| const name = item.name || ''; | |||
| const category = categoryMap[code]?.category || ''; | |||
| // Format: "PP1162 瑞士汁(1磅/包)" or "PP1162 瑞士汁(1磅/包) (FG)" | |||
| let label = name ? `${code} ${name}` : code; | |||
| if (category) { | |||
| label = `${label} (${category})`; | |||
| } | |||
| return { label, value: code }; | |||
| }); | |||
| setDynamicOptions((prev) => ({ ...prev, [field.name]: options })); | |||
| return; | |||
| } | |||
| // Handle other reports with dynamic options | |||
| const token = localStorage.getItem("accessToken"); | |||
| // Handle multiple stockCategory values (comma-separated) | |||
| @@ -98,45 +112,12 @@ export default function ReportPage() { | |||
| if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); | |||
| const itemCodesWithName: ItemCodeWithName[] = await response.json(); | |||
| // Fetch item codes with category to show labels | |||
| const categoryUrl = `${NEXT_PUBLIC_API_URL}/report/semi-fg-item-codes-with-category${paramValue && paramValue !== 'All' && !paramValue.includes('All') ? `?stockCategory=${paramValue}` : ''}`; | |||
| const categoryResponse = await fetch(categoryUrl, { | |||
| method: 'GET', | |||
| headers: { | |||
| 'Authorization': `Bearer ${token}`, | |||
| 'Content-Type': 'application/json', | |||
| }, | |||
| }); | |||
| let categoryMap: Record<string, ItemCodeWithCategory> = {}; | |||
| if (categoryResponse.ok) { | |||
| const itemsWithCategory: ItemCodeWithCategory[] = await categoryResponse.json(); | |||
| itemsWithCategory.forEach(item => { | |||
| categoryMap[item.code] = item; | |||
| }); | |||
| setItemCodesWithCategory((prev) => ({ ...prev, ...categoryMap })); | |||
| } | |||
| // Create options with code and name format: "PP1162 瑞士汁(1磅/包)" | |||
| const options = itemCodesWithName.map(item => { | |||
| const code = item.code; | |||
| const name = item.name || ''; | |||
| const category = categoryMap[code]?.category || ''; | |||
| // Format: "PP1162 瑞士汁(1磅/包)" or "PP1162 瑞士汁(1磅/包) (FG)" | |||
| let label = name ? `${code} ${name}` : code; | |||
| if (category) { | |||
| label = `${label} (${category})`; | |||
| } | |||
| return { label, value: code }; | |||
| }); | |||
| const data = await response.json(); | |||
| const options = Array.isArray(data) | |||
| ? data.map((item: any) => ({ label: item.label || item.name || item.code || String(item), value: item.value || item.code || String(item) })) | |||
| : []; | |||
| setDynamicOptions((prev) => ({ ...prev, [field.name]: options })); | |||
| // Do NOT clear itemCode when stockCategory changes - preserve user's selection | |||
| } catch (error) { | |||
| console.error("Failed to fetch dynamic options:", error); | |||
| setDynamicOptions((prev) => ({ ...prev, [field.name]: [] })); | |||
| @@ -170,25 +151,11 @@ export default function ReportPage() { | |||
| return; | |||
| } | |||
| if (currentReport.id === 'rep-005' && criteria.itemCode) { | |||
| const selectedCodes = criteria.itemCode.split(',').filter(code => code.trim()); | |||
| const itemCodesInfo: ItemCodeWithCategory[] = selectedCodes.map(code => { | |||
| const codeTrimmed = code.trim(); | |||
| const categoryInfo = itemCodesWithCategory[codeTrimmed]; | |||
| return { | |||
| code: codeTrimmed, | |||
| category: categoryInfo?.category || 'Unknown', | |||
| name: categoryInfo?.name || '' | |||
| }; | |||
| }); | |||
| setSelectedItemCodesInfo(itemCodesInfo); | |||
| setShowConfirmDialog(true); | |||
| return; | |||
| // For rep-005, the print logic is handled by SemiFGProductionAnalysisReport component | |||
| // For other reports, execute print directly | |||
| if (currentReport.id !== 'rep-005') { | |||
| await executePrint(); | |||
| } | |||
| // Direct print for other reports | |||
| await executePrint(); | |||
| }; | |||
| const executePrint = async () => { | |||
| @@ -457,79 +424,30 @@ export default function ReportPage() { | |||
| </Grid> | |||
| <Box sx={{ mt: 4, display: 'flex', justifyContent: 'flex-end' }}> | |||
| <Button | |||
| variant="contained" | |||
| size="large" | |||
| startIcon={<PrintIcon />} | |||
| onClick={handlePrint} | |||
| disabled={loading} | |||
| sx={{ px: 4 }} | |||
| > | |||
| {loading ? "生成報告..." : "列印報告"} | |||
| </Button> | |||
| {currentReport.id === 'rep-005' ? ( | |||
| <SemiFGProductionAnalysisReport | |||
| criteria={criteria} | |||
| requiredFieldLabels={currentReport.fields.filter(f => f.required && !criteria[f.name]).map(f => f.label)} | |||
| loading={loading} | |||
| setLoading={setLoading} | |||
| reportTitle={currentReport.title} | |||
| /> | |||
| ) : ( | |||
| <Button | |||
| variant="contained" | |||
| size="large" | |||
| startIcon={<PrintIcon />} | |||
| onClick={handlePrint} | |||
| disabled={loading} | |||
| sx={{ px: 4 }} | |||
| > | |||
| {loading ? "生成報告..." : "列印報告"} | |||
| </Button> | |||
| )} | |||
| </Box> | |||
| </CardContent> | |||
| </Card> | |||
| )} | |||
| {/* Confirmation Dialog for 成品/半成品生產分析報告 */} | |||
| <Dialog | |||
| open={showConfirmDialog} | |||
| onClose={() => setShowConfirmDialog(false)} | |||
| maxWidth="md" | |||
| fullWidth | |||
| > | |||
| <DialogTitle> | |||
| <Typography variant="h6" fontWeight="bold"> | |||
| 已選擇的物料編號以及列印成品/半成品生產分析報告 | |||
| </Typography> | |||
| </DialogTitle> | |||
| <DialogContent> | |||
| <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}> | |||
| 請確認以下已選擇的物料編號及其類別: | |||
| </Typography> | |||
| <TableContainer component={Paper} variant="outlined"> | |||
| <Table> | |||
| <TableHead> | |||
| <TableRow> | |||
| <TableCell><strong>物料編號及名稱</strong></TableCell> | |||
| <TableCell><strong>類別</strong></TableCell> | |||
| </TableRow> | |||
| </TableHead> | |||
| <TableBody> | |||
| {selectedItemCodesInfo.map((item, index) => { | |||
| const displayName = item.name ? `${item.code} ${item.name}` : item.code; | |||
| return ( | |||
| <TableRow key={index}> | |||
| <TableCell>{displayName}</TableCell> | |||
| <TableCell> | |||
| <Chip | |||
| label={item.category || 'Unknown'} | |||
| color={item.category === 'FG' ? 'primary' : item.category === 'WIP' ? 'secondary' : 'default'} | |||
| size="small" | |||
| /> | |||
| </TableCell> | |||
| </TableRow> | |||
| ); | |||
| })} | |||
| </TableBody> | |||
| </Table> | |||
| </TableContainer> | |||
| </DialogContent> | |||
| <DialogActions sx={{ p: 2 }}> | |||
| <Button onClick={() => setShowConfirmDialog(false)}> | |||
| 取消 | |||
| </Button> | |||
| <Button | |||
| variant="contained" | |||
| onClick={executePrint} | |||
| disabled={loading} | |||
| startIcon={<PrintIcon />} | |||
| > | |||
| {loading ? "生成報告..." : "確認列印報告"} | |||
| </Button> | |||
| </DialogActions> | |||
| </Dialog> | |||
| </Box> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,116 @@ | |||
| import { NEXT_PUBLIC_API_URL } from '@/config/api'; | |||
| export interface ItemCodeWithName { | |||
| code: string; | |||
| name: string; | |||
| } | |||
| export interface ItemCodeWithCategory { | |||
| code: string; | |||
| category: string; | |||
| name?: string; | |||
| } | |||
| /** | |||
| * Fetch item codes for SemiFG Production Analysis Report | |||
| * @param stockCategory - Comma-separated stock categories (e.g., "FG,WIP") or empty string for all | |||
| * @returns Array of item codes with names | |||
| */ | |||
| export const fetchSemiFGItemCodes = async ( | |||
| stockCategory: string = '' | |||
| ): Promise<ItemCodeWithName[]> => { | |||
| const token = localStorage.getItem("accessToken"); | |||
| let url = `${NEXT_PUBLIC_API_URL}/report/semi-fg-item-codes`; | |||
| if (stockCategory && stockCategory !== 'All' && !stockCategory.includes('All')) { | |||
| url = `${url}?stockCategory=${stockCategory}`; | |||
| } | |||
| const response = await fetch(url, { | |||
| method: 'GET', | |||
| headers: { | |||
| 'Authorization': `Bearer ${token}`, | |||
| 'Content-Type': 'application/json', | |||
| }, | |||
| }); | |||
| if (!response.ok) { | |||
| throw new Error(`HTTP error! status: ${response.status}`); | |||
| } | |||
| return await response.json(); | |||
| }; | |||
| /** | |||
| * Fetch item codes with category information for SemiFG Production Analysis Report | |||
| * @param stockCategory - Comma-separated stock categories (e.g., "FG,WIP") or empty string for all | |||
| * @returns Array of item codes with category and name | |||
| */ | |||
| export const fetchSemiFGItemCodesWithCategory = async ( | |||
| stockCategory: string = '' | |||
| ): Promise<ItemCodeWithCategory[]> => { | |||
| const token = localStorage.getItem("accessToken"); | |||
| let url = `${NEXT_PUBLIC_API_URL}/report/semi-fg-item-codes-with-category`; | |||
| if (stockCategory && stockCategory !== 'All' && !stockCategory.includes('All')) { | |||
| url = `${url}?stockCategory=${stockCategory}`; | |||
| } | |||
| const response = await fetch(url, { | |||
| method: 'GET', | |||
| headers: { | |||
| 'Authorization': `Bearer ${token}`, | |||
| 'Content-Type': 'application/json', | |||
| }, | |||
| }); | |||
| if (!response.ok) { | |||
| throw new Error(`HTTP error! status: ${response.status}`); | |||
| } | |||
| return await response.json(); | |||
| }; | |||
| /** | |||
| * Generate and download the SemiFG Production Analysis Report PDF | |||
| * @param criteria - Report criteria parameters | |||
| * @param reportTitle - Title of the report for filename | |||
| * @returns Promise that resolves when download is complete | |||
| */ | |||
| export const generateSemiFGProductionAnalysisReport = async ( | |||
| criteria: Record<string, string>, | |||
| reportTitle: string = '成品/半成品生產分析報告' | |||
| ): Promise<void> => { | |||
| const token = localStorage.getItem("accessToken"); | |||
| const queryParams = new URLSearchParams(criteria).toString(); | |||
| const url = `${NEXT_PUBLIC_API_URL}/report/print-semi-fg-production-analysis?${queryParams}`; | |||
| const response = await fetch(url, { | |||
| method: 'GET', | |||
| headers: { | |||
| 'Authorization': `Bearer ${token}`, | |||
| 'Accept': 'application/pdf', | |||
| }, | |||
| }); | |||
| if (!response.ok) { | |||
| throw new Error(`HTTP error! status: ${response.status}`); | |||
| } | |||
| const blob = await response.blob(); | |||
| const downloadUrl = window.URL.createObjectURL(blob); | |||
| const link = document.createElement('a'); | |||
| link.href = downloadUrl; | |||
| const contentDisposition = response.headers.get('Content-Disposition'); | |||
| let fileName = `${reportTitle}.pdf`; | |||
| if (contentDisposition?.includes('filename=')) { | |||
| fileName = contentDisposition.split('filename=')[1].split(';')[0].replace(/"/g, ''); | |||
| } | |||
| link.setAttribute('download', fileName); | |||
| document.body.appendChild(link); | |||
| link.click(); | |||
| link.remove(); | |||
| window.URL.revokeObjectURL(downloadUrl); | |||
| }; | |||
| @@ -131,43 +131,43 @@ const GoodsReceiptStatus: React.FC = () => { | |||
| </Box> | |||
| ) : ( | |||
| <TableContainer component={Paper}> | |||
| <Table size="small" sx={{ minWidth: 1200 }}> | |||
| <Table size="small" sx={{ minWidth: 900 }}> | |||
| <TableHead> | |||
| <TableRow sx={{ backgroundColor: 'grey.100' }}> | |||
| <TableCell sx={{ fontWeight: 600 }}>{t("Supplier")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600 }} align="center">{t("Expected No. of Delivery")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600 }} align="center">{t("No. of Orders Received at Dock")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600 }} align="center">{t("No. of Items Inspected")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600 }} align="center">{t("No. of Items with IQC Issue")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600 }} align="center">{t("No. of Items Completed Put Away at Store")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600, width: '200px', padding: '8px 12px' }}>{t("Supplier")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600, width: '120px', padding: '8px 12px' }} align="center">{t("Expected No. of Delivery")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600, width: '150px', padding: '8px 12px' }} align="center">{t("No. of Orders Received at Dock")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600, width: '120px', padding: '8px 12px' }} align="center">{t("No. of Items Inspected")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600, width: '150px', padding: '8px 12px' }} align="center">{t("No. of Items with IQC Issue")}</TableCell> | |||
| <TableCell sx={{ fontWeight: 600, width: '180px', padding: '8px 12px' }} align="center">{t("No. of Items Completed Put Away at Store")}</TableCell> | |||
| </TableRow> | |||
| <TableRow sx={{ backgroundColor: 'grey.50' }}> | |||
| <TableCell> | |||
| <TableCell sx={{ padding: '6px 12px' }}> | |||
| <Typography variant="caption" color="text.secondary"> | |||
| {t("Show Supplier Name")} | |||
| </Typography> | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||
| <Typography variant="caption" color="text.secondary"> | |||
| {t("Based on Expected Delivery Date")} | |||
| </Typography> | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||
| <Typography variant="caption" color="text.secondary"> | |||
| {t("Upon entry of DN and Lot No. for all items of the order")} | |||
| </Typography> | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||
| <Typography variant="caption" color="text.secondary"> | |||
| {t("Upon any IQC decision received")} | |||
| </Typography> | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||
| <Typography variant="caption" color="text.secondary"> | |||
| {t("Count any item with IQC defect in any IQC criteria")} | |||
| </Typography> | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||
| <Typography variant="caption" color="text.secondary"> | |||
| {t("Upon completion of put away for an material in order. Count no. of items being put away")} | |||
| </Typography> | |||
| @@ -191,22 +191,22 @@ const GoodsReceiptStatus: React.FC = () => { | |||
| '&:hover': { backgroundColor: 'grey.50' } | |||
| }} | |||
| > | |||
| <TableCell> | |||
| <TableCell sx={{ padding: '8px 12px' }}> | |||
| {row.supplierName || '-'} | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||
| {row.expectedNoOfDelivery ?? 0} | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||
| {row.noOfOrdersReceivedAtDock ?? 0} | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||
| {row.noOfItemsInspected ?? 0} | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||
| {row.noOfItemsWithIqcIssue ?? 0} | |||
| </TableCell> | |||
| <TableCell align="center"> | |||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||
| {row.noOfItemsCompletedPutAwayAtStore ?? 0} | |||
| </TableCell> | |||
| </TableRow> | |||