# 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, | Button, | ||||
| Grid, | Grid, | ||||
| Divider, | Divider, | ||||
| Dialog, | |||||
| DialogTitle, | |||||
| DialogContent, | |||||
| DialogActions, | |||||
| Table, | |||||
| TableBody, | |||||
| TableCell, | |||||
| TableContainer, | |||||
| TableHead, | |||||
| TableRow, | |||||
| Paper, | |||||
| Chip, | Chip, | ||||
| Autocomplete | Autocomplete | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import PrintIcon from '@mui/icons-material/Print'; | import PrintIcon from '@mui/icons-material/Print'; | ||||
| import { REPORTS, ReportDefinition } from '@/config/reportConfig'; | import { REPORTS, ReportDefinition } from '@/config/reportConfig'; | ||||
| import { getSession } from "next-auth/react"; | |||||
| import { NEXT_PUBLIC_API_URL } from '@/config/api'; | 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 { | interface ItemCodeWithName { | ||||
| code: string; | code: string; | ||||
| @@ -46,9 +33,6 @@ export default function ReportPage() { | |||||
| const [criteria, setCriteria] = useState<Record<string, string>>({}); | const [criteria, setCriteria] = useState<Record<string, string>>({}); | ||||
| const [loading, setLoading] = useState(false); | const [loading, setLoading] = useState(false); | ||||
| const [dynamicOptions, setDynamicOptions] = useState<Record<string, { label: string; value: string }[]>>({}); | 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 | // Find the configuration for the currently selected report | ||||
| const currentReport = useMemo(() => | const currentReport = useMemo(() => | ||||
| @@ -77,6 +61,36 @@ export default function ReportPage() { | |||||
| if (!field.dynamicOptionsEndpoint) return; | if (!field.dynamicOptionsEndpoint) return; | ||||
| try { | 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"); | const token = localStorage.getItem("accessToken"); | ||||
| // Handle multiple stockCategory values (comma-separated) | // 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}`); | 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 })); | setDynamicOptions((prev) => ({ ...prev, [field.name]: options })); | ||||
| // Do NOT clear itemCode when stockCategory changes - preserve user's selection | |||||
| } catch (error) { | } catch (error) { | ||||
| console.error("Failed to fetch dynamic options:", error); | console.error("Failed to fetch dynamic options:", error); | ||||
| setDynamicOptions((prev) => ({ ...prev, [field.name]: [] })); | setDynamicOptions((prev) => ({ ...prev, [field.name]: [] })); | ||||
| @@ -170,25 +151,11 @@ export default function ReportPage() { | |||||
| return; | 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 () => { | const executePrint = async () => { | ||||
| @@ -457,79 +424,30 @@ export default function ReportPage() { | |||||
| </Grid> | </Grid> | ||||
| <Box sx={{ mt: 4, display: 'flex', justifyContent: 'flex-end' }}> | <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> | </Box> | ||||
| </CardContent> | </CardContent> | ||||
| </Card> | </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> | </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> | </Box> | ||||
| ) : ( | ) : ( | ||||
| <TableContainer component={Paper}> | <TableContainer component={Paper}> | ||||
| <Table size="small" sx={{ minWidth: 1200 }}> | |||||
| <Table size="small" sx={{ minWidth: 900 }}> | |||||
| <TableHead> | <TableHead> | ||||
| <TableRow sx={{ backgroundColor: 'grey.100' }}> | <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> | ||||
| <TableRow sx={{ backgroundColor: 'grey.50' }}> | <TableRow sx={{ backgroundColor: 'grey.50' }}> | ||||
| <TableCell> | |||||
| <TableCell sx={{ padding: '6px 12px' }}> | |||||
| <Typography variant="caption" color="text.secondary"> | <Typography variant="caption" color="text.secondary"> | ||||
| {t("Show Supplier Name")} | {t("Show Supplier Name")} | ||||
| </Typography> | </Typography> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||||
| <Typography variant="caption" color="text.secondary"> | <Typography variant="caption" color="text.secondary"> | ||||
| {t("Based on Expected Delivery Date")} | {t("Based on Expected Delivery Date")} | ||||
| </Typography> | </Typography> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||||
| <Typography variant="caption" color="text.secondary"> | <Typography variant="caption" color="text.secondary"> | ||||
| {t("Upon entry of DN and Lot No. for all items of the order")} | {t("Upon entry of DN and Lot No. for all items of the order")} | ||||
| </Typography> | </Typography> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||||
| <Typography variant="caption" color="text.secondary"> | <Typography variant="caption" color="text.secondary"> | ||||
| {t("Upon any IQC decision received")} | {t("Upon any IQC decision received")} | ||||
| </Typography> | </Typography> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||||
| <Typography variant="caption" color="text.secondary"> | <Typography variant="caption" color="text.secondary"> | ||||
| {t("Count any item with IQC defect in any IQC criteria")} | {t("Count any item with IQC defect in any IQC criteria")} | ||||
| </Typography> | </Typography> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '6px 12px' }} align="center"> | |||||
| <Typography variant="caption" color="text.secondary"> | <Typography variant="caption" color="text.secondary"> | ||||
| {t("Upon completion of put away for an material in order. Count no. of items being put away")} | {t("Upon completion of put away for an material in order. Count no. of items being put away")} | ||||
| </Typography> | </Typography> | ||||
| @@ -191,22 +191,22 @@ const GoodsReceiptStatus: React.FC = () => { | |||||
| '&:hover': { backgroundColor: 'grey.50' } | '&:hover': { backgroundColor: 'grey.50' } | ||||
| }} | }} | ||||
| > | > | ||||
| <TableCell> | |||||
| <TableCell sx={{ padding: '8px 12px' }}> | |||||
| {row.supplierName || '-'} | {row.supplierName || '-'} | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||||
| {row.expectedNoOfDelivery ?? 0} | {row.expectedNoOfDelivery ?? 0} | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||||
| {row.noOfOrdersReceivedAtDock ?? 0} | {row.noOfOrdersReceivedAtDock ?? 0} | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||||
| {row.noOfItemsInspected ?? 0} | {row.noOfItemsInspected ?? 0} | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||||
| {row.noOfItemsWithIqcIssue ?? 0} | {row.noOfItemsWithIqcIssue ?? 0} | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="center"> | |||||
| <TableCell sx={{ padding: '8px 12px' }} align="center"> | |||||
| {row.noOfItemsCompletedPutAwayAtStore ?? 0} | {row.noOfItemsCompletedPutAwayAtStore ?? 0} | ||||
| </TableCell> | </TableCell> | ||||
| </TableRow> | </TableRow> | ||||