2026-06-23 06:30:38 +00:00
/* eslint-disable */
// Sample PDF generators for visual verification. Logos are loaded as
// SVG data URIs from `public/letterhead/{cnl,isherwood}.svg` (see
// `loadLetterheadLogoDataUri` in src/lib/letterhead.ts). We use SVG
// instead of the original raster (PNG/JPEG) logos because @react-pdf
// v4.5.1 corrupts any byte ≥ 0x80 in raster image data; SVG is text
// and sidesteps that code path entirely.
import { renderQuotePdf } from "@/lib/pdf/render" ;
import { loadLetterheadLogoDataUri } from "@/lib/letterhead" ;
import type { Letterhead } from "@/lib/letterhead" ;
import type { Customer , Quote , QuoteItem } from "@/lib/types" ;
import fs from "fs" ;
import path from "path" ;
async function main() {
const outDir = path . join ( "/Volumes/EXT/DEVELOPMENT/WFDASH_NEXTJS/docs/example-quotes" ) ;
const baseItem = {
created : "2026-06-22T13:40:00Z" ,
updated : "2026-06-22T13:40:00Z" ,
collectionId : "pbc_quote_items" ,
collectionName : "quote_items" ,
quote_number : "Q009638" ,
quote_reference : "" ,
quantity : 1 ,
supplier : "" ,
cost_price : 0 ,
notes : "" ,
is_processed : true ,
markup : 0 ,
quote_pdf_id : "" ,
user_edited : true ,
} ;
const cnlLh : Letterhead = {
id : "lh1" , collectionId : "pbc_1010367695" , collectionName : "letterhead_settings" ,
created : "2026-06-22T20:31:27.165Z" , updated : "2026-06-22T20:31:27.165Z" ,
display_name : "CNL Mining Supplies" ,
address : "47 Station Street\nCarletonville, Gauteng 2499" ,
phone : "+27 18 786 2897" , email : "quotes@wfsales.co.za" ,
vat_number : "4840229449" , registration_number : "2014/004024/07" ,
bank_name : "Standard Bank - Carletonville" ,
bank_account_number : "Current Account\n022196552" ,
bank_branch_code : "016141" ,
terms : "Terms and Conditions:\n1. This quotation is valid for 30 days from the date of issue.\n2. Prices are quoted excluding VAT unless otherwise stated.\n3. Lead time will be confirmed upon receipt of order." ,
default_markup_percent : 30 , footer_text : "" , logo : "" ,
is_active : true , company : "CNL Mining Supplies (Pty) Ltd" , accent_color : "#738224" ,
} ;
const isherwoodLh : Letterhead = {
. . . cnlLh ,
display_name : "ISHERWOOD MINING SUPPLIES" ,
vat_number : "4590136331" ,
registration_number : "" ,
bank_account_number : "Current Account\n02 290 746 7" ,
accent_color : "#7ed957" ,
terms : "Terms and Conditions:\n1. This quotation is valid for 30 days from the date of issue.\n2. Prices are quoted excluding VAT unless otherwise stated.\n3. Lead time will be confirmed upon receipt of order.\n4. Isherwood Mining Supplies standard terms apply to all orders." ,
} ;
const cust : Customer = {
id : "cust1" , collectionId : "pbc_customers" , collectionName : "customers" ,
created : "2026-06-22T00:00:00Z" , updated : "2026-06-22T00:00:00Z" ,
customer : "Cash Sales" , email : "james@microntec.co.za" ,
alternative_email : "" , buyer_email : "" , number : "0615829016" ,
company : "" , dateadded : "" , lastvisiteddate : "" , rep : "" ,
coordinates : "" , description : "" ,
} ;
const q : Quote = {
id : "q1" , collectionId : "pbc_quotes" , collectionName : "quotes" ,
created : "2026-06-22T13:40:00Z" , updated : "2026-06-22T13:40:00Z" ,
quote_number : "Q009638" , quote_reference : "" , external_number : "" ,
rfq_number : "" , markup : 0 , customer : "cust1" , company : "" , claimed_by : "" ,
description : "" , status : "new" , approved_by : "" , notes : "" ,
email_sender : "" , email_subject : "" , email_body : "" , has_attachments : false ,
company_letterhead : "CNL" , email_delivered : false , email_delivered_at : "" ,
email_received_at : "" , email_opened : false , email_opened_at : "" ,
email_tracking_id : "" , has_new_reply : false , last_reply_at : "" ,
email_failed_at : "" , pdf_generated_at : "" , email_message_id : "" ,
feat: add quote templates, improved email, new statuses
Add complete quote template functionality, enhanced outbound email sending, new quote statuses, and supporting infrastructure:
- Add new quote statuses (template, sending, mail_failed) with tailored UI styling for status pills
- Implement full template workflows: save real quotes as templates, create new quotes from existing templates
- Add support for custom quote dates and extended validity periods on generated PDF documents
- Build out improved email pipeline with persisted compose fields and retry functionality for failed sends
- Add attachment direction tracking to categorize inbound, outbound, and generated quote attachments
- Fix tooltip component to properly handle Radix `asChild` prop to avoid React DOM attribute errors
- Add comprehensive test coverage, schema migrations, and update sample test and production data
2026-06-24 20:57:01 +00:00
// Exercise the backdate + extended-validity features so the
// sample doubles as a smoke test for the new fields.
quote_date : "2026-06-15T00:00:00.000Z" ,
validity_days : 60 ,
is_template : false ,
template_source_id : "" ,
generated_from_template_id : "" ,
follow_up_due : "" ,
2026-06-23 06:30:38 +00:00
} ;
const items : QuoteItem [ ] = [
{ . . . baseItem , id : "qi1" , quote : "q1" , description : "JEICS30 SLUGGER M2-AL HSS" , selling_price : 648.7 , included_in_quote : true } as unknown as QuoteItem ,
{ . . . baseItem , id : "qi2" , quote : "q1" , description : "JEIPILOT 1" , selling_price : 88.36 , included_in_quote : true } as unknown as QuoteItem ,
] ;
const cnlLogo = await loadLetterheadLogoDataUri ( "CNL" ) ;
const isherwoodLogo = await loadLetterheadLogoDataUri ( "ISHERWOOD" ) ;
if ( ! cnlLogo ) throw new Error ( "CNL logo missing from public/letterhead/cnl.svg" ) ;
if ( ! isherwoodLogo ) throw new Error ( "ISHERWOOD logo missing from public/letterhead/isherwood.svg" ) ;
const cnl = await renderQuotePdf ( { quote : q , items , customer : cust , letterhead : cnlLh , logoDataUri : cnlLogo } ) ;
fs . writeFileSync ( path . join ( outDir , "sample-cnl.pdf" ) , cnl ) ;
console . log ( ` CNL: ${ cnl . length } bytes → sample-cnl.pdf ` ) ;
const ish = await renderQuotePdf ( { quote : q , items , customer : cust , letterhead : isherwoodLh , logoDataUri : isherwoodLogo } ) ;
fs . writeFileSync ( path . join ( outDir , "sample-isherwood.pdf" ) , ish ) ;
console . log ( ` Isherwood: ${ ish . length } bytes → sample-isherwood.pdf ` ) ;
}
main ( ) . catch ( ( err ) = > {
console . error ( "FAIL:" , err ) ;
process . exit ( 1 ) ;
} ) ;