Who is responsible?

Who is responsible?

Old forum URL: forums.lhotka.net/forums/t/3754.aspx


ajj3085 posted on Monday, October 22, 2007

hi,

I have another question along the lines of "who is responsible."  I have a quote, order, invoicing system.  All share many common behaviors, inheriting from Document, and containing a collection of line items.

It has come up that the Extended price for each line item on an Invoice should be calculated by using unit price and the quantity shipped, not the quantity ordered.  This is only entered at time of invoicing, and the quantity shipped is not even visible until the time of invoicing. 

I'm trying to figure out how best to do this.  Certainly one way would be to create other line item classes that do this, but that seems like overkill.  I have many different line item classes, because we have many items that behave slightly differently.  Another way would be to allow the line item to store a boolean to indicate if it should use qty or qty shipped.

A third option would be to have a price calculator class, which I sort of do now.  I have a static helper class which will computer the extended price for most line items.  Some do not use this though, because some items calculate based on another item or th collection of items.  But I suppose it would be possible to create a pricing object model that every line item would delegate to.  This would have to handle computing unit costs as well though, because some items are totally calculated, and of course I'd need something for taxes as well.

So.. are there other options I missed?  Which would be the soundest design?

Thanks
Andy

JonStonecash replied on Monday, October 22, 2007

Given how you have described your problem, I would go with a calculation class (or more precisely a calculation interface and one or more implementations of that interface).  You would build a factory (method or class) to create the line items and to plug in the appropriate instance of the calculation class into the slot in the line item that pointed to the interface.  One advantage of this approach is that you could dynamically change the calculation approach after the line item object was created; something that is not possible if you have a set of different line item classes.

In addition to having a pricing calculator for each line item, you could also take this same approach for the collection of line items.  I am thinking that the line items collection object would be a good place to hold the factory method for each line item.  That way, the line item collection could react to the addition of one of the special line items by adjusting the calculator objects in other line items. 

Jon Stonecash

david.wendelken replied on Monday, October 22, 2007

No problem, I was just kinda surprised! :)

Jon's approach seems like a good starting point for the object/interface portions of the algorithm.

I think you have two different sets of methods, based on two different objects.

One set of methods is to get the correct extended price on the sales line item, for the purchased quantity, including taxes.   This set of methods needs to be able to know the sales unit price, the quantity sold, and the tax structure.  The sales line item collection object seems the right place for this to me.

The second set of methods is to get the correct extended price on a shipment line item as you ship items.  This one needs to know the input from the sales line item that is being (partially or fully) shipped.  The shipment line item collection seems to be the right place for this.  The simplest way to calculate the amount would be to say the shipment extended price = (qty shipped / qty sold) * sales extended price.   But I still think you could end up with rounding errors on the tax portion doing it this way. :)   If you end up agreeing with that, then the methods would also need access to prior shipment data.

Is this more what you were asking for? :)





DavidDilworth replied on Tuesday, October 23, 2007

I think Jon's original suggestion makes good sense - a pricing class/engine/service- whatever you want to call it.

That way you have the possiblity to extend (i.e. implement further classes) when the rules change.

Trying to find a "one size fits all" solution is unlikely to be as future proof and dynamic enough to change with the future needs of the business. 

david.wendelken replied on Tuesday, October 23, 2007

DavidDilworth:

I think Jon's original suggestion makes good sense - a pricing class/engine/service- whatever you want to call it.

That way you have the possiblity to extend (i.e. implement further classes) when the rules change.

Trying to find a "one size fits all" solution is unlikely to be as future proof and dynamic enough to change with the future needs of the business. 

As I understand it, there are two fundamentally different calculations:

  1. Calculate extended price on the original sale, for the full quantity ordered including tax
  2. Calculate extended price on the full or partial shipment as a portion of the full, original sale price.

Would you advise one object to do both calculations, or one per calculation?

ajj3085 replied on Tuesday, October 23, 2007

David,

Its funny you mentioned the tax thing.  Even though my users knew ext. price was including tax amount, and even though we sent out almost 600 quotes that way, ONE customer was a little confused (although they did the math, and saw everything added properly).  So at EOD I was asked to change ext. price to not include taxes.  Not a big deal, only a few lines of code changed, and I only ever stored quantity and unit price anyway, so all those other amounts are calculated.

It sounds like the consensus is toward having "price manager" objects that do the proper calculations... one object to do both would be similar to the flag method I asked originally suggested, just not in the line item, in these new objects. 

So what I'm thinking of is a DocumentPriceManagerFactory and an InvoicePriceManagerFactory.  The factories would build an appropriate manager for the line item in question. The manager would be the one deciding which quantity to use.

It may also help with another question I had a while back; instead of a flag in the relevent LineItem, it could swap out the manager for a different one to have a different result.  Could work..

I'd still like to hear more though.. I have some leeway to get this done, as I have other priorities at the moment, but it will come up again soon. 

Also, yes, this is more along the lines of what I was asking David.  Thanks for coming back!

Andy

david.wendelken replied on Tuesday, October 23, 2007

ajj3085:

So what I'm thinking of is a DocumentPriceManagerFactory and an InvoicePriceManagerFactory. 

You mentioned sending out quotes earlier.  What's the document terminology for your business?

Quote becomes Order becomes Invoice(s)?

Is Document a generic term for Quote and/or Order?  Should it be a QuotePriceManagerFactory?  Or an OrderPriceManagerFactory instead? 

 

 

ajj3085 replied on Tuesday, October 23, 2007

Currently we have Quote, Order, Invoice, Rma.  It goes Q -> O -> I, or R -> I.  Depending on security, you can create any document "from scratch."

Document is the generic term for any one of those items.  All the documents do share 99% of the same behavior, so they share a common base class.  Which was nice, because the form to edit a document is pretty complex, even with the business rules encapsulated.  Lots of items in the Edit menu, etc.

So DocumentPriceManager would be the generic one everything but an Invoice uses, because they all should work the same way.

david.wendelken replied on Tuesday, October 23, 2007

ajj3085:
Currently we have Quote, Order, Invoice, Rma. 

...

So DocumentPriceManager would be the generic one everything but an Invoice uses, because they all should work the same way.

Rma = Return of Materials Authorization, or words to that effect?

What about re-stocking fees taken out of the sales price when calculating a refund?  Or would that be a separate line item type?

ajj3085 replied on Tuesday, October 23, 2007

They'd probably enter that as a custom product, or perhaps a discount (line item) on the negative amount.  I believe though that most of our Rmas are actually repair work, not vanilla returns. 
This is one area we didn't discuss too much, but what they have now works.

While my application is much more intellegent than the software they were using, there still is much room to have the application do more.  For now though the focus is on replacing their old, outdated, three or four disparete systems (ranging from recent access dbs, to proprietary dbs, even including an Alpha4 DOS database) into "one" system.  Once everything is in one place, we'll then begin making the different pieces more interactive (such as setting customer defaults on the contact information, for example, or automatically creating serial numbers for the software we sell).

david.wendelken replied on Monday, October 22, 2007


"It has come up that the Extended price for each line item on an Invoice should be calculated by using unit price and the quantity..."

Extended price should never be a calculated field.  The countless examples in textbooks and on the web showing it as = "qty * unit_price" are just plain wrong.

It is a value in its own right.

To prove my point, how would you record that we are selling 3 apples for $1, when Extended Price is a calculated field?

Unit price should be the calculated value, not extended price.  This is because Qty and Extended Price MUST BE CORRECT AND EXACT when they are passed to other systems, such as shipping and accounts receivable.  Unit price is a nice-to-have calculation for analysis and reporting.

 

ajj3085 replied on Monday, October 22, 2007

Except that what you describe is not how we operate.  We don't run sale specials; we don't discount for buying "in bulk." Also my users have been quite clear that extended price IS to be calculated.

Even if we did work like that, how would you suggest we proceed?  Going off of quantity shipped is due to a backorder process; we only invoice for what we've actually shipped.  Calculating unit price instead of extended price doesn't solve that problem.

esteban404 replied on Monday, October 22, 2007

ajj3085:
Except that what you describe is not how we operate.  We don't run sale specials; we don't discount for buying "in bulk." Also my users have been quite clear that extended price IS to be calculated.

Even if we did work like that, how would you suggest we proceed?  Going off of quantity shipped is due to a backorder process; we only invoice for what we've actually shipped.  Calculating unit price instead of extended price doesn't solve that problem.

I wonder if there is a language/terminology thing here...

Extended price = price total after calculation, 2 * 10 = 20 where 20 is the extended price as a line item total; OR
Extended price = price break based on quantity/time, etc.

It took me a few meetings to figure that out and I've hear both in the same organization mean different things to different people (usually in different departments where their needs/wants are always more critical than anyone else's). I created a HasSpecialPricing field for the items so it could flip between the two types with the standard being the default. The secondary used a business rule to determine eligibility and application (like a coupon code, etc.).

_E

ajj3085 replied on Monday, October 22, 2007

Our extended price is quantity * unit price + tax. 

david.wendelken replied on Monday, October 22, 2007

ajj3085:
Our extended price is quantity * unit price + tax. 

And, of course, you can only invoice the tax for what you ship also.

You may not be able to just pro-rate the tax because the tax may be calculated differently.

For example, the tax might be calculated as "You owe one penny for each full ten cents sold."

A sale of $0.09 owes no tax.

A sale of $0.10 thru $0.19 owes $0.01, $0.20 thru $0.29 owes $0.02, etc.

It all depends upon whether, in business terms, a sale with two invoiced shipments is considered one taxable sale or two.  If it is legally considered two sales, then you just owe tax based upon the amount you are sending.

If you must consider them as one sale, then you owe tax based upon the total amount of product shipped, minus the amount of tax already invoiced.

Now, I happen to think that including the tax on a per item basis is a dangerous thing.  Tax should be computed on the sum of all products in the sale in the same tax category. (Some items are not taxed, others may be taxed at a higher rate than normal products.)

So, let's say we just sold 9 for a $1 and we end up sending them 1 of them right away, and we must consider separate shipments as one taxable sale.

The sales tax structure is as stated above, which means that we cannot, repeat cannot, include sales tax on a line item basis.  Why?

Because if I bought the following items and only paid tax on a per item basis, I would owe no tax:

qty   unit price   ext price with tax

1      0.05         0.05

4      0.02         0.08

9      0.01         0.09

               ttl      0.22

Tax on this should be $0.02.  but no single line item ever reached the taxable limit, so we charged $0.00 in tax.

If the tax were rounded up to the nearest ten cents instead of down, we would be overcharging instead:

qty   unit price   ext price with tax

1      0.05         0.06

2      0.02         0.05

3      0.01         0.04

               ttl      0.15

The tax on this should be $0.02, but we charged $0.03. 

Simply put, tax should not be included in an extended price.  Even if the current tax structure does not cause this problem, remember that your company does not control the sales tax structure.  It can be changed (with the force of law) at any time.

 

ajj3085 replied on Monday, October 22, 2007

Hmm, I twice posted a reply, and neither have appeared.   Weird.  I don't feel like typing it again though.

I appreciate the time you've taken to respond.  However, I know how we operate and tax and how we compute extended prices is something we've discussed.  Believe me when I say that tax is something I certainly want to get right for them, because it will come back to me if we end up owing sales tax.  What is in place now is what they want, and what works.  I can't spend lots of time to solve issues that haven't even come up yet.

I would be greatful if you stopped hijacking this thread, especially because Jon's approach likely could also solve any issues you are currently raising, but I'd like to here more ideas specifically around the problem I presented.

Thanks
Andy

david.wendelken replied on Monday, October 22, 2007

ajj3085:
I would be greatful if you stopped hijacking this thread...

I'll be glad to stop trying to help you on this topic.

I do object to the phrase "hijacking this thread".  Here, in your own words, is why:

ajj3085:
Even if we did work like that, how would you suggest we proceed?

ajj3085 replied on Monday, October 22, 2007

David, its not that I don't appreciate that you're trying to be helpful, but I believe I was not clear with that question.  It should have read "Even if we did work like that, how would you suggest we proceed solving the original problem," which is that calculations need to use either quantity or quantity shipped, depending on the type of document that contains the items. 

I will certainly keep your other comments in mind, but for now, what I have built is what my employer wants, and it satisfies their requirements. 

At any rate, if I offended you I do appologize, as that was not my intent.  I do value the insights you've given on this forum.

david.wendelken replied on Monday, October 22, 2007

ajj3085:
Except that what you describe is not how we operate.  We don't run sale specials; we don't discount for buying "in bulk."

That is a business decision that could be changed at any time.  All it takes is one big enough order and a savvy customer to negotiate the terms.  Ask your boss this question: "If David agrees to buy 500,000 of these items today, will you give him a 5% price break, rounded down to the nearest dollar?"

Care to wager what the answer would be?

ajj3085:
Also my users have been quite clear that extended price IS to be calculated.

Never, ever, ever, blindly trust a user when they give you mathematical instructions. 

Well, ok, if they are a mathematician you can (probably) trust them.

Most people are innumerate - that's illiterate with numbers.  They are not simply competent to make mathemateical decisions beyond simple arithmetic. 

That's not an insult.  I am not competent to fly an airplane because I don't know how.  If properly taught, I'm sure I could do so.  But I don't know how, so I'm not competent to do it.

ajj3085:

Even if we did work like that, how would you suggest we proceed?  Going off of quantity shipped is due to a backorder process; we only invoice for what we've actually shipped.  Calculating unit price instead of extended price doesn't solve that problem.

Pro-rate the amount to bill based upon the percentage of the items being shipped.  Round down until the final item is shipped, then round up to make the overall billed total match the intended extended price.

So, in my example, we sell 3 for $1, but ship one.

You bill 1/3 of $1, rounded down to $0.33.

You then ship the second item, 1/3 of $1, rounded down to $0.33.

You then ship the third item, and bill $1 minus the sum of all other items already shipped ($0.66), which is $0.34.

You can take the shortcut on it you were aiming for, but you are gambling that unit price will always be in whole pennies (or whatever your currency is).  Maybe it will, maybe it won't.  That's why it's a gamble. :)  

I routinely make such gambles when I design a system.  I just make sure I understand the odds - and that my users understand the odds also.  That means that I question the users with "what if?" scenarios that break the assumptions that underly the instructions they gave to me.  Sometimes I'm told, "We already thought about it, it's not a problem."  Sometimes I'm told, "Golly!  We never thought about that!" or "Gosh!  We forgot to tell you about that!"

 

 

 

Copyright (c) Marimer LLC