solidus_friendly_promotions 1.0.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/MIGRATING.md +1 -1
- data/README.md +22 -16
- data/app/assets/config/solidus_friendly_promotions/manifest.js +7 -1
- data/app/controllers/solidus_friendly_promotions/admin/benefits_controller.rb +85 -0
- data/app/controllers/solidus_friendly_promotions/admin/conditions_controller.rb +69 -0
- data/app/controllers/solidus_friendly_promotions/admin/promotions_controller.rb +3 -3
- data/app/decorators/models/solidus_friendly_promotions/adjustment_decorator.rb +4 -4
- data/app/decorators/models/solidus_friendly_promotions/line_item_decorator.rb +2 -2
- data/app/decorators/models/solidus_friendly_promotions/order_decorator.rb +6 -6
- data/app/helpers/solidus_friendly_promotions/admin/benefits_helper.rb +19 -0
- data/app/helpers/solidus_friendly_promotions/admin/conditions_helper.rb +12 -0
- data/app/javascript/solidus_friendly_promotions/controllers/product_option_values_controller.js +1 -1
- data/app/javascript/solidus_friendly_promotions/web_components/number_with_currency.js +35 -0
- data/app/javascript/solidus_friendly_promotions/{jquery → web_components}/option_value_picker.js +8 -0
- data/app/javascript/solidus_friendly_promotions/web_components/product_picker.js +7 -0
- data/app/javascript/solidus_friendly_promotions/web_components/select_two.js +11 -0
- data/app/javascript/solidus_friendly_promotions/web_components/taxon_picker.js +7 -0
- data/app/javascript/solidus_friendly_promotions/web_components/user_picker.js +7 -0
- data/app/javascript/solidus_friendly_promotions/web_components/variant_picker.js +7 -0
- data/app/javascript/solidus_friendly_promotions.js +7 -11
- data/app/models/concerns/solidus_friendly_promotions/{actions/order_level_action.rb → benefits/order_benefit.rb} +2 -2
- data/app/models/concerns/solidus_friendly_promotions/{rules/line_item_applicable_order_rule.rb → conditions/line_item_applicable_order_condition.rb} +2 -2
- data/app/models/concerns/solidus_friendly_promotions/{rules/line_item_level_rule.rb → conditions/line_item_level_condition.rb} +2 -2
- data/app/models/concerns/solidus_friendly_promotions/{rules/order_level_rule.rb → conditions/order_level_condition.rb} +2 -2
- data/app/models/concerns/solidus_friendly_promotions/{rules/shipment_level_rule.rb → conditions/shipment_level_condition.rb} +2 -2
- data/app/models/solidus_friendly_promotions/{promotion_action.rb → benefit.rb} +48 -11
- data/app/models/solidus_friendly_promotions/{actions → benefits}/adjust_line_item.rb +6 -2
- data/app/models/solidus_friendly_promotions/{actions → benefits}/adjust_line_item_quantity_groups.rb +3 -3
- data/app/models/solidus_friendly_promotions/{actions → benefits}/adjust_shipment.rb +6 -2
- data/app/models/solidus_friendly_promotions/{actions → benefits}/create_discounted_item.rb +6 -7
- data/app/models/solidus_friendly_promotions/calculators/distributed_amount.rb +1 -1
- data/app/models/solidus_friendly_promotions/calculators/tiered_flat_rate.rb +1 -1
- data/app/models/solidus_friendly_promotions/calculators/tiered_percent.rb +1 -1
- data/app/models/solidus_friendly_promotions/calculators/tiered_percent_on_eligible_item_quantity.rb +4 -2
- data/app/models/solidus_friendly_promotions/{promotion_rule.rb → condition.rb} +13 -7
- data/app/models/solidus_friendly_promotions/condition_product.rb +8 -0
- data/app/models/solidus_friendly_promotions/condition_store.rb +8 -0
- data/app/models/solidus_friendly_promotions/condition_taxon.rb +8 -0
- data/app/models/solidus_friendly_promotions/{promotion_rules_user.rb → condition_user.rb} +2 -2
- data/app/models/solidus_friendly_promotions/{rules → conditions}/discounted_item_total.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/first_order.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/first_repeat_purchase_since.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/item_total.rb +5 -5
- data/app/models/solidus_friendly_promotions/{rules → conditions}/line_item_option_value.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/line_item_product.rb +8 -8
- data/app/models/solidus_friendly_promotions/{rules → conditions}/line_item_taxon.rb +8 -8
- data/app/models/solidus_friendly_promotions/{rules → conditions}/minimum_quantity.rb +8 -8
- data/app/models/solidus_friendly_promotions/{rules → conditions}/nth_order.rb +5 -5
- data/app/models/solidus_friendly_promotions/{rules → conditions}/one_use_per_user.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/option_value.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/product.rb +9 -9
- data/app/models/solidus_friendly_promotions/{rules → conditions}/shipping_method.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/store.rb +6 -6
- data/app/models/solidus_friendly_promotions/{rules → conditions}/taxon.rb +12 -12
- data/app/models/solidus_friendly_promotions/{rules → conditions}/user.rb +7 -7
- data/app/models/solidus_friendly_promotions/{rules → conditions}/user_logged_in.rb +3 -3
- data/app/models/solidus_friendly_promotions/{rules → conditions}/user_role.rb +3 -3
- data/app/models/solidus_friendly_promotions/eligibility_result.rb +1 -1
- data/app/models/solidus_friendly_promotions/eligibility_results.rb +7 -7
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/discount_order.rb +28 -29
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/load_promotions.rb +10 -11
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/persist_discounted_order.rb +2 -2
- data/app/models/solidus_friendly_promotions/order_promotion.rb +1 -1
- data/app/models/solidus_friendly_promotions/permission_sets/friendly_promotion_management.rb +1 -1
- data/app/models/solidus_friendly_promotions/promotion.rb +14 -43
- data/app/models/solidus_friendly_promotions/promotion_advertiser.rb +10 -0
- data/app/models/solidus_friendly_promotions/promotion_code.rb +1 -1
- data/app/models/solidus_friendly_promotions/shipping_rate_discount.rb +1 -1
- data/app/views/solidus_friendly_promotions/admin/benefit_fields/_adjust_line_item.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_actions/actions → benefit_fields}/_adjust_line_item_quantity_groups.html.erb +4 -4
- data/app/views/solidus_friendly_promotions/admin/benefit_fields/_adjust_shipment.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/benefit_fields/_calculator_fields.erb +11 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_actions/actions → benefit_fields}/_create_discounted_item.html.erb +8 -6
- data/app/views/solidus_friendly_promotions/admin/benefits/_benefit.html.erb +50 -0
- data/app/views/solidus_friendly_promotions/admin/benefits/_calculator_select.html.erb +16 -0
- data/app/views/solidus_friendly_promotions/admin/benefits/_form.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/benefits/_new_benefit.html.erb +33 -0
- data/app/views/solidus_friendly_promotions/admin/benefits/_type_select.html.erb +16 -0
- data/app/views/solidus_friendly_promotions/admin/benefits/edit.html.erb +19 -0
- data/app/views/solidus_friendly_promotions/admin/benefits/new.html.erb +1 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_actions/calculators → calculator_fields}/_default_fields.html.erb +1 -1
- data/app/views/solidus_friendly_promotions/admin/{promotion_actions/calculators → calculator_fields}/distributed_amount/_fields.html.erb +3 -3
- data/app/views/solidus_friendly_promotions/admin/calculator_fields/flat_rate/_fields.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/calculator_fields/flexi_rate/_fields.html.erb +24 -0
- data/app/views/solidus_friendly_promotions/admin/calculator_fields/percent/_fields.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/calculator_fields/tiered_flat_rate/_fields.html.erb +32 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_actions/calculators → calculator_fields}/tiered_flat_rate/_tier_fields.html.erb +7 -8
- data/app/views/solidus_friendly_promotions/admin/calculator_fields/tiered_percent/_fields.html.erb +47 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_actions/calculators → calculator_fields}/tiered_percent/_tier_fields.html.erb +8 -7
- data/app/views/solidus_friendly_promotions/admin/{promotion_actions/calculators → calculator_fields}/tiered_percent_on_eligible_item_quantity/_fields.html.erb +11 -9
- data/app/views/solidus_friendly_promotions/admin/calculator_fields/tiered_percent_on_eligible_item_quantity/_tier_fields.html.erb +35 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_first_order.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_first_repeat_purchase_since.html.erb +7 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_item_total.html.erb +15 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_line_item_option_value.html.erb +25 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_rules/rules → condition_fields}/_line_item_product.html.erb +7 -7
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_line_item_taxon.html.erb +17 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_minimum_quantity.html.erb +5 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_nth_order.html.erb +15 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_one_use_per_user.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_rules/rules → condition_fields}/_option_value.html.erb +10 -10
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_product.html.erb +28 -0
- data/app/views/solidus_friendly_promotions/admin/{promotion_rules/rules → condition_fields}/_shipping_method.html.erb +3 -3
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_store.html.erb +9 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_taxon.html.erb +28 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_user.html.erb +7 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_user_logged_in.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/_user_role.html.erb +15 -0
- data/app/views/solidus_friendly_promotions/admin/condition_fields/line_item_option_value/_option_value_fields.html.erb +21 -0
- data/app/views/solidus_friendly_promotions/admin/conditions/_condition.html.erb +26 -0
- data/app/views/solidus_friendly_promotions/admin/conditions/_new_condition.html.erb +26 -0
- data/app/views/solidus_friendly_promotions/admin/conditions/_type_select.html.erb +20 -0
- data/app/views/solidus_friendly_promotions/admin/conditions/new.html.erb +1 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_code_batches/_form_fields.html.erb +5 -5
- data/app/views/solidus_friendly_promotions/admin/promotions/_form.html.erb +4 -4
- data/app/views/solidus_friendly_promotions/admin/promotions/_table_filter.html.erb +6 -6
- data/app/views/solidus_friendly_promotions/admin/promotions/edit.html.erb +7 -41
- data/app/views/solidus_friendly_promotions/admin/shared/_number_with_currency.html.erb +20 -0
- data/app/views/solidus_friendly_promotions/admin/shared/preference_fields/_boolean.html.erb +14 -0
- data/app/views/solidus_friendly_promotions/admin/shared/preference_fields/_decimal.html.erb +12 -0
- data/app/views/solidus_friendly_promotions/admin/shared/preference_fields/_encrypted_string.html.erb +12 -0
- data/app/views/solidus_friendly_promotions/admin/shared/preference_fields/_integer.html.erb +12 -0
- data/app/views/solidus_friendly_promotions/admin/shared/preference_fields/_password.html.erb +12 -0
- data/app/views/solidus_friendly_promotions/admin/shared/preference_fields/_string.html.erb +12 -0
- data/app/views/solidus_friendly_promotions/admin/shared/preference_fields/_text.html.erb +12 -0
- data/bin/sandbox +3 -3
- data/config/importmap.rb +2 -0
- data/config/locales/en.yml +128 -94
- data/config/routes.rb +3 -2
- data/db/migrate/20231011120928_add_db_comments_to_friendly_promotion_rules_taxons.rb +2 -2
- data/db/migrate/20231011142040_add_db_comments_to_friendly_promotion_rules_users.rb +1 -1
- data/db/migrate/20231011190222_add_db_comments_to_friendly_promotion_actions.rb +1 -1
- data/db/migrate/20240409093831_add_action_reference_to_rules.rb +34 -0
- data/db/migrate/20240506142650_remove_promotion_rules_promotion_id.rb +5 -0
- data/db/migrate/20240508080834_rename_promotion_rules_to_conditions.rb +19 -0
- data/db/migrate/20240508131514_rename_friendly_promotion_actions_to_friendly_benefits.rb +19 -0
- data/db/migrate/20240612113608_update_column_comments_for_benefits.rb +31 -0
- data/db/migrate/20240612114132_update_column_comments_for_conditions.rb +30 -0
- data/db/migrate/20240612115209_update_column_comments_for_condition_stores.rb +23 -0
- data/db/migrate/20240612115749_update_column_comments_for_condition_products.rb +22 -0
- data/db/migrate/20240612120411_update_column_comments_for_condition_taxons.rb +24 -0
- data/db/migrate/20240612121049_update_column_comments_for_condition_users.rb +23 -0
- data/lib/generators/solidus_friendly_promotions/install/templates/initializer.rb +30 -30
- data/lib/solidus_friendly_promotions/configuration.rb +11 -3
- data/lib/solidus_friendly_promotions/migrate_adjustments.rb +11 -11
- data/lib/solidus_friendly_promotions/promotion_map.rb +17 -17
- data/lib/solidus_friendly_promotions/promotion_migrator.rb +16 -16
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_promotion_factory.rb +8 -34
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_shipping_rate_discount_factory.rb +2 -2
- data/lib/solidus_friendly_promotions/version.rb +1 -1
- data/lib/tasks/solidus_friendly_promotions/migrate_adjustments.rake +2 -2
- data/solidus_friendly_promotions.gemspec +2 -2
- metadata +114 -86
- data/.rubocop_todo.yml +0 -157
- data/app/controllers/solidus_friendly_promotions/admin/promotion_actions_controller.rb +0 -103
- data/app/controllers/solidus_friendly_promotions/admin/promotion_rules_controller.rb +0 -105
- data/app/helpers/solidus_friendly_promotions/admin/promotion_actions_helper.rb +0 -23
- data/app/helpers/solidus_friendly_promotions/admin/promotion_rules_helper.rb +0 -25
- data/app/models/solidus_friendly_promotions/products_promotion_rule.rb +0 -8
- data/app/models/solidus_friendly_promotions/promotion_rules_store.rb +0 -8
- data/app/models/solidus_friendly_promotions/promotion_rules_taxon.rb +0 -8
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_calculator_select.html.erb +0 -16
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_form.html.erb +0 -3
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_promotion_action.html.erb +0 -29
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_type_select.html.erb +0 -14
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_line_item.html.erb +0 -6
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_shipment.html.erb +0 -6
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_calculator_fields.erb +0 -9
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/flat_rate/_fields.html.erb +0 -6
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_flat_rate/_fields.html.erb +0 -34
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_percent/_fields.html.erb +0 -34
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_percent_on_eligible_item_quantity/_tier_fields.html.erb +0 -27
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/edit.html.erb +0 -23
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/new.html.erb +0 -26
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/_promotion_rule.html.erb +0 -22
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/_type_select.html.erb +0 -20
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/new.html.erb +0 -24
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_first_order.html.erb +0 -3
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_first_repeat_purchase_since.html.erb +0 -6
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_item_total.html.erb +0 -17
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_option_value.html.erb +0 -25
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_taxon.html.erb +0 -17
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_minimum_quantity.html.erb +0 -5
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_nth_order.html.erb +0 -15
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_one_use_per_user.html.erb +0 -3
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_product.html.erb +0 -44
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_store.html.erb +0 -9
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_taxon.html.erb +0 -44
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user.html.erb +0 -7
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user_logged_in.html.erb +0 -3
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user_role.html.erb +0 -15
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/line_item_option_value/_option_value_fields.html.erb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c80d1d515ec8f0e3b4a5742c3715d92394e054b7b53bc41df7b8ba0c0532824
|
4
|
+
data.tar.gz: 2aa767f69a6df858b9ccf19cda5c65db70770feb3a087ca0fbc62f6d82ce4e37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80d3369aed9485a308424965906944f8ccc10159fd125da74a1f5446866727c6b8df986df7c13d0bceac1a8e24a191383ac18bc011c7fd7962ca03f3168ec1cf
|
7
|
+
data.tar.gz: 2dfd860061b46abd2324e86cc4e3bd89a8627b57097484c121fa4bc7282c7a976f7472b3f2033df2dddc5daf85f2af060bb6531ff9080f2321ae7b4a0bdafc69
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.9.0](https://github.com/friendlycart/solidus_friendly_promotions/tree/v1.9.0) (2024-06-13)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/friendlycart/solidus_friendly_promotions/compare/v1.0.1...v1.9.0)
|
6
|
+
|
7
|
+
**Merged pull requests:**
|
8
|
+
|
9
|
+
- Documentation updates [\#116](https://github.com/friendlycart/solidus_friendly_promotions/pull/116) ([mamhoff](https://github.com/mamhoff))
|
10
|
+
- Fix homepage path in gemspec [\#115](https://github.com/friendlycart/solidus_friendly_promotions/pull/115) ([pelargir](https://github.com/pelargir))
|
11
|
+
- Use Bootstrap cards for admin UI [\#114](https://github.com/friendlycart/solidus_friendly_promotions/pull/114) ([mamhoff](https://github.com/mamhoff))
|
12
|
+
- Rename promotion actions to benefits [\#113](https://github.com/friendlycart/solidus_friendly_promotions/pull/113) ([mamhoff](https://github.com/mamhoff))
|
13
|
+
- Include Discarded Promotions [\#112](https://github.com/friendlycart/solidus_friendly_promotions/pull/112) ([manleyac](https://github.com/manleyac))
|
14
|
+
- Rename promotion rules to conditions [\#111](https://github.com/friendlycart/solidus_friendly_promotions/pull/111) ([mamhoff](https://github.com/mamhoff))
|
15
|
+
- Rules per action [\#110](https://github.com/friendlycart/solidus_friendly_promotions/pull/110) ([mamhoff](https://github.com/mamhoff))
|
16
|
+
- Promotion advertiser [\#109](https://github.com/friendlycart/solidus_friendly_promotions/pull/109) ([mamhoff](https://github.com/mamhoff))
|
17
|
+
|
3
18
|
## [v1.0.1](https://github.com/friendlycart/solidus_friendly_promotions/tree/v1.0.1) (2024-05-07)
|
4
19
|
|
5
20
|
[Full Changelog](https://github.com/friendlycart/solidus_friendly_promotions/compare/v1.0.0...v1.0.1)
|
data/Gemfile
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
5
5
|
|
6
|
-
branch = ENV.fetch("SOLIDUS_BRANCH", "
|
6
|
+
branch = ENV.fetch("SOLIDUS_BRANCH", "v4.3")
|
7
7
|
gem "solidus", github: "solidusio/solidus", branch: branch
|
8
8
|
|
9
9
|
# The solidus_frontend gem has been pulled out since v3.2
|
data/MIGRATING.md
CHANGED
data/README.md
CHANGED
@@ -10,11 +10,7 @@ The basic architecture is very similar to the one in core Solidus, but with a fe
|
|
10
10
|
|
11
11
|
This extension centralizes promotion handling in the order updater. A service class, the `SolidusFriendlyPromotions::FriendlyPromotionAdjuster` applies the current promotion configuration to the order, adjusting or removing adjustments as necessary.
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
The design decision here is to make the code path easier to follow, and consequently to make it more performant ("Make it easy, then make it fast").
|
16
|
-
|
17
|
-
`SolidusFriendlyPromotions::Promotion` objects have rules and actions, just like `Spree::Promotion`. However, both rules and actions work slightly differently.
|
13
|
+
`SolidusFriendlyPromotions::Promotion` objects have benefits, and benefits have conditions. For example, a promotion that is "20% off shirts" would have a benefit of type "AdjustLineItem", and that benefit would have a condition of type "LineItemTaxon" that makes sure only line items with the "shirts" taxon will get the benefit.
|
18
14
|
|
19
15
|
### Promotion lanes
|
20
16
|
|
@@ -31,25 +27,37 @@ SolidusFriendlyPromotions.configure do |config|
|
|
31
27
|
end
|
32
28
|
```
|
33
29
|
|
34
|
-
###
|
30
|
+
### Benefits
|
31
|
+
|
32
|
+
Solidus Friendly Promotions ships with only three benefit types by default that should cover most use cases: `AdjustLineItem`, `AdjustShipment` and `CreateDiscountedItem`. There is no benefit that creates order-level adjustments, as this feature of Solidus' legacy promotions system has proven to be very difficult for customer service and finance departments due to the difficulty of accruing order-level adjustments to individual line items when e.g. processing returns. In order to give a fixed discount to all line items in an order, use the `AdjustLineItem` benefit with the `DistributedAmount` calculator.
|
33
|
+
|
34
|
+
Alle benefits are calculable. By setting their `calculator` to one of the classes provided, a great range of discounts is possible.
|
35
35
|
|
36
|
-
|
36
|
+
#### `AdjustLineItem`
|
37
37
|
|
38
|
-
|
38
|
+
Benefits of this class will create promotion adjustments on line items. By default, they will create a discount on every line item in the order. If you want to restrict which line items get the discount, add line-item level conditions, such as `LineItemProduct`.
|
39
39
|
|
40
|
-
|
40
|
+
#### `AdjustShipment`
|
41
41
|
|
42
|
-
|
42
|
+
Benefits of this class will create promotion adjustments on shipments. By default, they will create a discount on every shipment in the order. If you want to restrict which shipments get a discount, add shipment-level conditions, such as `ShippingMethod`.
|
43
|
+
|
44
|
+
### Conditions
|
45
|
+
|
46
|
+
Every type of benefit has a list of rules that can be applied to them. When calculating adjustments for an order, benefits will only produce adjustments on line items or shipments if all their respective conditions are true.
|
43
47
|
|
44
48
|
### Connecting promotions to orders
|
45
49
|
|
46
|
-
When there is a join record `SolidusFriendlyPromotions::OrderPromotion`, the promotion and the order will be "connected", and the promotion will be applied even if it does not `apply_automatically` (see below).
|
50
|
+
When there is a join record `SolidusFriendlyPromotions::OrderPromotion`, the promotion and the order will be "connected", and the promotion will be applied even if it does not `apply_automatically` (see below). This is different from Solidus' legacy promotion system here in that promotions are not automatically connected to orders when they produce an adjustment.
|
47
51
|
|
48
|
-
|
52
|
+
If you want to create an `OrderPromotion` record, the usual way to do this is via a promotion handler:
|
53
|
+
|
54
|
+
- `SolidusFriendlyPromotions::PromotionHandler::Coupon`: Connects orders to promotions if a customer or service agent enters a matching promotion code.
|
55
|
+
- `SolidusFriendlyPromotions::PromotionHandler::Page`: Connects orders to promotions if a customer visits a page with the correct path. This handler is not integrated in core Solidus, and must be integrated by you.
|
56
|
+
- `SolidusFriendlyPromotions::PromotionHandler::Page`: Connects orders to promotions if a customer visits a page with the correct path. This handler is not integrated in core Solidus, and must be integrated by you.
|
49
57
|
|
50
58
|
### Promotion categories
|
51
59
|
|
52
|
-
Promotion categories simply allow admins to group
|
60
|
+
Promotion categories simply allow admins to group promotions. They have no further significance with regards to the functionality of the promotion system.
|
53
61
|
|
54
62
|
### Promotion recalculation
|
55
63
|
|
@@ -78,9 +86,7 @@ bin/rails generate solidus_friendly_promotions:install
|
|
78
86
|
```
|
79
87
|
|
80
88
|
This will create the tables for this extension. It will also replace the promotion administration system under
|
81
|
-
`/admin/promotions` with a new one that needs `turbo-rails`.
|
82
|
-
|
83
|
-
It will also create an initializer within which Solidus is configured to use this extension's `SimpleOrderContents` and `FriendlyPromotionAdjuster` classes. Feel free to override with your own implementations!
|
89
|
+
`/admin/promotions` with a new one that needs `turbo-rails`. It will also create an initializer within which Solidus is configured to use `Spree::SimpleOrderContents` and this extension's `FriendlyPromotionAdjuster` classes. Feel free to override with your own implementations!
|
84
90
|
|
85
91
|
## Usage
|
86
92
|
|
@@ -4,4 +4,10 @@
|
|
4
4
|
//= link solidus_friendly_promotions/controllers/calculator_tiers_controller.js
|
5
5
|
//= link solidus_friendly_promotions/controllers/flash_controller.js
|
6
6
|
//= link solidus_friendly_promotions/controllers/product_option_values_controller.js
|
7
|
-
//= link solidus_friendly_promotions/
|
7
|
+
//= link solidus_friendly_promotions/web_components/option_value_picker.js
|
8
|
+
//= link solidus_friendly_promotions/web_components/product_picker.js
|
9
|
+
//= link solidus_friendly_promotions/web_components/user_picker.js
|
10
|
+
//= link solidus_friendly_promotions/web_components/taxon_picker.js
|
11
|
+
//= link solidus_friendly_promotions/web_components/variant_picker.js
|
12
|
+
//= link solidus_friendly_promotions/web_components/number_with_currency.js
|
13
|
+
//= link solidus_friendly_promotions/web_components/select_two.js
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
module Admin
|
5
|
+
class BenefitsController < Spree::Admin::BaseController
|
6
|
+
before_action :load_promotion, only: [:create, :destroy, :new, :update, :edit]
|
7
|
+
before_action :validate_benefit_type, only: [:create, :edit]
|
8
|
+
|
9
|
+
def new
|
10
|
+
@benefit = @promotion.benefits.build(benefit_params)
|
11
|
+
render layout: false
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
@benefit = @benefit_type.new(benefit_params)
|
16
|
+
@benefit.promotion = @promotion
|
17
|
+
if @benefit.save(validate: false)
|
18
|
+
flash[:success] =
|
19
|
+
t("spree.successfully_created", resource: SolidusFriendlyPromotions::Benefit.model_name.human)
|
20
|
+
redirect_to location_after_save, format: :html
|
21
|
+
else
|
22
|
+
render :new, layout: false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit
|
27
|
+
@benefit = @promotion.benefits.find(params[:id])
|
28
|
+
if params.dig(:benefit, :calculator_type)
|
29
|
+
@benefit.calculator_type = params[:benefit][:calculator_type]
|
30
|
+
end
|
31
|
+
render layout: false
|
32
|
+
end
|
33
|
+
|
34
|
+
def update
|
35
|
+
@benefit = @promotion.benefits.find(params[:id])
|
36
|
+
@benefit.assign_attributes(benefit_params)
|
37
|
+
if @benefit.save
|
38
|
+
flash[:success] =
|
39
|
+
t("spree.successfully_updated", resource: SolidusFriendlyPromotions::Benefit.model_name.human)
|
40
|
+
redirect_to location_after_save, format: :html
|
41
|
+
else
|
42
|
+
render :edit
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy
|
47
|
+
@benefit = @promotion.benefits.find(params[:id])
|
48
|
+
if @benefit.destroy
|
49
|
+
flash[:success] =
|
50
|
+
t("spree.successfully_removed", resource: SolidusFriendlyPromotions::Benefit.model_name.human)
|
51
|
+
end
|
52
|
+
redirect_to location_after_save, format: :html
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def location_after_save
|
58
|
+
solidus_friendly_promotions.edit_admin_promotion_path(@promotion)
|
59
|
+
end
|
60
|
+
|
61
|
+
def load_promotion
|
62
|
+
@promotion = SolidusFriendlyPromotions::Promotion.find(params[:promotion_id])
|
63
|
+
end
|
64
|
+
|
65
|
+
def benefit_params
|
66
|
+
params[:benefit].try(:permit!) || {}
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_benefit_type
|
70
|
+
requested_type = params[:benefit].delete(:type)
|
71
|
+
benefit_types = SolidusFriendlyPromotions.config.actions
|
72
|
+
@benefit_type = benefit_types.detect do |klass|
|
73
|
+
klass.name == requested_type
|
74
|
+
end
|
75
|
+
return if @benefit_type
|
76
|
+
|
77
|
+
flash[:error] = t("solidus_friendly_promotions.invalid_benefit")
|
78
|
+
respond_to do |format|
|
79
|
+
format.html { redirect_to solidus_friendly_promotions.edit_admin_promotion_path(@promotion) }
|
80
|
+
format.js { render layout: false }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
module Admin
|
5
|
+
class ConditionsController < Spree::Admin::BaseController
|
6
|
+
helper "solidus_friendly_promotions/admin/conditions"
|
7
|
+
|
8
|
+
before_action :load_benefit, only: [:create, :destroy, :update, :new]
|
9
|
+
rescue_from ActiveRecord::SubclassNotFound, with: :invalid_condition_error
|
10
|
+
|
11
|
+
def new
|
12
|
+
@condition = @benefit.conditions.build(condition_params)
|
13
|
+
render layout: false
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
@condition = @benefit.conditions.build(condition_params)
|
18
|
+
if @condition.save
|
19
|
+
flash[:success] =
|
20
|
+
t("spree.successfully_created", resource: model_class.model_name.human)
|
21
|
+
end
|
22
|
+
redirect_to location_after_save
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@condition = @benefit.conditions.find(params[:id])
|
27
|
+
@condition.assign_attributes(condition_params)
|
28
|
+
if @condition.save
|
29
|
+
flash[:success] =
|
30
|
+
t("spree.successfully_updated", resource: model_class.model_name.human)
|
31
|
+
end
|
32
|
+
redirect_to location_after_save
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy
|
36
|
+
@condition = @benefit.conditions.find(params[:id])
|
37
|
+
if @condition.destroy
|
38
|
+
flash[:success] =
|
39
|
+
t("spree.successfully_removed", resource: model_class.model_name.human)
|
40
|
+
end
|
41
|
+
redirect_to location_after_save
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def invalid_condition_error
|
47
|
+
flash[:error] = t("solidus_friendly_promotions.invalid_condition")
|
48
|
+
redirect_to location_after_save
|
49
|
+
end
|
50
|
+
|
51
|
+
def location_after_save
|
52
|
+
solidus_friendly_promotions.edit_admin_promotion_path(@promotion)
|
53
|
+
end
|
54
|
+
|
55
|
+
def load_benefit
|
56
|
+
@promotion = SolidusFriendlyPromotions::Promotion.find(params[:promotion_id])
|
57
|
+
@benefit = @promotion.benefits.find(params[:benefit_id])
|
58
|
+
end
|
59
|
+
|
60
|
+
def model_class
|
61
|
+
SolidusFriendlyPromotions::Condition
|
62
|
+
end
|
63
|
+
|
64
|
+
def condition_params
|
65
|
+
params[:condition].try(:permit!) || {}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -5,8 +5,8 @@ module SolidusFriendlyPromotions
|
|
5
5
|
class PromotionsController < BaseController
|
6
6
|
before_action :load_data
|
7
7
|
|
8
|
-
helper "solidus_friendly_promotions/admin/
|
9
|
-
helper "solidus_friendly_promotions/admin/
|
8
|
+
helper "solidus_friendly_promotions/admin/conditions"
|
9
|
+
helper "solidus_friendly_promotions/admin/benefits"
|
10
10
|
helper "solidus_friendly_promotions/admin/promotions"
|
11
11
|
|
12
12
|
def create
|
@@ -46,7 +46,7 @@ module SolidusFriendlyPromotions
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def promotion_includes
|
49
|
-
[:
|
49
|
+
[:benefits]
|
50
50
|
end
|
51
51
|
|
52
52
|
def model_class
|
@@ -3,16 +3,16 @@
|
|
3
3
|
module SolidusFriendlyPromotions
|
4
4
|
module AdjustmentDecorator
|
5
5
|
def self.prepended(base)
|
6
|
-
base.scope :friendly_promotion, -> { where(source_type: "SolidusFriendlyPromotions::
|
7
|
-
base.scope :promotion, -> { where(source_type: ["SolidusFriendlyPromotions::
|
6
|
+
base.scope :friendly_promotion, -> { where(source_type: "SolidusFriendlyPromotions::Benefit") }
|
7
|
+
base.scope :promotion, -> { where(source_type: ["SolidusFriendlyPromotions::Benefit", "Spree::PromotionAction"]) }
|
8
8
|
end
|
9
9
|
|
10
10
|
def friendly_promotion?
|
11
|
-
source_type == "SolidusFriendlyPromotions::
|
11
|
+
source_type == "SolidusFriendlyPromotions::Benefit"
|
12
12
|
end
|
13
13
|
|
14
14
|
def promotion?
|
15
|
-
super || source_type == "SolidusFriendlyPromotions::
|
15
|
+
super || source_type == "SolidusFriendlyPromotions::Benefit"
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
@@ -4,7 +4,7 @@ module SolidusFriendlyPromotions
|
|
4
4
|
module LineItemDecorator
|
5
5
|
def self.prepended(base)
|
6
6
|
base.attr_accessor :quantity_setter
|
7
|
-
base.belongs_to :
|
7
|
+
base.belongs_to :managed_by_order_benefit, class_name: "SolidusFriendlyPromotions::Benefit", optional: true
|
8
8
|
base.validate :validate_managed_quantity_same, on: :update
|
9
9
|
base.after_save :reset_quantity_setter
|
10
10
|
end
|
@@ -12,7 +12,7 @@ module SolidusFriendlyPromotions
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def validate_managed_quantity_same
|
15
|
-
if
|
15
|
+
if managed_by_order_benefit && quantity_changed? && quantity_setter != managed_by_order_benefit
|
16
16
|
errors.add(:quantity, :cannot_be_changed_for_automated_items)
|
17
17
|
end
|
18
18
|
end
|
@@ -29,11 +29,11 @@ module SolidusFriendlyPromotions
|
|
29
29
|
shipments.each(&:reset_current_discounts)
|
30
30
|
end
|
31
31
|
|
32
|
-
# This helper method excludes line items that are managed by an order
|
33
|
-
# of calculators and
|
34
|
-
# order
|
32
|
+
# This helper method excludes line items that are managed by an order benefit for the benefit
|
33
|
+
# of calculators and benefits that discount normal line items. Line items that are managed by an
|
34
|
+
# order benefits handle their discounts themselves.
|
35
35
|
def discountable_line_items
|
36
|
-
line_items.reject(&:
|
36
|
+
line_items.reject(&:managed_by_order_benefit)
|
37
37
|
end
|
38
38
|
|
39
39
|
def apply_shipping_promotions
|
@@ -44,8 +44,8 @@ module SolidusFriendlyPromotions
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
48
|
-
!line_item.
|
47
|
+
def free_from_order_benefit?(line_item, _options)
|
48
|
+
!line_item.managed_by_order_benefit
|
49
49
|
end
|
50
50
|
|
51
51
|
Spree::Order.prepend self
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
module Admin
|
5
|
+
module BenefitsHelper
|
6
|
+
def options_for_benefit_calculator_types(benefit)
|
7
|
+
calculators = benefit.available_calculators
|
8
|
+
options = calculators.map { |calculator| [calculator.model_name.human, calculator.name] }
|
9
|
+
options_for_select(options, benefit.calculator_type.to_s)
|
10
|
+
end
|
11
|
+
|
12
|
+
def options_for_benefit_types(benefit)
|
13
|
+
benefits = SolidusFriendlyPromotions.config.actions
|
14
|
+
options = benefits.map { |action| [action.model_name.human, action.name] }
|
15
|
+
options_for_select(options, benefit&.type&.to_s)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
module Admin
|
5
|
+
module ConditionsHelper
|
6
|
+
def options_for_condition_types(benefit, condition)
|
7
|
+
options = benefit.available_conditions.map { |condition| [condition.model_name.human, condition.name] }
|
8
|
+
options_for_select(options, condition&.type.to_s)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/app/javascript/solidus_friendly_promotions/controllers/product_option_values_controller.js
CHANGED
@@ -5,7 +5,7 @@ export default class extends Controller {
|
|
5
5
|
|
6
6
|
connect() {
|
7
7
|
this.wrapperClass =
|
8
|
-
this.data.get("wrapperClass") || "promo-
|
8
|
+
this.data.get("wrapperClass") || "promo-condition-option-value";
|
9
9
|
|
10
10
|
this.element.querySelectorAll("." + this.wrapperClass).forEach((element) => this.buildSelects(element))
|
11
11
|
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class NumberWithCurrency extends HTMLElement {
|
2
|
+
connectedCallback() {
|
3
|
+
this.currencySelector = this.querySelector('.number-with-currency-select');
|
4
|
+
this.render()
|
5
|
+
this.addEventListener('change', this);
|
6
|
+
}
|
7
|
+
|
8
|
+
handleEvent() {
|
9
|
+
this.render()
|
10
|
+
}
|
11
|
+
|
12
|
+
get currency() {
|
13
|
+
if (this.currencySelector) {
|
14
|
+
return this.currencySelector.value;
|
15
|
+
} else {
|
16
|
+
return this.querySelector('.number-with-currency-addon')?.dataset?.currency;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
get currencySymbol() {
|
21
|
+
const currency = this.currency;
|
22
|
+
if (currency) {
|
23
|
+
const currencyInfo = Spree.currencyInfo[currency];
|
24
|
+
return currencyInfo[0];
|
25
|
+
} else {
|
26
|
+
return '';
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
render() {
|
31
|
+
this.querySelector('.number-with-currency-symbol').textContent = this.currencySymbol;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
customElements.define('number-with-currency', NumberWithCurrency);
|
data/app/javascript/solidus_friendly_promotions/{jquery → web_components}/option_value_picker.js
RENAMED
@@ -42,3 +42,11 @@ $.fn.optionValueAutocomplete = function (options) {
|
|
42
42
|
formatSelection: formatOptionValue
|
43
43
|
});
|
44
44
|
};
|
45
|
+
|
46
|
+
class OptionValuePicker extends HTMLInputElement {
|
47
|
+
connectedCallback() {
|
48
|
+
$(this).optionValueAutocomplete();
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
customElements.define('option-value-picker', OptionValuePicker, { extends: 'input' });
|
@@ -1,15 +1,11 @@
|
|
1
1
|
import "@hotwired/turbo-rails";
|
2
2
|
import "solidus_friendly_promotions/controllers";
|
3
|
-
import "solidus_friendly_promotions/
|
3
|
+
import "solidus_friendly_promotions/web_components/option_value_picker"
|
4
|
+
import "solidus_friendly_promotions/web_components/product_picker"
|
5
|
+
import "solidus_friendly_promotions/web_components/user_picker"
|
6
|
+
import "solidus_friendly_promotions/web_components/taxon_picker"
|
7
|
+
import "solidus_friendly_promotions/web_components/variant_picker"
|
8
|
+
import "solidus_friendly_promotions/web_components/number_with_currency"
|
9
|
+
import "solidus_friendly_promotions/web_components/select_two"
|
4
10
|
|
5
11
|
Turbo.session.drive = false;
|
6
|
-
|
7
|
-
const initPickers = ({ _target }) => {
|
8
|
-
Spree.initNumberWithCurrency();
|
9
|
-
$(".product_picker").productAutocomplete();
|
10
|
-
$(".user_picker").userAutocomplete();
|
11
|
-
$(".taxon_picker").taxonAutocomplete();
|
12
|
-
$(".variant_autocomplete").variantAutocomplete();
|
13
|
-
};
|
14
|
-
document.addEventListener("turbo:frame-load", initPickers);
|
15
|
-
document.addEventListener("DOMContentLoaded", initPickers);
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SolidusFriendlyPromotions
|
4
|
-
module
|
5
|
-
module
|
4
|
+
module Conditions
|
5
|
+
module LineItemApplicableOrderCondition
|
6
6
|
def self.included(klass)
|
7
7
|
klass.preference :line_item_applicable, :boolean, default: true
|
8
8
|
end
|