Commit graph

9 commits

Author SHA1 Message Date
ff58af7586 fix(pdf): render through renderToBuffer, not pdf().toString()
Every renderer funneled the PDF through a JS string and re-encoded it as
latin1. Three separate problems, only the first of which was ever real:

  1. `pdf(el).toBuffer()` is NOT the buffer API — it resolves to the PDFKit
     *stream* (react-pdf carries a TODO to rename it `toStream`), and under
     jsdom it resolves to a bare PDFDocument handle. That is the jsdom
     breakage an old comment described, but it applies to that method, not
     to the module-level `renderToBuffer()` helper.
  2. `toString()` renders with `compress: false`. react-pdf's own source
     says why: "when rendering to string if compress=true the document is
     blank". The method is flagged upstream as buggy (#2112, #2095).
  3. The string round-trip mangles binary streams. Text is ASCII in the
     content stream so it survives; a raster image is a compressed blob
     that does not — the image object lands in the file but is never
     painted. Poppler was already reporting "Bad FCHECK in flate stream".

It stayed latent because the only image in these documents is the letterhead
logo, and that logo is an SVG. SVG is text, so it round-tripped perfectly and
hid the whole thing. `0xFD` in the old comments is the fingerprint: latin1's
truncation of U+FFFD, the Unicode replacement char.

`renderToBuffer()` fixes all three in a single pass and works under jsdom, so
no fallback is needed. Note you cannot "try toBuffer, fall back to toString" —
calling `toBuffer()` first consumes the render and a later `toString()` on the
same instance returns a document with the content missing.

Three more instances of the same pattern lived outside render.tsx and are fixed
here too: the print-bundle, delivery-note-print and picking-slip routes.

`render-image-pipeline.test.ts` is the regression guard. Its size assertion is
expressed against the old uncompressed baseline rather than a round number
picked when the document was smaller — an absolute byte count is a tripwire
that fires on every feature addition, which is how a real regression gets
tuned away. Guard verified by reintroducing the old path: 2 tests fail.
2026-10-04 13:14:59 +02:00
7555196166 feat(audit): implement audit trail for delivery notes and orders
- Added an audit trail feature that logs every create, update, and delete action on delivery notes and orders, capturing detailed changes per field.
- Introduced the `AuditTimeline` component to display the history of changes for delivery notes and orders, enhancing traceability.
- Updated the `page.tsx` files for delivery notes and orders to fetch and display audit logs, ensuring users can view the history of modifications.
- Enhanced the `package.json` with a new migration script for setting up the audit log functionality.

This feature improves accountability and transparency in the management of delivery notes and orders.
2026-09-30 01:48:44 +02:00
Dave
6344948b0b feat: add driverless collection confirm and new order tooling
This commit adds several key features, improvements, and cleanups across the codebase:
- Add `order_items.confirm_collected` MCP/REST endpoint to mark order items as collected without requiring driver assignment
- Add standalone order creation and order split APIs for flexible order management
- Update order list sort to oldest-first to align with user workflow of working through oldest orders first
- Improve order search to show cross-tab matches and display source tab indicators on search results
- Add customer name similarity check to warn about mismatched QuickBooks customers during invoice creation
- Remove supplier name column from delivery note PDFs and clean up related data passing across delivery note routes
- Add validation and debug logging to ItemIntelPopover for missing item ID on apply actions
- Remove unused OrderItemContextPopoverTrigger component from order detail page
- Add delivery note regeneration script and update test suites for new and existing functionality
- Update documentation and add test coverage for the new collection confirm tool
2026-08-12 01:13:46 +02:00
SJCoetz
45f1ec6bb7 feat(pdf): list-pdf documents for stock orders + stocktake
Two new @react-pdf/renderer documents backed by renderStockPurchaseListPdf
and renderStockItemStocktakePdf in render.tsx. The Orders PDF mirrors
the on-screen table; the Stocktake PDF adds a blank 'Actual' column
for the operator to fill in during the walk-through. Both inherit
the toString() → Buffer pattern so they run under the same jsdom
test setup as the other PDF renderers.

Co-authored-by: Orca <help@stably.ai>
2026-08-03 16:13:14 +02:00
SJCoetz
ae88a2f3bc feat(invoicing): add complete delivery note workflow
This commit adds the full end-to-end delivery note workflow for the invoicing system:
- Added `letterheadForCompany` utility to infer the correct letterhead from a company name
- Created the DeliveryNoteDocument PDF component and server-side render function
- Added API endpoints for delivery note creation, PDF retrieval, printing, and print tracking
- Updated the PickingSlip component to support both invoice and delivery note headers
- Added view models for grouping, filtering, and displaying delivery note items
- Updated AGENTS.md with PocketBase schema and attachment best practices for new workflows
- Added comprehensive test coverage for all new components and API routes
2026-07-14 17:35:36 +02:00
SJCoetz
9cdcb3b096 feat: implement sku-based catalogue pricing matching workflow
This commit adds the full end-to-end SKU pricing match flow for quote items:
- Add new QuoteItem and PriceListRow fields for SKU and pricing metadata
- Add sku_normalised to price_list for robust format-agnostic SKU matching
- Refactor price list search to use modular search builder and filter helpers
- Add database migrations, backfill scripts, and new package commands
- Update catalogue search UI and fix quote list accidental click behavior
- Add comprehensive unit, smoke, and end-to-end test suites
- Update documentation for the new price search and extraction logic
2026-06-30 21:20:53 +02:00
SJCoetz
6c07a91693 refactor: drop order-level status, shift to item-driven workflow
This commit overhauls the order management system to use item-level status tracking instead of a single order-level status:
- Remove deprecated `orders.status` field and add `invoiced` and quote match audit fields
- Add `isOrderComplete` utility with tests to validate fully delivered orders
- Add purchase order PDF rendering support and tooling
- Add geo coordinate fields for companies/customers with map link UI
- Add REST management APIs for customers, companies, and suppliers
- Update customer/company services to use relation fields instead of free text
- Add status pill and tab filter components for item status visualization
- Add quote-to-order matching logic and unit tests
- Update all pages, components, and tests to match the new schema
- Include all required PocketBase migrations and schema updates
2026-06-29 13:06:01 +02:00
SJCoetz
588e9762c2 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 22:57:01 +02:00
SJCoetz
714e910949 feat: add branded quote PDF generation and in-app viewer
This commit adds full quote PDF generation functionality with per-company letterhead branding:
- Server-side PDF rendering using @react-pdf/renderer matching the sample quote layout
- In-app modal PDF viewer with print, download, and new-tab controls
- Letterhead service to fetch and apply company-specific branding (CNL/ISHERWOOD)
- ZAR currency and date formatting utilities for South African quotes
- Updated QuoteAttachment type to handle PocketBase's array-based file tokens
- Fixed PocketBase attachment URL generation in quote email card
- Removed deprecated `included_in_quote` field from QuoteItem and quotes service
- Updated quote item creation test to validate draft item logic
- Added comprehensive unit tests for PDF rendering and formatting helpers
- Added dev scripts for debugging PDF and image rendering issues
- Added sample generated PDF files for visual verification
- Updated tsconfig to exclude development scripts directory
- Added @react-pdf/renderer production dependency
- Removed JEI as a valid letterhead option per requirements
2026-06-23 08:30:38 +02:00