Commit graph

470 commits

Author SHA1 Message Date
Dave
bfcddb9d82 feat(quote-form): allow empty quantity input for operator convenience
- Updated the `DraftQuoteItem` interface to allow `quantity` to be an empty string, enabling operators to type counts directly without needing to delete a default value.
- Modified the `QuoteFormItemCard` to handle empty input gracefully, falling back to 1 on submission if the field is left blank.
- Adjusted the `addItem` function in `QuoteForm` to initialize `quantity` as an empty string, enhancing user experience during item addition.
2026-08-18 07:28:25 +02:00
Dave
8ed0952364 refactor(forms): update layout and structure of form components
- Adjusted the `SheetContent` width in multiple form components to improve responsiveness.
- Enhanced the `CompanyForm` layout by reorganizing fields for better clarity and usability, including the addition of coordinates input.
- Updated the `CustomerForm` and `SupplierForm` to maintain consistency in design and structure.
- Improved the `DataTable` component's card styling for better visual appeal and user interaction.
- Refined the `QuotesPage` card styling to enhance the user experience when selecting quotes.
2026-08-17 23:34:30 +02:00
Dave
0b6171b851 feat(collection-pool): enhance stock row handling and filtering logic
- Added `drv_id` to the stock row data structure to ensure proper assignment tracking.
- Implemented a new `isReadyForCollection` function to streamline the logic for determining if stock rows are ready for collection.
- Updated the `buildVisibleRows` function to utilize the new readiness check, improving the accuracy of row filtering based on the ready status.
- Added a test case to verify that stock rows are correctly included in the ready filter, ensuring expected behavior in the collection pool view.
- Enhanced coordinate parsing logic to handle various input formats, improving robustness in the driver stops API.
2026-08-17 22:33:47 +02:00
Dave
519fb422ae fix(pdf): adjust totals alignment in quote document
- Updated the `totals` style in the PDF generation to ensure totals are pushed to the right edge of the totals row, regardless of the presence of the operator note. This prevents shifting when the note is empty, enhancing the layout consistency.
2026-08-17 15:44:21 +02:00
Dave
50944a3526 feat(quotes): add operator-facing notes functionality to quotes
- Introduced a new `quote_notes` field to store operator-facing free-text notes, distinct from the existing `notes` field used for rejection audit logs.
- Updated the quote processing page to include a `QuoteNoteCard` for editing and displaying the operator notes, ensuring seamless integration into the PDF generation flow.
- Enhanced the PDF generation logic to render the operator notes in a blue callout below the totals, improving visibility for end-users.
- Implemented a new service function `setQuoteNotes` to handle the saving of notes, including trimming whitespace and handling non-string inputs defensively.
- Added unit tests for the `setQuoteNotes` function to ensure correct behavior and data integrity when updating notes.
- Updated relevant types and documentation to reflect the new functionality and its intended use cases.
2026-08-17 15:22:16 +02:00
Dave
9e8bb0a1ad feat(order-splitting): enhance order item splitting functionality and error handling
- Implemented a new split mechanism for order items, allowing operators to split quantities based on in-stock and non-in-stock statuses.
- Updated the payload for creating split order items to ensure it adheres to the PocketBase schema, avoiding empty strings for relation fields and removing deprecated fields.
- Enhanced error handling in the split route to log unexpected errors for better debugging.
- Improved the UI to conditionally render split buttons based on item availability, ensuring a clearer user experience.
- Added unit tests to validate the new splitting logic and payload structure, ensuring robustness against schema changes.
2026-08-17 14:14:27 +02:00
Dave
437ed3529c feat(collection-confirm): implement confirmation dialog for stock collection
- Introduced a new `ConfirmStockDialog` to handle stock collection confirmations, allowing operators to review per-line quantities and any short lines before finalizing the action.
- Updated the `CollectionConfirmPage` to manage the new confirmation state and trigger the dialog upon clicking the "Confirm collection" button.
- Enhanced tests to cover the new dialog functionality, ensuring correct behavior for both full and short quantity lines during the confirmation process.
- Improved documentation to clarify the flow and user interactions with the new confirmation dialog.
2026-08-17 11:41:55 +02:00
Dave
d29b91c7c0 feat(collection-confirm): update stock item filtering logic in listCollectedItems
- Modified the filter criteria in the `listCollectedItems` function to exclude stock lines that have been fully received, ensuring only pending items are displayed.
- Updated related tests to reflect the new filtering logic, enhancing clarity on the conditions under which stock items are included in the list.
- Improved documentation comments to explain the filtering behavior and its implications for the stock confirmation process.
2026-08-17 08:27:36 +02:00
Dave
9d80d52c17 feat(collection-confirm): improve idempotency handling in stock confirmation
- Updated the `confirmStockRows` function to handle cases where a stock line is already fully received, returning a success response without throwing an error. This change prevents the confirm-stock button from becoming inoperable due to previous confirmations.
- Enhanced tests to verify the new behavior, ensuring that full-quantity rows are omitted from updates and partial rows are processed correctly.
- Added documentation to clarify the idempotency behavior and its implications for the stock confirmation process.
2026-08-17 08:19:38 +02:00
Dave
fc55613070 feat(collection-confirm): add quantity editing tests for order items and stock sources
- Implemented tests for quantity editing functionality, ensuring that pressing Enter updates the quantity for order items and stock sources correctly.
- Added validation for input errors, rejecting fractions and negatives with appropriate inline error messages.
- Enhanced test coverage for the quantity handling logic, confirming correct API calls and data submissions for both customer and stock items.
2026-08-17 07:21:50 +02:00
Dave
d0fb8e81f0 feat(collection-confirm): add quantity collection handling and deduplication improvements
- Introduced a new `handleQtyChange` function to manage per-row quantity updates for both customer and stock items, ensuring correct data submission to the appropriate endpoints.
- Enhanced the `dedupeAttachments` function to handle additional document sources, including parent purchase orders, and skip empty filenames to prevent 404 errors.
- Updated the `ItemsTable` and `PoCard` components to support quantity editing, allowing users to modify collected quantities directly in the UI.
- Added tests to validate the new quantity handling logic and attachment deduplication, ensuring robust functionality across various scenarios.
2026-08-17 02:17:27 +02:00
Dave
4a59288a01 feat(deliveries): enhance delivery notes management and UI
- Introduced a new `DeliveryNoteRow` type to track delivery notes alongside items, improving the organization of delivery data.
- Updated the `DeliveryListResponse` type to include delivery notes, allowing for better integration with the existing delivery management system.
- Enhanced the `groupByCustomerOrder` function to accommodate delivery notes, ensuring they are grouped correctly with their respective orders.
- Implemented state management for delivery notes in the `DeliveriesPage` component, including loading and error handling.
- Added search functionality for delivery notes, enabling operators to filter by delivery note number, customer PO, and order details.
- Updated the UI to display delivery notes alongside items, improving the overall user experience in the deliveries management interface.
- Enhanced tests to cover new delivery notes functionality and ensure correct behavior across various scenarios.
2026-08-17 01:27:03 +02:00
Dave
1640c1e09a feat(delivery-notes): implement QuickBooks invoice auto-close functionality
- Added a new service function `markDeliveryNoteCompletedByInvoice` to auto-close delivery notes after successful QuickBooks invoice creation, updating the status to "completed" and appending an audit banner to the notes.
- Enhanced the delivery note detail page with a modal for creating invoices via QuickBooks, including customer selection and billing company options.
- Implemented state management for the invoice modal, including loading states and error handling for customer fetching.
- Updated tests to cover the new auto-close functionality and ensure correct behavior across various scenarios.
- Improved documentation for the delivery notes service to reflect the new functionality and its usage.
2026-08-16 22:24:08 +02:00
Dave
426bcb188a feat(duplicate-orders): refine duplicate order detection logic and UI enhancements
- Improved the `DuplicateOrdersDialog` component with better tab navigation for order number and line aggregate views.
- Enhanced the data structure for duplicate records to include `totalQuantity` and `totalSellingPrice` for more accurate detection.
- Implemented auto-flipping logic to ensure users see relevant content without encountering empty views.
- Expanded test coverage for the `findDuplicateOrders` function to validate new matching logic.
- Updated documentation to clarify duplicate identification criteria.
2026-08-16 16:27:45 +02:00
Dave
46e0683635 feat(duplicate-orders): enhance duplicate order detection and UI
- Introduced a new `DuplicateKind` type to differentiate between "order_number" and "line_aggregate" duplicates.
- Updated the `DuplicateOrdersDialog` component to support tabbed navigation between order number and line aggregate views, improving user experience.
- Enhanced the data structure for duplicate records to include `totalQuantity` and `totalSellingPrice`, facilitating more accurate duplicate detection.
- Implemented logic to auto-flip to the tab with available content, ensuring operators do not encounter empty views.
- Expanded test coverage for the `findDuplicateOrders` function to validate new line-aggregate matching logic and ensure accurate detection of duplicates across different scenarios.
- Improved documentation for the duplicate order handling process, clarifying the criteria for identifying duplicates.
2026-08-16 11:25:00 +02:00
Dave
17580b5280 feat(invoicing): implement detailed view toggle for supplier and PO number
- Added a switch to toggle the visibility of supplier names and PO numbers in the invoicing page, enhancing user experience by allowing operators to view detailed information as needed.
- Updated the `RowIdentity` component to conditionally render supplier and PO details based on the toggle state.
- Introduced localStorage persistence for the detailed view preference, ensuring user settings are retained across sessions.
- Enhanced tests to verify the functionality of the detailed view toggle and its impact on displayed data.
2026-08-16 11:01:52 +02:00
Dave
1bc80dc686 feat(orders): enhance order retrieval and statistics functionality
- Updated the `GET /api/v1/orders` endpoint to support additional query parameters including `customer`, `createdAfter`, `createdBefore`, and `status`, allowing for more granular order filtering.
- Implemented logic to resolve customer IDs from names and aggregate order items by their statuses for improved data retrieval.
- Introduced new helper functions in `orders-service.ts` for fetching order statistics and daily summaries, enhancing reporting capabilities.
- Added comprehensive documentation for the new query parameters and their usage in the API documentation.
- Improved error handling for invalid customer and status inputs, ensuring clearer feedback for API consumers.
2026-08-16 00:51:24 +02:00
Dave
cf87a370cf feat(quotes): enhance quotes.submit functionality and error handling
- Updated the `quotes.submit` tool to allow submission of quotes with unpriced items by introducing a `partial: true` flag, transitioning the quote to `partial_approval_pending` instead of `approval_pending`.
- Enhanced the response structure of `submitQuote` to include `previousStatus`, `submittedAt`, and `targetStatus`, providing better context for the agent.
- Improved error handling in the `sendQuoteEmail` function to surface detailed readiness issues when a PDF cannot be generated, allowing operators to address specific gaps in quote items.
- Regenerated API documentation in `docs/api-mcp-layer.md` to reflect these changes, ensuring accuracy and clarity in tool descriptions.
- Added comprehensive tests to validate the new functionality and error handling improvements.
2026-08-15 23:57:51 +02:00
Dave
e5e31a7bdc feat(mcp): implement upstream origin resolution for internal API calls
- Added a new `upstreamOrigin` function to resolve the correct upstream API origin for internal MCP to REST calls, addressing issues with container deployments where `req.nextUrl.origin` resolves incorrectly.
- The function prioritizes environment variables for configuration, ensuring proper routing in various deployment scenarios.
- Updated multiple API fetch calls to utilize the new `upstreamOrigin` function, improving reliability and consistency in internal API interactions.
2026-08-15 23:22:19 +02:00
Dave
e7672ab7c9 feat(mcp): implement structured MCP error handling for upstream fetches
- Introduced structured error handling for MCP upstream fetches, distinguishing between network errors (`-32010`) and upstream errors (`-32011`). This allows the agent to provide more informative feedback based on the type of failure encountered.
- Updated the `fetchUpstreamJson` function to throw `McpUpstreamError` with detailed error data, including hints and next actions for specific tools.
- Enhanced the `TOOL_HINTS` mapping to provide tool-specific guidance for handling errors, improving the agent's ability to respond to various failure scenarios.
- Added comprehensive unit tests to validate the new error handling logic and ensure correct behavior across different error cases.
- Updated documentation in `docs/agents/hermes-skill.md` to include a new section on structured MCP errors, detailing the error codes and their meanings.
2026-08-15 22:32:11 +02:00
Dave
151ae8d67f feat(quotes): introduce quotes.submit tool for approval transition
- Added a new `quotes.submit` tool that transitions a quote from `new` to `approval_pending` once all line items are priced. This tool ensures that only fully priced quotes can be submitted for approval, enhancing the integrity of the approval process.
- Updated the API documentation in `docs/api-mcp-layer.md` to include the new `quotes.submit` tool and its usage details.
- Enhanced the `quotes` status enum in `docs/agents/hermes-skill.md` to reflect the new transition and its implications.
- Regenerated documentation to ensure accuracy, increasing the total tool count from 126 to 127.
- Added comprehensive tests for the `submitQuote` function to cover various scenarios, including idempotency and error handling for unpriced items.
2026-08-15 19:01:52 +02:00
Dave
c4b53bcc4b feat(mcp): add walk-in quote creation and enhance customer filtering
- Introduced a new `quotes.create` tool for creating quotes from scratch without an inbound email, allowing operators to generate quotes directly from the dashboard.
- Updated `customers.list` to support filtering by representative using either a 15-char PB user ID or a case-insensitive name/email match.
- Enhanced API documentation in `docs/api-mcp-layer.md` to reflect the addition of the new quote creation tool and updated customer filtering capabilities.
- Regenerated documentation to ensure accuracy, increasing the total tool count from 125 to 126.
2026-08-15 11:50:48 +02:00
Dave
80a08a742b feat(mcp): enhance API documentation and add new tools
- Updated `docs/api-mcp-layer.md` to reflect the current state of the API, including new endpoints and tools.
- Added `category` field to `QUOTE_ITEM_PATCH_FIELDS` and `ORDER_ITEM_PATCH_FIELDS` to support item categorization.
- Introduced 22 new MCP tools to cover previously missing REST functionalities, increasing the total tool count from 103 to 125.
- Improved descriptions for several existing tools to clarify their usage and parameters.
- Regenerated the API documentation to ensure accuracy and completeness.
2026-08-15 00:06:40 +02:00
Dave
48053a6205 feat: add support for stock purchase attachments
- update backend service to fetch stock purchase attachments
- refactor dedupe logic to avoid filename collisions between customer and stock attachments
- adjust PoCard to generate correct file URLs for stock attachments
- update test expectations for the modified service query
2026-08-14 18:25:05 +02:00
Dave
e27184245b refactor(agent scan route): remove debug logs and redundant sanity check
Remove dev-time console logging and the unnecessary stock_purchases collection probe check to clean up the route handler.
2026-08-14 17:55:58 +02:00
Dave
162e47e80e refactor: clean imports, update types and fix issues
- move CollectionConfirmValidationError imports from stock-purchase-items-service to collection-confirm-service
- update ConfirmRow type: add supplier_sku field and remove unused nested expand properties
- refactor sortRowsByField generic in orders-service to fix type access errors
- add non-null assertion to firstRow.stock_purchase_id in collection confirm page upload handler
2026-08-14 17:13:04 +02:00
Dave
59f245d798 feat(collection-confirm): add stock item edits
- Add new POST API endpoints at `/api/v1/stock-purchase-items/[id]/sku` and `/api/v1/stock-purchase-items/[id]/cost` for updating stock purchase item details
- Update ItemsTable to support cost and SKU edits for all row types, add supplier SKU column and editing for stock rows
- Extend PoCard to pass edit callbacks and add stock-specific invoice upload functionality
- Update all related test suites to cover new editing and UI features
- Adjust invoice upload messaging to differentiate between customer and stock purchase orders
2026-08-14 16:39:46 +02:00
Dave
9e74968b5e feat: add PO agent workflow and inline SKU editing
Add full purchase order agent tooling and supporting changes:
- Add server-side purchase-order-agent-service for scanning both stock and customer POs, with complete test coverage
- Add inline SKU and supplier SKU editing flows to stock order detail pages
- Update MCP API route to support new PO agent tools (purchase_orders.scan, diff, record_diff_report) and stock_purchase_items.list
- Fix flaky CollectionPoolPage tests by wrapping state-dependent assertions in waitFor
- Refactor CollectionPoolPage auto-collapse logic to avoid react-hooks lint trap and run exactly once on initial load
- Delete temporary .tmp-inspect-pool.mjs development script
2026-08-14 12:37:13 +02:00
Dave
541676dabb refactor(invoicing): remove intermediate trimmedOverride variable 2026-08-14 11:25:10 +02:00
Dave
999948861e feat: add server-side quote search & PO number format update
Implement new server-side ranked quote search endpoint at `/api/v1/quotes/search`, replacing the legacy 500-row client-side substring scan that missed older quotes and didn't rank results by relevance. The new search scores matches across quote identifiers, customer/company headers, and line item fields.
Update PO number generation and validation to use a dashless format (POYYYYMMNNNXXX) with per-company scoped sequence numbers, and ignore legacy PO formats when calculating new sequences.
Remove legacy `searchQuotesWithItems` function and its associated test file, then update the quotes page to use the new server-side search API.
Add comprehensive unit and integration tests for the new quote search service and updated PO number logic.
2026-08-14 11:15:38 +02:00
Dave
3b8bc0fc35 feat(delivery-notes, migrations): add tabs, grouping, markup, and fix DN relations
- Add shared env loader for migration scripts to load .env and .env.local files at module init
- Add migration script to fix broken delivery note relation fields and backfill missing company data
- Update delivery notes list page: add status filter tabs, company-based collapsible grouping, increased fetch limit, and improved global search
- Add per-item cost price, markup calculations, and total summary rows for cost, selling price, markup, and margin to delivery note detail pages
2026-08-14 09:41:14 +02:00
Dave
43de97501c feat(tv): add TV dashboard + refine workflows
Add full PIN-protected TV dashboard stack including auth, redirects, map view, APIs, and server services.

Also include these critical refinements:
- Overhaul PO number generation to use per-company monthly sequences
- Rework quote rejection to bounce quotes back to operator queues instead of marking them terminal
- Add post_processing order tab group for clearer workflow visibility
- Fix collection pool tooltip positioning, overflow clipping, and default collapsed state
- Refactor customer list API, clean up unused form props, and fix item intel popover target ID handling
- Add comprehensive tests for new components and update existing test expectations
2026-08-13 20:55:22 +02:00
Dave
dce9bfb04a feat(invoicing, dn): add surplus tracking, fix qty, update branding
- Fix resolveInvoiceLineDefaults to prioritize customer order quantity over supplier-collected quantity, ensuring invoices reflect what the customer actually ordered
- Add surplusQty utility function to calculate supplier MOQ overflow that should be booked to stock via /api/v1/stock/surplus-book
- Add surplus stock indicators in order and delivery note modals with descriptive tooltips explaining the surplus amount
- Expand supported letterhead codes to include WESTSCOTT GROUP, and configure all delivery notes to use the Westcott Group letterhead globally per business branding rules
- Improve error handling and logging in the delivery notes API POST route to include PocketBase error details and request context for easier debugging
- Add comprehensive unit tests for the updated invoice line logic and new surplusQty function to prevent regressions
2026-08-13 13:02:37 +02:00
Dave
8a224a7a24 feat(delivery-notes): add order disambiguation, fix PDF layout, update combine flow and qty resolution
- Fix delivery note PDF signature section overlapping page contents by removing fixed absolute positioning
- Add client-side picker for duplicate order numbers when merging delivery notes
- Add orderId parameter to combine delivery notes API for direct order lookup
- Update resolveDeliveryNoteLineQty to prioritize operator-edited quantity first
- Refactor combine delivery notes service and API to handle order lookup errors and candidate selection
2026-08-13 12:00:51 +02:00
Dave
617c5b3422 feat(delivery-notes): add inline qty editing and bulk combine features
Add inline quantity editing for delivery note items:
- New PATCH API endpoint and service function to update item quantities
- Optimistic UI updates on the detail page with error and loading states
- Input validation and status gating for draft/sent delivery notes

Add bulk delivery note combine functionality:
- New POST API endpoint and service to merge multiple draft/sent notes
- Row selection support in DataTable across pagination
- Confirmation modal with selected notes preview and optional order linking
- Automatic audit trail updates for merged and cancelled records

Extend OrderItem TypeScript interface with optional order expand field
Fix minor type casting issues in createAdHocDeliveryNote utility
2026-08-13 11:24:05 +02:00
Dave
4dd5898007 feat(delivery-notes): add pdf regeneration and fix ad-hoc pdf saves
Add new POST API endpoint at /api/v1/delivery-notes/[id]/regenerate-pdf to re-render and save delivery note PDFs from current line items. Add a "Regenerate PDF" button to the delivery note detail page with loading state and single-flight protection to prevent duplicate requests. Update ad-hoc delivery note creation to automatically attach PDFs to order items so print and download buttons work immediately after creation. Add helper utilities for resolving relation names and calculating line item quantities for PDF rendering.
2026-08-13 10:59:22 +02:00
Dave
18397bc9be feat(counter): add standalone counter order PWA
This commit adds a full unauthenticated PWA for in-store retail order taking:
- Dedicated `/new-order` route with complete order form, customer/company picker
- Public `/api/counter/*` endpoints for search, order creation, and photo uploads
- Photo capture and gallery selection with 10-photo per order limit
- Offline caching via dedicated service worker and app manifest
- Shortcut redirect at `/counter` for quick installation
- Comprehensive setup and usage documentation in `docs/counter-pwa.md`
- Minor cleanup to root layout metadata and service worker registration
- Small layout fix for collection pool row text truncation

Orders submitted via the PWA appear immediately in the main CRM's New tab, and the app is designed for trusted office kiosk phones without requiring user login.
2026-08-13 09:27:20 +02:00
Dave
c0ec3c99ef feat(orders,invoicing): add duplicate order cleanup and soft cancellation
Add a complete workflow for managing duplicate intake orders:
- Add new server API endpoints for single order cancellation, duplicate detection, and bulk duplicate cancellation
- Add client UI components for bulk duplicate cleanup and single order soft cancellation
- Add a "Duplicates" button to the orders dashboard for quick access to the cleanup tool
- Refactor invoicing module: rename customerNameSimilarity to nameSimilarity, update QB customer picker to use radio buttons and remove automatic preselection
- Add comprehensive test coverage for the new order service utilities
2026-08-13 09:02:27 +02:00
Dave
756597068e fix(delivery-notes): correct DN cancellation and filter issues
Update the cancel delivery note dialog description to correctly state items are marked as cancelled
Fix PocketBase expand field whitelisting for delivery items to avoid missing related entity data
Change order item status to "cancelled" instead of "completed" when cancelling a delivery note, with updated JSDoc explaining the choice of status
Update the buyer tasks PO sent filter and its regression test to cover all current ItemStatus values
2026-08-12 15:36:31 +02:00
Dave
9eea138662 feat(delivery-notes): add mark complete and cancel delivery note functionality
Add backend API routes and service functions for delivery note status updates with strict validation rules
Add UI action buttons and cancellation confirmation modal to the delivery note detail page
Update table layouts and styling across delivery notes and invoicing pages to improve responsiveness
Fix text overflow issues by adding whitespace-nowrap and break-words classes
Refactor order items table to display status inline and reduce redundant layout code
2026-08-12 08:55:56 +02:00
Dave
8efb952c76 feat(order-status): add delivery_note and fix tab mappings
- add `delivery_note` to the ItemStatus union type
- move delivery_note visual config from EXTRA_ITEM_STATUS_VISUAL to ITEM_STATUS_VISUAL
- update tab group mappings: add delivery_note to processing tab, expand collected tab with post-pickup statuses
- move removed status to the cancelled tab group
- replace silent fallback in itemStatusToTabGroup with explicit error for unmapped statuses
- add comprehensive regression test to ensure all ItemStatus values are mapped to a tab
2026-08-12 08:09:36 +02:00
Dave
8856146023 fix(orders,delivery-notes): resolve build type errors after supplier removal 2026-08-12 01:42:19 +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
Dave
cfc56f5c86 feat(quotes): add approval page and email updates
- add operator (claimer) display section to quote approval review page
- add per-line-item supplier pricing proof popover with lazy-loaded attachment previews
- improve customer/company text styling and responsive layout on approvals pages
- fix markup and selling price rounding to whole currency values for cleaner outputs
- completely overhaul default quote email templates for better readability and clear CTAs
- update sticky action bar styling and responsive behavior on approval page
- remove hardcoded "The Sales Team" fallback sender name in email templates
2026-08-11 16:09:40 +02:00
Dave
7d4e4c34f2 feat(api/v1/items): add item intel refresh route
Add a new Next.js POST API endpoint that regenerates AI item insights for specific quote_item or order_item records. Support dry-run mode to preview insights without persisting changes, validate input parameters and existing records to return clear error responses, and use admin-level PocketBase access for trusted server-side callers including n8n webhooks and batch cron jobs.
2026-08-11 11:28:51 +02:00
Dave
397df8e2b2 fix: correct quote expiry handling for PocketBase's 0 default
PocketBase returns 0 for unset number fields, which broke the original
null-coalescing check in effectiveValidityDays, leading to PDFs showing
"Valid until: today" for all new quotes created via email ingest.

Changes include:
- Update effectiveValidityDays to treat 0, negatives, null/undefined as falling back to 30-day default
- Add test cases for 0 and negative validity_days inputs
- Explicitly set validity_days to QUOTE_VALID_DAYS when creating new quotes
- Add one-time idempotent migration script to backfill legacy invalid validity values
- Refactor item intel popover patch logic to use PocketBase SDK for authenticated requests
- Add n8n workflow for AI-powered item insight matching
2026-08-11 08:32:17 +02:00
Dave
608a6ab978 feat(invoicing): widen the recent-window filter from 3 to 5 days
Single-line behavioural change: buildRecentInvoiceRange now subtracts
5 days from today instead of 3. The "in last 3 days OR unprinted" rule
shipped in the previous commit picks up the new window automatically —
the window affects which old-but-unprinted rows are still considered
"in the window" (purely a UX nuance; the unprinted branch already
covers anything older).

Also tighten the section-header + empty-state copy and the test
fixtures to reflect the new window. The "INV-OLD-*" dates in the
range test had to push back from 2026-07-05 to 2026-07-02 — 2026-07-05
fell inside the new 5-day window, which would have flipped the test's
expectation (it was asserting that printed-old dates are hidden).

Files:
- src/app/(app)/invoicing/view-model.ts — buildRecentInvoiceRange: -3 → -5
- src/app/(app)/invoicing/view-model.test.ts — expected `from` date
  shifts by 2 days; test name updated
- src/app/(app)/invoicing/page.tsx — section header + empty state +
  inline comments mention "5 days" instead of "3 days"
- src/app/(app)/invoicing/page.test.tsx — test name updated;
  INV-OLD-*/INV-OLD-PRINTED fixture dates pushed back from 07-05 to 07-02
  to stay outside the new 5-day window
2026-08-11 07:43:05 +02:00
Dave
228caf1680 feat(invoicing): surface all unprinted invoices + delivery notes on the Invoiced tab
The Invoiced tab used to filter to the last 3 days only, which
meant an invoice or delivery note that fell off the window would
disappear from the operator's list even if they hadn't printed
it yet. The only way back was the per-row "Print" button on a row
that no longer existed in the tab.

Change the filter rule from "in last 3 days" to "in last 3 days OR
unprinted". A row surfaces if either:
  - its date falls inside recentInvoiceRange, OR
  - it has not been printed yet (printed !== true).

This means an invoice or DN stays on the operator's list until it's
printed, regardless of age. The list doubles as the "what's still
outstanding" view — print a row, it drops off the next reload.

Stock bookings are unchanged (still windowed to the last 3 days
only) — there's no print tracking on stock_purchases yet, so
"unprinted stock booking" is undefined.

Also broaden the bulk-print button from "Print Today's Unprinted"
to "Print All Unprinted" so the operator can clear the backlog
in one pass instead of having to print each row individually.
The button iterates every invoice + DN group whose items haven't
all been printed, regardless of date.

Section header + empty state text updated to reflect the new rule.

Files:
- src/app/(app)/invoicing/page.tsx — filter logic, button copy,
  section header, empty state, bulk-print handler
- src/app/(app)/invoicing/page.test.tsx — updated existing tests
  to match the new behaviour; renamed "bulk prints only today's
  unprinted invoices" to "bulk prints every unprinted invoice,
  regardless of date"
2026-08-11 07:36:01 +02:00
Dave
3a59fa104c feat(item-intel): add new item intel popover and backend workflows
This commit replaces the legacy item history and AI insights system with a standardized, fuzzy-matched item intel workflow:
- Update AiItemHistoryTrigger component to support both quote and order items via the `collection` prop, replacing the old `insights` prop with `intel`
- Add full `ItemIntel` type definitions to `src/lib/types.ts` for the new standardized insight payload
- Create new REST API endpoints for fetching and computing item intel for `quote_items` and `order_items`
- Rewrite the MCP insight endpoint to use the new shared `item-intel-service` instead of legacy individual insight functions
- Reorder quotes page tabs to place Delivery Note quotes alongside New quotes for better daily operator workflow
- Add item intel triggers to quote process and order process pages
- Remove deprecated document-level `AiInsightsPanel` components from quote and order detail pages
- Add bulk backfill endpoint for populating intel across existing active items
2026-08-11 02:57:57 +02:00
Dave
47d58db0c9 feat(mcp): add price_list.add_items tool for agent-driven catalogue upsert
Add a new MCP tool that lets the agent read a supplier PDF, quote PDF,
or pasted supplier email with its native vision, extract the per-line
fields, and commit them to the price_list catalogue in one round-trip.

Why: the only pre-existing path was operator upload via /pricelist ->
n8n ingest -> raw_price_list -> AI extraction -> price_list. That flow
is async, human-in-the-loop, and gates on n8n being healthy. This
tool gives the agent a synchronous shortcut for ad-hoc catalogue
updates -- paste a PDF, get the catalogue updated, no async hops.

The agent does the OCR; the tool does the commit. No LLM work moves
into the MCP server.

Behaviour:

- Dedupe by (sku, supplier) -- exact match. Different suppliers with
  the same SKU get separate rows.
- Upsert policy: cost_price overwrites (latest price wins).
  Description, selling_price, unit, category, subcategory, brand,
  markup, stock_qty, search_text, sku_normalised also patched in
  place on update.
- sku_normalised auto-computed (uppercase, strip non-alphanumeric --
  same canonical form price-list-match.ts uses).
- search_text auto-computed (lowercased, space-separated concat of
  sku + description + brand + supplier + category + subcategory +
  synonyms).
- Skipped items returned with per-item reason (missing_sku,
  missing_supplier, invalid_cost_price, pb_write_failed). Never
  silent.
- Bulk cap 500 items per call; larger lists rejected with
  too_many_items reason.
- source_file_id + source_label supported so new rows can be
  traced back to a raw_price_list upload (optional).
- Supplier stored verbatim on price_list.supplier (free-text field,
  no FK resolution -- same as the live schema).

Files:

- src/lib/server/price-list-service.ts (new) -- addPriceListItems +
  buildSearchText + computeSellingPrice helpers
- src/lib/server/price-list-service.test.ts (new) -- 17 tests
  covering validation, upsert, dedupe filter shape, normalisation
- src/app/api/mcp/route.ts -- new tool definition + dispatch block
- src/app/api/mcp/route.test.ts -- 2 dispatch tests + tool-list
  assertion update
- .agents/skills/wfdash-giellie/SKILL.md -- new section "8. Price-
  list catalogue" documenting input/output shapes + failure modes

Tests:

- 134/134 pass across the affected files
- 1775/1778 in the full suite (3 pre-existing failures unrelated
  to this change: pocketbase-admin.test.ts PB mock mismatch,
  quotes/items/[id]/attachments/upload/route.test.ts timeout,
  supplier-form.test.tsx race -- all reproducible on main)
- npm run build clean
2026-08-10 12:45:05 +02:00