allow select producers for ordering

This commit is contained in:
Guido Oliveira
2021-06-03 11:01:00 -03:00
parent c5471fc25c
commit baca89c575
10 changed files with 107 additions and 25 deletions

View File

@@ -1,12 +1,14 @@
angular.module("admin.enterprises")
.controller "enterpriseCtrl", ($scope, $http, $window, NavigationCheck, enterprise, Enterprises, EnterprisePaymentMethods, EnterpriseShippingMethods, SideMenu, StatusMessage) ->
.controller "enterpriseCtrl", ($scope, $http, $window, NavigationCheck, enterprise, Enterprises, EnterprisePaymentMethods, EnterpriseShippingMethods, SideMenu, StatusMessage, RequestMonitor) ->
$scope.Enterprise = enterprise
$scope.Enterprises = Enterprises
$scope.PaymentMethods = EnterprisePaymentMethods.paymentMethods
$scope.ShippingMethods = EnterpriseShippingMethods.shippingMethods
$scope.navClear = NavigationCheck.clear
$scope.menu = SideMenu
$scope.newManager = { id: null, email: (t('add_manager')) }
$scope.StatusMessage = StatusMessage
$scope.RequestMonitor = RequestMonitor
$scope.$watch 'enterprise_form.$dirty', (newValue) ->
StatusMessage.display 'notice', t('admin.unsaved_changes') if newValue
@@ -90,3 +92,5 @@ angular.module("admin.enterprises")
$scope.translation = (key) ->
t('js.admin.enterprises.form.images.' + key)
RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")

View File

@@ -0,0 +1,30 @@
angular.module("admin.enterprises").directive "ofnProducerAutocomplete", (Enterprises, $sanitize) ->
scope: true
link: (scope,element,attrs) ->
multiple = scope.$eval attrs.multipleSelection
placeholder = attrs.placeholder
initialSelection = scope.$eval attrs.ngModel
suppliers = scope.suppliers
setTimeout ->
element.select2
placeholder: placeholder
multiple: multiple
initSelection: (element, callback) ->
if multiple
callback Enterprises.findByIDs(initialSelection)
else
callback Enterprises.findByID(initialSelection)
query: (query) ->
query.callback { results: Enterprises.findByTerm(suppliers, query.term) }
formatResult: (producer) ->
$sanitize(producer.name)
formatSelection: (producer) ->
producer.name
#Allows drag and drop
if multiple
element.select2("container").find("ul.select2-choices").sortable
containment: 'parent'
start: -> element.select2("onSortStart")
update: -> element.select2("onSortEnd")

View File

@@ -1,4 +1,4 @@
angular.module("admin.resources").factory 'Enterprises', ($q, EnterpriseResource) ->
angular.module("admin.resources").factory 'Enterprises', ($q, $filter, EnterpriseResource) ->
new class Enterprises
byID: {}
pristineByID: {}
@@ -50,6 +50,17 @@ angular.module("admin.resources").factory 'Enterprises', ($q, EnterpriseResource
))
deferred.promise
findByID: (id) ->
@byID[id]
# For finding multiple Enterprises represented by comma delimited string
findByIDs: (ids) ->
@byID[id] for id in ids.split(",") when @byID[id]
findByTerm: (enterprises, term) ->
$filter('filter')(enterprises, term)
removeLogo: performActionOnEnterpriseResource(EnterpriseResource.removeLogo)
removePromoImage: performActionOnEnterpriseResource(EnterpriseResource.removePromoImage)
removeTermsAndConditions: performActionOnEnterpriseResource(EnterpriseResource.removeTermsAndConditions)

View File

@@ -4,7 +4,7 @@ angular.module("admin.taxons").directive "ofnTaxonAutocomplete", (Taxons, $sanit
link: (scope,element,attrs) ->
multiple = scope.$eval attrs.multipleSelection
placeholder = attrs.placeholder
initalSelection = scope.$eval attrs.ngModel
initialSelection = scope.$eval attrs.ngModel
setTimeout ->
element.select2
@@ -12,9 +12,9 @@ angular.module("admin.taxons").directive "ofnTaxonAutocomplete", (Taxons, $sanit
multiple: multiple
initSelection: (element, callback) ->
if multiple
callback Taxons.findByIDs(initalSelection)
callback Taxons.findByIDs(initialSelection)
else
callback Taxons.findByID(initalSelection)
callback Taxons.findByID(initialSelection)
query: (query) ->
query.callback { results: Taxons.findByTerm(query.term) }
formatResult: (taxon) ->

View File

@@ -16,4 +16,8 @@ input[type='button'], input[type='submit'] {
.select2-choice > .select2-chosen {
color: #a1a1a1;
}
.select2-search-choice {
background-color: #c3c3c3 !important;
}
}

View File

@@ -98,6 +98,7 @@ class Enterprise < ApplicationRecord
validates :owner, presence: true
validates :permalink, uniqueness: true, presence: true
validate :shopfront_taxons
validate :shopfront_producers
validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? }
before_validation :initialize_permalink, if: lambda { permalink.nil? }
@@ -461,6 +462,12 @@ class Enterprise < ApplicationRecord
end
end
def shopfront_producers
unless preferred_shopfront_producer_order =~ /\A((\d+,)*\d+)?\z/
errors.add(:shopfront_category_ordering, "must contain a list of producers.")
end
end
def restore_permalink
# If the permalink has errors, reset it to it's original value, so we can update the form
self.permalink = permalink_was if permalink_changed? && errors[:permalink].present?

View File

@@ -60,10 +60,11 @@ class ProductsRenderer
end
def taxon_order
if distributor.preferred_shopfront_product_sorting_method == "by_producer"
# todo: replace with preferred_shopfront_producer_order like for category
# todo: order per producer or category alphabetically if no perferred order is present?
"spree_products.supplier_id, spree_products.id"
if distributor.preferred_shopfront_product_sorting_method == "by_producer" && distributor.preferred_shopfront_producer_order.present?
distributor
.preferred_shopfront_producer_order
.split(",").map { |id| "spree_products.supplier_id=#{id} DESC" }
.join(", ") + ", spree_products.name ASC, spree_products.id ASC"
elsif distributor.preferred_shopfront_product_sorting_method == "by_category" && distributor.preferred_shopfront_taxon_order.present?
distributor
.preferred_shopfront_taxon_order

View File

@@ -30,11 +30,10 @@
.three.columns.alpha
= radio_button :enterprise, :preferred_shopfront_product_sorting_method, :by_producer, { 'ng-model' => 'Enterprise.preferred_shopfront_product_sorting_method' }
= label :enterprise, :preferred_shopfront_product_sorting_method_by_producer, t('.shopfront_sort_by_producer')
-# todo: create directive to support producer selector below
-# .eight.columns.omega
-# %textarea.fullwidth{ id: 'enterprise_preferred_shopfront_producer_order', name: 'enterprise[preferred_shopfront_producer_order]', rows: 6,
-# 'ofn-producer-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Producer',
-# ng: { model: 'Enterprise.preferred_shopfront_producer_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_producer'" }}
.eight.columns.omega
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_producer_order', name: 'enterprise[preferred_shopfront_producer_order]', rows: 6,
'ofn-producer-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Producer',
ng: { model: 'Enterprise.preferred_shopfront_producer_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_producer'" }}
.row
.three.columns.alpha

View File

@@ -188,7 +188,40 @@ describe Enterprise do
end
end
# todo: describe "preferred_shopfront_producer_order"
describe "preferred_shopfront_producer_order" do
it "empty strings are valid" do
enterprise = build(:enterprise, preferred_shopfront_producer_order: "")
expect(enterprise).to be_valid
end
it "a single integer is valid" do
enterprise = build(:enterprise, preferred_shopfront_producer_order: "11")
expect(enterprise).to be_valid
end
it "comma delimited integers are valid" do
enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,2,3")
expect(enterprise).to be_valid
enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,22,333")
expect(enterprise).to be_valid
end
it "commas at the beginning and end are disallowed" do
enterprise = build(:enterprise, preferred_shopfront_producer_order: ",1,2,3")
expect(enterprise).to be_invalid
enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,2,3,")
expect(enterprise).to be_invalid
end
it "any other characters are invalid" do
enterprise = build(:enterprise, preferred_shopfront_producer_order: "a1,2,3")
expect(enterprise).to be_invalid
enterprise = build(:enterprise, preferred_shopfront_producer_order: ".1,2,3")
expect(enterprise).to be_invalid
enterprise = build(:enterprise, preferred_shopfront_producer_order: " 1,2,3")
expect(enterprise).to be_invalid
end
end
end
describe "callbacks" do

View File

@@ -32,20 +32,13 @@ describe ProductsRenderer do
expect(products).to eq([p2, p4, p1, p3])
end
it "sorts products by producer id" do # todo: remove this temporary test
it "sorts products by the distributor's preferred producer list" do
allow(distributor).to receive(:preferred_shopfront_product_sorting_method) { "by_producer" }
puts(distributor.preferred_shopfront_product_sorting_method)
allow(distributor).to receive(:preferred_shopfront_producer_order) { "#{s2.id},#{s1.id}" }
products = products_renderer.send(:products)
expect(products).to eq([p1, p3, p2, p4])
expect(products).to eq([p2, p4, p1, p3])
end
# todo: it "sorts products by the distributor's preferred producer list" do
# allow(distributor).to receive(:preferred_shopfront_product_sorting_method) { "by_producer" }
# allow(distributor).to receive(:preferred_shopfront_producer_order) { "#{s2.id},#{s1.id}" }
# products = products_renderer.send(:products)
# expect(products).to eq([p2, p4, p1, p3])
# end
it "alphabetizes products by name when taxon list is not set" do
allow(distributor).to receive(:preferred_shopfront_taxon_order) { "" }
products = products_renderer.send(:products)