Line items

Line items

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


ajj3085 posted on Tuesday, June 20, 2006

Hi all,

I'm sure some of you have done this, so any ideas would be appreciated.

I'm building some new functionality for Sales and Invoicing so that they can create quotes, orders, invoices, and RMAs.  From my requirements, it seems like linte items are going to be the most tricky part.

A few of the requirements for line items..

They must be orderable (this should be easy).
You can 'group' a set of line items so that it becomes one indivisible unit
A product bundle should act as a group
Need to have a 'note' line item
Need to be able to discount all or some line items.

The grouping and discount seem the most tricky to me. 

One option is that a line item contains a list of products.  Grouping would simply be a matter of taking each line item should should be in the group, moving the part to the 'parent' and deleting the old containing line item.  Another option is that line items can contain other line items, and can contain 0 or 1 parts.

Should a discount act as a group, but displays itself differently?

The really tricky part is in the display though; how have people displayed these items in an editable grid?  (That's currently what the users are working with, and would like to keep a similar UI).  A single line item may contain 5 parts, and each of those parts should be listed on its own line.. for a total of 6 lines taken up.

So, what have others done?  What other grid controls would be able to handle this (I don't think a standard datagridview is going to cut it... but am I wrong?) ?

Thanks
Andy

malloc1024 replied on Tuesday, June 20, 2006

You could use the decorator pattern to apply discounts on lineitems.  The decorator would wrap a line item and apply the discount.

ajj3085 replied on Tuesday, June 20, 2006

I'll look into that; the only pattern I know is the singleton, still need to find a good book covering them (perferablly targeted at .net programmers).

Michael Hildner replied on Tuesday, June 20, 2006

Andy,

Allow me to make a book recommendation. Head First Design Patterns is a really good book I think, and it's fun to read.

The Head First series is aimed at Java developers, so the code is all Java. I don't think that's a showstopper though, as the principles apply to any OO language. There's one part of the book that focuses on something specific in the Java framework, but I just blew that off.

It'll probably be easier to look at the code if you know C# syntax, as it's more like Java than VB.

Anyway, check it out at the bookstore. I'm no expert, but it's the only patterns book I've seen that gives good examples on why you would apply a particular pattern, rather than just dryly talk about theory.

Mike

malloc1024 replied on Tuesday, June 20, 2006

I agree with Mike.  This is a very good book for someone who wants to learn design patterns.  Don't limit yourself to .Net.  The best design pattern books are usually in Java.  The same priciples apply to all languages. 

ajj3085 replied on Wednesday, June 21, 2006

Yes, I've seen that book, but wasn't sure what others thought of it.  I was hoping they'd do a .Net version, just because it might be possible to augement some of the patterns with .Net specific stuff, like attributes (or does Java have attributes now?  Its been a while since I took my Java course in college). 

The syntax will be a breeze, since I came up the C / C++ route.

Thanks
Andy

hurcane replied on Tuesday, June 20, 2006

Be sure that the decorator pattern solves your problem in the best way. The decorator pattern is great for dynamically adding behavior to objects. I have found the decorator pattern not as useful when the behavior is not dynamic.

Take the discount behavior as an example. I presume the 'note' line item can't take a discount. I presume a regular line item can take a discount. If lines are grouped, can discounts apply to the group and the lines individually? Or do lines only take a discount when they are not part of a group?

No matter what pattern(s) you use, you should identify the common behavior between all your line types and formalize that with an interface.

If a regular line item is not allowed to have a discount when it is part of a group, then the decorator pattern is a good usage for this change in behavior. If regular line items can always take a discount, then I might lean toward defining an interface for discounts and implementing that on the regular line item, but not on the note line item.

One area that complicates the decorator pattern (as well as other patterns), is object persistence. If you use the decorator pattern for your discount, and the added behavior has to be persisted (e.g. storing the discount %), who is responsible for persisting the data (i.e. knows the table name and column name)? The decorator? The contained base line object?

Also keep in mind that many complex business cases are implementing using a combination of design patterns.

I know this is kind of muddying the waters. I have been working on a project that uses bills of material. These bills of material can contain objects of many different types, both tangible and intangible. These objects also have varying behavior. I tried the Decorator, but I wasn't able to satisfactorily resolve the persistence issue in my database, so I am extending by implementing additional interfaces.

ajj3085 replied on Wednesday, June 21, 2006

hurcane:
Be sure that the decorator pattern solves your problem in the best way. The decorator pattern is great for dynamically adding behavior to objects. I have found the decorator pattern not as useful when the behavior is not dynamic.


Point well taken.  There's another problem with the decorator pattern as well; I may be required to have the discount itself show up as its own line item. 

hurcane:
Take the discount behavior as an example. I presume the 'note' line item can't take a discount. I presume a regular line item can take a discount. If lines are grouped, can discounts apply to the group and the lines individually? Or do lines only take a discount when they are not part of a group?


A note wouldn't take a discount.  Groups become 'indivisible' so you can't order the items within a group or modify the quanities (except for the 'parent').  Well, possibly the exception is a bundle.  For a bundle part, the parts administrator will have the ability to set a fixed price for the bundle, or let the price simply be the sum of the current prices for the components of the bundle.

hurcane:
No matter what pattern(s) you use, you should identify the common behavior between all your line types and formalize that with an interface.


Definatly..

hurcane:
If a regular line item is not allowed to have a discount when it is part of a group, then the decorator pattern is a good usage for this change in behavior. If regular line items can always take a discount, then I might lean toward defining an interface for discounts and implementing that on the regular line item, but not on the note line item.


That's part of the desicion I need to make.  Can line items contain other line items?  Or just contain a part list?  I'm leaning toward a line item ONLY being able to contain a  list of parts, and not other line items, since that seems like it would make things simpler.

hurcane:
One area that complicates the decorator pattern (as well as other patterns), is object persistence. If you use the decorator pattern for your discount, and the added behavior has to be persisted (e.g. storing the discount %), who is responsible for persisting the data (i.e. knows the table name and column name)? The decorator? The contained base line object?


I've thought of this as well.  Fortunalty I've already decided to design my business objects before I decide on a database schema.

hurcane:
Also keep in mind that many complex business cases are implementing using a combination of design patterns.

I know this is kind of muddying the waters. I have been working on a project that uses bills of material. These bills of material can contain objects of many different types, both tangible and intangible. These objects also have varying behavior. I tried the Decorator, but I wasn't able to satisfactorily resolve the persistence issue in my database, so I am extending by implementing additional interfaces.


Nope, not muddying the waters, I knew this was going to be a fairly complex piece of the application. 

Thanks for the input.

Andy

malloc1024 replied on Wednesday, June 21, 2006

I agree that you should make sure that the decorator is useful for you in this situation.  It was only a suggestion for you to look into.  Many of the projects that I have seen have used a decorator to apply discounts.  However, this does not mean that it is appropriate in your situation.  The alternative to this solution is to create a discount interface and implement that in the line item class.   Hurcane already explained this well in his previous post.  You know your project better than I.  Therefore, the best I can do is to give you ideas on how to finish your project.  I was merely trying to give an alternative idea to the more obvious solution.  I should have explained both solutions and the pros and cons for each. 

ajj3085 replied on Wednesday, June 21, 2006

malloc1024:
I agree that you should make sure that the decorator is useful for you in this situation.  It was only a suggestion for you to look into.  Many of the projects that I have seen have used a decorator to apply discounts.  However, this does not mean that it is appropriate in your situation.  The alternative to this solution is to create a discount interface and implement that in the line item class.   Hurcane already explained this well in his previous post.  You know your project better than I.  Therefore, the best I can do is to give you ideas on how to finish your project.  I was merely trying to give an alternative idea to the more obvious solution.  I should have explained both solutions and the pros and cons for each. 


malloc,

I very much appreciated your idea (and its a good excuse to get me to start studying patterns; I did order the Head First book mentioned above, since it had quite a few good reviews).   I don't think there was anything wrong with your inital post.

In fact I do feel that it would be an appropriate pattern to apply, but the wrinkle is that the discount must display as its own line item..  which is frustrating, because it feels like I now need a line item object just for the sake of the UI, not any real business purpose. 

On the UI front, has anyone used the standard DataGridView for display / edit of line items?  Or are people using the Infragistics grid?  Are there any other 3rd party grid controls which someone here recommends?

Thanks for all the input so far.
andy

dean replied on Wednesday, June 21, 2006

Andy

- I use the standard Datagridview for displaying/editing line items

- I also have a fairly complicated line item (but not like yours) - I have a common interface that each line item implements and this is what is displayed in the datagridview. To edit the other specific properties the user double clicks the line and a detail form is displayed that is configured for that type of line item. You could do something similar but instead have either another datagridview come up with the collection of line items if it is a group ir a detail form if it isn't a group.

One other comment - sometimes UI specific behavior may be handled better in the UI. A wrapper function could be built around the object by the UI developer with the UI specific behaviors built in

Dean

ajj3085 replied on Wednesday, June 21, 2006

dean:
I also have a fairly complicated line item (but not like yours) - I have a common interface that each line item implements and this is what is displayed in the datagridview. To edit the other specific properties the user double clicks the line and a detail form is displayed that is configured for that type of line item. You could do something similar but instead have either another datagridview come up with the collection of line items if it is a group ir a detail form if it isn't a group.


I like the idea of double clicking to set information which is extra from the base line item.  I don't think I'll be able to get away with forcing the users to double click to display 'sub items' though.. their current software doesn't do this, and they won't be happy with extra steps.  Fortunatly a 3rd party control may be able to help here, since the Infragistics grid lets you have expandable rows.

I got some clarifications on the requirements; to do a discount, they want to force that a subtotal line item has been added (the behavior I think will work is that it will total line items above it, but stopping at another sub-total (since they want to have multiple subtotals) ). 

So, I'm feeling better.  I guess i won't be able to use the decorater pattern, but I think I have a good idea how to proceed.

Thanks for all the input everyone (but of course keep posting ify ou have something to add, I'm only doing UML diagrams at the moment).
Andy

Copyright (c) Marimer LLC