Invoice Discount: Negative line items vs Internal properties

Posted by FreshCode on Stack Overflow See other posts from Stack Overflow or by FreshCode
Published on 2010-04-23T15:09:04Z Indexed on 2010/04/23 16:13 UTC
Read the original article Hit count: 548

Should discount on invoice items and entire invoices be negative line items or separate properties of an invoice?

In a similar question, Should I incorporate list of fees/discounts into an order class or have them be itemlines, the asker focuses more on orders than invoices (which is a slightly different business entity). Discount is proposed to be separate from order items since it is not equivalent to a fee or product and may have different reporting requirements. Hence, discount should not simply be a negative line item.

Previously I have successfully used negative line items to clearly indicate and calculate discount, but this feels inflexible and inaccurate from a business perspective. Now I am opting to add discount to each line item, along with an invoice-wide discount.

  • Is this the right way to do it?
  • Should each item have its own discount amount and percentage?

Domain Model Code Sample

This is what my domain model, which maps to an SQL repository, looks like:

public class Invoice
{
    public int ID { get; set; }
    public Guid JobID { get; set; }
    public string InvoiceNumber { get; set; }
    public Guid UserId { get; set; } // user who created it
    public DateTime Date { get; set; }
    public decimal DiscountPercent { get; set; } // all lines discount %?
    public decimal DiscountAmount { get; set; } // all lines discount $?

    public LazyList<InvoiceLine> InvoiceLines { get; set; }
    public LazyList<Payment> Payments { get; set; } // for payments received

    public boolean IsVoided { get; set; }   // Invoices are immutable.
                                            // To change: void -> new invoice.

    public decimal Total
    {
        get {
            return (1.0M - DiscountPercent)
                    * InvoiceLines.Sum(i => i.LineTotal)
                    - DiscountAmount;
        }
    }
}

public class InvoiceLine
{
    public int ID { get; set; }
    public int InvoiceID { get; set; }
    public string Title { get; set; }
    public decimal Quantity { get; set; }
    public decimal LineItemPrice { get; set; }

    public decimal DiscountPercent { get; set; } // line discount %?
    public decimal DiscountAmount { get; set; } // line discount amount?

    public decimal LineTotal {
        get {
            return (1.0M - DiscountPercent)
                    * (this.Quantity * (this.LineItemPrice))
                    - DiscountAmount;
        }
    }
}

© Stack Overflow or respective owner

Related posts about database-design

Related posts about invoice