solidus_promotions 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.eslintrc.json +10 -0
- data/.github/stale.yml +1 -0
- data/MIGRATING.md +184 -0
- data/README.md +122 -0
- data/Rakefile +20 -0
- data/app/assets/config/solidus_promotions/manifest.js +13 -0
- data/app/decorators/models/solidus_promotions/adjustment_decorator.rb +11 -0
- data/app/decorators/models/solidus_promotions/line_item_decorator.rb +27 -0
- data/app/decorators/models/solidus_promotions/order_decorator.rb +42 -0
- data/app/decorators/models/solidus_promotions/order_recalculator_decorator.rb +15 -0
- data/app/decorators/models/solidus_promotions/shipment_decorator.rb +14 -0
- data/app/decorators/models/solidus_promotions/shipping_rate_decorator.rb +29 -0
- data/app/helpers/solidus_promotions/admin/benefits_helper.rb +19 -0
- data/app/helpers/solidus_promotions/admin/conditions_helper.rb +14 -0
- data/app/helpers/solidus_promotions/admin/promotions_helper.rb +15 -0
- data/app/javascript/backend/solidus_promotions/controllers/application.js +9 -0
- data/app/javascript/backend/solidus_promotions/controllers/calculator_tiers_controller.js +37 -0
- data/app/javascript/backend/solidus_promotions/controllers/flash_controller.js +10 -0
- data/app/javascript/backend/solidus_promotions/controllers/index.js +8 -0
- data/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js +62 -0
- data/app/javascript/backend/solidus_promotions/web_components/number_with_currency.js +35 -0
- data/app/javascript/backend/solidus_promotions/web_components/option_value_picker.js +52 -0
- data/app/javascript/backend/solidus_promotions/web_components/product_picker.js +7 -0
- data/app/javascript/backend/solidus_promotions/web_components/select_two.js +11 -0
- data/app/javascript/backend/solidus_promotions/web_components/taxon_picker.js +7 -0
- data/app/javascript/backend/solidus_promotions/web_components/user_picker.js +7 -0
- data/app/javascript/backend/solidus_promotions/web_components/variant_picker.js +7 -0
- data/app/javascript/backend/solidus_promotions.js +11 -0
- data/app/jobs/solidus_promotions/promotion_code_batch_job.rb +26 -0
- data/app/mailers/solidus_promotions/promotion_code_batch_mailer.rb +15 -0
- data/app/models/concerns/solidus_promotions/benefits/line_item_benefit.rb +15 -0
- data/app/models/concerns/solidus_promotions/benefits/order_benefit.rb +15 -0
- data/app/models/concerns/solidus_promotions/benefits/shipment_benefit.rb +15 -0
- data/app/models/concerns/solidus_promotions/calculators/promotion_calculator.rb +11 -0
- data/app/models/concerns/solidus_promotions/conditions/line_item_applicable_order_level_condition.rb +23 -0
- data/app/models/concerns/solidus_promotions/conditions/line_item_level_condition.rb +15 -0
- data/app/models/concerns/solidus_promotions/conditions/order_level_condition.rb +15 -0
- data/app/models/concerns/solidus_promotions/conditions/shipment_level_condition.rb +15 -0
- data/app/models/concerns/solidus_promotions/discountable_amount.rb +21 -0
- data/app/models/solidus_promotions/benefit.rb +123 -0
- data/app/models/solidus_promotions/benefits/adjust_line_item.rb +13 -0
- data/app/models/solidus_promotions/benefits/adjust_line_item_quantity_groups.rb +107 -0
- data/app/models/solidus_promotions/benefits/adjust_shipment.rb +13 -0
- data/app/models/solidus_promotions/benefits/create_discounted_item.rb +49 -0
- data/app/models/solidus_promotions/calculators/distributed_amount.rb +31 -0
- data/app/models/solidus_promotions/calculators/flat_rate.rb +23 -0
- data/app/models/solidus_promotions/calculators/flexi_rate.rb +26 -0
- data/app/models/solidus_promotions/calculators/percent.rb +19 -0
- data/app/models/solidus_promotions/calculators/tiered_flat_rate.rb +58 -0
- data/app/models/solidus_promotions/calculators/tiered_percent.rb +68 -0
- data/app/models/solidus_promotions/calculators/tiered_percent_on_eligible_item_quantity.rb +40 -0
- data/app/models/solidus_promotions/condition.rb +61 -0
- data/app/models/solidus_promotions/condition_product.rb +8 -0
- data/app/models/solidus_promotions/condition_store.rb +8 -0
- data/app/models/solidus_promotions/condition_taxon.rb +8 -0
- data/app/models/solidus_promotions/condition_user.rb +8 -0
- data/app/models/solidus_promotions/conditions/discounted_item_total.rb +22 -0
- data/app/models/solidus_promotions/conditions/first_order.rb +31 -0
- data/app/models/solidus_promotions/conditions/first_repeat_purchase_since.rb +31 -0
- data/app/models/solidus_promotions/conditions/item_total.rb +75 -0
- data/app/models/solidus_promotions/conditions/line_item_option_value.rb +37 -0
- data/app/models/solidus_promotions/conditions/line_item_product.rb +56 -0
- data/app/models/solidus_promotions/conditions/line_item_taxon.rb +59 -0
- data/app/models/solidus_promotions/conditions/minimum_quantity.rb +42 -0
- data/app/models/solidus_promotions/conditions/nth_order.rb +40 -0
- data/app/models/solidus_promotions/conditions/one_use_per_user.rb +25 -0
- data/app/models/solidus_promotions/conditions/option_value.rb +28 -0
- data/app/models/solidus_promotions/conditions/product.rb +85 -0
- data/app/models/solidus_promotions/conditions/shipping_method.rb +19 -0
- data/app/models/solidus_promotions/conditions/store.rb +26 -0
- data/app/models/solidus_promotions/conditions/taxon.rb +98 -0
- data/app/models/solidus_promotions/conditions/user.rb +35 -0
- data/app/models/solidus_promotions/conditions/user_logged_in.rb +16 -0
- data/app/models/solidus_promotions/conditions/user_role.rb +42 -0
- data/app/models/solidus_promotions/distributed_amounts_handler.rb +39 -0
- data/app/models/solidus_promotions/eligibility_result.rb +5 -0
- data/app/models/solidus_promotions/eligibility_results.rb +47 -0
- data/app/models/solidus_promotions/item_discount.rb +21 -0
- data/app/models/solidus_promotions/migration_support/order_promotion_syncer.rb +54 -0
- data/app/models/solidus_promotions/order_adjuster/choose_discounts.rb +21 -0
- data/app/models/solidus_promotions/order_adjuster/discount_order.rb +93 -0
- data/app/models/solidus_promotions/order_adjuster/load_promotions.rb +53 -0
- data/app/models/solidus_promotions/order_adjuster/persist_discounted_order.rb +79 -0
- data/app/models/solidus_promotions/order_adjuster.rb +33 -0
- data/app/models/solidus_promotions/order_promotion.rb +23 -0
- data/app/models/solidus_promotions/permission_sets/solidus_promotion_management.rb +15 -0
- data/app/models/solidus_promotions/promotion.rb +163 -0
- data/app/models/solidus_promotions/promotion_advertiser.rb +10 -0
- data/app/models/solidus_promotions/promotion_category.rb +9 -0
- data/app/models/solidus_promotions/promotion_code/batch_builder.rb +73 -0
- data/app/models/solidus_promotions/promotion_code.rb +56 -0
- data/app/models/solidus_promotions/promotion_code_batch.rb +25 -0
- data/app/models/solidus_promotions/promotion_finder.rb +10 -0
- data/app/models/solidus_promotions/promotion_handler/coupon.rb +113 -0
- data/app/models/solidus_promotions/promotion_handler/page.rb +30 -0
- data/app/models/solidus_promotions/shipping_rate_discount.rb +11 -0
- data/app/subscribers/solidus_promotions/order_promotion_subscriber.rb +20 -0
- data/bin/rails +13 -0
- data/config/importmap.rb +14 -0
- data/config/locales/en.yml +376 -0
- data/config/locales/promotion_categories.en.yml +6 -0
- data/config/locales/promotions.en.yml +6 -0
- data/config/routes.rb +38 -0
- data/db/migrate/20230703101637_create_promotions.rb +25 -0
- data/db/migrate/20230703113625_create_promotion_benefits.rb +15 -0
- data/db/migrate/20230703141116_create_promotion_categories.rb +14 -0
- data/db/migrate/20230703143943_create_promotion_conditions.rb +12 -0
- data/db/migrate/20230704083830_add_condition_join_tables.rb +31 -0
- data/db/migrate/20230704102444_create_promotion_codes.rb +11 -0
- data/db/migrate/20230704102656_create_promotion_code_batches.rb +34 -0
- data/db/migrate/20230705171556_create_order_promotions.rb +11 -0
- data/db/migrate/20230725074235_create_shipping_rate_discounts.rb +12 -0
- data/db/migrate/20231011100059_add_db_comments_to_order_promotions.rb +61 -0
- data/db/migrate/20231011120928_add_db_comments_to_condition_taxons.rb +54 -0
- data/db/migrate/20231011131324_add_db_comments_to_conditions.rb +60 -0
- data/db/migrate/20231011142040_add_db_comments_to_condition_users.rb +53 -0
- data/db/migrate/20231011155822_add_db_comments_to_promotions.rb +123 -0
- data/db/migrate/20231011163030_add_db_comments_to_promotion_codes.rb +60 -0
- data/db/migrate/20231011173312_add_db_comments_to_promotion_code_batches.rb +91 -0
- data/db/migrate/20231011184205_add_db_comments_to_condition_stores.rb +53 -0
- data/db/migrate/20231011190222_add_db_comments_to_benefits.rb +61 -0
- data/db/migrate/20231012020928_add_db_comments_to_condition_products.rb +52 -0
- data/db/migrate/20231012120928_add_db_comments_to_promotion_categories.rb +52 -0
- data/db/migrate/20231104135812_add_managed_by_order_benefit_to_line_items.rb +5 -0
- data/lib/components/admin/solidus_admin/orders/show/adjustments/index/source/solidus_promotions_benefit/component.rb +17 -0
- data/lib/components/admin/solidus_promotions/orders/index/component.rb +15 -0
- data/lib/components/admin/solidus_promotions/orders/index/component.yml +3 -0
- data/lib/components/admin/solidus_promotions/promotion_categories/index/component.rb +60 -0
- data/lib/components/admin/solidus_promotions/promotions/index/component.rb +108 -0
- data/lib/components/admin/solidus_promotions/promotions/index/component.yml +10 -0
- data/lib/controllers/admin/solidus_promotions/promotion_categories_controller.rb +29 -0
- data/lib/controllers/admin/solidus_promotions/promotions_controller.rb +46 -0
- data/lib/controllers/backend/solidus_promotions/admin/base_controller.rb +15 -0
- data/lib/controllers/backend/solidus_promotions/admin/benefits_controller.rb +85 -0
- data/lib/controllers/backend/solidus_promotions/admin/conditions_controller.rb +69 -0
- data/lib/controllers/backend/solidus_promotions/admin/promotion_categories_controller.rb +13 -0
- data/lib/controllers/backend/solidus_promotions/admin/promotion_code_batches_controller.rb +42 -0
- data/lib/controllers/backend/solidus_promotions/admin/promotion_codes_controller.rb +58 -0
- data/lib/controllers/backend/solidus_promotions/admin/promotions_controller.rb +65 -0
- data/lib/generators/solidus_promotions/install/install_generator.rb +56 -0
- data/lib/generators/solidus_promotions/install/templates/initializer.rb +6 -0
- data/lib/solidus_promotions/configuration.rb +125 -0
- data/lib/solidus_promotions/engine.rb +115 -0
- data/lib/solidus_promotions/migrate_adjustments.rb +62 -0
- data/lib/solidus_promotions/migrate_order_promotions.rb +73 -0
- data/lib/solidus_promotions/promotion_map.rb +126 -0
- data/lib/solidus_promotions/promotion_migrator.rb +103 -0
- data/lib/solidus_promotions/testing_support/factories/completed_order_with_solidus_promotion_factory.rb +20 -0
- data/lib/solidus_promotions/testing_support/factories/solidus_order_promotion_factory.rb +8 -0
- data/lib/solidus_promotions/testing_support/factories/solidus_promotion_category_factory.rb +7 -0
- data/lib/solidus_promotions/testing_support/factories/solidus_promotion_code_factory.rb +8 -0
- data/lib/solidus_promotions/testing_support/factories/solidus_promotion_factory.rb +65 -0
- data/lib/solidus_promotions/testing_support/factories/solidus_shipping_rate_discount_factory.rb +14 -0
- data/lib/solidus_promotions/testing_support/factory_bot.rb +30 -0
- data/lib/solidus_promotions.rb +37 -0
- data/lib/tasks/solidus_promotions/migrate_adjustments.rake +17 -0
- data/lib/tasks/solidus_promotions/migrate_existing_promotions.rake +12 -0
- data/lib/tasks/solidus_promotions/migrate_order_promotions.rake +17 -0
- data/lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_line_item.html.erb +6 -0
- data/lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_line_item_quantity_groups.html.erb +13 -0
- data/lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_shipment.html.erb +6 -0
- data/lib/views/backend/solidus_promotions/admin/benefit_fields/_calculator_fields.erb +11 -0
- data/lib/views/backend/solidus_promotions/admin/benefit_fields/_create_discounted_item.html.erb +21 -0
- data/lib/views/backend/solidus_promotions/admin/benefits/_benefit.html.erb +50 -0
- data/lib/views/backend/solidus_promotions/admin/benefits/_calculator_select.html.erb +16 -0
- data/lib/views/backend/solidus_promotions/admin/benefits/_form.html.erb +3 -0
- data/lib/views/backend/solidus_promotions/admin/benefits/_new_benefit.html.erb +33 -0
- data/lib/views/backend/solidus_promotions/admin/benefits/_type_select.html.erb +16 -0
- data/lib/views/backend/solidus_promotions/admin/benefits/edit.html.erb +19 -0
- data/lib/views/backend/solidus_promotions/admin/benefits/new.html.erb +1 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/_default_fields.html.erb +6 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/distributed_amount/_fields.html.erb +18 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/flat_rate/_fields.html.erb +6 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/flexi_rate/_fields.html.erb +24 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/percent/_fields.html.erb +6 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_flat_rate/_fields.html.erb +32 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_flat_rate/_tier_fields.html.erb +31 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent/_fields.html.erb +47 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent/_tier_fields.html.erb +33 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent_on_eligible_item_quantity/_fields.html.erb +36 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent_on_eligible_item_quantity/_tier_fields.html.erb +35 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_first_order.html.erb +3 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_first_repeat_purchase_since.html.erb +7 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_item_total.html.erb +15 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb +25 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_product.html.erb +21 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_taxon.html.erb +17 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_minimum_quantity.html.erb +5 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_nth_order.html.erb +15 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_one_use_per_user.html.erb +3 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_option_value.html.erb +63 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_product.html.erb +27 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_shipping_method.html.erb +10 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_store.html.erb +9 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_taxon.html.erb +27 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_user.html.erb +7 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_user_logged_in.html.erb +3 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_user_role.html.erb +15 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/line_item_option_value/_option_value_fields.html.erb +21 -0
- data/lib/views/backend/solidus_promotions/admin/conditions/_condition.html.erb +26 -0
- data/lib/views/backend/solidus_promotions/admin/conditions/_new_condition.html.erb +26 -0
- data/lib/views/backend/solidus_promotions/admin/conditions/_type_select.html.erb +20 -0
- data/lib/views/backend/solidus_promotions/admin/conditions/new.html.erb +1 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_categories/_form.html.erb +14 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_categories/edit.html.erb +10 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_categories/index.html.erb +47 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_categories/new.html.erb +10 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/_form_fields.html.erb +22 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/download.csv.ruby +8 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/index.html.erb +65 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/new.html.erb +8 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_codes/index.csv.ruby +8 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_codes/index.html.erb +32 -0
- data/lib/views/backend/solidus_promotions/admin/promotion_codes/new.html.erb +31 -0
- data/lib/views/backend/solidus_promotions/admin/promotions/_form.html.erb +124 -0
- data/lib/views/backend/solidus_promotions/admin/promotions/_table.html.erb +57 -0
- data/lib/views/backend/solidus_promotions/admin/promotions/_table_filter.html.erb +78 -0
- data/lib/views/backend/solidus_promotions/admin/promotions/edit.html.erb +41 -0
- data/lib/views/backend/solidus_promotions/admin/promotions/index.html.erb +23 -0
- data/lib/views/backend/solidus_promotions/admin/promotions/new.html.erb +9 -0
- data/lib/views/backend/solidus_promotions/admin/shared/_number_with_currency.html.erb +20 -0
- data/lib/views/backend/solidus_promotions/admin/shared/_promotion_sub_menu.html.erb +14 -0
- data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_boolean.html.erb +14 -0
- data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_decimal.html.erb +12 -0
- data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_encrypted_string.html.erb +12 -0
- data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_integer.html.erb +12 -0
- data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_password.html.erb +12 -0
- data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_string.html.erb +12 -0
- data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_text.html.erb +12 -0
- data/lib/views/backend/solidus_promotions/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
- data/lib/views/backend/solidus_promotions/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
- data/solidus_promotions.gemspec +33 -0
- metadata +366 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusPromotions
|
|
4
|
+
class PromotionCodeBatch < Spree::Base
|
|
5
|
+
class CantProcessStartedBatch < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
belongs_to :promotion
|
|
9
|
+
has_many :promotion_codes, dependent: :destroy
|
|
10
|
+
|
|
11
|
+
validates :number_of_codes, numericality: { greater_than: 0 }
|
|
12
|
+
validates :base_code, :number_of_codes, presence: true
|
|
13
|
+
|
|
14
|
+
def finished?
|
|
15
|
+
state == "completed"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def process
|
|
19
|
+
raise CantProcessStartedBatch, "Batch #{id} already started" unless state == "pending"
|
|
20
|
+
|
|
21
|
+
update!(state: "processing")
|
|
22
|
+
PromotionCodeBatchJob.perform_later(self)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusPromotions
|
|
4
|
+
class PromotionFinder
|
|
5
|
+
def self.by_code_or_id(coupon_code_or_id)
|
|
6
|
+
SolidusPromotions::Promotion.with_coupon_code(coupon_code_or_id.to_s) ||
|
|
7
|
+
SolidusPromotions::Promotion.find(coupon_code_or_id)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusPromotions
|
|
4
|
+
module PromotionHandler
|
|
5
|
+
class Coupon
|
|
6
|
+
attr_reader :order, :coupon_code, :errors
|
|
7
|
+
attr_accessor :error, :success, :status_code
|
|
8
|
+
|
|
9
|
+
def initialize(order)
|
|
10
|
+
@order = order
|
|
11
|
+
@errors = []
|
|
12
|
+
@coupon_code = order&.coupon_code&.downcase
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def apply
|
|
16
|
+
if coupon_code.present?
|
|
17
|
+
if promotion.present? && promotion.active?
|
|
18
|
+
handle_present_promotion
|
|
19
|
+
elsif promotion_code&.promotion&.expired?
|
|
20
|
+
set_error_code :coupon_code_expired
|
|
21
|
+
else
|
|
22
|
+
set_error_code :coupon_code_not_found
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def remove
|
|
30
|
+
if promotion.blank?
|
|
31
|
+
set_error_code :coupon_code_not_found
|
|
32
|
+
elsif !promotion_exists_on_order?(order, promotion)
|
|
33
|
+
set_error_code :coupon_code_not_present
|
|
34
|
+
else
|
|
35
|
+
order.solidus_order_promotions.destroy_by(
|
|
36
|
+
promotion: promotion
|
|
37
|
+
)
|
|
38
|
+
order.recalculate
|
|
39
|
+
set_success_code :coupon_code_removed
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def successful?
|
|
46
|
+
success.present? && error.blank?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def promotion
|
|
50
|
+
@promotion ||= if promotion_code&.promotion&.active?
|
|
51
|
+
promotion_code.promotion
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def set_success_code(status_code)
|
|
58
|
+
@status_code = status_code
|
|
59
|
+
@success = I18n.t(status_code, scope: "solidus_promotions.eligibility_results")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def set_error_code(status_code, options = {})
|
|
63
|
+
@status_code = status_code
|
|
64
|
+
@error = options[:error] || I18n.t(status_code, scope: "solidus_promotions.eligibility_errors")
|
|
65
|
+
@errors = options[:errors] || [@error]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def promotion_code
|
|
69
|
+
@promotion_code ||= SolidusPromotions::PromotionCode.where(value: coupon_code).first
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def handle_present_promotion
|
|
73
|
+
return promotion_usage_limit_exceeded if promotion.usage_limit_exceeded? || promotion_code.usage_limit_exceeded?
|
|
74
|
+
return promotion_applied if promotion_exists_on_order?(order, promotion)
|
|
75
|
+
|
|
76
|
+
# Try applying this promotion, with no effects
|
|
77
|
+
Spree::Config.promotions.order_adjuster_class.new(order, dry_run_promotion: promotion).call
|
|
78
|
+
|
|
79
|
+
if promotion.eligibility_results.success?
|
|
80
|
+
order.solidus_order_promotions.create!(
|
|
81
|
+
promotion: promotion,
|
|
82
|
+
promotion_code: promotion_code
|
|
83
|
+
)
|
|
84
|
+
order.recalculate
|
|
85
|
+
set_success_code :coupon_code_applied
|
|
86
|
+
else
|
|
87
|
+
set_promotion_eligibility_error(promotion)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def set_promotion_eligibility_error(promotion)
|
|
92
|
+
eligibility_error = promotion.eligibility_results.detect { |result| !result.success }
|
|
93
|
+
set_error_code(eligibility_error.code, error: eligibility_error.message, errors: promotion.eligibility_results.error_messages)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def promotion_usage_limit_exceeded
|
|
97
|
+
set_error_code :coupon_code_max_usage
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def ineligible_for_this_order
|
|
101
|
+
set_error_code :coupon_code_not_eligible
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def promotion_applied
|
|
105
|
+
set_error_code :coupon_code_already_applied
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def promotion_exists_on_order?(order, promotion)
|
|
109
|
+
order.solidus_promotions.include? promotion
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusPromotions
|
|
4
|
+
module PromotionHandler
|
|
5
|
+
class Page
|
|
6
|
+
attr_reader :order, :path
|
|
7
|
+
|
|
8
|
+
def initialize(order, path)
|
|
9
|
+
@order = order
|
|
10
|
+
@path = path.delete_prefix('/')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def activate
|
|
14
|
+
if promotion
|
|
15
|
+
Spree::Config.promotions.order_adjuster_class.new(order, dry_run_promotion: promotion).call
|
|
16
|
+
if promotion.eligibility_results.success?
|
|
17
|
+
order.solidus_promotions << promotion
|
|
18
|
+
order.recalculate
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def promotion
|
|
26
|
+
@promotion ||= SolidusPromotions::Promotion.active.find_by(path: path)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusPromotions
|
|
4
|
+
class ShippingRateDiscount < Spree::Base
|
|
5
|
+
belongs_to :shipping_rate, inverse_of: :discounts, class_name: "Spree::ShippingRate"
|
|
6
|
+
belongs_to :benefit, inverse_of: :shipping_rate_discounts
|
|
7
|
+
|
|
8
|
+
extend Spree::DisplayMoney
|
|
9
|
+
money_methods :amount
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusPromotions
|
|
4
|
+
# Clears promotions from an emptied order
|
|
5
|
+
class OrderPromotionSubscriber
|
|
6
|
+
include Omnes::Subscriber
|
|
7
|
+
|
|
8
|
+
handle :order_emptied,
|
|
9
|
+
with: :clear_order_promotions,
|
|
10
|
+
id: :solidus_promotions_order_promotion_clear_order_promotions
|
|
11
|
+
|
|
12
|
+
# Clears all promotions from the order
|
|
13
|
+
#
|
|
14
|
+
# @param event [Omnes::UnstructuredEvent]
|
|
15
|
+
def clear_order_promotions(event)
|
|
16
|
+
order = event[:order]
|
|
17
|
+
order.solidus_order_promotions.destroy_all
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/bin/rails
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
|
3
|
+
# installed from the root of your application.
|
|
4
|
+
|
|
5
|
+
ENGINE_ROOT = File.expand_path('..', __dir__)
|
|
6
|
+
ENGINE_PATH = File.expand_path('../lib/solidus_promotions/engine', __dir__)
|
|
7
|
+
|
|
8
|
+
# Set up gems listed in the Gemfile.
|
|
9
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
|
10
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
|
11
|
+
|
|
12
|
+
require 'rails/all'
|
|
13
|
+
require 'rails/engine/commands'
|
data/config/importmap.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
|
|
4
|
+
|
|
5
|
+
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
|
|
6
|
+
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
|
|
7
|
+
pin_all_from SolidusPromotions::Engine.root.join("app/javascript/backend/solidus_promotions/controllers"),
|
|
8
|
+
under: "backend/solidus_promotions/controllers"
|
|
9
|
+
pin_all_from SolidusPromotions::Engine.root.join("app/javascript/backend/solidus_promotions/jquery"),
|
|
10
|
+
under: "backend/solidus_promotions/jquery"
|
|
11
|
+
pin_all_from SolidusPromotions::Engine.root.join("app/javascript/backend/solidus_promotions/web_components"),
|
|
12
|
+
under: "backend/solidus_promotions/web_components"
|
|
13
|
+
|
|
14
|
+
pin "backend/solidus_promotions", to: "backend/solidus_promotions.js", preload: true
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# Sample localization file for English. Add more files in this directory for other locales.
|
|
2
|
+
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
|
|
3
|
+
|
|
4
|
+
en:
|
|
5
|
+
spree:
|
|
6
|
+
admin:
|
|
7
|
+
tab:
|
|
8
|
+
promotions: Promotions
|
|
9
|
+
promotion_categories: Promotion Categories
|
|
10
|
+
legacy_promotions: Legacy Promotions
|
|
11
|
+
legacy_promotion_categories: Legacy Promotion Categories
|
|
12
|
+
hints:
|
|
13
|
+
solidus_promotions/promotion:
|
|
14
|
+
expires_at: This determines when the promotion expires. <br> If no value is specified, the promotion will never expire.
|
|
15
|
+
promo_code_will_be_disabled: Selecting this option, promo codes will be disabled for this promotion because all its conditions / benefits will be applied automatically to all orders.
|
|
16
|
+
starts_at: This determines when the promotion can be applied to orders. <br> If no value is specified, the promotion will be immediately available.
|
|
17
|
+
solidus_promotions:
|
|
18
|
+
hints:
|
|
19
|
+
solidus_promotions/benefit:
|
|
20
|
+
conditions: This is used to determine if the benefit should be applied.
|
|
21
|
+
type: This is the type of benefit that will be applied.
|
|
22
|
+
calculator: This is used to determine the promotional discount to be applied to an order, an item, or shipping charges.
|
|
23
|
+
benefits: Benefits
|
|
24
|
+
adjustment_labels:
|
|
25
|
+
line_item: "%{promotion} (%{promotion_customer_label})"
|
|
26
|
+
shipment: "%{promotion} (%{promotion_customer_label})"
|
|
27
|
+
shipping_rate: "%{promotion} (%{promotion_customer_label})"
|
|
28
|
+
adjustment_type: Adjustment type
|
|
29
|
+
add_benefit: Add Benefit
|
|
30
|
+
add_condition: Add Condition
|
|
31
|
+
order_conditions: Order Conditions
|
|
32
|
+
line_item_conditions: Line Item Conditions
|
|
33
|
+
shipment_conditions: Shipment Conditions
|
|
34
|
+
line_item_benefits: Line Item Benefits
|
|
35
|
+
shipment_benefits: Shipment Benefits
|
|
36
|
+
order_benefits: Order Benefits
|
|
37
|
+
invalid_benefit: Invalid promotion benefit.
|
|
38
|
+
invalid_condition: Invalid promotion condition.
|
|
39
|
+
create_promotion_code: Create promotion code
|
|
40
|
+
current_promotion_usage: 'Current Usage: %{count}'
|
|
41
|
+
discount_conditions: Promotion Conditions
|
|
42
|
+
download_promotion_codes_list: Download codes list
|
|
43
|
+
new_promotion: New Promotion
|
|
44
|
+
new_promotion_category: New Promotion Category
|
|
45
|
+
new_promotion_code_batch: New Promotion Code Batch
|
|
46
|
+
number_of_codes: "%{count} codes"
|
|
47
|
+
legacy_promotions: Legacy Promotions
|
|
48
|
+
no_conditions_added: No Conditions Added
|
|
49
|
+
promotion_successfully_created: Promotion has been successfully created!
|
|
50
|
+
promotion_total_changed_before_complete: One or more of the promotions on your order have become ineligible and were removed. Please check the new order amounts and try again.
|
|
51
|
+
promotion_code_batches:
|
|
52
|
+
finished: Finished
|
|
53
|
+
errored: Errored
|
|
54
|
+
view_promotion_codes_list: View codes list
|
|
55
|
+
conditions:
|
|
56
|
+
line_item_product:
|
|
57
|
+
match_policies:
|
|
58
|
+
include: Line item's product is one of the chosen products
|
|
59
|
+
exclude: Line item's product is not one of the chosen products
|
|
60
|
+
line_item_taxon:
|
|
61
|
+
match_policies:
|
|
62
|
+
include: Line item's product has one of the chosen taxons
|
|
63
|
+
exclude: Line item's product does not have one of the chosen taxons
|
|
64
|
+
item_total_condition:
|
|
65
|
+
operators:
|
|
66
|
+
gt: greater than
|
|
67
|
+
gte: greater than or equal to
|
|
68
|
+
user_condition:
|
|
69
|
+
choose_users: Choose Users
|
|
70
|
+
user_role_condition:
|
|
71
|
+
choose_roles: Choose Roles
|
|
72
|
+
label: User must contain %{select} of these roles
|
|
73
|
+
match_all: all
|
|
74
|
+
match_any: at least one
|
|
75
|
+
coupon_code: Coupon code
|
|
76
|
+
eligibility_results:
|
|
77
|
+
coupon_code_applied: The coupon code was successfully applied to your order.
|
|
78
|
+
coupon_code_removed: The coupon code was successfully removed from this order.
|
|
79
|
+
eligibility_errors:
|
|
80
|
+
coupon_code_already_applied: The coupon code has already been applied to this order
|
|
81
|
+
coupon_code_expired: The coupon code is expired
|
|
82
|
+
coupon_code_max_usage: Coupon code usage limit exceeded
|
|
83
|
+
coupon_code_not_eligible: This coupon code is not eligible for this order
|
|
84
|
+
coupon_code_not_found: The coupon code you entered doesn't exist. Please try again.
|
|
85
|
+
coupon_code_not_present: The coupon code you are trying to remove is not present on this order.
|
|
86
|
+
coupon_code_unknown_error: This coupon code could not be applied to the cart at this time.
|
|
87
|
+
solidus_promotions/conditions/first_order:
|
|
88
|
+
not_first_order: This coupon code can only be applied to your first order.
|
|
89
|
+
solidus_promotions/conditions/first_repeat_purchase_since:
|
|
90
|
+
solidus_promotions/conditions/item_total:
|
|
91
|
+
item_total_doesnt_match_with_operator: This coupon code can't be applied to orders %{operator} %{amount}.
|
|
92
|
+
item_total_less_than: This coupon code can't be applied to orders less than %{amount}.
|
|
93
|
+
item_total_less_than_or_equal: This coupon code can't be applied to orders less than or equal to %{amount}.
|
|
94
|
+
solidus_promotions/conditions/discounted_item_total:
|
|
95
|
+
item_total_doesnt_match_with_operator: This coupon code can't be applied to orders %{operator} %{amount}.
|
|
96
|
+
item_total_less_than: This coupon code can't be applied to orders less than %{amount}.
|
|
97
|
+
item_total_less_than_or_equal: This coupon code can't be applied to orders less than or equal to %{amount}.
|
|
98
|
+
solidus_promotions/conditions/landing_page:
|
|
99
|
+
solidus_promotions/conditions/nth_order:
|
|
100
|
+
solidus_promotions/conditions/one_use_per_user:
|
|
101
|
+
no_user_specified: You need to login before applying this coupon code.
|
|
102
|
+
limit_once_per_user: This coupon code can only be used once per user.
|
|
103
|
+
solidus_promotions/conditions/option_value:
|
|
104
|
+
solidus_promotions/conditions/line_item_option_value:
|
|
105
|
+
solidus_promotions/conditions/product:
|
|
106
|
+
has_excluded_product: Your cart contains a product that prevents this coupon code from being applied.
|
|
107
|
+
missing_product: This coupon code can't be applied because you don't have all of the necessary products in your cart.
|
|
108
|
+
no_applicable_products: You need to add an applicable product before applying this coupon code.
|
|
109
|
+
solidus_promotions/conditions/line_item_product:
|
|
110
|
+
has_excluded_product: Your cart contains a product that prevents this coupon code from being applied.
|
|
111
|
+
missing_product: This coupon code can't be applied because you don't have all of the necessary products in your cart.
|
|
112
|
+
no_applicable_products: You need to add an applicable product before applying this coupon code.
|
|
113
|
+
solidus_promotions/conditions/taxon:
|
|
114
|
+
has_excluded_taxon: Your cart contains a product from an excluded category that prevents this coupon code from being applied.
|
|
115
|
+
missing_taxon: You need to add a product from all applicable categories before applying this coupon code.
|
|
116
|
+
no_matching_taxons: You need to add a product from an applicable category before applying this coupon code.
|
|
117
|
+
solidus_promotions/conditions/line_item_taxon:
|
|
118
|
+
has_excluded_taxon: Your cart contains a product from an excluded category that prevents this coupon code from being applied.
|
|
119
|
+
missing_taxon: You need to add a product from all applicable categories before applying this coupon code.
|
|
120
|
+
no_matching_taxons: You need to add a product from an applicable category before applying this coupon code.
|
|
121
|
+
solidus_promotions/conditions/user:
|
|
122
|
+
no_user_specified: You need to login before applying this coupon code.
|
|
123
|
+
solidus_promotions/conditions/user_logged_in:
|
|
124
|
+
no_user_specified: You need to login before applying this coupon code.
|
|
125
|
+
solidus_promotions/conditions/user_role:
|
|
126
|
+
solidus_promotions/conditions/minimum_quantity:
|
|
127
|
+
quantity_less_than_minimum:
|
|
128
|
+
one: "You need to add a least 1 applicable item to your order."
|
|
129
|
+
other: "You need to add a least %{count} applicable items to your order."
|
|
130
|
+
product_condition:
|
|
131
|
+
choose_products: Choose products
|
|
132
|
+
label: Order must contain %{select} these products
|
|
133
|
+
match_all: all of
|
|
134
|
+
match_any: at least one of
|
|
135
|
+
match_none: none of
|
|
136
|
+
match_only: only
|
|
137
|
+
product_source:
|
|
138
|
+
group: From product group
|
|
139
|
+
manual: Manually choose
|
|
140
|
+
taxon_condition:
|
|
141
|
+
choose_taxons: Choose taxons
|
|
142
|
+
label: Order must contain %{select} of these taxons
|
|
143
|
+
match_all: all
|
|
144
|
+
match_any: at least one
|
|
145
|
+
match_none: none
|
|
146
|
+
line_item_option_value_condition:
|
|
147
|
+
add_product: Add product
|
|
148
|
+
option_value_condition:
|
|
149
|
+
add_product: Add product
|
|
150
|
+
crud:
|
|
151
|
+
add: Add
|
|
152
|
+
destroy: Delete
|
|
153
|
+
update: Update
|
|
154
|
+
admin:
|
|
155
|
+
promotions:
|
|
156
|
+
benefits:
|
|
157
|
+
calculator_label: Calculated by
|
|
158
|
+
activations_edit:
|
|
159
|
+
auto: All orders will attempt to use this promotion
|
|
160
|
+
multiple_codes_html: This promotion uses %{count} promotion codes
|
|
161
|
+
single_code_html: 'This promotion uses the promotion code: <code>%{code}</code>'
|
|
162
|
+
activations_new:
|
|
163
|
+
auto: Apply to all orders
|
|
164
|
+
multiple_codes: Multiple promotion codes
|
|
165
|
+
single_code: Single promotion code
|
|
166
|
+
form:
|
|
167
|
+
activation: Activation
|
|
168
|
+
expires_at_placeholder: Never
|
|
169
|
+
general: General
|
|
170
|
+
starts_at_placeholder: Immediately
|
|
171
|
+
codes_present: This promotion has promotion codes defined. You cannot select the apply automatically option.
|
|
172
|
+
edit:
|
|
173
|
+
order_conditions: Order Conditions
|
|
174
|
+
calculator:
|
|
175
|
+
add_tier: Add tier
|
|
176
|
+
promotion_status:
|
|
177
|
+
active: Active
|
|
178
|
+
expired: Expired
|
|
179
|
+
inactive: Inactive
|
|
180
|
+
not_started: Not started
|
|
181
|
+
promotion_code_batch_mailer:
|
|
182
|
+
promotion_code_batch_errored:
|
|
183
|
+
message: 'Promotion code batch errored (%{error}) for promotion: '
|
|
184
|
+
subject: Promotion code batch errored
|
|
185
|
+
promotion_code_batch_finished:
|
|
186
|
+
message: 'All %{number_of_codes} codes have been created for promotion: '
|
|
187
|
+
subject: Promotion code batch finished
|
|
188
|
+
activerecord:
|
|
189
|
+
models:
|
|
190
|
+
solidus_promotions/benefits/adjust_shipment: Discount matching shipments
|
|
191
|
+
solidus_promotions/benefits/adjust_line_item: Discount matching line items
|
|
192
|
+
solidus_promotions/benefits/create_discounted_item: Create discounted line item
|
|
193
|
+
solidus_promotions/benefits/adjust_line_item_quantity_groups: Discount matching line items based on quantity groups
|
|
194
|
+
solidus_promotions/calculators/distributed_amount: Distributed Amount
|
|
195
|
+
solidus_promotions/calculators/percent: Percent
|
|
196
|
+
solidus_promotions/calculators/flat_rate: Flat Rate
|
|
197
|
+
solidus_promotions/calculators/flexi_rate: Flexible Rate
|
|
198
|
+
solidus_promotions/calculators/tiered_flat_rate: Tiered Flat Rate
|
|
199
|
+
solidus_promotions/calculators/tiered_percent: Tiered Percent
|
|
200
|
+
solidus_promotions/calculators/tiered_percent_on_eligible_item_quantity: Tiered Percent based on eligible item quantity
|
|
201
|
+
solidus_promotions/conditions/first_order: First Order
|
|
202
|
+
solidus_promotions/conditions/first_repeat_purchase_since: First Repeat Purchase Since
|
|
203
|
+
solidus_promotions/conditions/item_total: Item Total
|
|
204
|
+
solidus_promotions/conditions/discounted_item_total: Item Total after previous lanes
|
|
205
|
+
solidus_promotions/conditions/landing_page: Landing Page
|
|
206
|
+
solidus_promotions/conditions/minimum_quantity: Minimum Quantity
|
|
207
|
+
solidus_promotions/conditions/nth_order: Nth Order
|
|
208
|
+
solidus_promotions/conditions/one_use_per_user: One Use Per User
|
|
209
|
+
solidus_promotions/conditions/option_value: Option Value(s)
|
|
210
|
+
solidus_promotions/conditions/line_item_option_value: Line Item Option Value(s)
|
|
211
|
+
solidus_promotions/conditions/product: Order Product(s)
|
|
212
|
+
solidus_promotions/conditions/line_item_product: Line Item Product(s)
|
|
213
|
+
solidus_promotions/conditions/taxon: Order Taxon(s)
|
|
214
|
+
solidus_promotions/conditions/line_item_taxon: Line Item Taxon(s)
|
|
215
|
+
solidus_promotions/conditions/user: User
|
|
216
|
+
solidus_promotions/conditions/user_logged_in: User Logged In
|
|
217
|
+
solidus_promotions/conditions/user_role: User Role(s)
|
|
218
|
+
solidus_promotions/promotion_code_batch:
|
|
219
|
+
one: Code batch
|
|
220
|
+
other: Code batches
|
|
221
|
+
attributes:
|
|
222
|
+
solidus_promotions/promotion:
|
|
223
|
+
active: Active
|
|
224
|
+
customer_label: Customer-facing label
|
|
225
|
+
usage: Usage
|
|
226
|
+
lanes:
|
|
227
|
+
pre: Pre
|
|
228
|
+
default: Default
|
|
229
|
+
post: Post
|
|
230
|
+
solidus_promotions/benefit:
|
|
231
|
+
type: Benefit Type
|
|
232
|
+
solidus_promotions/condition:
|
|
233
|
+
type: Condition Type
|
|
234
|
+
solidus_promotions/benefits/adjust_line_item:
|
|
235
|
+
description: Creates a promotion credit on matching line items
|
|
236
|
+
solidus_promotions/benefits/adjust_shipment:
|
|
237
|
+
description: Creates a promotion credit on matching shipments
|
|
238
|
+
solidus_promotions/benefits/create_discounted_item:
|
|
239
|
+
description: Creates a discounted item with the quantity the applicable line items.
|
|
240
|
+
preferred_quantity: Quantity per applicable line item quantity
|
|
241
|
+
preferred_necessary_quantity: Number of items needed for a discounted item
|
|
242
|
+
solidus_promotions/conditions/first_order:
|
|
243
|
+
description: Must be the customer's first order
|
|
244
|
+
solidus_promotions/conditions/first_repeat_purchase_since:
|
|
245
|
+
description: Available only to users who have not purchased in a while
|
|
246
|
+
preferred_days_ago: Last purchase was at least this many days ago
|
|
247
|
+
solidus_promotions/conditions/item_total:
|
|
248
|
+
description: Order total must be greater than or equal to the specified amount
|
|
249
|
+
preferred_operator: Operator
|
|
250
|
+
preferred_amount: Amount
|
|
251
|
+
solidus_promotions/conditions/landing_page:
|
|
252
|
+
description: Customer must have visited the specified page
|
|
253
|
+
solidus_promotions/conditions/nth_order:
|
|
254
|
+
description: Apply a promotion to the nth order a user has completed.
|
|
255
|
+
form_text: 'Apply this promotion on the users Nth order: '
|
|
256
|
+
solidus_promotions/conditions/one_use_per_user:
|
|
257
|
+
description: Only one use per user
|
|
258
|
+
solidus_promotions/conditions/option_value:
|
|
259
|
+
description: Order includes specified product(s) with matching option value(s)
|
|
260
|
+
preferred_line_item_applicable: Should also apply to line items
|
|
261
|
+
solidus_promotions/conditions/line_item_option_value:
|
|
262
|
+
description: Line Item has specified product with matching option value
|
|
263
|
+
solidus_promotions/conditions/minimum_quantity:
|
|
264
|
+
description: Order contains minimum quantity of applicable items
|
|
265
|
+
solidus_promotions/conditions/product:
|
|
266
|
+
description: Order includes specified product(s)
|
|
267
|
+
line_item_level_description: 'Line item matches the specified products:'
|
|
268
|
+
preferred_line_item_applicable: Should also apply to line items
|
|
269
|
+
solidus_promotions/conditions/line_item_product:
|
|
270
|
+
description: Line item matches specified product(s)
|
|
271
|
+
preferred_match_policy: Match Policy
|
|
272
|
+
solidus_promotions/conditions/store:
|
|
273
|
+
description: Available only to the specified stores
|
|
274
|
+
solidus_promotions/conditions/taxon:
|
|
275
|
+
description: Order includes products with specified taxon(s)
|
|
276
|
+
preferred_line_item_applicable: Should also apply to line items
|
|
277
|
+
solidus_promotions/conditions/line_item_taxon:
|
|
278
|
+
description: Line Item has product with specified taxon(s)
|
|
279
|
+
preferred_match_policy: Match Policy
|
|
280
|
+
solidus_promotions/conditions/user:
|
|
281
|
+
description: Available only to the specified users
|
|
282
|
+
solidus_promotions/conditions/user_logged_in:
|
|
283
|
+
description: Available only to logged in users
|
|
284
|
+
solidus_promotions/conditions/user_role:
|
|
285
|
+
description: Order includes User with specified Role(s)
|
|
286
|
+
solidus_promotions/calculators/tiered_flat_rate:
|
|
287
|
+
description: Flat Rate in tiers based on item amount
|
|
288
|
+
preferred_base_amount: Base Amount
|
|
289
|
+
tiers: Tiers
|
|
290
|
+
solidus_promotions/calculators/tiered_percent:
|
|
291
|
+
description: Tiered percentage based on order's item total
|
|
292
|
+
preferred_base_percent: Base Percent
|
|
293
|
+
tiers: Tiers
|
|
294
|
+
order_item_total: Order Item Total
|
|
295
|
+
percent: Percent
|
|
296
|
+
solidus_promotions/calculators/tiered_percent_on_eligible_item_quantity:
|
|
297
|
+
description: Tiered percentage based on eligible item quantity
|
|
298
|
+
preferred_base_percent: Base Percent
|
|
299
|
+
tiers: Tiers
|
|
300
|
+
order_item_total: Order Item Total
|
|
301
|
+
discount: Discount
|
|
302
|
+
solidus_promotions/calculators/flat_rate:
|
|
303
|
+
description: Provides a flat rate discount
|
|
304
|
+
solidus_promotions/calculators/flexi_rate:
|
|
305
|
+
description: Calculates a discount for the first item and (separately) any additional items, with a maximum number of items that can be specified.
|
|
306
|
+
preferred_first_item: Discount for the first item
|
|
307
|
+
preferred_additional_item: Discount for additional items
|
|
308
|
+
preferred_max_items: Maximum number of items
|
|
309
|
+
preferred_currency: Currency
|
|
310
|
+
solidus_promotions/calculators/percent:
|
|
311
|
+
description: Provides a discount calculated by percent of the discountable amount of the item being discounted
|
|
312
|
+
solidus_promotions/calculators/distributed_amount:
|
|
313
|
+
description: Distributes the configured amount among all eligible line items of the order.
|
|
314
|
+
explanation: |
|
|
315
|
+
<p>
|
|
316
|
+
This amount will be distributed to line items weighted relative to
|
|
317
|
+
their price. More expensive line items will receive a greater share
|
|
318
|
+
of the adjustment.
|
|
319
|
+
</p>
|
|
320
|
+
<p>
|
|
321
|
+
For example, with three line items and a preferred amount of $15 we
|
|
322
|
+
would end up with the following distribution:
|
|
323
|
+
</p>
|
|
324
|
+
<table>
|
|
325
|
+
<thead>
|
|
326
|
+
<tr>
|
|
327
|
+
<th></th>
|
|
328
|
+
<th>Price</th>
|
|
329
|
+
<th>Weighted Adj.</th>
|
|
330
|
+
</tr>
|
|
331
|
+
</thead>
|
|
332
|
+
<tbody>
|
|
333
|
+
<tr>
|
|
334
|
+
<td>Socks</td>
|
|
335
|
+
<td>$5</td>
|
|
336
|
+
<td>-$1.5</td>
|
|
337
|
+
</tr>
|
|
338
|
+
<tr>
|
|
339
|
+
<td>Shoes</td>
|
|
340
|
+
<td>$30</td>
|
|
341
|
+
<td>-$9</td>
|
|
342
|
+
</tr>
|
|
343
|
+
<tr>
|
|
344
|
+
<td>Slippers</td>
|
|
345
|
+
<td>$15</td>
|
|
346
|
+
<td>-$4.5</td>
|
|
347
|
+
</tr>
|
|
348
|
+
</tbody>
|
|
349
|
+
</table>
|
|
350
|
+
preferred_amount: Amount
|
|
351
|
+
|
|
352
|
+
errors:
|
|
353
|
+
models:
|
|
354
|
+
solidus_promotions/benefit:
|
|
355
|
+
attributes:
|
|
356
|
+
base:
|
|
357
|
+
cannot_destroy_if_order_completed: Benefit has been applied to complete orders. It cannot be destroyed.
|
|
358
|
+
solidus_promotions/condition:
|
|
359
|
+
attributes:
|
|
360
|
+
benefit:
|
|
361
|
+
already_contains_condition_type: already contains this condition type
|
|
362
|
+
type:
|
|
363
|
+
invalid_condition_type: is not a valid condition type
|
|
364
|
+
solidus_promotions/promotion_code:
|
|
365
|
+
attributes:
|
|
366
|
+
base:
|
|
367
|
+
disallowed_with_apply_automatically: Could not create promotion code on promotion that apply automatically
|
|
368
|
+
spree/line_item:
|
|
369
|
+
attributes:
|
|
370
|
+
quantity:
|
|
371
|
+
cannot_be_changed_for_automated_items: cannot be changed on a line item managed by a promotion benefit
|
|
372
|
+
solidus_promotions/promotion:
|
|
373
|
+
attributes:
|
|
374
|
+
apply_automatically:
|
|
375
|
+
disallowed_with_path: cannot be set to true when path is present
|
|
376
|
+
disallowed_with_promotion_codes: cannot be set to true when promotion code is present
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
SolidusPromotions::Engine.routes.draw do
|
|
4
|
+
if SolidusSupport.admin_available?
|
|
5
|
+
require "solidus_admin/admin_resources"
|
|
6
|
+
extend SolidusAdmin::AdminResources
|
|
7
|
+
|
|
8
|
+
constraints(->(request) {
|
|
9
|
+
request.cookies["solidus_admin"] == "true" ||
|
|
10
|
+
request.params["solidus_admin"] == "true" ||
|
|
11
|
+
SolidusPromotions.config.use_new_admin?
|
|
12
|
+
}) do
|
|
13
|
+
scope :admin do
|
|
14
|
+
scope :solidus do
|
|
15
|
+
admin_resources :promotion_categories, only: [:index, :destroy]
|
|
16
|
+
admin_resources :promotions, only: [:index, :destroy]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
if SolidusSupport.backend_available?
|
|
22
|
+
namespace :admin do
|
|
23
|
+
scope :solidus do
|
|
24
|
+
resources :promotion_categories, except: [:show]
|
|
25
|
+
|
|
26
|
+
resources :promotions do
|
|
27
|
+
resources :benefits do
|
|
28
|
+
resources :conditions
|
|
29
|
+
end
|
|
30
|
+
resources :promotion_codes, only: [:index, :new, :create]
|
|
31
|
+
resources :promotion_code_batches, only: [:index, :new, :create] do
|
|
32
|
+
get "/download", to: "promotion_code_batches#download", defaults: { format: "csv" }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|