The modifier system needs some serious thought. It is difficult to understand how it should be used.
The code is not clear and concise.
MVC "View" code is coupled with "Model" code. What is possible to do with modifiers is not well understood, documented,
or unit tested.
Definition of modifiers: Non-item deductions or additions that affect the order total.
Here is a breakdown of possible types of lines that would show in an order:
- OrderAttribute (Lines)
- Items
* Product
* Digital Download
* Custom Product
* Free Gift
- Modifiers
- Add
- Shipping
- Tax
- Payment Gateway Fees
- Subtract
- Coupon Discount
- Group Discount
- Credit
- SubTotal
- RunningTotal
- Information
- Total
Some lines should not be classed as a modifiers, but just an extra piece of displayed information.
Advantage of having modifiers as their own set/class of lines?
- common rendering systems
- scalable - a standardised interface for creating new footer lines
Could these simply be applied to an order as additional fields? eg: ShippingCost, TaxCost, Discount.
New additional fields can be added via decorators. Yes, but modifiers will be considered the default solution.
Shipping was once done with ShippingCalculators ...I wonder if that should be adopted once again?
This is what I think you should be able to do:
-
define the order in which lines are displayed/calculated eg: items...subtotal->shipping->subtotal->discount->tax...total.
-
ability to include/exclude, eg add/remove a discount, or place an order with no shipping.
-
pick from different sub-types: eg - shipping provider options
- options can automatically change, based on order information
- optionally require one be chosen before order is placed, such as shipping
-
chargable (eg shipping), deductable (eg discount), or ignored (eg tax inclusive).
-
display modifier info anywhere on site, eg shipping info, or entered coupon.
-
graceful degredation - historical orders still total up correctly, even if modifiers have been disabled.
- what about if they have been removed from system? ->not a priority: possibly include migration scripts.
-
display subtotals, or running totals at any point, without having them save to database.
-
individual template/view per line. ie each line need not look the same.
-
recalculate values on cart (or modifiers) modification, and especially final checkout steps...or on every request?
- database writes should not be preformed on every request, if they are not needed.
-
All order information should be stored in the database, and not require code to do any calculations. It is ok to do calculations
before an order is placed, but afterwards all order information should be retrieved from database.
- Split out all the view/rendering-related code into a ViewableData class. It should be separate from model code.
- Should orders be completely immutable once they have been placed? > more yes than no
- Should lines be stored as negative values, or be flagged?
- Can an order have more than one of the same modifier?...probably not needed in most cases, but it might be useful to allow it anyway. eg: two discount coupons applied to an order.
When to calculate orders. They need to be calculated after any changes have been made, but not until all changes have been made.
Possible solutions:
-
Overload controller, and add a hook after actions have been called
-
Use a different function for adding Cart to templates, which does a recalculation
-
Run calculation every time order is accessed
-
Calculate only if changes dirty