How Invoice Line Item Calculations and Side Effects Work
Source: invoice_item.rb:229-382, invoice_items_controller.rb:73-76
- Item amount = quantity * unit_price, rounded to 2 decimal places
- Product type is always re-set from the product record on save (product_type and item_code are refreshed from the master Product)
- Invoice totals recalculate after every item save or destroy via the set_invoice_totals callback
- Vehicle visuals attachment is auto-added when a product has a vehicle_visuals_url and no existing attachment for that product on the invoice
- Vehicle visuals attachment is auto-removed when the invoice item is deleted
- Reserved stock quantity is recalculated on item save for invoice/internal types (non-labor, non-dont_update_quantity products)
- Deleting an invoice item subtracts its quantity from the product's qty_reserved
- Cannot delete invoice items that are integrated with Xero (have a xero_id) or are on closed invoices
Support scenarios
- "Why does the invoice total change every time I save a line item?" -> each line item save triggers a full invoice total recalculation
- "Why did a vehicle visual attachment appear on my invoice?" -> the product has a vehicle_visuals_url configured, which auto-creates the attachment
- "Why can't I delete this invoice item?" -> it has been synced to Xero (has a xero_id) or the invoice is closed; void the invoice instead
- "The product type keeps resetting on my line item" -> product_type is refreshed from the product record on every save; to change it, update the master product