Purpose: Admins create professional multi-line quotes to send to customers
Location: /quotes (admin only)
Features:
Models:
Quote (new dedicated model)QuoteLineItem (line items with product, quantity, price)Product has product_type field (rental/fee/service)Order has quote_id to link backWorkflow:
/quotes/newStatus: Disabled (not in use)
Previous Location: App::QuotesController at /quote/new
What it was:
Order record with status: "quote"Why deprecated:
Files to remove (when ready):
app/controllers/app/quotes_controller.rbapp/views/app/quotes/*namespace :app for quotesWhen ready to allow customers to create their own quotes, here's the plan:
Use case: Customer requests a quote, admin creates formal Quote
Implementation:
QuoteRequest model (not full Quote)/quote_requestsBenefits:
Use case: Customer builds their own multi-line quote and submits
Implementation:
created_by_customer flag/app/quotes/newBenefits:
Use case: Customer creates quote and immediately accepts
Implementation:
Benefits:
# 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
Rental - Equipment needing individual tracking
Fee - One-time charges
Service - One-time services
# 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
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).
Existing Orders with status="quote":
Product Types:
/products and adjust if neededOrders Created from Quotes:
quote_id linking back to parent QuoteOrder.where(quote_id: 123)@quote.ordersFor questions or issues with the quote system:
app/models/quote.rbapp/controllers/quotes_controller.rb