Status: ✅ COMPLETE Date Completed: October 4, 2025 Developer: Claude Code
Phase 2 expanded beyond the original plan to include vendor availability management and immediate order notifications, in addition to the core delivery confirmation system required for Ramp integration.
Allows vendors to manage when they can accept new orders through the vendor portal.
Database:
db/migrate/20251004181413_add_availability_rules_to_vendors.rb
minimum_advance_hours - Hours notice required for ordersdefault_working_days - Days of week vendor works (JSONB array)db/migrate/20251004181418_create_vendor_blocked_dates.rb
db/migrate/20251004181423_create_vendor_working_overrides.rb
Models:
app/models/vendor_blocked_date.rbapp/models/vendor_working_override.rbapp/models/vendor.rb - Enhanced with availability methods:
available_for_delivery?(delivery_datetime)sufficient_advance_notice?(delivery_datetime)working_on?(datetime)next_available_delivery_date(from_date:)blocked_dates_between(start_date, end_date)System:
config/initializers/holidays.rb - US Federal Holidays module
us_federal_holidays(year), between(start, end), us_federal_holiday?(date)Portal:
app/controllers/vendors/availability_controller.rbapp/views/vendors/availability/index.html.erbhttps://vendors.quarryrents.com/availabilityFeatures:
Vendors receive instant email notifications when orders are created or cancelled.
Mailer Methods:
app/mailers/vendor_mailer.rb
order_created(order) - Sent immediately when order placedorder_cancelled(order) - Sent immediately when order cancelledEmail Templates:
app/views/vendor_mailer/order_created.html.erb (styled, blue theme)app/views/vendor_mailer/order_created.text.erbapp/views/vendor_mailer/order_cancelled.html.erb (styled, red theme)app/views/vendor_mailer/order_cancelled.text.erbIntegration:
app/controllers/app/quotes_controller.rb
app/models/order.rb
Email Design:
The critical piece that triggers Ramp card creation and tracks delivery verification.
Database:
db/migrate/20251004182139_create_delivery_confirmations.rb
db/migrate/20251004182201_add_confirmation_fields_to_orders.rb
delivery_confirmed_atdelivery_confirmed_by_vendorpickup_confirmed_atpickup_confirmed_by_vendorModel:
app/models/delivery_confirmation.rb
confirm! method with fraud scoringJob:
app/jobs/send_delivery_confirmation_emails_job.rb
config/recurring.ymlMailer:
VendorMailer.delivery_confirmations(vendor, confirmations)app/views/vendor_mailer/delivery_confirmations.html.erb (styled, dark theme)app/views/vendor_mailer/delivery_confirmations.text.erbController:
app/controllers/vendors/confirmations_controller.rb
index - Portal dashboard (requires login)confirm - Portal confirmation actionconfirm_delivery - Public token confirmation (no login)confirm_all_deliveries - Bulk confirmation (no login)report_issue - Issue reporting pageViews:
Portal (requires login):
app/views/vendors/confirmations/index.html.erb
Public (token-based, no login):
confirmed.html.erb - Success page with order detailsalready_confirmed.html.erb - Already processed messageexpired.html.erb - Token expired, go to portalinvalid_token.html.erb - Token not founderror.html.erb - Generic error handlingbulk_confirmed.html.erb - Bulk confirmation successreport_issue.html.erb - Issue reporting with contact infoAll public views are standalone with embedded CSS, professional design matching email templates.
Routes:
# Portal (requires login)
GET /confirmations vendors/confirmations#index
POST /confirmations/:id/confirm vendors/confirmations#confirm
# Public (no login required)
GET /confirm/:token vendors/confirmations#confirm_delivery
GET /confirm-all vendors/confirmations#confirm_all_deliveries
GET /report-issue/:token vendors/confirmations#report_issue
Vendor Portal Pages:
https://vendors.quarryrents.com/availability - Manage availabilityhttps://vendors.quarryrents.com/confirmations - View/confirm deliveriesPublic Confirmation Links (from email):
https://vendors.quarryrents.com/confirm/:token - Confirm single deliveryhttps://vendors.quarryrents.com/confirm-all?vendor_id=X&date=YYYY-MM-DD - Bulk confirmhttps://vendors.quarryrents.com/report-issue/:token - Report delivery issueConfidence Score Calculation:
Tracked Data:
Phase 1 Integration:
CaptureAuthorizedPaymentsJob from Phase 1VendorMailer.delivery_notification from Phase 1Phase 4 Readiness:
DeliveryConfirmation#handle_delivery_confirmed
CreateVendorPaymentCardJobDeliveryConfirmation#handle_pickup_confirmed
CancelVendorPaymentCardJobOrder Model:
Vendor Availability:
# Test availability checking
vendor = Vendor.first
vendor.available_for_delivery?(2.days.from_now.to_datetime) # => true/false
vendor.next_available_delivery_date # => Date object
vendor.blocked_dates_between(Date.current, 1.month.from_now) # => Array of dates
Delivery Confirmation:
# Test job manually
SendDeliveryConfirmationEmailsJob.perform_now
# Test confirmation
confirmation = DeliveryConfirmation.pending.first
confirmation.confirm!(
ip_address: "127.0.0.1",
user_agent: "Test Browser",
method: "portal_login"
)
Email Previews:
http://localhost:3000/rails/mailers/vendor_mailer/order_createdhttp://localhost:3000/rails/mailers/vendor_mailer/order_cancelledhttp://localhost:3000/rails/mailers/vendor_mailer/delivery_confirmationsMigrations:
db/migrate/20251004181413_add_availability_rules_to_vendors.rbdb/migrate/20251004181418_create_vendor_blocked_dates.rbdb/migrate/20251004181423_create_vendor_working_overrides.rbdb/migrate/20251004182139_create_delivery_confirmations.rbdb/migrate/20251004182201_add_confirmation_fields_to_orders.rbModels:
app/models/vendor.rb (enhanced)app/models/vendor_blocked_date.rb (new)app/models/vendor_working_override.rb (new)app/models/delivery_confirmation.rb (new)app/models/order.rb (enhanced)Controllers:
app/controllers/vendors/availability_controller.rb (new)app/controllers/vendors/confirmations_controller.rb (new)app/controllers/app/quotes_controller.rb (modified)Mailers:
app/mailers/vendor_mailer.rb (enhanced)Views:
app/views/vendors/availability/index.html.erb (new)app/views/vendors/confirmations/index.html.erb (new)app/views/vendors/confirmations/confirmed.html.erb (new)app/views/vendors/confirmations/already_confirmed.html.erb (new)app/views/vendors/confirmations/expired.html.erb (new)app/views/vendors/confirmations/invalid_token.html.erb (new)app/views/vendors/confirmations/error.html.erb (new)app/views/vendors/confirmations/bulk_confirmed.html.erb (new)app/views/vendors/confirmations/report_issue.html.erb (new)app/views/vendor_mailer/order_created.{html,text}.erb (new)app/views/vendor_mailer/order_cancelled.{html,text}.erb (new)app/views/vendor_mailer/delivery_confirmations.{html,text}.erb (new)Jobs:
app/jobs/send_delivery_confirmation_emails_job.rb (new)Initializers:
config/initializers/holidays.rb (new)Configuration:
config/recurring.yml (modified - added send_delivery_confirmations job)config/routes.rb (modified - added vendor availability and confirmations routes)Phase 3: Vendor Pickup/Removal Workflow
Phase 4: Ramp Card Integration
All code is production-ready with: