Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the 'modifiers' concept from shop? #128

Open
jedateach opened this issue Dec 18, 2012 · 6 comments
Open

Remove the 'modifiers' concept from shop? #128

jedateach opened this issue Dec 18, 2012 · 6 comments
Labels

Comments

@jedateach
Copy link
Contributor

Modifiers are a way of abstracting away different types of order sub total lines. These can be additive (shipping cost, payment surcharge), or subtractive (coupons, credit notes). Modifiers have been around pretty much since the start of the ecommerce module.

Benefits include:

  • being able to include modifiers with submodules to add on extra order subtotal lines
  • simple way of processing subtotal lines in templates
  • ability to choose the order of subtotals

Problems with modifiers

Whilst the original intention has been for developers to create their own modifiers, to be plugged into the system as desired, this has only really been done by core developers creating things like custom shipping methods. Also, I'm seeing more and more cases where one system relies on another. Some examples:

Shipping methods were the main way in which modifiers have been historically used. We have a separate shipping system now, which I believe was a step in the right direction. It only relies on modifiers to store the shipping value, but all the shipping methods and calculations are separate. Plus, it's relatively easy to have multiple shipping options.

Solution

My initial thoughts are to 'hard code' a lot more features, although I'm not entirely sure how this should happen.

It may be that we still want to retain the ability to order sub totals, and what totals are available.

Or, on the other hand, we could take a 'convention over configuration' approach. This would mean the most, if not all, of the ordering and what is available is hard coded. This may give us subtotals like:

  • items subtotal
  • item tax
  • shipping
  • handling fee
  • shipping tax
  • shipping discount
  • payment surcharge
  • payment surcharge tax
  • payment surcharge discount
  • eco tax
  • IE browser tax?
  • more subtotals here

As you see, this convention approach could get quite complex, and realistically it would be nice if the subtotals were optional, and orderable.

Related: #127

@jedateach
Copy link
Contributor Author

@nimeso @wildflower do you have any thoughts on this?

@wildflower
Copy link
Contributor

I'm guessing when you say orderable you mean a sort order when they're displayed, or a sequence that they should be applied in a particular order of precedence.

If you have a % rate coupon discount to apply on an already discounted Sale Price item, which modifier/discount should win or should it be cumulative.

Sometime coupons could be %15 off or $10 off, possibly on only a selection of products - just Lego and not Barbie

You've mentioned discounts on shipping only (which I've come across as a project request)
the whole coupon thing should be separate module I believe simply because of the complexity in all the use cases.

I guess modifiers provide hooks you can swing off for this type of processing?

VIP member pricing was another big issue (in a previous role), and whether coupons should apply to those prices or if there was an absolute minimum price for a product (cost plus a slice of profit) and how that should be calculated.

I guess a barebones system needs a flat tax calculation for GST/VAT at least in NZ/AU/UK - (America goes silly with all it's state taxes rules - which are probably easier to ignore for us)

I guess it depends how "complete" you want 1.0 to be

I haven't read the modifier bits of code or how it holds together yet

@jedateach
Copy link
Contributor Author

Thanks for your feedback @wildflower.

Modifiers

Yes, I mean order of display and calculation. Modifiers calculations will start by taking the subtotal of the order items, perform any changes, and then pass the new subtotal to the next modifier, and so on. Sometimes you want tax to be calculated before, or after, or somewhere between everything else.

Modifiers are set up by adding them to an array of modifier class names. For example:

Order::set_modifiers(array(
    'OrderCouponModifier',
    'ShippingFrameworkModifier',
    'FlatTaxModifier'
));

Individual modifiers can currently be accessed by $order->getModifier('ClassOfModifier',true), where the second argument forces a write.

Discounts

You've brought up some good points and ideas about discounts. I'm currently trying to flesh out the discount module more. I see it that there are multiple places where discounts could be introduced.

  • Products - eg 10% off this product this week (new price, and struck out old price), regionalised prices
  • Order Items - eg 3 for the price of 1
  • Order - eg free shipping for Christmas day only, VIP members special rates
  • Order Coupon / voucher

Definitely a valid point about how discounts are combined, or not. Unit tests are definitely mandatory to ensure the

shop 1.0

Regarding 1.0 completeness, I guess it doesn't need to be full featured, but desire that the core is written in a way that keeps these features in mind. It does make sense to abstract the core, and allow additional features to be added via submodules, however I'm beginning to see more and more inter-reliance on some modules. Speaking about discounts, I see discounting as a core part of ecommerce, that can simply be ignored if not desired.

any further thoughts?

@jedateach
Copy link
Contributor Author

For the mean time, modifiers are here to stay. I'm going to remove the '1.0' milestone from this issue.

@jedateach jedateach removed this from the 1.0.0 - for SilverStripe 3 milestone Feb 14, 2014
@jedateach
Copy link
Contributor Author

Relates to #41

@jedateach
Copy link
Contributor Author

The following notes have been moved from https://github.com/burnbright/silverstripe-shop/wiki/Modifiers-Upgrade-Plan

March 2012

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.

Why even use modifiers?

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?

Requirements

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?

Plan

  • Split out all the view/rendering-related code into a ViewableData class. It should be separate from model code.

To Consider

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants