-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
Problem
I would like to introduce catalogue promotions that are specific to certain customer groups. Those promotion rules should be considered as additional catalogue rule meaning that best of "standard" catalogue rules and "group specific" catalogue rules is applied.
Example 1:
Product X: price 100 EUR (from Category 1)
Promotion A: -10 EUR on product X
Promotion B: -15% on Category 1 for customer group LoyalCustomer
Price displayed in storefront: 90 EUR (100EUR minus discount from promotion A)
Price when LoyalCustomer adds product to the cart: 85 EUR (100EUR minus discount from promotion B which is better than A)
Example 2:
Product X: price 100 EUR (from Category 1)
Promotion A: -15 EUR on product X
Promotion B: -10% on Category 1 for customer group LoyalCustomer
Price displayed in storefront: 85 EUR (100EUR minus discount from promotion A)
Price when LoyalCustomer adds product to the cart: 85 EUR (100EUR minus discount from promotion A which is better than B)
Possible solutions with existing APIs
- Use separate channel for LoyalCustomer - possible for small e-commerce, but not for large international store. With many channels number of possible options for customer groups and regular channels would explode. It would also mean that all the channel settings need to be duplicated between "regular" channel and "customer group" channels
- Use middleware with
price
field fromCheckoutLineUpdateInput
. This solution does not allow to control for "regular" Promotions. I.e. if I use it to apply promotion B, promotion A will be applied on top of this (so final price in example 1 would be 76.5 EUR). This approach changesundiscountedPrice
, so all the fields related to discounts in promotions become useless.
Discord Discussion Link
https://discord.com/channels/864066819866624010/1098185593160216666/1359481364004605985
General Assumptions
I propose:
- To introduce a concept of Customer Group for Users
- To allow for promotion rules to be specific for a Customer Group
Such promotion rule:
- Would not be applied to discontedPrice in
Product/VariantChannelListing
- Would be applied in checkout if checkout user is assigned to given
CustomerGroup
- Would be treated as additional
CatalogueRule
- meaning that it will be applied only if it is more beneficial than other CatalogueRules
API Changes
Mutations
mutation CustomerGroupCreate($name: String!) {
customerGroupCreate(input: {name: $name}) {
id
name
}
}
mutation AccountUpdate($customerId: ID!, $addGroups: [ID!], $removeGroups: [ID!]) {
accountUpdate(customerId: $customerId, input: {addGroups: $addGroups, removeGroups: $deleteGroups}) {
customerGroups {
id
name
translation(languageCode: PL) {
name
}
}
}
}
Add field customerGroups
([ID!]
) to PromotionRuleInput
Add fields addCustomerGroups
([ID!]
) and removeCustomerGroups
([ID!]
) to PromotionRuleUpdateInput
Database Changes
- Create new model
CustomerGroup
(fields: name) - Create new model
CustomerGroupTranslation
- Add field customer_groups (ManyToMany with
CustomerGroup
) to model User (saleor/saleor/account/models.py
Line 160 in 36a9a14
class User( - Add field customer_groups (ManyToMany with
CustomerGroup
) to modelPromotionRule
(saleor/saleor/discount/models.py
Line 318 in e4f90c6
class Promotion(ModelWithMetadata): - Add field customer_group_specific (Boolean) to easily filter Rules with no
CustomerGroup
constraints
UML Diagrams
No response
To Do List
Logic changes:
- Only consider
PromotionRules
withcustomer_group_specific=False
in functionget_product_promotion_discounts
(possibly rename to something like get_public_product_promotion_discountssaleor/saleor/discount/utils/promotion.py
Line 137 in 36a9a14
def get_product_promotion_discounts( - Filter
rules_info
inprepare_checkout_line_discount_objects_for_catalogue_promotions
bycustomer_groups
before taking first (i.e. best) one (saleor/saleor/discount/utils/checkout.py
Line 147 in 5829c1f
rule_info = line_info.rules_info[0]
Testing Requirements
No response