Adding default tag rules

This commit is contained in:
Rob Harrington
2016-05-23 10:19:21 +10:00
parent bf0db2287b
commit fa3b43a970
14 changed files with 151 additions and 85 deletions

View File

@@ -1,10 +1,11 @@
angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, enterprise) ->
$scope.tagGroups = enterprise.tag_groups
$scope.defaultTagGroup = enterprise.default_tag_group
$scope.visibilityOptions = [ { id: "visible", name: "VISIBLE" }, { id: "hidden", name: "NOT VISIBLE" } ]
updateRuleCounts = ->
index = 0
index = $scope.defaultTagGroup.rules.length
for tagGroup in $scope.tagGroups
tagGroup.startIndex = index
index = index + tagGroup.rules.length
@@ -18,6 +19,7 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, ente
$scope.addNewRuleTo = (tagGroup, ruleType) ->
newRule =
id: null
is_default: tagGroup == $scope.defaultTagGroup
preferred_customer_tags: (tag.text for tag in tagGroup.tags).join(",")
type: "TagRule::#{ruleType}"
switch ruleType

View File

@@ -1,6 +1,8 @@
angular.module("admin.tagRules").directive 'newTagRuleDialog', ($compile, $templateCache, $window) ->
restrict: 'A'
scope: true
scope:
tagGroup: '='
addNewRuleTo: '='
link: (scope, element, attr) ->
# Compile modal template
template = $compile($templateCache.get('admin/new_tag_rule_dialog.html'))(scope)

View File

@@ -16,6 +16,11 @@
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][type]",
ng: { value: "rule.type" } }
%input{ type: "hidden",
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_is_default",
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][is_default]",
ng: { value: "rule.is_default" } }
%input{ type: "hidden",
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_customer_tags",
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_customer_tags]",

View File

@@ -65,58 +65,60 @@ tbody.panel-ctrl {
}
&.expanded{
td {
border-bottom: 1px solid #6788a2;
>tr:not(.panel-row) {
>td {
border-bottom: 1px solid #6788a2;
&.selected {
background-color: #ffffff;
border-left: 1px solid #6788a2;
border-right: 1px solid #6788a2;
border-top: 1px solid #6788a2;
border-bottom: none;
&:hover {
&.selected {
background-color: #ffffff;
}
border-left: 1px solid #6788a2;
border-right: 1px solid #6788a2;
border-top: 1px solid #6788a2;
border-bottom: none;
* {
color: #1b3c56;
}
&:hover {
background-color: #ffffff;
}
i.icon-status::before {
opacity: 1.0;
}
* {
color: #1b3c56;
}
i.icon-chevron::before {
content: "\f077";
}
}
}
}
}
tr.panel-row {
&:hover {
td {
background-color: #ffffff;
}
}
>td {
border-color: #6788a2;
padding: 0;
.panel {
.row{
margin: 0px -4px;
padding: 20px 0px;
.column.alpha, .columns.alpha {
padding-left: 20px;
}
.column.omega, .columns.omega {
padding-right: 20px;
i.icon-status::before {
opacity: 1.0;
}
i.icon-chevron::before {
content: "\f077";
}
}
}
}
}
tr.panel-row {
&:hover {
td {
background-color: #ffffff;
}
}
>td {
border-color: #6788a2;
padding: 0;
.panel {
.row{
margin: 0px -4px;
padding: 20px 0px;
.column.alpha, .columns.alpha {
padding-left: 20px;
}
.column.omega, .columns.omega {
padding-right: 20px;
}
}
}
}

View File

@@ -5,7 +5,7 @@
font-weight: bold;
}
.customer_tag {
.customer_tag, .default_rules {
border: 1px solid #cee1f4;
margin-bottom: 40px;

View File

@@ -7,7 +7,7 @@ class TagRule < ActiveRecord::Base
validates :enterprise, presence: true
attr_accessible :enterprise, :enterprise_id, :preferred_customer_tags
attr_accessible :enterprise, :enterprise_id, :is_default, :preferred_customer_tags
scope :for, ->(enterprise) { where(enterprise_id: enterprise) }
scope :of_type, ->(type) { where(type: "TagRule::#{type}") }

View File

@@ -3,19 +3,23 @@ class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
attributes :producer_profile_only, :email, :long_description, :permalink
attributes :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order
attributes :preferred_product_selection_from_inventory_only
attributes :owner, :users, :tag_groups
attributes :owner, :users, :tag_groups, :default_tag_group
has_one :owner, serializer: Api::Admin::UserSerializer
has_many :users, serializer: Api::Admin::UserSerializer
def tag_groups
tag_groups = []
object.tag_rules.each do |tag_rule|
object.tag_rules.reject(&:is_default).each_with_object([]) do |tag_rule, tag_groups|
tag_group = find_match(tag_groups, tag_rule.preferred_customer_tags.split(",").map{ |t| { text: t } })
tag_groups << tag_group if tag_group[:rules].empty?
tag_group[:rules] << Api::Admin::TagRuleSerializer.new(tag_rule).serializable_hash
end
tag_groups
end
def default_tag_group
default_rules = object.tag_rules.select(&:is_default)
serialized_rules = ActiveModel::ArraySerializer.new(default_rules, each_serializer: Api::Admin::TagRuleSerializer)
{ tags: [], rules: serialized_rules }
end
def find_match(tag_groups, tags)

View File

@@ -10,7 +10,7 @@ end
module Api::Admin::TagRule
class BaseSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id, :type, :preferred_customer_tags
attributes :id, :enterprise_id, :type, :is_default, :preferred_customer_tags
end
class DiscountOrderSerializer < BaseSerializer

View File

@@ -3,6 +3,8 @@
.eleven.columns.alpha.omega
.no_tags{ ng: { show: "tagGroups.length == 0" } }
No tags apply to this enterprise yet
= render 'admin/enterprises/form/tag_rules/default_rules'
-# = render 'customer_tags'
.customer_tag{ ng: { repeat: "tagGroup in tagGroups" } }
.header
%table
@@ -22,6 +24,6 @@
No rules apply to this tag yet
.tag_rule{ ng: { repeat: "rule in tagGroup.rules" } }
.add_rule.text-center
%input.button.icon-plus{ type: 'button', value: "+ Add A New Rule", "new-tag-rule-dialog" => true }
%input.button.icon-plus{ type: 'button', value: "+ Add A 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: "+ Add A New Tag", ng: { click: 'addNewTag()' } }

View File

@@ -0,0 +1,14 @@
.default_rules
.header
%table
%colgroup
%col{width: '100%'}
%tr
%td
%h5
By Default:
.no_rules{ ng: { show: "defaultTagGroup.rules.length == 0" } }
No default rules apply yet
.tag_rule{ ng: { repeat: "rule in defaultTagGroup.rules" } }
.add_rule.text-center
%input.button.icon-plus{ type: 'button', value: "+ Add A New Default Rule", "add-new-rule-to" => "addNewRuleTo", "tag-group" => "defaultTagGroup", "new-tag-rule-dialog" => true }

View File

@@ -0,0 +1,5 @@
class AddIsDefaultToTagRule < ActiveRecord::Migration
def change
add_column :tag_rules, :is_default, :boolean, default: false, null: false
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20160401043927) do
ActiveRecord::Schema.define(:version => 20160520065217) do
create_table "account_invoices", :force => true do |t|
t.integer "user_id", :null => false
@@ -1159,10 +1159,11 @@ ActiveRecord::Schema.define(:version => 20160401043927) do
end
create_table "tag_rules", :force => true do |t|
t.integer "enterprise_id", :null => false
t.string "type", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "enterprise_id", :null => false
t.string "type", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "is_default", :default => false, :null => false
end
create_table "taggings", :force => true do |t|

View File

@@ -26,7 +26,7 @@ feature 'Tag Rules', js: true do
click_button '+ Add A New Rule'
select2_select 'Show or Hide shipping methods at checkout', from: 'rule_type_selector'
click_button "Add Rule"
within("#tr_0") do
within(".customer_tag #tr_0") do
find(:css, "tags-input .tags input").set "volunteers-only\n"
select2_select "NOT VISIBLE", from: "enterprise_tag_rules_attributes_0_preferred_matched_shipping_methods_visibility"
end
@@ -35,7 +35,7 @@ feature 'Tag Rules', js: true do
click_button '+ Add A New Rule'
select2_select 'Show or Hide variants in my shop', from: 'rule_type_selector'
click_button "Add Rule"
within("#tr_1") do
within(".customer_tag #tr_1") do
find(:css, "tags-input .tags input").set "volunteers-only1\n"
select2_select "VISIBLE", from: "enterprise_tag_rules_attributes_1_preferred_matched_variants_visibility"
end
@@ -44,20 +44,29 @@ feature 'Tag Rules', js: true do
click_button '+ Add A New Rule'
select2_select 'Show or Hide payment methods at checkout', from: 'rule_type_selector'
click_button "Add Rule"
within("#tr_2") do
within(".customer_tag #tr_2") do
find(:css, "tags-input .tags input").set "volunteers-only2\n"
select2_select "VISIBLE", from: "enterprise_tag_rules_attributes_2_preferred_matched_payment_methods_visibility"
end
# New FilterPaymentMethods Rule
# New FilterOrderCycles Rule
click_button '+ Add A New Rule'
select2_select 'Show or Hide order cycles in my shopfront', from: 'rule_type_selector'
click_button "Add Rule"
within("#tr_3") do
within(".customer_tag #tr_3") do
find(:css, "tags-input .tags input").set "volunteers-only3\n"
select2_select "NOT VISIBLE", from: "enterprise_tag_rules_attributes_3_preferred_matched_order_cycles_visibility"
end
# New DEFAULT FilterOrderCycles Rule
click_button '+ Add A New Default Rule'
select2_select 'Show or Hide order cycles in my shopfront', from: 'rule_type_selector'
click_button "Add Rule"
within(".default_rules #tr_0") do
find(:css, "tags-input .tags input").set "wholesale\n"
select2_select "NOT VISIBLE", from: "enterprise_tag_rules_attributes_0_preferred_matched_order_cycles_visibility"
end
# New DiscountOrder Rule
# click_button '+ Add A New Rule'
# select2_select 'Apply a discount to orders', from: 'rule_type_selector'
@@ -85,18 +94,24 @@ feature 'Tag Rules', js: true do
expect(tag_rule.preferred_payment_method_tags).to eq "volunteers-only2"
expect(tag_rule.preferred_matched_payment_methods_visibility).to eq "visible"
tag_rule = TagRule::FilterOrderCycles.last
tag_rule = TagRule::FilterOrderCycles.all.reject(&:is_default).last
expect(tag_rule.preferred_customer_tags).to eq "volunteer"
expect(tag_rule.preferred_exchange_tags).to eq "volunteers-only3"
expect(tag_rule.preferred_matched_order_cycles_visibility).to eq "hidden"
tag_rule = TagRule::FilterOrderCycles.all.select(&:is_default).last
expect(tag_rule.preferred_customer_tags).to eq ""
expect(tag_rule.preferred_exchange_tags).to eq "wholesale"
expect(tag_rule.preferred_matched_order_cycles_visibility).to eq "hidden"
end
end
context "updating" do
let!(:fsm_tag_rule) { create(:filter_shipping_methods_tag_rule, enterprise: enterprise, preferred_matched_shipping_methods_visibility: "hidden", preferred_customer_tags: "local", preferred_shipping_method_tags: "local" ) }
let!(:default_fsm_tag_rule) { create(:filter_shipping_methods_tag_rule, enterprise: enterprise, preferred_matched_shipping_methods_visibility: "visible", is_default: true, preferred_shipping_method_tags: "local" ) }
let!(:fp_tag_rule) { create(:filter_products_tag_rule, enterprise: enterprise, preferred_matched_variants_visibility: "visible", preferred_customer_tags: "member", preferred_variant_tags: "member" ) }
let!(:fpm_tag_rule) { create(:filter_payment_methods_tag_rule, enterprise: enterprise, preferred_matched_payment_methods_visibility: "hidden", preferred_customer_tags: "trusted", preferred_payment_method_tags: "trusted" ) }
let!(:foc_tag_rule) { create(:filter_order_cycles_tag_rule, enterprise: enterprise, preferred_matched_order_cycles_visibility: "visible", preferred_customer_tags: "wholesale", preferred_exchange_tags: "wholesale" ) }
let!(:fsm_tag_rule) { create(:filter_shipping_methods_tag_rule, enterprise: enterprise, preferred_matched_shipping_methods_visibility: "hidden", preferred_customer_tags: "local", preferred_shipping_method_tags: "local" ) }
# let!(:do_tag_rule) { create(:tag_rule, enterprise: enterprise, preferred_customer_tags: "member" ) }
before do
@@ -115,16 +130,16 @@ feature 'Tag Rules', js: true do
expect(page).to have_selector '.customer_tag .header tags-input .tag-list ti-tag-item', text: "trusted", count: 1
all(:css, ".customer_tag .header tags-input .tags input").each { |node| node.set "volunteer\n" }
# FilterShippingMethods rule
within "#tr_0" do
# DEFAULT FilterShippingMethods rule
within ".default_rules #tr_0" do
expect(first('tags-input .tag-list ti-tag-item')).to have_content "local"
find(:css, "tags-input .tags input").set "volunteers-only\n"
expect(page).to have_select2 "enterprise_tag_rules_attributes_0_preferred_matched_shipping_methods_visibility", selected: 'NOT VISIBLE'
select2_select 'VISIBLE', from: "enterprise_tag_rules_attributes_0_preferred_matched_shipping_methods_visibility"
expect(page).to have_select2 "enterprise_tag_rules_attributes_0_preferred_matched_shipping_methods_visibility", selected: 'VISIBLE'
select2_select 'NOT VISIBLE', from: "enterprise_tag_rules_attributes_0_preferred_matched_shipping_methods_visibility"
end
# FilterProducts rule
within "#tr_1" do
within ".customer_tag #tr_1" do
expect(first('tags-input .tag-list ti-tag-item')).to have_content "member"
find(:css, "tags-input .tags input").set "volunteers-only1\n"
expect(page).to have_select2 "enterprise_tag_rules_attributes_1_preferred_matched_variants_visibility", selected: 'VISIBLE'
@@ -132,7 +147,7 @@ feature 'Tag Rules', js: true do
end
# FilterPaymentMethods rule
within "#tr_2" do
within ".customer_tag #tr_2" do
expect(first('tags-input .tag-list ti-tag-item')).to have_content "trusted"
find(:css, "tags-input .tags input").set "volunteers-only2\n"
expect(page).to have_select2 "enterprise_tag_rules_attributes_2_preferred_matched_payment_methods_visibility", selected: 'NOT VISIBLE'
@@ -140,13 +155,21 @@ feature 'Tag Rules', js: true do
end
# FilterOrderCycles rule
within "#tr_3" do
within ".customer_tag #tr_3" do
expect(first('tags-input .tag-list ti-tag-item')).to have_content "wholesale"
find(:css, "tags-input .tags input").set "volunteers-only3\n"
expect(page).to have_select2 "enterprise_tag_rules_attributes_3_preferred_matched_order_cycles_visibility", selected: 'VISIBLE'
select2_select 'NOT VISIBLE', from: "enterprise_tag_rules_attributes_3_preferred_matched_order_cycles_visibility"
end
# FilterShippingMethods rule
within ".customer_tag #tr_4" do
expect(first('tags-input .tag-list ti-tag-item')).to have_content "local"
find(:css, "tags-input .tags input").set "volunteers-only4\n"
expect(page).to have_select2 "enterprise_tag_rules_attributes_4_preferred_matched_shipping_methods_visibility", selected: 'NOT VISIBLE'
select2_select 'VISIBLE', from: "enterprise_tag_rules_attributes_4_preferred_matched_shipping_methods_visibility"
end
# # DiscountOrder rule
# within "#tr_2" do
# expect(page).to have_field "enterprise_tag_rules_attributes_2_calculator_attributes_preferred_flat_percent", with: '0'
@@ -155,9 +178,14 @@ feature 'Tag Rules', js: true do
click_button 'Update'
# FilterShippingMethods rule
expect(default_fsm_tag_rule.preferred_customer_tags).to eq ""
expect(default_fsm_tag_rule.preferred_shipping_method_tags).to eq "local,volunteers-only"
expect(default_fsm_tag_rule.preferred_matched_shipping_methods_visibility).to eq "hidden"
# FilterShippingMethods rule
expect(fsm_tag_rule.preferred_customer_tags).to eq "local,volunteer"
expect(fsm_tag_rule.preferred_shipping_method_tags).to eq "local,volunteers-only"
expect(fsm_tag_rule.preferred_shipping_method_tags).to eq "local,volunteers-only4"
expect(fsm_tag_rule.preferred_matched_shipping_methods_visibility).to eq "visible"
# FilterProducts rule

View File

@@ -7,6 +7,7 @@ describe "TagRulesCtrl", ->
module('admin.tagRules')
enterprise =
id: 45
default_tag_group: { tags: "", rules: [{ id: 7, preferred_customer_tags: "trusted" }] }
tag_groups: [
{ tags: "member", rules: [{ id: 1, preferred_customer_tags: "member" }, { id: 2, preferred_customer_tags: "member" }] },
{ tags: "volunteer", rules: [{ id: 3, preferred_customer_tags: "local" }] }
@@ -18,8 +19,8 @@ describe "TagRulesCtrl", ->
describe "tagGroup start indices", ->
it "updates on initialization", ->
expect(scope.tagGroups[0].startIndex).toEqual 0
expect(scope.tagGroups[1].startIndex).toEqual 2
expect(scope.tagGroups[0].startIndex).toEqual 1
expect(scope.tagGroups[1].startIndex).toEqual 3
describe "adding a new tag group", ->
beforeEach ->
@@ -30,8 +31,8 @@ describe "TagRulesCtrl", ->
expect(scope.tagGroups[0].rules[2].type).toEqual "TagRule::DiscountOrder"
it "updates tagGroup start indices", ->
expect(scope.tagGroups[0].startIndex).toEqual 0
expect(scope.tagGroups[1].startIndex).toEqual 3
expect(scope.tagGroups[0].startIndex).toEqual 1
expect(scope.tagGroups[1].startIndex).toEqual 4
describe "deleting a tag group", ->
describe "where the rule is not in the rule list for the tagGroup", ->
@@ -58,8 +59,8 @@ describe "TagRulesCtrl", ->
expect(scope.tagGroups[0].rules.indexOf(rule)).toEqual -1
it "updates tagGroup start indices", ->
expect(scope.tagGroups[0].startIndex).toEqual 0
expect(scope.tagGroups[1].startIndex).toEqual 1
expect(scope.tagGroups[0].startIndex).toEqual 1
expect(scope.tagGroups[1].startIndex).toEqual 2
describe "without an id", ->
rule = null
@@ -75,5 +76,5 @@ describe "TagRulesCtrl", ->
expect(scope.tagGroups[0].rules.indexOf(rule)).toEqual -1
it "updates tagGroup start indices", ->
expect(scope.tagGroups[0].startIndex).toEqual 0
expect(scope.tagGroups[1].startIndex).toEqual 1
expect(scope.tagGroups[0].startIndex).toEqual 1
expect(scope.tagGroups[1].startIndex).toEqual 2