Comments (11)
Another use case would be user entered price (ie. variable priced gift cards), which I guess falls under pricing by custom attributes? We also do item pricing based on customization in our store, and we do all our price determination at add to cart (before_validation on: :create
), or whenever the line item is updated but the order is not yet complete. For example a cart edit type interaction.
from solidus.
👍 But how would this differ from adjustments on line items? Much like @paultyng we do pricing based on customization with adjustments. One thing also to consider is price changes that one wouldn't want to be affected by promotions. In our use cause we want promotions to only affect the price of the product not the fees that would be incurred through customization.
from solidus.
I wonder if some of these could also be able to be solved by #419 with promotion rules for the situation (e.g. item quantity greater than, ship address country equal, email address in list)?
from solidus.
i solved some similar problems with the "Price Lists" approach, see here: https://github.com/alepore/rfcs/blob/705601769eaec76319308a6108d8b15452523f93/active/000-price-lists.md
from solidus.
@alepore love the RFC :D
from solidus.
The multiple prices support is a common problem that keeps coming out on my projects.
I'm wondering if the "price list" approach could be taken into consideration to be included on the Solidus core.
Full explanation from the former Spree RFC:
Abstract
I'd like to move the current "price belongs to currency" Solidus logic to a more
flexible "price belongs to a price list".
A price list is a way to differentiate multiple prices of the same item.
Motivation
A Store may need different prices for the same product/variant, for
different reasons (see below for a non-exhaustive list of examples).
Solidus currently supports different prices if they have different currencies,
but in my experience this is not always the case in the real world.
I'm proposing this because I needed this feature on some projects and the
current Solidus prices/currency logic was a clear limit.
Here are some use cases (actual sites, 2 on production and 2 on development):
- A fashion store needs a different price for each zone. Actually, some brands
have a specific price list for some countries and they want to follow this.
They like to use the same base currency (EUR) on all lists to keep things simple.
The payment gateway will do all the currency conversions. - A B2B store has 3 different price lists. Each agent is assigned to a price
list. Currency is the same for all lists because the target is the same country. - A B2B + B2C store has different prices for public clients and internal
agents. Currency is the same. - A furniture store wants to use two different prices, one for their home
country and one for the rest of the europe. Currency is always EUR.
Detailed Design
I've done a Spree extension for this feature, the code is at
https://github.com/freego/spree_price_lists.
It's probably not production ready, it was extracted from a project and it's
missing tests.
Looks like this is similar to https://github.com/spree-contrib/spree_price_books,
but I think my version is more simple and "generic".
I saw some logics on spree_price_books that are probably extracted from a
project with very specific needs.
On Solidus, a variant has many prices. This is a good start point, but it's also
very limited in my opinion because of the currency
stuff.
Inside Solidus, currency
is just a string and is passed as parameter on many
methods, expecially during the checkout process.
I want to change this to pass a price list reference instead.
A price list is a simple model which can just have a name
and a currency
in
the most basic form.
This will not change any behavior for simple stores, because you'll just have
a default price list with your preferred currency.
This should enable flexibility to easily add any kind of custom logic for price
list selection.
For example, on the mentioned fashion store I get the user location from the IP
address and I load the right price list on the fly.
On the B2B store, I get the price list from current_user
object.
This should be just a matter of overriding a method, which by default gets the
default price list.
Drawbacks
We have to add some logic to determine which list should be used on each
request.
This can degrade performance, but on a basic Solidus store this can be just a
single, cachable query like PriceList.first
or similar.
Alternatives
I can just keep improving the extension.
I'm totally for keeping the Solidus core as simple as possibile and using
extensions, but in this case I think needed changes are too "low level".
I need many decorators to overwrite many important methods, and it's only to
switch from currency to price list.
Those methods also change often: I basically rewrited everything between Spree
2.3 and 2.4, and it needs some more work for 3.0.
Another alternative I tried was to keep Solidus as is and to add "fake"
currencies, like "EU1", "EU2", all with the same € symbol.
The main problem here is that fake currencies doesn't work in the real world.
For example, you can't pass them to a payment gateway.
from solidus.
👍
from solidus.
I see two distinct problems:
One is price differentiating, or looking up a specific price for a variant based on some criteria. Examples of this are:
- different pricing by country
- different pricing by user
Two is price modification, or calculating an adjustment on the price of variant based on some criteria. Examples of this are:
- bulk discounts
- pricing by certain attributes
This comment focuses on problem two; as our project uses two extensions of that nature, one performs bulk discounts and the other does "pricing by certain attributes".
I think @athal7 is on the right track, but attempting to extend promotion rules will run into problems when you:
- Need to make positive adjustments (add $1 for bacon on your burger)
- Are forced to choose between these promotions
- Extend with arbitrarily complex logic
I propose the solution lies in providing well-defined extension points into the item adjustment framework, so new types can easily be added and hooked into ItemAdjustments for recalculating. This is what we do with our extensions (but in the class_eval style) and it has worked out tremendously.
For instance, we have a BulkDiscount model that mirrors the TaxRate model in a lot of ways, it is automatically added to a LineItem during it's after_create
callback and then recalculates itself in ItemAdjustment's update. All of it's logic is neatly encapsulated and it just "works" (minus having to class_eval).
In general, the adjustment flexibility comes from:
- Adjustments can be applied in arbitrarily complex ways, you can have something like the TaxRate which is always added or PromotionAction which is applied using a ton of "outside" information (i.e. coupon codes, order, user, etc) and logic.
- Adjustments can be calculated in arbitrarily complex, you can have a PromotionAction that uses a simple calculator, or a TaxRate which is calculated using a ton of "outside" information (i.e. zones, addresses, taxation systems) and logic.
But despite all the potential complexity, at the end of the day there is a simple API for items to take on, and keep updated (through ItemAdjustment), any number of adjustments.
There are some definitely some tricky parts but all in all I think if there was an easy way to hook into ItemAdjustment so that arbitrary adjustment scopes could have their adjustments updated and value updated on the item in question, stores could write extensions of type two quite cleanly.
Side notes:
We use the term modifier for "pricing by custom attributes. This is a term we pulled from the restaurant industry that fits this pretty well (ex: burger ($6) + add bacon ($1) + add jalapenos ($0.50)).
from solidus.
For supporting VAT, I need to be able to modify prices as well, but automatically. I have time for implementing this, and if this discussion comes up with something useful, I'd be more than happy to use that.
In #532, @cbrunsdon mentioned that the core team prefers a solution that'd be as simple as possible. I reference this issue here so I can close #532.
from solidus.
Is the PriceSelector
that's been in core since 1.3 good enough to close this issue? Are we missing features?
from solidus.
PriceSelector
certainly fulfills this issue. If there are other requirements, they should be in a new issue.
from solidus.
Related Issues (20)
- [Admin] Reuse typography styles
- [Admin] Live search functionality
- [Admin] Align the admin and backend menus for a transparent switch HOT 1
- [Admin] Review batch actions a11y
- Unable to upload an image from Solidus API HOT 3
- Unable to add product in admin panel HOT 3
- [Admin] Release SolidusAdmin v0.0.1.alpha.1 HOT 1
- [Admin] add a banner for turning solidus_admin `on` and `off` HOT 2
- [Admin] allow to reuse or back port custom backend menu items in solidus_admin
- [Admin] Refactor "accounts/show" view into a separate component HOT 2
- Psych minimum version with Solidus-3.4 should be v4.0.1
- [Admin] Add page to create products
- [Admin] Integrate i18n-tasks with the new admin
- [Admin] Add order list index page
- PromotionCodeBatch fails generating million codes
- [admin] Backend sections to be ported to SolidusAdmin
- Release v4.2.0
- New admin breaks `assets:precompile` when host app has default Tailwind setup. HOT 2
- [Admin] Search by name in stock HOT 7
- Spree::Variant#set_position conflicts with acts_as_list
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from solidus.