|
|
|
@@ -11,6 +11,7 @@ import { FileDownload, Print, SettingsEthernet, Lan, Router } from "@mui/icons-m |
|
|
|
import dayjs from "dayjs"; |
|
|
|
import { NEXT_PUBLIC_API_URL } from "@/config/api"; |
|
|
|
import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; |
|
|
|
import * as XLSX from "xlsx"; |
|
|
|
|
|
|
|
// Simple TabPanel component for conditional rendering |
|
|
|
interface TabPanelProps { |
|
|
|
@@ -87,6 +88,9 @@ export default function TestingPage() { |
|
|
|
}, |
|
|
|
]); |
|
|
|
|
|
|
|
// --- 6. GRN Preview (M18) --- |
|
|
|
const [grnPreviewReceiptDate, setGrnPreviewReceiptDate] = useState("2026-03-16"); |
|
|
|
|
|
|
|
// Generic handler for inline table edits |
|
|
|
const handleItemChange = (setter: any, id: number, field: string, value: string) => { |
|
|
|
setter((prev: any[]) => prev.map(item => |
|
|
|
@@ -207,6 +211,42 @@ export default function TestingPage() { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// GRN Preview CSV Download (Section 6) |
|
|
|
const handleDownloadGrnPreviewXlsx = async () => { |
|
|
|
try { |
|
|
|
const response = await clientAuthFetch( |
|
|
|
`${NEXT_PUBLIC_API_URL}/report/grn-preview-m18?receiptDate=${encodeURIComponent(grnPreviewReceiptDate)}`, |
|
|
|
{ method: "GET" }, |
|
|
|
); |
|
|
|
if (response.status === 401 || response.status === 403) return; |
|
|
|
if (!response.ok) throw new Error(`Download failed: ${response.status}`); |
|
|
|
|
|
|
|
const data = await response.json(); |
|
|
|
const rows = Array.isArray(data?.rows) ? data.rows : []; |
|
|
|
|
|
|
|
const ws = XLSX.utils.json_to_sheet(rows); |
|
|
|
const wb = XLSX.utils.book_new(); |
|
|
|
XLSX.utils.book_append_sheet(wb, ws, "GRN Preview"); |
|
|
|
|
|
|
|
const xlsxArrayBuffer = XLSX.write(wb, { bookType: "xlsx", type: "array" }); |
|
|
|
const blob = new Blob([xlsxArrayBuffer], { |
|
|
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
|
|
|
}); |
|
|
|
|
|
|
|
const url = window.URL.createObjectURL(blob); |
|
|
|
const link = document.createElement("a"); |
|
|
|
link.href = url; |
|
|
|
link.setAttribute("download", `grn-preview-m18-${grnPreviewReceiptDate}.xlsx`); |
|
|
|
document.body.appendChild(link); |
|
|
|
link.click(); |
|
|
|
link.remove(); |
|
|
|
window.URL.revokeObjectURL(url); |
|
|
|
} catch (e) { |
|
|
|
console.error("GRN Preview XLSX Download Error:", e); |
|
|
|
alert("GRN Preview XLSX download failed. Check console/network."); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// Layout Helper |
|
|
|
const Section = ({ title, children }: { title: string, children?: React.ReactNode }) => ( |
|
|
|
<Paper sx={{ p: 3, minHeight: '450px', display: 'flex', flexDirection: 'column' }}> |
|
|
|
@@ -227,6 +267,7 @@ export default function TestingPage() { |
|
|
|
<Tab label="3. OnPack" /> |
|
|
|
<Tab label="4. Laser" /> |
|
|
|
<Tab label="5. HANS600S-M" /> |
|
|
|
<Tab label="6. GRN Preview" /> |
|
|
|
</Tabs> |
|
|
|
|
|
|
|
<TabPanel value={tabValue} index={0}> |
|
|
|
@@ -455,6 +496,33 @@ export default function TestingPage() { |
|
|
|
</Section> |
|
|
|
</TabPanel> |
|
|
|
|
|
|
|
<TabPanel value={tabValue} index={5}> |
|
|
|
<Section title="6. GRN Preview (M18)"> |
|
|
|
<Stack direction="row" spacing={2} sx={{ mb: 2, alignItems: "center" }}> |
|
|
|
<TextField |
|
|
|
size="small" |
|
|
|
label="Receipt Date" |
|
|
|
type="date" |
|
|
|
value={grnPreviewReceiptDate} |
|
|
|
onChange={(e) => setGrnPreviewReceiptDate(e.target.value)} |
|
|
|
InputLabelProps={{ shrink: true }} |
|
|
|
/> |
|
|
|
<Button |
|
|
|
variant="contained" |
|
|
|
color="success" |
|
|
|
size="medium" |
|
|
|
startIcon={<FileDownload />} |
|
|
|
onClick={handleDownloadGrnPreviewXlsx} |
|
|
|
> |
|
|
|
Download GRN Preview XLSX |
|
|
|
</Button> |
|
|
|
</Stack> |
|
|
|
<Typography variant="body2" color="textSecondary"> |
|
|
|
Backend endpoint: <code>/report/grn-preview-m18?receiptDate=YYYY-MM-DD</code> |
|
|
|
</Typography> |
|
|
|
</Section> |
|
|
|
</TabPanel> |
|
|
|
|
|
|
|
{/* Dialog for OnPack */} |
|
|
|
<Dialog open={isPrinterModalOpen} onClose={() => setIsPrinterModalOpen(false)} fullWidth maxWidth="sm"> |
|
|
|
<DialogTitle sx={{ bgcolor: 'success.main', color: 'white' }}>OnPack Printer Job Details</DialogTitle> |
|
|
|
|