solidus_promotions 4.6.2 → 4.7.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 +4 -4
- data/MIGRATING.md +10 -4
- data/README.md +7 -0
- data/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js +3 -26
- data/app/javascript/backend/solidus_promotions/web_components/option_value_picker.js +36 -19
- data/app/javascript/backend/solidus_promotions/web_components/product_picker.js +6 -1
- data/app/jobs/solidus_promotions/promotion_code_batch_job.rb +1 -1
- data/app/models/concerns/solidus_promotions/adjustment_discounts.rb +20 -0
- data/app/models/concerns/solidus_promotions/benefits/line_item_benefit.rb +5 -0
- data/app/models/concerns/solidus_promotions/benefits/order_benefit.rb +5 -0
- data/app/models/concerns/solidus_promotions/benefits/shipment_benefit.rb +5 -0
- data/app/models/concerns/solidus_promotions/calculators/promotion_calculator.rb +7 -0
- data/app/models/concerns/solidus_promotions/conditions/line_item_applicable_order_level_condition.rb +17 -5
- data/app/models/concerns/solidus_promotions/conditions/line_item_level_condition.rb +15 -2
- data/app/models/concerns/solidus_promotions/conditions/option_value_condition.rb +21 -0
- data/app/models/concerns/solidus_promotions/conditions/order_level_condition.rb +15 -2
- data/app/models/concerns/solidus_promotions/conditions/product_condition.rb +28 -0
- data/app/models/concerns/solidus_promotions/conditions/shipment_level_condition.rb +15 -2
- data/app/models/concerns/solidus_promotions/conditions/taxon_condition.rb +77 -0
- data/app/models/concerns/solidus_promotions/coupon_code_normalizer.rb +37 -0
- data/app/models/concerns/solidus_promotions/discountable_amount.rb +3 -4
- data/app/models/concerns/solidus_promotions/discounted_amount.rb +54 -0
- data/app/models/solidus_promotions/benefit.rb +257 -36
- data/app/models/solidus_promotions/benefits/adjust_line_item.rb +28 -3
- data/app/models/solidus_promotions/benefits/adjust_line_item_quantity_groups.rb +1 -0
- data/app/models/solidus_promotions/benefits/adjust_shipment.rb +45 -3
- data/app/models/solidus_promotions/benefits/advertise_price.rb +28 -0
- data/app/models/solidus_promotions/benefits/create_discounted_item.rb +30 -7
- data/app/models/solidus_promotions/calculators/distributed_amount.rb +34 -8
- data/app/models/solidus_promotions/calculators/flat_rate.rb +52 -6
- data/app/models/solidus_promotions/calculators/flexi_rate.rb +69 -6
- data/app/models/solidus_promotions/calculators/percent.rb +40 -4
- data/app/models/solidus_promotions/calculators/percent_with_cap.rb +44 -3
- data/app/models/solidus_promotions/calculators/tiered_flat_rate.rb +81 -19
- data/app/models/solidus_promotions/calculators/tiered_percent.rb +96 -25
- data/app/models/solidus_promotions/calculators/tiered_percent_on_eligible_item_quantity.rb +101 -16
- data/app/models/solidus_promotions/condition.rb +186 -7
- data/app/models/solidus_promotions/conditions/first_order.rb +3 -1
- data/app/models/solidus_promotions/conditions/first_repeat_purchase_since.rb +3 -2
- data/app/models/solidus_promotions/conditions/item_total.rb +2 -1
- data/app/models/solidus_promotions/conditions/line_item_option_value.rb +4 -12
- data/app/models/solidus_promotions/conditions/line_item_product.rb +4 -22
- data/app/models/solidus_promotions/conditions/line_item_taxon.rb +7 -38
- data/app/models/solidus_promotions/conditions/minimum_quantity.rb +3 -2
- data/app/models/solidus_promotions/conditions/nth_order.rb +3 -2
- data/app/models/solidus_promotions/conditions/one_use_per_user.rb +2 -1
- data/app/models/solidus_promotions/conditions/option_value.rb +6 -11
- data/app/models/solidus_promotions/conditions/order_option_value.rb +19 -0
- data/app/models/solidus_promotions/conditions/order_product.rb +62 -0
- data/app/models/solidus_promotions/conditions/order_taxon.rb +60 -0
- data/app/models/solidus_promotions/conditions/price_option_value.rb +26 -0
- data/app/models/solidus_promotions/conditions/price_product.rb +36 -0
- data/app/models/solidus_promotions/conditions/price_taxon.rb +28 -0
- data/app/models/solidus_promotions/conditions/product.rb +17 -59
- data/app/models/solidus_promotions/conditions/shipping_method.rb +3 -5
- data/app/models/solidus_promotions/conditions/store.rb +2 -1
- data/app/models/solidus_promotions/conditions/taxon.rb +24 -73
- data/app/models/solidus_promotions/conditions/user.rb +2 -1
- data/app/models/solidus_promotions/conditions/user_logged_in.rb +1 -3
- data/app/models/solidus_promotions/conditions/user_role.rb +1 -3
- data/app/models/solidus_promotions/distributed_amounts_handler.rb +2 -6
- data/app/models/solidus_promotions/eligibility_results.rb +1 -0
- data/app/models/solidus_promotions/item_discount.rb +1 -0
- data/app/models/solidus_promotions/order_adjuster/discount_order.rb +29 -35
- data/app/models/solidus_promotions/order_adjuster/recalculate_promo_totals.rb +45 -0
- data/app/models/solidus_promotions/order_adjuster/set_discounts_to_zero.rb +33 -0
- data/app/models/solidus_promotions/order_adjuster.rb +4 -14
- data/app/models/solidus_promotions/order_promotion.rb +1 -0
- data/app/models/solidus_promotions/product_advertiser.rb +57 -0
- data/app/models/solidus_promotions/promotion.rb +12 -10
- data/app/models/solidus_promotions/promotion_code/batch_builder.rb +1 -1
- data/app/models/solidus_promotions/promotion_code.rb +4 -4
- data/app/models/solidus_promotions/promotion_code_batch.rb +1 -1
- data/app/models/solidus_promotions/promotion_handler/coupon.rb +1 -1
- data/app/models/solidus_promotions/promotion_handler/page.rb +1 -1
- data/app/models/solidus_promotions/promotion_lane.rb +48 -0
- data/app/models/solidus_promotions/shipping_rate_discount.rb +3 -0
- data/app/patches/models/solidus_promotions/line_item_patch.rb +2 -0
- data/app/patches/models/solidus_promotions/order_patch.rb +8 -0
- data/app/patches/models/solidus_promotions/order_recalculator_patch.rb +3 -1
- data/app/patches/models/solidus_promotions/price_patch.rb +31 -0
- data/app/patches/models/solidus_promotions/shipment_patch.rb +2 -0
- data/app/patches/models/solidus_promotions/shipping_rate_patch.rb +15 -0
- data/config/locales/en.yml +47 -11
- data/config/routes.rb +1 -1
- data/db/migrate/20230703101637_create_promotions.rb +2 -2
- data/db/migrate/20230703113625_create_promotion_benefits.rb +3 -3
- data/db/migrate/20230703141116_create_promotion_categories.rb +1 -1
- data/db/migrate/20230703143943_create_promotion_conditions.rb +1 -1
- data/db/migrate/20230704083830_add_condition_join_tables.rb +8 -8
- data/db/migrate/20230704102444_create_promotion_codes.rb +1 -1
- data/db/migrate/20230704102656_create_promotion_code_batches.rb +1 -1
- data/db/migrate/20230705171556_create_order_promotions.rb +3 -3
- data/db/migrate/20230725074235_create_shipping_rate_discounts.rb +2 -2
- data/db/migrate/20231104135812_add_managed_by_order_benefit_to_line_items.rb +1 -1
- data/db/migrate/20251104170913_update_promotion_code_value_collation.rb +38 -0
- data/db/migrate/20251104214304_separate_out_order_only_conditions.rb +41 -0
- data/eslint.config.mjs +29 -0
- data/lib/components/admin/solidus_promotions/promotion_categories/index/component.rb +6 -6
- data/lib/components/admin/solidus_promotions/promotions/index/component.rb +5 -5
- data/lib/solidus_promotions/configuration.rb +57 -12
- data/lib/solidus_promotions/promotion_map.rb +14 -14
- data/lib/solidus_promotions/testing_support/shared_examples/option_value_condition.rb +18 -0
- data/lib/solidus_promotions/testing_support/shared_examples/product_condition.rb +37 -0
- data/lib/solidus_promotions/testing_support/shared_examples/promotion_calculator.rb +11 -0
- data/lib/solidus_promotions/testing_support/shared_examples/taxon_condition.rb +37 -0
- data/lib/solidus_promotions/testing_support/shared_examples.rb +6 -0
- data/lib/views/backend/solidus_promotions/admin/benefit_fields/_advertise_price.html.erb +7 -0
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/_default_fields.html.erb +1 -1
- data/lib/views/backend/solidus_promotions/admin/calculator_fields/percent/_fields.html.erb +1 -1
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb +6 -5
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_option_value.html.erb +6 -12
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_price_option_value.html.erb +26 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_price_product.html.erb +21 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_price_taxon.html.erb +17 -0
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_product.html.erb +0 -7
- data/lib/views/backend/solidus_promotions/admin/condition_fields/_taxon.html.erb +0 -7
- data/lib/views/backend/solidus_promotions/admin/condition_fields/line_item_option_value/_option_value_fields.html.erb +10 -4
- data/solidus_promotions.gemspec +1 -1
- metadata +37 -6
- data/.eslintrc.json +0 -10
- data/app/models/solidus_promotions/order_adjuster/persist_discounted_order.rb +0 -79
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.shared_examples "an option value condition" do
|
|
4
|
+
let(:condition) do
|
|
5
|
+
super()
|
|
6
|
+
rescue NoMethodError
|
|
7
|
+
described_class.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "#preferred_eligible_values" do
|
|
11
|
+
subject { condition.preferred_eligible_values }
|
|
12
|
+
|
|
13
|
+
it "assigns a nicely formatted hash" do
|
|
14
|
+
condition.preferred_eligible_values = {"5" => "1,2", "6" => "1"}
|
|
15
|
+
expect(subject).to eq({5 => [1, 2], 6 => [1]})
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.shared_examples "a product condition" do
|
|
4
|
+
let(:condition) do
|
|
5
|
+
super()
|
|
6
|
+
rescue NoMethodError
|
|
7
|
+
described_class.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it { is_expected.to have_many :products }
|
|
11
|
+
|
|
12
|
+
describe "#product_ids_string" do
|
|
13
|
+
it "returns a string of product ids" do
|
|
14
|
+
condition.products = [create(:product), create(:product)]
|
|
15
|
+
expect(condition.product_ids_string).to eq("#{condition.products[0].id},#{condition.products[1].id}")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#preload_relations" do
|
|
20
|
+
subject { condition.preload_relations }
|
|
21
|
+
it { is_expected.to eq([:products]) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#product_ids_string=" do
|
|
25
|
+
it "sets products based on a string of product ids" do
|
|
26
|
+
product_one = create(:product)
|
|
27
|
+
product_two = create(:product)
|
|
28
|
+
condition.product_ids_string = "#{product_one.id},#{product_two.id}"
|
|
29
|
+
expect(condition.products).to eq([product_one, product_two])
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "#preload_relations" do
|
|
34
|
+
subject { condition.preload_relations }
|
|
35
|
+
it { is_expected.to eq([:products]) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.shared_examples "a taxon condition" do
|
|
4
|
+
let(:condition) do
|
|
5
|
+
super()
|
|
6
|
+
rescue NoMethodError
|
|
7
|
+
described_class.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it { is_expected.to have_many :taxons }
|
|
11
|
+
|
|
12
|
+
describe "#taxon_ids_string" do
|
|
13
|
+
it "returns a string of taxon ids" do
|
|
14
|
+
condition.taxons = [create(:taxon), create(:taxon)]
|
|
15
|
+
expect(condition.taxon_ids_string).to eq("#{condition.taxons[0].id},#{condition.taxons[1].id}")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#preload_relations" do
|
|
20
|
+
subject { condition.preload_relations }
|
|
21
|
+
it { is_expected.to eq([:taxons]) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#taxon_ids_string=" do
|
|
25
|
+
it "sets taxons based on a string of taxon ids" do
|
|
26
|
+
taxon_one = create(:taxon)
|
|
27
|
+
taxon_two = create(:taxon)
|
|
28
|
+
condition.taxon_ids_string = "#{taxon_one.id},#{taxon_two.id}"
|
|
29
|
+
expect(condition.taxons).to eq([taxon_one, taxon_two])
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "#preload_relations" do
|
|
34
|
+
subject { condition.preload_relations }
|
|
35
|
+
it { is_expected.to eq([:taxons]) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "solidus_promotions/testing_support/shared_examples/product_condition"
|
|
4
|
+
require "solidus_promotions/testing_support/shared_examples/taxon_condition"
|
|
5
|
+
require "solidus_promotions/testing_support/shared_examples/option_value_condition"
|
|
6
|
+
require "solidus_promotions/testing_support/shared_examples/promotion_calculator"
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
<%= render "solidus_promotions/admin/shared/preference_fields/#{calculator.preference_type(name)}",
|
|
3
3
|
name: "#{prefix}[calculator_attributes][preferred_#{name}]",
|
|
4
4
|
value: calculator.get_preference(name),
|
|
5
|
-
label: calculator.class.human_attribute_name("preferred_#{name}", default: I18n.t(name, scope: :spree, default: name.humanize)) %>
|
|
5
|
+
label: calculator.class.human_attribute_name("preferred_#{name}", default: I18n.t(name, scope: :spree, default: name.to_s.humanize)) %>
|
|
6
6
|
<% end %>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div class="form-group">
|
|
2
2
|
<%= fields_for "#{prefix}[calculator_attributes]", calculator do |f| %>
|
|
3
3
|
<%= f.label :preferred_percent %>
|
|
4
|
-
<%= f.number_field :preferred_percent, step:
|
|
4
|
+
<%= f.number_field :preferred_percent, step: 0.01, min: 1, max: 100, default: 1, class: "form-control" %>
|
|
5
5
|
<% end %>
|
|
6
6
|
</div>
|
data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb
CHANGED
|
@@ -5,19 +5,20 @@
|
|
|
5
5
|
<div class="field promo-condition-option-values">
|
|
6
6
|
<div class="param-prefix hidden" data-param-prefix="<%= param_prefix %>"></div>
|
|
7
7
|
<div class="row">
|
|
8
|
-
<div class="col-
|
|
8
|
+
<div class="col-5"><%= label_tag nil, Spree::Product.model_name.human %></div>
|
|
9
9
|
<div class="col-6"><%= label_tag nil, plural_resource_name(Spree::OptionValue) %></div>
|
|
10
|
+
<div class="col-1"> </div>
|
|
10
11
|
</div>
|
|
11
12
|
|
|
12
13
|
<div class="form-group">
|
|
13
14
|
<div data-controller="product-option-values">
|
|
14
15
|
<template data-product-option-values-target="template">
|
|
15
|
-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form %>
|
|
16
|
+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form, index: 0 %>
|
|
16
17
|
</template>
|
|
17
|
-
<% form.object.preferred_eligible_values.each do |product_option_values| %>
|
|
18
|
-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values
|
|
18
|
+
<% form.object.preferred_eligible_values.each.with_index do |product_option_values, index| %>
|
|
19
|
+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values:, form:, index: %>
|
|
19
20
|
<% end %>
|
|
20
|
-
<div class="
|
|
21
|
+
<div class="mt-3" data-product-option-values-target="links">
|
|
21
22
|
<%= link_to t(:add_product, scope: [:solidus_promotions, :line_item_option_value_condition]), "#", class: "btn btn-outline-primary", data: { action: "click->product-option-values#add_row" } %>
|
|
22
23
|
</div>
|
|
23
24
|
</div>
|
|
@@ -7,30 +7,24 @@
|
|
|
7
7
|
<div class="field promo-condition-option-values">
|
|
8
8
|
<div class="param-prefix hidden" data-param-prefix="<%= param_prefix %>"></div>
|
|
9
9
|
<div class="row">
|
|
10
|
-
<div class="col-
|
|
10
|
+
<div class="col-5"><%= label_tag nil, Spree::Product.model_name.human %></div>
|
|
11
11
|
<div class="col-6"><%= label_tag nil, plural_resource_name(Spree::OptionValue) %></div>
|
|
12
|
+
<div class="col-1"> </div>
|
|
12
13
|
</div>
|
|
13
14
|
|
|
14
15
|
<div class="form-group">
|
|
15
16
|
<div data-controller="product-option-values">
|
|
16
17
|
<template data-product-option-values-target="template">
|
|
17
|
-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form:
|
|
18
|
+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form:, index: 0 %>
|
|
18
19
|
</template>
|
|
19
|
-
<% form.object.preferred_eligible_values.each do |product_option_values| %>
|
|
20
|
-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values
|
|
20
|
+
<% form.object.preferred_eligible_values.each.with_index do |product_option_values, index| %>
|
|
21
|
+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values:, form:, index: %>
|
|
21
22
|
<% end %>
|
|
22
|
-
<div class="
|
|
23
|
+
<div class="mt-3" data-product-option-values-target="links">
|
|
23
24
|
<%= link_to t(:add_product, scope: [:solidus_promotions, :option_value_condition]), "#", class: "btn btn-outline-primary", data: { action: "click->product-option-values#add_row" } %>
|
|
24
25
|
</div>
|
|
25
26
|
</div>
|
|
26
27
|
</div>
|
|
27
|
-
|
|
28
|
-
<div class="form-group">
|
|
29
|
-
<%= form.label :preferred_line_item_applicable do %>
|
|
30
|
-
<%= form.check_box :preferred_line_item_applicable %>
|
|
31
|
-
<%= condition.class.human_attribute_name(:preferred_line_item_applicable) %>
|
|
32
|
-
<% end %>
|
|
33
|
-
</div>
|
|
34
28
|
</div>
|
|
35
29
|
<% else %>
|
|
36
30
|
<p>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
<p>
|
|
3
|
+
<%= condition.class.human_attribute_name(:description) %>
|
|
4
|
+
</p>
|
|
5
|
+
<div class="field promo-condition-option-values">
|
|
6
|
+
<div class="param-prefix hidden" data-param-prefix="<%= param_prefix %>"></div>
|
|
7
|
+
<div class="row">
|
|
8
|
+
<div class="col-5"><%= label_tag nil, Spree::Product.model_name.human %></div>
|
|
9
|
+
<div class="col-6"><%= label_tag nil, plural_resource_name(Spree::OptionValue) %></div>
|
|
10
|
+
<div class="col-1"> </div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div class="form-group">
|
|
14
|
+
<div data-controller="product-option-values">
|
|
15
|
+
<template data-product-option-values-target="template">
|
|
16
|
+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form, index: 0 %>
|
|
17
|
+
</template>
|
|
18
|
+
<% form.object.preferred_eligible_values.each.with_index do |product_option_values, index| %>
|
|
19
|
+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values:, form:, index: %>
|
|
20
|
+
<% end %>
|
|
21
|
+
<div class="mt-3" data-product-option-values-target="links">
|
|
22
|
+
<%= link_to t(:add_product, scope: [:solidus_promotions, :line_item_option_value_condition]), "#", class: "btn btn-outline-primary", data: { action: "click->product-option-values#add_row" } %>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<p>
|
|
2
|
+
<%= condition.class.human_attribute_name(:description) %>
|
|
3
|
+
</p>
|
|
4
|
+
<div class="row">
|
|
5
|
+
<div class="col-12">
|
|
6
|
+
<div class="field products_condition_products">
|
|
7
|
+
<%= label_tag "#{param_prefix}_product_ids_string", t('solidus_promotions.product_condition.choose_products') %>
|
|
8
|
+
<%= hidden_field_tag "#{param_prefix}[product_ids_string]", condition.product_ids.join(","), class: "fullwidth", is: "product-picker" %>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="col-12">
|
|
12
|
+
<div class="form-group">
|
|
13
|
+
<%= label_tag("#{param_prefix}_preferred_match_policy", condition.class.human_attribute_name(:preferred_match_policy)) %>
|
|
14
|
+
<%= select_tag(
|
|
15
|
+
"#{param_prefix}[preferred_match_policy]",
|
|
16
|
+
options_for_select(I18n.t("solidus_promotions.conditions.price_product.match_policies").to_a.map(&:reverse), condition.preferred_match_policy),
|
|
17
|
+
class: "custom-select fullwidth"
|
|
18
|
+
) %>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<p>
|
|
2
|
+
<%= condition.class.human_attribute_name(:description) %>
|
|
3
|
+
</p>
|
|
4
|
+
<div class="field taxons_condition_taxons">
|
|
5
|
+
<%= label_tag "#{param_prefix}_taxon_ids_string", t("solidus_promotions.taxon_condition.choose_taxons") %>
|
|
6
|
+
<%= hidden_field_tag "#{param_prefix}[taxon_ids_string]", condition.taxon_ids.join(","), is: "taxon-picker", class: "fullwidth", id: "product_taxon_ids" %>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="form-group">
|
|
9
|
+
<div class="form-group">
|
|
10
|
+
<%= label_tag("#{param_prefix}_preferred_match_policy", condition.class.human_attribute_name(:preferred_match_policy)) %>
|
|
11
|
+
<%= select_tag(
|
|
12
|
+
"#{param_prefix}[preferred_match_policy]",
|
|
13
|
+
options_for_select(I18n.t("solidus_promotions.conditions.price_taxon.match_policies").to_a.map(&:reverse), condition.preferred_match_policy),
|
|
14
|
+
class: "custom-select fullwidth",
|
|
15
|
+
) %>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
@@ -17,11 +17,4 @@
|
|
|
17
17
|
<% select = form.select :preferred_match_policy, match_policy_options %>
|
|
18
18
|
<%= form.label :preferred_match_policy, t('solidus_promotions.product_condition.label', select: select).html_safe %>
|
|
19
19
|
</div>
|
|
20
|
-
|
|
21
|
-
<div class="form-group">
|
|
22
|
-
<%= form.label :preferred_line_item_applicable do %>
|
|
23
|
-
<%= form.check_box :preferred_line_item_applicable %>
|
|
24
|
-
<%= condition.class.human_attribute_name(:preferred_line_item_applicable) %>
|
|
25
|
-
<% end %>
|
|
26
|
-
</div>
|
|
27
20
|
<% end %>
|
|
@@ -17,11 +17,4 @@
|
|
|
17
17
|
<% select = form.select :preferred_match_policy, match_policy_options %>
|
|
18
18
|
<%= form.label :preferred_match_policy, t('solidus_promotions.taxon_condition.label', select: select).html_safe %>
|
|
19
19
|
</div>
|
|
20
|
-
|
|
21
|
-
<div class="form-group">
|
|
22
|
-
<%= form.label :preferred_line_item_applicable do %>
|
|
23
|
-
<%= form.check_box :preferred_line_item_applicable %>
|
|
24
|
-
<%= condition.class.human_attribute_name(:preferred_line_item_applicable) %>
|
|
25
|
-
<% end %>
|
|
26
|
-
</div>
|
|
27
20
|
<% end %>
|
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
<div class="
|
|
2
|
-
<div class="
|
|
1
|
+
<div class="promo-condition-option-value row">
|
|
2
|
+
<div class="col-5">
|
|
3
3
|
<input
|
|
4
4
|
is="product-picker"
|
|
5
|
+
id="ov-product-picker-<%= index %>"
|
|
5
6
|
class="w-100"
|
|
6
7
|
data-action="select2Change->product-option-values#propagate_product_id_to_value_input"
|
|
8
|
+
data-multiple="false"
|
|
7
9
|
type="hidden"
|
|
8
10
|
value="<%= product_option_values[0] %>"
|
|
9
11
|
>
|
|
10
12
|
</div>
|
|
11
|
-
<div class="
|
|
13
|
+
<div class="col-6">
|
|
12
14
|
<input
|
|
13
15
|
is="option-value-picker"
|
|
16
|
+
id="option-value-picker-<%= index %>"
|
|
14
17
|
class="fullwidth"
|
|
15
18
|
name="<%= form.object_name %>[preferred_eligible_values][<%= product_option_values[0] %>]"
|
|
16
19
|
type="hidden"
|
|
20
|
+
data-product-id="<%= product_option_values[0] %>"
|
|
17
21
|
value="<%= product_option_values[1].join(",") %>"
|
|
18
22
|
>
|
|
19
23
|
</div>
|
|
20
|
-
<
|
|
24
|
+
<div class="col-1">
|
|
25
|
+
<a class="fa fa-trash remove p-2 float-right" data-action="click->product-option-values#remove_row"></a>
|
|
26
|
+
</div>
|
|
21
27
|
</div>
|
data/solidus_promotions.gemspec
CHANGED
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
|
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
19
19
|
|
|
20
|
-
spec.required_ruby_version = ">= 3.
|
|
20
|
+
spec.required_ruby_version = ">= 3.2.0"
|
|
21
21
|
|
|
22
22
|
# Specify which files should be added to the gem when it is released.
|
|
23
23
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
metadata
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solidus_promotions
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martin Meyerhoff
|
|
8
8
|
- Solidus Team
|
|
9
|
+
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
+
date: 2026-04-15 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: csv
|
|
@@ -126,7 +127,6 @@ executables: []
|
|
|
126
127
|
extensions: []
|
|
127
128
|
extra_rdoc_files: []
|
|
128
129
|
files:
|
|
129
|
-
- ".eslintrc.json"
|
|
130
130
|
- ".github/stale.yml"
|
|
131
131
|
- MIGRATING.md
|
|
132
132
|
- README.md
|
|
@@ -150,19 +150,26 @@ files:
|
|
|
150
150
|
- app/javascript/backend/solidus_promotions/web_components/variant_picker.js
|
|
151
151
|
- app/jobs/solidus_promotions/promotion_code_batch_job.rb
|
|
152
152
|
- app/mailers/solidus_promotions/promotion_code_batch_mailer.rb
|
|
153
|
+
- app/models/concerns/solidus_promotions/adjustment_discounts.rb
|
|
153
154
|
- app/models/concerns/solidus_promotions/benefits/line_item_benefit.rb
|
|
154
155
|
- app/models/concerns/solidus_promotions/benefits/order_benefit.rb
|
|
155
156
|
- app/models/concerns/solidus_promotions/benefits/shipment_benefit.rb
|
|
156
157
|
- app/models/concerns/solidus_promotions/calculators/promotion_calculator.rb
|
|
157
158
|
- app/models/concerns/solidus_promotions/conditions/line_item_applicable_order_level_condition.rb
|
|
158
159
|
- app/models/concerns/solidus_promotions/conditions/line_item_level_condition.rb
|
|
160
|
+
- app/models/concerns/solidus_promotions/conditions/option_value_condition.rb
|
|
159
161
|
- app/models/concerns/solidus_promotions/conditions/order_level_condition.rb
|
|
162
|
+
- app/models/concerns/solidus_promotions/conditions/product_condition.rb
|
|
160
163
|
- app/models/concerns/solidus_promotions/conditions/shipment_level_condition.rb
|
|
164
|
+
- app/models/concerns/solidus_promotions/conditions/taxon_condition.rb
|
|
165
|
+
- app/models/concerns/solidus_promotions/coupon_code_normalizer.rb
|
|
161
166
|
- app/models/concerns/solidus_promotions/discountable_amount.rb
|
|
167
|
+
- app/models/concerns/solidus_promotions/discounted_amount.rb
|
|
162
168
|
- app/models/solidus_promotions/benefit.rb
|
|
163
169
|
- app/models/solidus_promotions/benefits/adjust_line_item.rb
|
|
164
170
|
- app/models/solidus_promotions/benefits/adjust_line_item_quantity_groups.rb
|
|
165
171
|
- app/models/solidus_promotions/benefits/adjust_shipment.rb
|
|
172
|
+
- app/models/solidus_promotions/benefits/advertise_price.rb
|
|
166
173
|
- app/models/solidus_promotions/benefits/create_discounted_item.rb
|
|
167
174
|
- app/models/solidus_promotions/calculators/distributed_amount.rb
|
|
168
175
|
- app/models/solidus_promotions/calculators/flat_rate.rb
|
|
@@ -188,6 +195,12 @@ files:
|
|
|
188
195
|
- app/models/solidus_promotions/conditions/nth_order.rb
|
|
189
196
|
- app/models/solidus_promotions/conditions/one_use_per_user.rb
|
|
190
197
|
- app/models/solidus_promotions/conditions/option_value.rb
|
|
198
|
+
- app/models/solidus_promotions/conditions/order_option_value.rb
|
|
199
|
+
- app/models/solidus_promotions/conditions/order_product.rb
|
|
200
|
+
- app/models/solidus_promotions/conditions/order_taxon.rb
|
|
201
|
+
- app/models/solidus_promotions/conditions/price_option_value.rb
|
|
202
|
+
- app/models/solidus_promotions/conditions/price_product.rb
|
|
203
|
+
- app/models/solidus_promotions/conditions/price_taxon.rb
|
|
191
204
|
- app/models/solidus_promotions/conditions/product.rb
|
|
192
205
|
- app/models/solidus_promotions/conditions/shipping_method.rb
|
|
193
206
|
- app/models/solidus_promotions/conditions/store.rb
|
|
@@ -205,9 +218,11 @@ files:
|
|
|
205
218
|
- app/models/solidus_promotions/order_adjuster/choose_discounts.rb
|
|
206
219
|
- app/models/solidus_promotions/order_adjuster/discount_order.rb
|
|
207
220
|
- app/models/solidus_promotions/order_adjuster/load_promotions.rb
|
|
208
|
-
- app/models/solidus_promotions/order_adjuster/
|
|
221
|
+
- app/models/solidus_promotions/order_adjuster/recalculate_promo_totals.rb
|
|
222
|
+
- app/models/solidus_promotions/order_adjuster/set_discounts_to_zero.rb
|
|
209
223
|
- app/models/solidus_promotions/order_promotion.rb
|
|
210
224
|
- app/models/solidus_promotions/permission_sets/solidus_promotion_management.rb
|
|
225
|
+
- app/models/solidus_promotions/product_advertiser.rb
|
|
211
226
|
- app/models/solidus_promotions/promotion.rb
|
|
212
227
|
- app/models/solidus_promotions/promotion_advertiser.rb
|
|
213
228
|
- app/models/solidus_promotions/promotion_category.rb
|
|
@@ -217,11 +232,13 @@ files:
|
|
|
217
232
|
- app/models/solidus_promotions/promotion_finder.rb
|
|
218
233
|
- app/models/solidus_promotions/promotion_handler/coupon.rb
|
|
219
234
|
- app/models/solidus_promotions/promotion_handler/page.rb
|
|
235
|
+
- app/models/solidus_promotions/promotion_lane.rb
|
|
220
236
|
- app/models/solidus_promotions/shipping_rate_discount.rb
|
|
221
237
|
- app/patches/models/solidus_promotions/adjustment_patch.rb
|
|
222
238
|
- app/patches/models/solidus_promotions/line_item_patch.rb
|
|
223
239
|
- app/patches/models/solidus_promotions/order_patch.rb
|
|
224
240
|
- app/patches/models/solidus_promotions/order_recalculator_patch.rb
|
|
241
|
+
- app/patches/models/solidus_promotions/price_patch.rb
|
|
225
242
|
- app/patches/models/solidus_promotions/shipment_patch.rb
|
|
226
243
|
- app/patches/models/solidus_promotions/shipping_rate_patch.rb
|
|
227
244
|
- app/subscribers/solidus_promotions/order_promotion_subscriber.rb
|
|
@@ -251,6 +268,9 @@ files:
|
|
|
251
268
|
- db/migrate/20231012020928_add_db_comments_to_condition_products.rb
|
|
252
269
|
- db/migrate/20231012120928_add_db_comments_to_promotion_categories.rb
|
|
253
270
|
- db/migrate/20231104135812_add_managed_by_order_benefit_to_line_items.rb
|
|
271
|
+
- db/migrate/20251104170913_update_promotion_code_value_collation.rb
|
|
272
|
+
- db/migrate/20251104214304_separate_out_order_only_conditions.rb
|
|
273
|
+
- eslint.config.mjs
|
|
254
274
|
- lib/components/admin/solidus_admin/orders/show/adjustments/index/source/solidus_promotions_benefit/component.rb
|
|
255
275
|
- lib/components/admin/solidus_promotions/orders/index/component.rb
|
|
256
276
|
- lib/components/admin/solidus_promotions/orders/index/component.yml
|
|
@@ -288,12 +308,18 @@ files:
|
|
|
288
308
|
- lib/solidus_promotions/testing_support/factories/solidus_promotion_factory.rb
|
|
289
309
|
- lib/solidus_promotions/testing_support/factories/solidus_shipping_rate_discount_factory.rb
|
|
290
310
|
- lib/solidus_promotions/testing_support/factory_bot.rb
|
|
311
|
+
- lib/solidus_promotions/testing_support/shared_examples.rb
|
|
312
|
+
- lib/solidus_promotions/testing_support/shared_examples/option_value_condition.rb
|
|
313
|
+
- lib/solidus_promotions/testing_support/shared_examples/product_condition.rb
|
|
314
|
+
- lib/solidus_promotions/testing_support/shared_examples/promotion_calculator.rb
|
|
315
|
+
- lib/solidus_promotions/testing_support/shared_examples/taxon_condition.rb
|
|
291
316
|
- lib/tasks/solidus_promotions/migrate_adjustments.rake
|
|
292
317
|
- lib/tasks/solidus_promotions/migrate_existing_promotions.rake
|
|
293
318
|
- lib/tasks/solidus_promotions/migrate_order_promotions.rake
|
|
294
319
|
- lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_line_item.html.erb
|
|
295
320
|
- lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_line_item_quantity_groups.html.erb
|
|
296
321
|
- lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_shipment.html.erb
|
|
322
|
+
- lib/views/backend/solidus_promotions/admin/benefit_fields/_advertise_price.html.erb
|
|
297
323
|
- lib/views/backend/solidus_promotions/admin/benefit_fields/_calculator_fields.erb
|
|
298
324
|
- lib/views/backend/solidus_promotions/admin/benefit_fields/_create_discounted_item.html.erb
|
|
299
325
|
- lib/views/backend/solidus_promotions/admin/benefits/_benefit.html.erb
|
|
@@ -324,6 +350,9 @@ files:
|
|
|
324
350
|
- lib/views/backend/solidus_promotions/admin/condition_fields/_nth_order.html.erb
|
|
325
351
|
- lib/views/backend/solidus_promotions/admin/condition_fields/_one_use_per_user.html.erb
|
|
326
352
|
- lib/views/backend/solidus_promotions/admin/condition_fields/_option_value.html.erb
|
|
353
|
+
- lib/views/backend/solidus_promotions/admin/condition_fields/_price_option_value.html.erb
|
|
354
|
+
- lib/views/backend/solidus_promotions/admin/condition_fields/_price_product.html.erb
|
|
355
|
+
- lib/views/backend/solidus_promotions/admin/condition_fields/_price_taxon.html.erb
|
|
327
356
|
- lib/views/backend/solidus_promotions/admin/condition_fields/_product.html.erb
|
|
328
357
|
- lib/views/backend/solidus_promotions/admin/condition_fields/_shipping_method.html.erb
|
|
329
358
|
- lib/views/backend/solidus_promotions/admin/condition_fields/_store.html.erb
|
|
@@ -370,6 +399,7 @@ licenses:
|
|
|
370
399
|
- BSD-3-Clause
|
|
371
400
|
metadata:
|
|
372
401
|
homepage_uri: https://github.com/solidusio/solidus/blob/main/promotions/README.md
|
|
402
|
+
post_install_message:
|
|
373
403
|
rdoc_options: []
|
|
374
404
|
require_paths:
|
|
375
405
|
- lib
|
|
@@ -377,14 +407,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
377
407
|
requirements:
|
|
378
408
|
- - ">="
|
|
379
409
|
- !ruby/object:Gem::Version
|
|
380
|
-
version: 3.
|
|
410
|
+
version: 3.2.0
|
|
381
411
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
382
412
|
requirements:
|
|
383
413
|
- - ">="
|
|
384
414
|
- !ruby/object:Gem::Version
|
|
385
415
|
version: '0'
|
|
386
416
|
requirements: []
|
|
387
|
-
rubygems_version: 3.
|
|
417
|
+
rubygems_version: 3.5.22
|
|
418
|
+
signing_key:
|
|
388
419
|
specification_version: 4
|
|
389
420
|
summary: New promotion system for Solidus
|
|
390
421
|
test_files: []
|
data/.eslintrc.json
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SolidusPromotions
|
|
4
|
-
class OrderAdjuster
|
|
5
|
-
class PersistDiscountedOrder
|
|
6
|
-
def initialize(order)
|
|
7
|
-
@order = order
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def call
|
|
11
|
-
order.line_items.each do |line_item|
|
|
12
|
-
update_adjustments(line_item, line_item.current_discounts)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
order.shipments.each do |shipment|
|
|
16
|
-
update_adjustments(shipment, shipment.current_discounts)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
order.shipments.flat_map(&:shipping_rates).each do |shipping_rate|
|
|
20
|
-
shipping_rate.discounts = shipping_rate.current_discounts.map do |discount|
|
|
21
|
-
SolidusPromotions::ShippingRateDiscount.create!(
|
|
22
|
-
shipping_rate: shipping_rate,
|
|
23
|
-
amount: discount.amount,
|
|
24
|
-
label: discount.label,
|
|
25
|
-
benefit: discount.source
|
|
26
|
-
)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
order.reset_current_discounts
|
|
30
|
-
order
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
attr_reader :order
|
|
36
|
-
|
|
37
|
-
# Walk through the discounts for an item and update adjustments for it. Once
|
|
38
|
-
# all of the discounts have been added as adjustments, remove any old promotion
|
|
39
|
-
# adjustments that weren't touched.
|
|
40
|
-
#
|
|
41
|
-
# @private
|
|
42
|
-
# @param [#adjustments] item a {Spree::LineItem} or {Spree::Shipment}
|
|
43
|
-
# @param [Array<SolidusPromotions::ItemDiscount>] item_discounts a list of calculated discounts for an item
|
|
44
|
-
# @return [void]
|
|
45
|
-
def update_adjustments(item, item_discounts)
|
|
46
|
-
promotion_adjustments = item.adjustments.select(&:promotion?)
|
|
47
|
-
|
|
48
|
-
active_adjustments = item_discounts.map do |item_discount|
|
|
49
|
-
update_adjustment(item, item_discount)
|
|
50
|
-
end
|
|
51
|
-
item.update(promo_total: active_adjustments.sum(&:amount))
|
|
52
|
-
# Remove any promotion adjustments tied to promotion benefits which no longer match.
|
|
53
|
-
unmatched_adjustments = promotion_adjustments - active_adjustments
|
|
54
|
-
|
|
55
|
-
item.adjustments.destroy(unmatched_adjustments)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Update or create a new promotion adjustment on an item.
|
|
59
|
-
#
|
|
60
|
-
# @private
|
|
61
|
-
# @param [#adjustments] item a {Spree::LineItem} or {Spree::Shipment}
|
|
62
|
-
# @param [SolidusPromotions::ItemDiscount] discount_item calculated discounts for an item
|
|
63
|
-
# @return [Spree::Adjustment] the created or updated promotion adjustment
|
|
64
|
-
def update_adjustment(item, discount_item)
|
|
65
|
-
adjustment = item.adjustments.detect do |item_adjustment|
|
|
66
|
-
item_adjustment.source == discount_item.source
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
adjustment ||= item.adjustments.new(
|
|
70
|
-
source: discount_item.source,
|
|
71
|
-
order_id: item.is_a?(Spree::Order) ? item.id : item.order_id,
|
|
72
|
-
label: discount_item.label
|
|
73
|
-
)
|
|
74
|
-
adjustment.update!(amount: discount_item.amount)
|
|
75
|
-
adjustment
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|