423 lines
14 KiB
TypeScript
423 lines
14 KiB
TypeScript
/**
|
|
* PDF Generation Utility
|
|
* In a production environment, this would use libraries like jsPDF, PDFKit, or React-PDF
|
|
* For now, we provide a simple text-based PDF generation placeholder
|
|
*/
|
|
|
|
import type { Document, Product } from "@shared/schema";
|
|
|
|
export interface PDFGenerationOptions {
|
|
format?: 'A4' | 'Letter';
|
|
orientation?: 'portrait' | 'landscape';
|
|
margins?: {
|
|
top: number;
|
|
right: number;
|
|
bottom: number;
|
|
left: number;
|
|
};
|
|
}
|
|
|
|
export class PDFGenerator {
|
|
private static formatDate(date: Date | string | null): string {
|
|
if (!date) return 'Unknown';
|
|
const d = typeof date === 'string' ? new Date(date) : date;
|
|
return d.toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
});
|
|
}
|
|
|
|
private static formatTime(date: Date | string | null): string {
|
|
if (!date) return 'Unknown';
|
|
const d = typeof date === 'string' ? new Date(date) : date;
|
|
return d.toLocaleTimeString('en-US', {
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
});
|
|
}
|
|
|
|
static generateDeliveryNote(document: Document, options?: PDFGenerationOptions): string {
|
|
const content = document.content as any;
|
|
const createdDate = this.formatDate(document.createdAt);
|
|
const createdTime = this.formatTime(document.createdAt);
|
|
|
|
return `
|
|
==============================================
|
|
WAREHOUSE TRACK PRO
|
|
==============================================
|
|
|
|
DELIVERY NOTE: ${document.documentNumber}
|
|
Date: ${createdDate} ${createdTime}
|
|
Status: ${document.status.toUpperCase()}
|
|
|
|
----------------------------------------------
|
|
CUSTOMER INFORMATION
|
|
----------------------------------------------
|
|
Name: ${content.customerName || 'N/A'}
|
|
Address: ${content.customerAddress || 'N/A'}
|
|
|
|
----------------------------------------------
|
|
ITEMS
|
|
----------------------------------------------
|
|
${content.items?.map((item: any, index: number) => `
|
|
${index + 1}. ${item.productName} (${item.productSku})
|
|
Quantity: ${item.quantity} ${item.unit}
|
|
${item.notes ? `Notes: ${item.notes}` : ''}
|
|
`).join('') || 'No items listed'}
|
|
|
|
----------------------------------------------
|
|
SUMMARY
|
|
----------------------------------------------
|
|
Total Items: ${content.totalItems || 0}
|
|
Created: ${createdDate} at ${createdTime}
|
|
|
|
----------------------------------------------
|
|
SIGNATURES
|
|
----------------------------------------------
|
|
Driver: _________________________ Date: _______
|
|
|
|
Customer: _______________________ Date: _______
|
|
|
|
==============================================
|
|
Generated by WarehouseTrack Pro
|
|
==============================================
|
|
`;
|
|
}
|
|
|
|
static generatePackingList(document: Document, options?: PDFGenerationOptions): string {
|
|
const content = document.content as any;
|
|
const createdDate = this.formatDate(document.createdAt);
|
|
const createdTime = this.formatTime(document.createdAt);
|
|
|
|
return `
|
|
==============================================
|
|
WAREHOUSE TRACK PRO
|
|
==============================================
|
|
|
|
PACKING LIST: ${document.documentNumber}
|
|
Date: ${createdDate} ${createdTime}
|
|
Status: ${document.status.toUpperCase()}
|
|
|
|
----------------------------------------------
|
|
CUSTOMER INFORMATION
|
|
----------------------------------------------
|
|
Name: ${content.customerName || 'N/A'}
|
|
Address: ${content.customerAddress || 'N/A'}
|
|
|
|
----------------------------------------------
|
|
PACKING DETAILS
|
|
----------------------------------------------
|
|
${content.items?.map((item: any, index: number) => `
|
|
Item ${index + 1}:
|
|
Product: ${item.productName}
|
|
SKU: ${item.productSku}
|
|
Quantity: ${item.quantity} ${item.unit}
|
|
${item.notes ? `Special Instructions: ${item.notes}` : ''}
|
|
|
|
Packed: [ ] Checked: [ ] Initial: _____
|
|
`).join('') || 'No items to pack'}
|
|
|
|
----------------------------------------------
|
|
PACKING SUMMARY
|
|
----------------------------------------------
|
|
Total Items: ${content.totalItems || 0}
|
|
Total Packages: _______________
|
|
Total Weight: _________________
|
|
|
|
----------------------------------------------
|
|
QUALITY CONTROL
|
|
----------------------------------------------
|
|
Packed By: ________________________ Date: _______
|
|
Checked By: _______________________ Date: _______
|
|
Approved By: ______________________ Date: _______
|
|
|
|
==============================================
|
|
Generated by WarehouseTrack Pro
|
|
==============================================
|
|
`;
|
|
}
|
|
|
|
static generateShippingLabel(document: Document, options?: PDFGenerationOptions): string {
|
|
const content = document.content as any;
|
|
const createdDate = this.formatDate(document.createdAt);
|
|
|
|
return `
|
|
==============================================
|
|
SHIPPING LABEL
|
|
==============================================
|
|
|
|
Tracking Number: ${document.documentNumber}
|
|
Date: ${createdDate}
|
|
|
|
----------------------------------------------
|
|
FROM:
|
|
WarehouseTrack Pro
|
|
[Your Warehouse Address]
|
|
[City, State ZIP]
|
|
|
|
----------------------------------------------
|
|
TO:
|
|
${content.customerName || '[Customer Name]'}
|
|
${content.customerAddress || '[Customer Address]'}
|
|
|
|
----------------------------------------------
|
|
PACKAGE DETAILS:
|
|
----------------------------------------------
|
|
Contents: ${content.totalItems || 0} items
|
|
Weight: ________________
|
|
Dimensions: ____________
|
|
|
|
Service Type: [ ] Standard [ ] Express [ ] Overnight
|
|
|
|
----------------------------------------------
|
|
BARCODE AREA
|
|
----------------------------------------------
|
|
||||| ${document.documentNumber} |||||
|
|
|
|
==============================================
|
|
Handle with Care
|
|
==============================================
|
|
`;
|
|
}
|
|
|
|
static generateGoodsReceipt(document: Document, options?: PDFGenerationOptions): string {
|
|
const content = document.content as any;
|
|
const createdDate = this.formatDate(document.createdAt);
|
|
const createdTime = this.formatTime(document.createdAt);
|
|
|
|
return `
|
|
==============================================
|
|
WAREHOUSE TRACK PRO
|
|
==============================================
|
|
|
|
GOODS RECEIPT: ${document.documentNumber}
|
|
Date: ${createdDate} ${createdTime}
|
|
Status: ${document.status.toUpperCase()}
|
|
|
|
----------------------------------------------
|
|
SUPPLIER INFORMATION
|
|
----------------------------------------------
|
|
Name: ${content.customerName || 'N/A'}
|
|
Address: ${content.customerAddress || 'N/A'}
|
|
|
|
----------------------------------------------
|
|
RECEIVED ITEMS
|
|
----------------------------------------------
|
|
${content.items?.map((item: any, index: number) => `
|
|
${index + 1}. ${item.productName} (${item.productSku})
|
|
Expected: ${item.quantity} ${item.unit}
|
|
Received: _______ ${item.unit}
|
|
Condition: [ ] Good [ ] Damaged [ ] Defective
|
|
${item.notes ? `Notes: ${item.notes}` : ''}
|
|
`).join('') || 'No items listed'}
|
|
|
|
----------------------------------------------
|
|
RECEIVING SUMMARY
|
|
----------------------------------------------
|
|
Total Items Expected: ${content.totalItems || 0}
|
|
Total Items Received: ________________
|
|
Discrepancies: _______________________
|
|
|
|
----------------------------------------------
|
|
AUTHORIZATION
|
|
----------------------------------------------
|
|
Received By: ______________________ Date: _______
|
|
Signature: ________________________
|
|
|
|
Checked By: _______________________ Date: _______
|
|
Signature: ________________________
|
|
|
|
==============================================
|
|
Generated by WarehouseTrack Pro
|
|
==============================================
|
|
`;
|
|
}
|
|
|
|
static generateStockReport(document: Document, products?: Product[], options?: PDFGenerationOptions): string {
|
|
const createdDate = this.formatDate(document.createdAt);
|
|
const createdTime = this.formatTime(document.createdAt);
|
|
|
|
const totalValue = products?.reduce((sum, product) => {
|
|
const price = parseFloat(product.price || "0");
|
|
return sum + (price * product.currentStock);
|
|
}, 0) || 0;
|
|
|
|
const inStockCount = products?.filter(p => p.currentStock > p.minThreshold).length || 0;
|
|
const lowStockCount = products?.filter(p => p.currentStock > 0 && p.currentStock <= p.minThreshold).length || 0;
|
|
const outOfStockCount = products?.filter(p => p.currentStock === 0).length || 0;
|
|
|
|
return `
|
|
==============================================
|
|
WAREHOUSE TRACK PRO
|
|
==============================================
|
|
|
|
STOCK REPORT: ${document.documentNumber}
|
|
Generated: ${createdDate} ${createdTime}
|
|
Report Period: Current Inventory Status
|
|
|
|
----------------------------------------------
|
|
INVENTORY SUMMARY
|
|
----------------------------------------------
|
|
Total Products: ${products?.length || 0}
|
|
Total Value: $${totalValue.toFixed(2)}
|
|
|
|
Stock Status:
|
|
In Stock: ${inStockCount}
|
|
Low Stock: ${lowStockCount}
|
|
Out of Stock: ${outOfStockCount}
|
|
|
|
----------------------------------------------
|
|
DETAILED INVENTORY
|
|
----------------------------------------------
|
|
${products?.map((product, index) => {
|
|
const status = product.currentStock === 0 ? 'OUT OF STOCK' :
|
|
product.currentStock <= product.minThreshold ? 'LOW STOCK' : 'IN STOCK';
|
|
const value = (parseFloat(product.price || "0") * product.currentStock).toFixed(2);
|
|
|
|
return `
|
|
${index + 1}. ${product.name}
|
|
SKU: ${product.sku}
|
|
Current Stock: ${product.currentStock} ${product.unit}
|
|
Min Threshold: ${product.minThreshold} ${product.unit}
|
|
Unit Price: $${product.price || '0.00'}
|
|
Total Value: $${value}
|
|
Status: ${status}
|
|
`;
|
|
}).join('') || 'No products in inventory'}
|
|
|
|
----------------------------------------------
|
|
LOW STOCK ALERTS
|
|
----------------------------------------------
|
|
${products?.filter(p => p.currentStock > 0 && p.currentStock <= p.minThreshold).map(product => `
|
|
⚠️ ${product.name} (${product.sku})
|
|
Current: ${product.currentStock} ${product.unit}
|
|
Minimum: ${product.minThreshold} ${product.unit}
|
|
`).join('') || 'No low stock items'}
|
|
|
|
----------------------------------------------
|
|
OUT OF STOCK ITEMS
|
|
----------------------------------------------
|
|
${products?.filter(p => p.currentStock === 0).map(product => `
|
|
❌ ${product.name} (${product.sku})
|
|
Minimum Required: ${product.minThreshold} ${product.unit}
|
|
`).join('') || 'No out of stock items'}
|
|
|
|
==============================================
|
|
Generated by WarehouseTrack Pro
|
|
==============================================
|
|
`;
|
|
}
|
|
|
|
static generateDispatchNote(document: Document, options?: PDFGenerationOptions): string {
|
|
const content = document.content as any;
|
|
const createdDate = this.formatDate(document.createdAt);
|
|
const createdTime = this.formatTime(document.createdAt);
|
|
|
|
return `
|
|
==============================================
|
|
WAREHOUSE TRACK PRO
|
|
==============================================
|
|
|
|
DISPATCH NOTE: ${document.documentNumber}
|
|
Date: ${createdDate} ${createdTime}
|
|
Status: ${document.status.toUpperCase()}
|
|
|
|
----------------------------------------------
|
|
DISPATCH INFORMATION
|
|
----------------------------------------------
|
|
Customer: ${content.customerName || 'N/A'}
|
|
Delivery Address: ${content.customerAddress || 'N/A'}
|
|
|
|
----------------------------------------------
|
|
DISPATCHED ITEMS
|
|
----------------------------------------------
|
|
${content.items?.map((item: any, index: number) => `
|
|
${index + 1}. ${item.productName} (${item.productSku})
|
|
Quantity Dispatched: ${item.quantity} ${item.unit}
|
|
${item.notes ? `Instructions: ${item.notes}` : ''}
|
|
Condition: [ ] Good [ ] Fragile [ ] Hazardous
|
|
`).join('') || 'No items dispatched'}
|
|
|
|
----------------------------------------------
|
|
DISPATCH SUMMARY
|
|
----------------------------------------------
|
|
Total Items: ${content.totalItems || 0}
|
|
Dispatch Time: ${createdTime}
|
|
Expected Delivery: ____________________
|
|
|
|
----------------------------------------------
|
|
TRANSPORTATION DETAILS
|
|
----------------------------------------------
|
|
Vehicle: _____________________________
|
|
Driver: ______________________________
|
|
Contact: _____________________________
|
|
|
|
----------------------------------------------
|
|
AUTHORIZATION
|
|
----------------------------------------------
|
|
Dispatched By: ____________________ Date: _______
|
|
Signature: ________________________
|
|
|
|
Authorized By: ____________________ Date: _______
|
|
Signature: ________________________
|
|
|
|
==============================================
|
|
Generated by WarehouseTrack Pro
|
|
==============================================
|
|
`;
|
|
}
|
|
|
|
static generateDocument(document: Document, products?: Product[], options?: PDFGenerationOptions): string {
|
|
switch (document.type) {
|
|
case 'delivery_note':
|
|
return this.generateDeliveryNote(document, options);
|
|
case 'packing_list':
|
|
return this.generatePackingList(document, options);
|
|
case 'shipping_label':
|
|
return this.generateShippingLabel(document, options);
|
|
case 'goods_receipt':
|
|
return this.generateGoodsReceipt(document, options);
|
|
case 'stock_report':
|
|
return this.generateStockReport(document, products, options);
|
|
case 'dispatch_note':
|
|
return this.generateDispatchNote(document, options);
|
|
default:
|
|
return `
|
|
==============================================
|
|
WAREHOUSE TRACK PRO
|
|
==============================================
|
|
|
|
DOCUMENT: ${document.documentNumber}
|
|
Type: ${document.type}
|
|
Title: ${document.title}
|
|
Date: ${this.formatDate(document.createdAt)}
|
|
Status: ${document.status.toUpperCase()}
|
|
|
|
Content:
|
|
${JSON.stringify(document.content, null, 2)}
|
|
|
|
==============================================
|
|
Generated by WarehouseTrack Pro
|
|
==============================================
|
|
`;
|
|
}
|
|
}
|
|
|
|
static async downloadPDF(doc: Document, products?: Product[], options?: PDFGenerationOptions): Promise<void> {
|
|
const pdfContent = this.generateDocument(doc, products, options);
|
|
|
|
const blob = new Blob([pdfContent], { type: 'text/plain' });
|
|
const url = window.URL.createObjectURL(blob);
|
|
const a = window.document.createElement('a');
|
|
a.href = url;
|
|
a.download = `${doc.documentNumber}.pdf`;
|
|
window.document.body.appendChild(a);
|
|
a.click();
|
|
window.URL.revokeObjectURL(url);
|
|
window.document.body.removeChild(a);
|
|
}
|
|
}
|
|
|
|
export default PDFGenerator;
|