From 11006c3a6046ff804504a2abf92bd9c884c3bc99 Mon Sep 17 00:00:00 2001 From: Gaetan Craig-Riou Date: Wed, 16 Jul 2025 14:20:35 +1000 Subject: [PATCH] Display default rule --- app/helpers/admin/enterprises_helper.rb | 34 ++++++++++++- app/models/tag_rule.rb | 5 ++ app/models/tag_rule/filter_order_cycles.rb | 4 ++ app/models/tag_rule/filter_payment_methods.rb | 4 ++ app/models/tag_rule/filter_products.rb | 4 ++ .../tag_rule/filter_shipping_methods.rb | 4 ++ .../enterprises/form/_tag_rules.html.haml | 35 +++----------- .../form/tag_rules/_default_rules.html.haml | 48 ++++++++++++++++--- .../_filter_order_cycles_input.html.haml | 9 ++++ .../_filter_payment_methods_input.html.haml | 10 ++++ .../_filter_products_input.html.haml | 9 ++++ .../_filter_shipping_methods_input.html.haml | 9 ++++ .../tag_rule/filter_order_cycles_spec.rb | 8 ++++ .../tag_rule/filter_payment_methods_spec.rb | 8 ++++ spec/models/tag_rule/filter_products_spec.rb | 10 +++- .../tag_rule/filter_shipping_methods_spec.rb | 8 ++++ spec/models/tag_rule_spec.rb | 11 +++++ 17 files changed, 184 insertions(+), 36 deletions(-) create mode 100644 app/views/admin/tag_rules/_filter_order_cycles_input.html.haml create mode 100644 app/views/admin/tag_rules/_filter_payment_methods_input.html.haml create mode 100644 app/views/admin/tag_rules/_filter_products_input.html.haml create mode 100644 app/views/admin/tag_rules/_filter_shipping_methods_input.html.haml diff --git a/app/helpers/admin/enterprises_helper.rb b/app/helpers/admin/enterprises_helper.rb index a82d96dd4a..c6f3c043f1 100644 --- a/app/helpers/admin/enterprises_helper.rb +++ b/app/helpers/admin/enterprises_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Admin - module EnterprisesHelper + module EnterprisesHelper # rubocop:disable Metrics/ModuleLength def add_check_if_single(count) if count == 1 { checked: true } @@ -76,6 +76,38 @@ module Admin Enterprise::SELLS.map { |s| [I18n.t(s, scope:), s] } end + def rule_data(rule) # rubocop:disable Metrics/MethodLength + case rule.type + when "TagRule::FilterShippingMethods" + { + text_top: t('js.admin.tag_rules.shipping_method_tagged_top'), + text_bottom: t('js.admin.tag_rules.shipping_method_tagged_bottom'), + taggable: "shipping_method", + input_template: "admin/tag_rules/filter_shipping_methods_input", + } + when "TagRule::FilterPaymentMethods" + { + text_top: t('js.admin.tag_rules.payment_method_tagged_top'), + text_bottom: t('js.admin.tag_rules.payment_method_tagged_bottom'), + taggable: "payment_method", + input_template: "admin/tag_rules/filter_payment_methods_input", + } + when "TagRule::FilterOrderCycles" + { + text_top: t('js.admin.tag_rules.order_cycle_tagged_top'), + text_bottom: t('js.admin.tag_rules.order_cycle_tagged_bottom'), + taggable: "exchange", + input_template: "admin/tag_rules/filter_order_cycles_input", + } + when "TagRule::FilterProducts" + { + text_top: t('js.admin.tag_rules.inventory_tagged_top'), + text_bottom: t('js.admin.tag_rules.inventory_tagged_bottom'), + taggable: "variant", + input_template: "admin/tag_rules/filter_products_input", + } + end + private def build_enterprise_side_menu_items(is_shop:, show_options: ) # rubocop:disable Metrics/MethodLength diff --git a/app/models/tag_rule.rb b/app/models/tag_rule.rb index a6b5ae4bb6..790e844334 100644 --- a/app/models/tag_rule.rb +++ b/app/models/tag_rule.rb @@ -19,4 +19,9 @@ class TagRule < ApplicationRecord end end end + + # The following method must be overriden in a concrete tagRule + def tags + raise NotImplementedError, 'please use concrete TagRule' + end end diff --git a/app/models/tag_rule/filter_order_cycles.rb b/app/models/tag_rule/filter_order_cycles.rb index 35fd5d9c58..7d0b1e4242 100644 --- a/app/models/tag_rule/filter_order_cycles.rb +++ b/app/models/tag_rule/filter_order_cycles.rb @@ -14,6 +14,10 @@ class TagRule::FilterOrderCycles < TagRule preferred_matched_order_cycles_visibility != "visible" end + def tags + preferred_exchange_tags + end + private def exchange_for(order_cycle) diff --git a/app/models/tag_rule/filter_payment_methods.rb b/app/models/tag_rule/filter_payment_methods.rb index bdf35fbff8..125517d9c7 100644 --- a/app/models/tag_rule/filter_payment_methods.rb +++ b/app/models/tag_rule/filter_payment_methods.rb @@ -13,4 +13,8 @@ class TagRule::FilterPaymentMethods < TagRule def reject_matched? preferred_matched_payment_methods_visibility != "visible" end + + def tags + preferred_payment_method_tags + end end diff --git a/app/models/tag_rule/filter_products.rb b/app/models/tag_rule/filter_products.rb index 86095f1c17..d9185b3719 100644 --- a/app/models/tag_rule/filter_products.rb +++ b/app/models/tag_rule/filter_products.rb @@ -18,5 +18,9 @@ class TagRule def reject_matched? preferred_matched_variants_visibility != "visible" end + + def tags + preferred_variant_tags + end end end diff --git a/app/models/tag_rule/filter_shipping_methods.rb b/app/models/tag_rule/filter_shipping_methods.rb index ddd28ec46f..cad423be7c 100644 --- a/app/models/tag_rule/filter_shipping_methods.rb +++ b/app/models/tag_rule/filter_shipping_methods.rb @@ -13,4 +13,8 @@ class TagRule::FilterShippingMethods < TagRule preferred_tags = preferred_shipping_method_tags.split(",") shipping_method_tags.intersect?(preferred_tags) end + + def tags + preferred_shipping_method_tags + end end diff --git a/app/views/admin/enterprises/form/_tag_rules.html.haml b/app/views/admin/enterprises/form/_tag_rules.html.haml index 7e73f424e8..88986a854d 100644 --- a/app/views/admin/enterprises/form/_tag_rules.html.haml +++ b/app/views/admin/enterprises/form/_tag_rules.html.haml @@ -1,29 +1,8 @@ -= render partial: "admin/json/injection_ams", locals: { ngModule: "admin.tagRules", name: "ruleTypes", json: @tag_rule_types.to_json } - -.row{ "ng-app" => "admin.tagRules", "ng-controller": "TagRulesCtrl" } +.row .eleven.columns.alpha.omega - %ofn-sortable{ axis: "y", handle: ".header", items: '.customer_tag', position: "tagGroup.position", "after-sort": "updateRuleCounts()" } - .no_tags{ "ng-show": "tagGroups.length == 0" } - = t('.no_tags_yet') - = render 'admin/enterprises/form/tag_rules/default_rules' - -# = render 'customer_tags' - .customer_tag{ id: "tg_{{tagGroup.position}}", "ng-repeat": "tagGroup in tagGroups" } - .header - %table - %colgroup - %col{width: '35%'} - %col{width: '65%'} - %tr - %td - %h5 - = t('.for_customers_tagged') - %td - %tags-with-translation{ object: "tagGroup", max: 1, "on-tag-added": "updateTagsRulesFor(tagGroup)", "on-tag-removed": "updateTagsRulesFor(tagGroup)" } - - .no_rules{ "ng-show": "tagGroup.rules.length == 0" } - = t('.no_rules_yet') - .tag_rule{ "ng-repeat": "rule in tagGroup.rules" } - .add_rule.text-center - %input.button.icon-plus{ type: 'button', value: t('.add_new_rule'), "add-new-rule-to" => "addNewRuleTo", "tag-group" => "tagGroup", "new-tag-rule-dialog" => true } - .add_tag - %input.button.red.icon-plus{ type: 'button', value: t('.add_new_tag'), "ng-click": 'addNewTag()' } + %div + - rules = @enterprise.tag_rules.prioritised.reject(&:is_default) + - if rules.empty? + .no_tags + = t('.no_tags_yet') + = render 'admin/enterprises/form/tag_rules/default_rules', f: f diff --git a/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml b/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml index 9bdb7570c6..622339c529 100644 --- a/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml +++ b/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml @@ -1,4 +1,4 @@ -.default_rules +.default_rules{ "data-turbo": true } .header %table %colgroup @@ -8,11 +8,47 @@ %h5 = t('.by_default') %i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "tag_rule_help_modal" } - .no_rules{ "ng-show": "defaultTagGroup.rules.length == 0" } - = t('.no_rules_yet') - .tag_rule{ "ng-repeat": "rule in defaultTagGroup.rules" } - .add_rule.text-center - %input.button.icon-plus{ type: 'button', value: t('.add_new_button'), "add-new-rule-to" => "addNewRuleTo", "tag-group" => "defaultTagGroup", "new-tag-rule-dialog" => true } + - default_rules = @enterprise.tag_rules.select(&:is_default) + - if default_rules.empty? + .no_rules + = t('.no_rules_yet') + .add_rule.text-center + %input.button.icon-plus{ type: 'button', value: t('.add_new_button') } + - else + - default_rules.each_with_index do |default_rule, index| + #default-tag-rule + %div{ id: "tr_#{index}" } + %table + %colgroup + %col.text{ width: "35%" } + %col.inputs{ width: "55%" } + %col.actions{ width: "10%" } + %tr + %td + %input{ type: "hidden", id: "enterprise_tag_rules_attributes_#{index}_id", name: "enterprise[tag_rules_attributes][#{index}][id]", value: default_rule.id } + %input{ type: "hidden", id: "enterprise_tag_rules_attributes_#{index}_type", name: "enterprise[tag_rules_attributes][#{index}][type]", value: default_rule.type } + %input{ type: "hidden", id: "enterprise_tag_rules_attributes_#{index}_priority", name: "enterprise[tag_rules_attributes][#{index}][priority]", value: index } + %input{ type: "hidden", id: "enterprise_tag_rules_attributes_#{index}_is_default", name: "enterprise[tag_rules_attributes][#{index}][is_default]", value: default_rule.is_default } + %input{ type: "hidden", id: "enterprise_tag_rules_attributes_#{index}_preferred_customer_tags", name: "enterprise[tag_rules_attributes][#{index}][preferred_customer_tags]", value: default_rule.preferred_customer_tags } + + %span.text-normal + = rule_data(default_rule)[:text_top] + %td + = # TODO limit to one tag + = render TagListInputComponent.new(form: f, method: "tag_rules_attributes][#{index}][preferred_#{rule_data(default_rule)[:taggable]}_tags", tags: default_rule.tags.split(",")) + %td.actions{ rowspan: 2 } + %a{ class: "delete-tag-rule icon-trash no-text" } + %tr + %td + %span.text-normal + = rule_data(default_rule)[:text_bottom] + %td + %div + = render partial: rule_data(default_rule)[:input_template], locals: { rule: default_rule, index: index } + %hr + + .add_rule.text-center + %input.button.icon-plus{ type: 'button', value: t('.add_new_button') } = render HelpModalComponent.new(id: "tag_rule_help_modal") do #tag-rule-help diff --git a/app/views/admin/tag_rules/_filter_order_cycles_input.html.haml b/app/views/admin/tag_rules/_filter_order_cycles_input.html.haml new file mode 100644 index 0000000000..ec04f837a8 --- /dev/null +++ b/app/views/admin/tag_rules/_filter_order_cycles_input.html.haml @@ -0,0 +1,9 @@ +%div + - if rule.is_default + = hidden_field_tag "enterprise[tag_rules_attributes][#{index}][preferred_matched_order_cycles_visibility]", "hidden" + %span.text-normal + =t(:not_visible) + - else + - #TODO + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_#{index}_preferred_matched_order_cycles_visibility", name: "enterprise[tag_rules_attributes][#{index}][preferred_matched_order_cycles_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_order_cycles_visibility", "ng-if": "!rule.is_default" } + diff --git a/app/views/admin/tag_rules/_filter_payment_methods_input.html.haml b/app/views/admin/tag_rules/_filter_payment_methods_input.html.haml new file mode 100644 index 0000000000..564fd722c2 --- /dev/null +++ b/app/views/admin/tag_rules/_filter_payment_methods_input.html.haml @@ -0,0 +1,10 @@ +%div + + - if rule.is_default + = hidden_field_tag "enterprise[tag_rules_attributes][#{index}][preferred_matched_payment_methods_visibility]", "hidden" + %span.text-normal + = t(:not_visible) + - else + - #TODO + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_#{index}_preferred_matched_payment_methods_visibility", name: "enterprise[tag_rules_attributes][#{index}][preferred_matched_payment_methods_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_payment_methods_visibility", "ng-if": "!rule.is_default" } + diff --git a/app/views/admin/tag_rules/_filter_products_input.html.haml b/app/views/admin/tag_rules/_filter_products_input.html.haml new file mode 100644 index 0000000000..ff6c4c9f10 --- /dev/null +++ b/app/views/admin/tag_rules/_filter_products_input.html.haml @@ -0,0 +1,9 @@ +%div + - if rule.is_default + = hidden_field_tag "enterprise[tag_rules_attributes][#{index}][preferred_matched_variants_visibility]", "hidden" + %span.text-normal + = t(:not_visible) + - else + - #TODO + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_#{index}_preferred_matched_variants_visibility", name: "enterprise[tag_rules_attributes][#{index}][preferred_matched_variants_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_variants_visibility", "ng-if": "!rule.is_default" } + diff --git a/app/views/admin/tag_rules/_filter_shipping_methods_input.html.haml b/app/views/admin/tag_rules/_filter_shipping_methods_input.html.haml new file mode 100644 index 0000000000..ad71207ee6 --- /dev/null +++ b/app/views/admin/tag_rules/_filter_shipping_methods_input.html.haml @@ -0,0 +1,9 @@ +%div + - if rule.is_default + = hidden_field_tag "enterprise[tag_rules_attributes][#{index}][preferred_matched_shipping_methods_visibility]", "hidden" + %span.text-normal + = t(:not_visible) + - else + - #TODO + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_#{index}_preferred_matched_shipping_methods_visibility", name: "enterprise[tag_rules_attributes][#{index}][preferred_matched_shipping_methods_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_shipping_methods_visibility", "ng-if": "!rule.is_default" } + diff --git a/spec/models/tag_rule/filter_order_cycles_spec.rb b/spec/models/tag_rule/filter_order_cycles_spec.rb index ed9529ab8b..7616453cdd 100644 --- a/spec/models/tag_rule/filter_order_cycles_spec.rb +++ b/spec/models/tag_rule/filter_order_cycles_spec.rb @@ -5,6 +5,14 @@ require 'spec_helper' RSpec.describe TagRule::FilterOrderCycles do let!(:tag_rule) { build_stubbed(:filter_order_cycles_tag_rule) } + describe "#tags" do + it "return the exchange tags" do + tag_rule = create(:filter_order_cycles_tag_rule, preferred_exchange_tags: "my_tag") + + expect(tag_rule.tags).to eq("my_tag") + end + end + describe "determining whether tags match for a given exchange" do context "when the exchange is nil" do before do diff --git a/spec/models/tag_rule/filter_payment_methods_spec.rb b/spec/models/tag_rule/filter_payment_methods_spec.rb index 633a65a3f2..a846c5d618 100644 --- a/spec/models/tag_rule/filter_payment_methods_spec.rb +++ b/spec/models/tag_rule/filter_payment_methods_spec.rb @@ -5,6 +5,14 @@ require 'spec_helper' RSpec.describe TagRule::FilterPaymentMethods do let!(:tag_rule) { build_stubbed(:filter_payment_methods_tag_rule) } + describe "#tags" do + it "return the payment method tags" do + tag_rule = create(:filter_payment_methods_tag_rule, preferred_payment_method_tags: "my_tag") + + expect(tag_rule.tags).to eq("my_tag") + end + end + describe "determining whether tags match for a given payment method" do context "when the payment method is nil" do it "returns false" do diff --git a/spec/models/tag_rule/filter_products_spec.rb b/spec/models/tag_rule/filter_products_spec.rb index 61aace0e28..41bfbaeba9 100644 --- a/spec/models/tag_rule/filter_products_spec.rb +++ b/spec/models/tag_rule/filter_products_spec.rb @@ -3,7 +3,15 @@ require 'spec_helper' RSpec.describe TagRule::FilterProducts do - let!(:tag_rule) { build_stubbed(:filter_products_tag_rule) } + let!(:tag_rule) { build_stubbed(:filter_products_tag_rule, preferred_variant_tags: "my_tag") } + + describe "#tags" do + it "return the variants tags" do + tag_rule = create(:filter_products_tag_rule, preferred_variant_tags: "my_tag") + + expect(tag_rule.tags).to eq("my_tag") + end + end describe "determining whether tags match for a given variant" do context "when the variant is nil" do diff --git a/spec/models/tag_rule/filter_shipping_methods_spec.rb b/spec/models/tag_rule/filter_shipping_methods_spec.rb index 8e53c51eb0..0222507fcd 100644 --- a/spec/models/tag_rule/filter_shipping_methods_spec.rb +++ b/spec/models/tag_rule/filter_shipping_methods_spec.rb @@ -5,6 +5,14 @@ require 'spec_helper' RSpec.describe TagRule::FilterShippingMethods do let!(:tag_rule) { build_stubbed(:filter_shipping_methods_tag_rule) } + describe "#tags" do + it "return the shipping method tags" do + tag_rule = create(:filter_shipping_methods_tag_rule, preferred_shipping_method_tags: "my_tag") + + expect(tag_rule.tags).to eq("my_tag") + end + end + describe "determining whether tags match for a given shipping method" do context "when the shipping method is nil" do it "returns false" do diff --git a/spec/models/tag_rule_spec.rb b/spec/models/tag_rule_spec.rb index b3dac6ac20..02a7183081 100644 --- a/spec/models/tag_rule_spec.rb +++ b/spec/models/tag_rule_spec.rb @@ -2,10 +2,21 @@ require 'spec_helper' +# This is used to test non implemented methods +class TestTagRule < TagRule; end + RSpec.describe TagRule do describe "validations" do it "requires a enterprise" do expect(subject).to belong_to(:enterprise) end end + + describe '#tags' do + subject(:rule) { TestTagRule.new } + + it "raises not implemented error" do + expect{ rule.tags }.to raise_error(NotImplementedError, 'please use concrete TagRule') + end + end end