First template code generated from replit.com
This commit is contained in:
422
client/src/lib/pdf-generator.ts
Normal file
422
client/src/lib/pdf-generator.ts
Normal file
@@ -0,0 +1,422 @@
|
||||
/**
|
||||
* 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;
|
||||
Reference in New Issue
Block a user