Files
star-erp/resources/js/Pages/Inventory/Count/Print.tsx
sky121113 56e30a85bb
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 1m6s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped
refactor: changes to inventory status (approved/unapprove)
2026-01-29 13:04:54 +08:00

167 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useRef } from 'react';
import { Head } from '@inertiajs/react';
import JsBarcode from 'jsbarcode';
interface PrintProps {
doc: {
doc_no: string;
warehouse_name: string;
snapshot_date: string;
created_at: string;
print_date: string;
created_by: string;
items: Array<{
id: string;
product_name: string;
product_code: string;
specification: string;
unit: string;
quantity: number;
counted_qty: number | null;
notes: string;
}>;
};
}
export default function Print({ doc }: PrintProps) {
const barcodeRef = useRef<SVGSVGElement>(null);
useEffect(() => {
if (barcodeRef.current) {
try {
JsBarcode(barcodeRef.current, doc.doc_no, {
format: "CODE128",
width: 2, // Thicker bars for better scanning
height: 50, // Taller
displayValue: false,
margin: 10, // Mandatory quiet zone for scanners
marginBottom: 5
});
} catch (e) {
console.error("Barcode generation failed", e);
}
}
// Delay print slightly to ensure render
const timer = setTimeout(() => {
window.print();
}, 500);
return () => clearTimeout(timer);
}, [doc.doc_no]);
return (
<div className="bg-white text-black font-sans text-sm min-h-screen">
<Head title={`列印盤點單 ${doc.doc_no}`} />
<style>{`
@media print {
@page {
size: A4 landscape;
margin: 10mm;
}
body {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
/* Hide browser default header/footer if possible (browser dependent) */
}
`}</style>
{/* Header Section */}
<div className="relative mb-6">
{/* Barcode - Top Right */}
<div className="absolute top-0 right-0 flex flex-col items-end">
<svg ref={barcodeRef}></svg>
{/* <span className="text-xs font-mono mt-1">{doc.doc_no}</span> */}
</div>
{/* Company & Title - Center */}
<div className="text-center pt-4">
<h1 className="text-2xl font-bold tracking-widest mb-2"></h1>
<h2 className="text-xl font-bold tracking-widest"></h2>
</div>
</div>
{/* Info Section */}
<div className="flex justify-between items-end mb-2 border-b-2 border-black pb-2">
<div className="space-y-1">
<div className="flex gap-4">
<span className="font-bold"></span>
<span className="font-mono font-bold">{doc.doc_no}</span>
</div>
<div className="flex gap-4">
<span className="font-bold"></span>
<span>{doc.created_at}</span>
</div>
<div className="flex gap-4">
<span className="font-bold"></span>
<span>{doc.warehouse_name}</span>
</div>
</div>
<div className="text-right">
<div className="flex gap-4">
<span className="font-bold"></span>
<span>{doc.print_date}</span>
</div>
</div>
</div>
{/* Table Section */}
<table className="w-full border-collapse border border-black mb-8">
<thead>
<tr className="bg-gray-100">
<th className="border border-black px-2 py-1 w-12 text-center"></th>
<th className="border border-black px-2 py-1 w-32 text-left"></th>
<th className="border border-black px-2 py-1 text-left"></th>
<th className="border border-black px-2 py-1 w-32 text-left"></th>
<th className="border border-black px-2 py-1 w-20 text-right"></th>
<th className="border border-black px-2 py-1 w-16 text-center"></th>
<th className="border border-black px-2 py-1 w-32 text-left"></th>
</tr>
</thead>
<tbody>
{doc.items.map((item, index) => (
<tr key={item.id}>
<td className="border border-black px-2 py-2 text-center">{index + 1}</td>
<td className="border border-black px-2 py-2 font-mono">{item.product_code}</td>
<td className="border border-black px-2 py-2">{item.product_name}</td>
<td className="border border-black px-2 py-2">{item.specification || '-'}</td>
<td className="border border-black px-2 py-2 text-right">
{item.counted_qty !== null ? Number(item.counted_qty).toFixed(2) : ''}
</td>
<td className="border border-black px-2 py-2 text-center">{item.unit || '-'}</td>
<td className="border border-black px-2 py-2">{item.notes}</td>
</tr>
))}
{/* Empty rows filler if needed, but usually not required unless strictly paging */}
</tbody>
</table>
{/* Footer Section */}
<div className="fixed bottom-0 w-full mb-4">
<div className="flex justify-between items-end px-4">
<div className="w-1/3 border-b border-black pb-1 mb-1">
<span className="font-bold"></span>
<span className="ml-2">{doc.created_by}</span>
</div>
<div className="w-1/3 border-b border-black pb-1 mb-1 mx-4">
<span className="font-bold"></span>
</div>
<div className="w-1/3 border-b border-black pb-1 mb-1">
<span className="font-bold"></span>
</div>
</div>
<div className="flex justify-between items-center text-xs mt-4 px-4">
<div>
&nbsp;&nbsp; {doc.created_by}
</div>
<div>
1 / 1
</div>
</div>
</div>
</div>
);
}