The original Stocktake PDF columns (Name, SKU, Location, Unit,
Current qty, blank Actual, Supplier) didn't match what the
operator sees on /stock. They pointed at the wrong list — they
worked for a blank-column walk-through stocktake form, but the
user wants to print the /stock list as it appears on screen.
This rewrite makes the Stocktake PDF mirror the /stock table
column-for-column:
- SKU, Name, Supplier, Current, Min, Target, Location, Status
- Status derived via getStockStatus + STOCK_STATUS_STYLES so
it matches the on-screen badge label
- Current qty now renders with the unit suffix (matching the
on-screen cell)
- Target renders '—' when null/undefined/0, matching /stock
Also:
- Switched to landscape A4 to give 8 columns room (was
portrait).
- Added a copy of the 'Download Stocktake PDF' button on the
/stock page next to 'New stock item' — both /stock and
/stock-orders now expose the same endpoint. Button uses the
same plain <a target='_blank' rel='noopener'> pattern as
the existing stock-orders buttons, with aria-hidden on the
Download icon.
- Added a test on /stock for the new link (href, target,
rel). 33/33 tests pass.
Co-authored-by: Orca <help@stably.ai>
Move the thead <View> out of the table and onto the page itself
with the @react-pdf/renderer 'fixed' prop, so reports that span
multiple A4 pages still label their columns. Without this, page 2+
of a long stock-orders report or stocktake would show data without
column headers — making the right-hand 'Actual' column on the
stocktake and the value columns on the orders list unreadable.
Co-authored-by: Orca <help@stably.ai>
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>
Add complete stock purchase order workflow including:
- Status tracking with sending/mail_failed states and UI labels
- Server-side PDF rendering and document storage
- File proxy API support for stock PO attachments
- Send outcome webhook callback for email notifications
Add driver app support:
- Unified stop list API for both customer deliveries and stock pickups
- Status update endpoint for collected quantities and problem reporting
- Collection map page support for stock pickup locations
Include matching PocketBase migrations, type definitions, and stock inventory fulfillment logic.
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
Overhaul the app's color system by replacing all hardcoded Tailwind color classes with semantic theme variables to ensure consistent theming across all components, pages, and tests.
Additional changes:
- Add assigned date support for order item status updates: add `assignedDate` field to the order item status PATCH API, implement server-side normalization/validation, and add corresponding tests
- Refactor purchase order PDF workflows to use the consolidated `purchase_orders.documents` field instead of the legacy separate `purchase_order_pdfs` collection
- Fix quote number parsing and formatting to support both dashed (Q-YYYY-MM-NNN) and dashless (QYYYYMMNNN) formats
- Rename `driver_pool` item status to `collection_pool` across the codebase
- Add null handling for order item quantities and pricing to display "—" for missing values
- Improve filter tab styling: make mobile tabs scrollable, prevent text wrapping, hide scrollbar
- Add new utility scripts, API routes, migrations, and polish small UI/UX fixes including tsconfig updates and theme hook improvements
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
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
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
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