The system SHALL create one add_on_fulfillments record for each add-on unit purchased in an order. Each record MUST have a unique, globally incrementing sequence number. The formatted code MUST be stored based on the variant's fulfillment_type.
- WHEN an order completes containing a line item with:
- variant.is_add_on = true
- variant.fulfillment_type = "raffle_entry"
- quantity = 5
- THEN 5
add_on_fulfillmentsrecords are created with:- Sequential sequence_numbers (e.g., 142, 143, 144, 145, 146)
- fulfillment_type = "raffle_entry"
- Formatted codes: "RAFFLE-00142", "RAFFLE-00143", "RAFFLE-00144", "RAFFLE-00145", "RAFFLE-00146"
- WHEN an order completes containing a line item with:
- variant.is_add_on = true
- variant.fulfillment_type = nil
- quantity = 2
- THEN 2
add_on_fulfillmentsrecords are created with:- Formatted codes using "ADDON-" prefix (e.g., "ADDON-00147", "ADDON-00148")
- WHEN an order completes with no line items where variant.is_add_on = true
- THEN no
add_on_fulfillmentsrecords are created - AND no fulfillment email is sent
The system SHALL format fulfillment codes based on the variant's fulfillment_type. Codes MUST be zero-padded to 5 digits minimum.
- WHEN a fulfillment is created with fulfillment_type = "raffle_entry" and sequence_number = 42
- THEN the code is formatted as "RAFFLE-00042"
- WHEN a fulfillment is created with fulfillment_type = "vip_pass" and sequence_number = 42
- THEN the code is formatted as "VIP-00042"
- WHEN a fulfillment is created with fulfillment_type = "food_voucher" and sequence_number = 42
- THEN the code is formatted as "FOOD-00042"
- WHEN a fulfillment is created with fulfillment_type = "merchandise" and sequence_number = 42
- THEN the code is formatted as "MERCH-00042"
- WHEN a fulfillment is created with fulfillment_type = "parking_pass" and sequence_number = 42
- THEN the code is formatted as "PARK-00042"
- WHEN a fulfillment is created with fulfillment_type = nil and sequence_number = 42
- THEN the code is formatted as "ADDON-00042"
The system SHALL send one email to the customer containing all add-on fulfillments from their order. The email MUST include order number, customer name, and each fulfillment code. The email sender name MUST use product.brand.name if present and non-blank; otherwise fall back to product.account.platform.name. The email MUST include any collected fulfillment field responses relevant to the fulfillment type.
- WHEN an order completes with 5 raffle ticket add-ons
- THEN customer receives one email containing:
- Order number (display_id)
- Customer first name greeting
- Section for "Raffle Entries" with all 5 codes listed
- Each code displayed prominently
- WHEN an order completes with:
- 2 raffle tickets (raffle_entry)
- 1 VIP pass (vip_pass)
- 1 parking pass (parking_pass)
- THEN customer receives one email containing:
- Separate section for each fulfillment type
- Raffle section with 2 codes
- VIP Pass section with 1 code
- Parking section with 1 code and the collected license plate number
- WHEN an order contains add-ons associated with an event product
- THEN the email includes:
- Event title
- Event date/time (if showtime available)
- Venue name
- WHEN an order contains add-ons and the order has an associated showtime variant
- THEN the email displays the showtime variant title (e.g., "Fri Jan 31, 8:00 PM") in smaller font below the event title
- WHEN the product has a brand with a non-blank name
- THEN the email sender name is product.brand.name
- WHEN the product has no brand or brand.name is blank
- THEN the email sender name is product.account.platform.name
- WHEN an order completes with a parking pass add-on
- AND customer provided license plate "ABC 123" at checkout
- THEN the parking pass section in the email displays:
- Parking pass code
- License plate: ABC 123
- WHEN an order completes with a merchandise add-on
- AND customer provided shipping address at checkout
- THEN the merchandise section in the email displays:
- Merchandise code
- Shipping address formatted on multiple lines
The system SHALL NOT create duplicate fulfillment records if order processing runs multiple times. Existing fulfillments for an order MUST be detected and skipped.
- WHEN order processing runs for an order that already has fulfillments created
- THEN no new fulfillment records are created
- AND no duplicate email is sent
- AND processing returns success
The system SHALL persist all fulfillment records to the database before attempting to send the email. If email sending fails, fulfillment records MUST still exist.
- WHEN fulfillment records are created successfully
- AND email delivery fails
- THEN fulfillment records remain in database
- AND error is logged
- AND processing continues (does not block order pipeline)