Quote System Documentation

Current State (October 2025)

Active: Admin Quote System

Purpose: Admins create professional multi-line quotes to send to customers

Location: /quotes (admin only)

Features:

Models:

Workflow:

  1. Admin creates quote via /quotes/new
  2. Add line items (product, quantity, price)
  3. Mark as "sent" to customer
  4. Customer accepts (manual for now)
  5. System auto-generates orders based on line items

Deprecated: Customer Quote Requests

Status: Disabled (not in use)

Previous Location: App::QuotesController at /quote/new

What it was:

Why deprecated:

Files to remove (when ready):


Future: Customer-Facing Quote System

When ready to allow customers to create their own quotes, here's the plan:

Option 1: Customer Quote Requests (Simple)

Use case: Customer requests a quote, admin creates formal Quote

Implementation:

  1. Build simple quote request form (customer portal)
  2. Creates a QuoteRequest model (not full Quote)
  3. Admin reviews requests at /quote_requests
  4. Admin creates formal Quote from request
  5. Send Quote to customer for acceptance

Benefits:

Option 2: Self-Service Quotes (Advanced)

Use case: Customer builds their own multi-line quote and submits

Implementation:

  1. Extend Quote model with created_by_customer flag
  2. Build customer quote builder at /app/quotes/new
  3. Customer selects products, quantities
  4. Pricing auto-populated from product catalog
  5. Submit → admin approval → convert to orders

Benefits:

Option 3: Instant Orders (Full Self-Service)

Use case: Customer creates quote and immediately accepts

Implementation:

  1. Customer builds quote
  2. Option to "Accept & Pay Now"
  3. Skips admin approval
  4. Auto-generates orders immediately
  5. Payment processed upfront

Benefits:


Recommended Path

Phase 1 (Current - ✅ Complete)

Phase 2 (Next - Email & PDF)

Phase 3 (Future - Customer Portal)

Phase 4 (Advanced - Self-Service)


Technical Details

Quote Acceptance Logic

# In Quote model
def accept!
  transaction do
    update!(status: "accepted", accepted_at: Time.current)
    generate_orders_from_quote
  end
end

def generate_orders_from_quote
  quote_line_items.each do |line_item|
    if line_item.product.rental?
      # Create separate order for each unit
      line_item.quantity.to_i.times do
        create_order_from_line_item(line_item, 1)
      end
    else
      # Create single order with full quantity
      create_order_from_line_item(line_item, line_item.quantity)
    end
  end
end

Product Types

Rental - Equipment needing individual tracking

Fee - One-time charges

Service - One-time services

Database Schema

# quotes table
t.references :company
t.references :contact
t.string :quote_number        # Q-YYYYMMDD-####
t.string :status              # draft, sent, accepted, expired
t.date :quote_date
t.date :valid_until
t.decimal :subtotal
t.decimal :tax_amount
t.decimal :total
t.string :public_token        # for customer access

# quote_line_items table
t.references :quote
t.references :product
t.text :description
t.decimal :quantity
t.decimal :unit_price
t.decimal :line_total
t.integer :rental_days

# products table
t.string :product_type        # rental, fee, service

# orders table
t.references :quote           # links back to parent

FAQ

Q: Can I edit a quote after sending? A: Yes, quotes with status "draft" or "sent" can be edited. Once accepted, they're locked.

Q: What happens to old quote request Orders? A: They remain as Order records with status: "quote". They can still be converted to regular orders manually. New quotes use the Quote model.

Q: Can I delete a quote? A: Yes, but only if it hasn't been accepted. Accepted quotes are linked to orders and should not be deleted.

Q: How do I handle quote expiration? A: Set the valid_until date. System will mark as expired automatically. You can manually change status too.

Q: Can customers accept quotes without an account? A: Not yet - currently admin accepts on behalf of customer. Phase 2 will add public acceptance via token link (no login required).


Migration Notes

Existing Orders with status="quote":

Product Types:

Orders Created from Quotes:


Support

For questions or issues with the quote system:

  1. Check this documentation
  2. Review code in app/models/quote.rb
  3. Check controller at app/controllers/quotes_controller.rb
  4. Contact development team