views:

113

answers:

1

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 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 InvoiceLines.Sum(i => i.LineTotal);
        }
    }
}

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;
        }
    }
}
+1  A: 

Negative line items

How are you going to handle credits? I.e., you invoice someone for three items but two are faulty so you will reverse the charge on the two faulty items. There are a couple of ways this is done. One solution is a credit which is a variant of an invoice except that the amounts are credited back to the person to whom the invoice was issued. If you do not allow negative numbers, then you will need to find a means to store credits separately or mark the invoice as being a credit. In this later scenario, they would issue another invoice, marked as being a credit. Another solution, of course, is to allow for storing negative line items. How credits are handled is really what will determine whether use of negative line items is the right approach.

Fees and Discounts

One approach is to break down discounts and fees into two types:

  1. Discounts that apply to specific order items
  2. Discounts that are enumerated as an item but do not apply to a specific order item.

Notice that I do not include a discount that applies to the order. That is intentional. Every discount or fee would have to be enumerated as an item (but not necessarily apply to a product). In this way, each discount and fee is explicit in its source. That prevents someone from throwing onto an order a discount for which no one can determine the source or authorization. The same would be true of fees other than tax.

Thomas
I see two ways of handling client refunds: 1.) Invoices should be *immutable*, so I would void the invoice and create a new invoice with any relevant +/- payments to account for two-way transactions. 2.) Simply create a negative payment in the `Payments` table, which keeps track of incoming and outgoing funds for a given invoice and add comments to invoice. (You'll note for this reason I don't have an `IsPaid` bit per invoice, since funds transferred can be inferred from `Payments`.) An invoice is a bill addressed to the client, so it should not represent a transaction.
FreshCode
+1 I agree on not having an invoice-wide discount, which is equivalent to applying a discount to each line item and summing the totals anyhow. Nice simplification.
FreshCode
@Thomas: I'd like to hear your comments on my first comment to your answer.
FreshCode
@FreshCode - Working on it. Work and SO addiction do not always play nicely :)
Thomas
@FreshCode - Invoices *must* be immutable as you will need a record of what was issued (and paper is somewhat immutable) You could not void the invoice in the example I provided as only two of the three items were faulty. So, you would need to issue a compensating invoice or a credit. I've seen acctg systems handle credits as a form of payment and/or (as in some do both) a form of invoice. If you go the payment route, it means you will need payment line items that can be negative or flagged as to indicate an outgoing payment vs an incoming payment.
Thomas