Commit Graph

35 Commits

Author SHA1 Message Date
twotalesanimation 124ab46507 refactor: Split shipping_address into component fields for ShipLogic API
- Create migration to add shipping_street_address, shipping_local_area, shipping_city, shipping_zone, shipping_country, shipping_postcode, shipping_type
- Update Order model fillable array with new address component fields
- Remove address parsing logic from CourierService
- Use individual address fields directly in ShipLogic API payload
- Fields match ShipLogic API requirements (street_address, local_area, city, zone, code, country, type)
- Note: Custom orders address collection can be implemented later
2026-01-02 21:40:16 +02:00
twotalesanimation 206ea2d35c fix: Update order status to ready_to_ship before handling intent
- Previously 'Ready to Ship' list movement was calling handler without updating status
- This caused status to remain 'packing' even after card moved to Ready to Ship
- Now status is updated to 'ready_to_ship' before attempting shipment creation
- Also added status update for Awaiting Collection list for consistency
2026-01-02 21:32:41 +02:00
twotalesanimation 027278c216 fix: Add datetime casts to Order model and null check in view
- Add casts array to Order model for packing_completed_at, delivered_at, qr_generated_at
- Update ops order-detail view to safely handle null packing_completed_at
- Prevents 'Call to a member function format() on string' error
2026-01-02 21:29:12 +02:00
twotalesanimation 22dfb12948 fix: Add height parameter to OrderPacked event
Added height to the OrderPacked event constructor and dispatch call to match
the packing form which captures width, length, height, and weight.
2026-01-02 21:25:05 +02:00
twotalesanimation 5cd8c05a7c feat: Move Trello card to Packing when inspection is passed
- Create InspectionPassed event
- Create MoveCardToPackingOnInspectionPassed listener
- Register event listener in EventServiceProvider
- Dispatch event when markInspectionPassed() is called

Now when an order passes inspection on the ops page, the Trello card
automatically moves from Inspection to Packing list.
2026-01-02 21:23:12 +02:00
twotalesanimation 341421d2a0 fix: Return available actions from getAvailableActions() method
The match statement wasn't returning the actions array, causing no actions
to display on inspection orders. Changed to directly return the match result.
2026-01-02 21:17:51 +02:00
twotalesanimation 66862df44b fix: Use flexible type check for is_admin authorization gate
Change strict equality check (=== true) to loose check that works with
both integer 1 and boolean true values.
2026-01-02 21:10:26 +02:00
twotalesanimation 4a8b4ddac2 fix: Double-charged shipping fee in Yoco payment + ops staff access
1. Fix Yoco payment amount calculation: order->total already includes
   shipping_fee, so don't add it again. Was charging 2x shipping.

2. Add authorization gate for ops staff access: users with is_admin=true
   can now access the ops page by scanning QR codes.
2026-01-02 21:07:21 +02:00
twotalesanimation ed57956694 feat: Attach QR sticker PDF to Trello card on order creation
When a new order is created and a Trello card is made, now automatically
generate the A6 QR sticker PDF and attach it to the card using Trello's
attachment API. Include error handling and logging.
2026-01-02 21:01:17 +02:00
twotalesanimation 93148ef9af fix: Use SVG data URI for QR code (no GD extension required)
Generate QR as SVG and encode as base64 data URI for embedding in PDF.
This avoids dependency on GD extension while keeping QR codes in PDF.
2026-01-02 20:43:59 +02:00
twotalesanimation 5dfb63dacb fix: Use base64-encoded PNG for QR code in PDF stickers
DomPDF renders embedded PNG images more reliably than inline SVG.
Changed QR code generation to OUTPUT_IMAGE_PNG with base64 encoding,
then embed as img tag in the PDF HTML.
2026-01-02 20:42:19 +02:00
twotalesanimation 09198a9f7d fix: Generate A6 sticker PDF with inline HTML instead of blade template
Build HTML directly in service without relying on view files. This eliminates
dependency on blade template file existing on production server.

Include all styling inline in heredoc string with:
- A6 dimensions (148mm  105mm)
- Order number, customer surname, design name
- Order status and date
- QR code in SVG format
- Clean, printable layout

Add helper methods:
- truncate(): Truncate design name to fit sticker
- formatStatus(): Format order status for display
2026-01-02 20:28:44 +02:00
twotalesanimation 12f42d5efc fix: Use View::file() to render sticker template directly, add missing test route, and allow GET for regenerate
- Changed from View::make() to View::file() with full path resolution
- Added file existence check with detailed error logging
- Allow GET/POST for regenerate sticker endpoint for easier testing
- Add design name and customer surname to A6 PDF stickers
- Add regenerate sticker endpoint POST /test/sticker/{orderNumber}/regenerate
- Add test sticker preview page at /test/sticker/{orderNumber}
2026-01-02 20:25:02 +02:00
twotalesanimation e503cd3479 fix: Correct web.php syntax and use correct QR library
- Fix malformed route on line 84 (missing closing paren and semicolon)
- Replace SimpleSoftwareIO QrCode with chillerlan/php-qrcode (already installed)
- Update QrStickerService to use chillerlan\QRCode\QRCode
- Configure QR options for SVG output with H error correction
2026-01-02 20:10:06 +02:00
twotalesanimation 3040681842 feat: Add A6 PDF QR stickers with human-readable order info
Implement QrStickerService to generate both SVG (web) and PDF (print) stickers:

- Generate 32x32mm QR codes using SimpleSoftwareIO
- Create A6 (148mm  105mm) PDF stickers using DomPDF
- Include human-readable info: order number, customer, status, date, tracking
- Store order type (STOCK/CUSTOM) with visual badge
- Add generation timestamp to footer

Create stickers/qr-sticker.blade.php template:
- Two-column layout: info left, QR right
- Styled for A6 landscape printing
- Shows order number, customer, status, date, tracking info
- QR code positioned for easy scanning
- Print-optimized CSS

Update GenerateQrCodeOnOrderCreated listener:
- Now calls QrStickerService::generateSticker()
- Generates both SVG and PDF on OrderCreated event
- Logs paths to both formats

Add OpsController::downloadSticker() endpoint:
- GET /ops/orders/{id}/sticker/download
- Returns PDF with filename QR-{order_number}.pdf
- Requires ops access authorization
- Logs all downloads with user context

Update ops order-detail view:
- Add download button for A6 sticker PDF
- Position next to QR code display
- Link to new sticker download route
2026-01-02 19:51:23 +02:00
twotalesanimation bb6b92df10 feat: Add Blade templates for ops QR interface (Phase 2)
Create state-driven UI templates:

Main Template (ops/order-detail.blade.php):
- Display order summary with status, type, customer, date
- Render QR code SVG for shop-floor access
- Conditionally include state-specific action forms
- Show order items, packing details, shipment info

Action Templates:
- ops/actions/packing.blade.php: Form to input weight/dimensions
- ops/actions/inspection.blade.php: Pass/Fail inspection with optional notes
- ops/actions/read-only.blade.php: Status display for read-only states

Error Pages:
- ops/order-not-found.blade.php: Invalid/expired QR token
- ops/unauthorized.blade.php: Insufficient permissions

All forms use AJAX submission with confirmation dialogs
2026-01-02 18:57:21 +02:00
twotalesanimation 74525e8955 feat: Implement QR code generation and ops interface scaffold
Phase 1: QR Code Generation
- Create GenerateQrCodeOnOrderCreated listener
- Generate secure random token on order creation
- Create SVG QR codes pointing to /ops/orders/{token}
- Store QR token and generation timestamp on order record
- Register listener in EventServiceProvider

Phase 2: Ops Controller & Routes
- Create OpsController with showOrder() landing page
- Implement confirmPacking() to capture dimensions via form
- Add markInspectionPassed() and flagInspectionIssue() methods
- Implement getAvailableActions() state machine for UI
- Add routes: GET /ops/orders/{token}, POST /ops/orders/{id}/pack, etc.
- Token-gated access, requires auth middleware

Next: Create Blade templates for state-driven UI
2026-01-02 18:55:53 +02:00
twotalesanimation db0454d102 refactor: Move shipment creation logic to CourierService for DRY principle
- Move all validation (packing, payment, status, duplicates) to CourierService::createShipmentForOrder()
- Move database updates to service layer
- Move document fetching to service layer
- Simplify ShippingController to just handle HTTP concerns (request/response)
- Simplify CreateShipmentOnReadyToShip listener to just dispatch events
- Single source of truth for business logic in CourierService
- Eliminates duplicate validation between controller and listener
2026-01-02 18:13:16 +02:00
twotalesanimation 2ddb3dc19f fix: Refactor CreateShipmentOnReadyToShip listener to directly call service
- Remove controller dependency and call CourierService directly
- Add proper validation before attempting shipment creation
- Log failures instead of silently succeeding
- Emit ShipmentCreated/ShipmentCreationFailed events properly
- Prevents false success logs when validation fails
2026-01-02 17:42:12 +02:00
twotalesanimation aa30111841 fix: Fix CreateShipmentOnReadyToShip listener syntax and add guard logging 2026-01-02 17:37:54 +02:00
twotalesanimation 1c68fff301 feat: Add CreateShipmentOnReadyToShip listener to handle webhook-triggered shipments
- Create new listener that fires on ReadyToShipIntent event
- Register listener in EventServiceProvider
- Fix log statements in ShippingController to use order UUID instead of ID
- Now when Trello card moves to 'Ready to Ship', backend automatically creates shipment
2026-01-02 17:26:11 +02:00
twotalesanimation 291393d497 feat: Implement full Trello webhook handling and event dispatch
- Parse incoming Trello webhook payloads for card movement actions
- Extract order number from card names (supports both numeric and full formats)
- Look up orders in database (Order or CustomOrder models)
- Emit ReadyToShipIntent event when cards moved to 'Ready to Ship' list
- Validate shipment exists before allowing 'Awaiting Collection' transition
- Add comprehensive logging for all Trello actions
- Handle validation pings and real events identically (both return 200)
- Card moves now trigger backend order processing workflows
2026-01-02 16:33:41 +02:00
twotalesanimation 986f12f685 fix: Correct print stock relationship accessor
- Change print_stocks (plural) to printStock (singular)
- Properly accesses the PrintStock model via OrderItem's belongsTo relationship
- Gets the correct print stock name from the print_stocks table
2026-01-02 16:25:18 +02:00
twotalesanimation 9fd138582a feat: Enhance Slack notification with design and size details
- Add emoji () and design name to order creation Slack message
- Include print size information (wallpaper length or mural dimensions)
- Extract design/size info once and reuse for both Slack and Trello
- Message format: 'New [type] order: Order #[number]\\nDesign: [name]\\nSize: [dimensions]'
2026-01-02 16:15:57 +02:00
twotalesanimation d29f08bd98 fix: Extract design_name and print_size from order items for Trello
- design_name: Get product name from first order item
- print_size: Calculate from item dimensions (wallpaper: length in m, mural: width x height in cm)
- Add fallback values ('') when items/dimensions unavailable
- Prevents null errors when populating Trello custom fields
2026-01-02 16:11:15 +02:00
twotalesanimation ca7d16da16 feat: Add Trello configuration fallback and test command
- Add fallback env parsing directly from .env file in config/trello.php
- Fixes issue where cached config prevents env() from reading .env values
- Add artisan trello:test command to diagnose Trello configuration
- Test command checks API credentials, board/list IDs, and connectivity
- Test successfully creates and moves a test Trello card
2026-01-02 15:36:27 +02:00
twotalesanimation 783cc88c6d feat: Update Order/CustomOrder models and controllers with event integration
- Add integration fields to Order model: packing_*, courier_*, trello_card_id, qr_token
- Add integration fields to CustomOrder model: packing_*, proof_approved_*, courier_*, trello_card_id, qr_token
- Update Order model fillable array and add relationships (packedBy)
- Update CustomOrder model fillable array, casts, and add relationships (packedBy)
- Add isCustomOrder() method to both models for type checking
- Update OrderController to emit OrderCreated and DepositPaid events on successful payment
- For standard orders: full payment -> prep status, emit events
- For custom orders: deposit -> design status, balance -> printing status, emit respective events
- Add approveProof() method to CustomOrderController (POST /custom-orders/{id}/approve-proof)
- Add requestChanges() method to CustomOrderController (POST /custom-orders/{id}/request-changes)
- Add markBalancePaid() method to CustomOrderController (POST /custom-orders/{id}/pay-balance)
- All new methods emit appropriate events (ProofApproved, ProofRevisionRequested, BalancePaid)
- Add database migration for proof_approved and proof_approved_at fields on custom_orders
- Add routes for new custom order endpoints with UUID binding
- Import all required event classes in both controllers
2026-01-02 14:35:01 +02:00
twotalesanimation 12aadfd917 feat: Implement Slack, Trello, and Courier (ShipLogic) integration
- Add 14 domain events for order lifecycle (OrderCreated, OrderPacked, ShipmentCreated, ParcelDelivered, etc.)
- Create SlackNotifierService with channels for orders, design, production, shipping, ops-alerts
- Create TrelloService to create cards, move cards between lists, attach files, check items
- Create CourierService to integrate with ShipLogic API for shipment creation and document retrieval
- Create PackingController to explicitly capture packing dimensions and weight
- Create ShippingController with multi-layer guards: packing validation, payment/approval verification, idempotency
- Create TrelloWebhookController to handle incoming Trello webhooks as intent signals
- Create CourierWebhookController to handle Shiplogic status updates
- Create event listeners for Slack notifications and Trello card updates
- Create EventServiceProvider to register all events and listeners
- Add database migration for packing, courier, and Trello data columns
- Create config files for slack, trello, and courier integration
- Update .env with integration secrets placeholders
- Add routes for /orders/{id}/pack, /orders/{id}/ship, /api/webhooks/trello, /api/webhooks/courier

Key architectural decisions:
- Packing is explicit ops action (not automatic from status)
- Shipment creation only after: Trello intent + packing confirmed + payment/approval rules met
- Courier API failures keep order in Ready to Ship state (safe retry)
- Trello and Slack are mirrors of backend state, not decision makers
- All side effects flow through event listeners, maintaining separation of concerns
2026-01-02 13:47:31 +02:00
twotalesanimation 4730f5770c update before thirdparty integration 2026-01-02 12:22:21 +02:00
twotalesanimation 94b90f603d Invoice system working 2025-12-30 22:10:30 +02:00
twotalesanimation e8e9b1f03c relocating 2025-12-30 20:59:58 +02:00
twotalesanimation a898c35a39 commit before consolodating payment methods 2025-12-30 10:40:45 +02:00
twotalesanimation 3c24c0e9ef everything semi working before sample implementation 2025-12-30 00:09:14 +02:00
twotalesanimation 00b8ff77b2 yoco updated to use webhook 2025-12-29 14:43:24 +02:00
twotalesanimation 6de01c13c5 New Initial Commit 2025-12-09 12:04:54 +02:00