refactor: changes to inventory status (approved/unapprove)
This commit is contained in:
166
resources/js/Pages/Inventory/Count/Print.tsx
Normal file
166
resources/js/Pages/Inventory/Count/Print.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
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>
|
||||
製單人員:系統管理員 印單人員:{doc.created_by}
|
||||
</div>
|
||||
<div>
|
||||
第 1 頁 / 共 1 頁
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user