diff --git a/app/assets/javascripts/admin/admin.js.coffee b/app/assets/javascripts/admin/admin.js.coffee index 76154e9e20..edebc019e5 100644 --- a/app/assets/javascripts/admin/admin.js.coffee +++ b/app/assets/javascripts/admin/admin.js.coffee @@ -1,3 +1,3 @@ -window.Admin = angular.module("ofn.admin", ["ngResource", "ngAnimate", "ofn.dropdown"]).config ($httpProvider) -> +angular.module("ofn.admin", ["ngResource", "ngAnimate", "ofn.dropdown"]).config ($httpProvider) -> $httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content") $httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*" \ No newline at end of file diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 99c936c4d7..3fdd45585a 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -16,5 +16,6 @@ //= require admin/spree_auth //= require admin/spree_promo //= require ./admin +//= require ./products/products //= require_tree . diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 7a1edcbca6..9ba34790a8 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -1,4 +1,4 @@ -Admin.controller "AdminOrderMgmtCtrl", [ +angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [ "$scope", "$http", "dataFetcher", "blankOption", "pendingChanges" ($scope, $http, dataFetcher, blankOption, pendingChanges) -> diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index 4df57d6689..8d50a3dc1f 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -1,4 +1,4 @@ -Admin.controller "AdminProductEditCtrl", [ +angular.module("ofn.admin").controller "AdminProductEditCtrl", [ "$scope", "$timeout", "$http", "dataFetcher", "DirtyProducts" ($scope, $timeout, $http, dataFetcher, DirtyProducts) -> $scope.updateStatusMessage = diff --git a/app/assets/javascripts/admin/controllers/enterprises_dashboard_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprises_dashboard_controller.js.coffee new file mode 100644 index 0000000000..ad72ff3529 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/enterprises_dashboard_controller.js.coffee @@ -0,0 +1,5 @@ +angular.module("ofn.admin").controller "enterprisesDashboardCtrl", [ + "$scope" + ($scope) -> + $scope.activeTab = "hubs" +] \ No newline at end of file diff --git a/app/assets/javascripts/admin/directives/confirm_link_path.js.coffee b/app/assets/javascripts/admin/directives/confirm_link_path.js.coffee index e0e0511f0c..2c8dba4baf 100644 --- a/app/assets/javascripts/admin/directives/confirm_link_path.js.coffee +++ b/app/assets/javascripts/admin/directives/confirm_link_path.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnConfirmLinkPath", (ofnConfirmHandler) -> +angular.module("ofn.admin").directive "ofnConfirmLinkPath", (ofnConfirmHandler) -> restrict: "A" scope: path: "@ofnConfirmLinkPath" diff --git a/app/assets/javascripts/admin/directives/confirm_model_change.js.coffee b/app/assets/javascripts/admin/directives/confirm_model_change.js.coffee index aba2cd919e..a0b5272981 100644 --- a/app/assets/javascripts/admin/directives/confirm_model_change.js.coffee +++ b/app/assets/javascripts/admin/directives/confirm_model_change.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnConfirmModelChange", (ofnConfirmHandler,$timeout) -> +angular.module("ofn.admin").directive "ofnConfirmModelChange", (ofnConfirmHandler,$timeout) -> restrict: "A" link: (scope, element, attrs) -> handler = ofnConfirmHandler scope, -> scope.fetchOrders() diff --git a/app/assets/javascripts/admin/directives/date_picker.js.coffee b/app/assets/javascripts/admin/directives/date_picker.js.coffee index 3a07bfd3f5..6b5cac3e1b 100644 --- a/app/assets/javascripts/admin/directives/date_picker.js.coffee +++ b/app/assets/javascripts/admin/directives/date_picker.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "datepicker", -> +angular.module("ofn.admin").directive "datepicker", -> require: "ngModel" link: (scope, element, attrs, ngModel) -> element.datepicker diff --git a/app/assets/javascripts/admin/directives/datetime_picker.js.coffee b/app/assets/javascripts/admin/directives/datetime_picker.js.coffee index 232d958b99..b0d91e538a 100644 --- a/app/assets/javascripts/admin/directives/datetime_picker.js.coffee +++ b/app/assets/javascripts/admin/directives/datetime_picker.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "datetimepicker", -> +angular.module("ofn.admin").directive "datetimepicker", -> require: "ngModel" link: (scope, element, attrs, ngModel) -> element.datetimepicker diff --git a/app/assets/javascripts/admin/directives/decimal.js.coffee b/app/assets/javascripts/admin/directives/decimal.js.coffee index 8077f90c06..f4bed8e371 100644 --- a/app/assets/javascripts/admin/directives/decimal.js.coffee +++ b/app/assets/javascripts/admin/directives/decimal.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnDecimal", -> +angular.module("ofn.admin").directive "ofnDecimal", -> require: "ngModel" link: (scope, element, attrs, ngModel) -> numRegExp = /^\d+(\.\d+)?$/ diff --git a/app/assets/javascripts/admin/directives/line_item_upd_attr.js.coffee b/app/assets/javascripts/admin/directives/line_item_upd_attr.js.coffee index a71aa42997..c83d7fdc0f 100644 --- a/app/assets/javascripts/admin/directives/line_item_upd_attr.js.coffee +++ b/app/assets/javascripts/admin/directives/line_item_upd_attr.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnLineItemUpdAttr", [ +angular.module("ofn.admin").directive "ofnLineItemUpdAttr", [ "switchClass", "pendingChanges" (switchClass, pendingChanges) -> require: "ngModel" diff --git a/app/assets/javascripts/admin/directives/select2_min_search.js.coffee b/app/assets/javascripts/admin/directives/select2_min_search.js.coffee index c33beb710e..1d55d886aa 100644 --- a/app/assets/javascripts/admin/directives/select2_min_search.js.coffee +++ b/app/assets/javascripts/admin/directives/select2_min_search.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnSelect2MinSearch", -> +angular.module("ofn.admin").directive "ofnSelect2MinSearch", -> require: 'ngModel' link: (scope, element, attrs, ngModel) -> element.select2 diff --git a/app/assets/javascripts/admin/directives/taxon_autocomplete.js.coffee b/app/assets/javascripts/admin/directives/taxon_autocomplete.js.coffee index 0705d04a23..e5713274ef 100644 --- a/app/assets/javascripts/admin/directives/taxon_autocomplete.js.coffee +++ b/app/assets/javascripts/admin/directives/taxon_autocomplete.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnTaxonAutocomplete", (Taxons) -> +angular.module("ofn.admin").directive "ofnTaxonAutocomplete", (Taxons) -> # Adapted from Spree's existing taxon autocompletion require: "ngModel" link: (scope,element,attrs,ngModel) -> diff --git a/app/assets/javascripts/admin/directives/toggle_column.js.coffee b/app/assets/javascripts/admin/directives/toggle_column.js.coffee index 2337a0fb58..1b8487eeb1 100644 --- a/app/assets/javascripts/admin/directives/toggle_column.js.coffee +++ b/app/assets/javascripts/admin/directives/toggle_column.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnToggleColumn", -> +angular.module("ofn.admin").directive "ofnToggleColumn", -> link: (scope, element, attrs) -> element.addClass "selected" if scope.column.visible element.click "click", -> diff --git a/app/assets/javascripts/admin/directives/toggle_variants.js.coffee b/app/assets/javascripts/admin/directives/toggle_variants.js.coffee index 8c07490359..879942d698 100644 --- a/app/assets/javascripts/admin/directives/toggle_variants.js.coffee +++ b/app/assets/javascripts/admin/directives/toggle_variants.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnToggleVariants", -> +angular.module("ofn.admin").directive "ofnToggleVariants", -> link: (scope, element, attrs) -> if scope.displayProperties[scope.product.id].showVariants element.removeClass "icon-chevron-right" diff --git a/app/assets/javascripts/admin/directives/track_product.js.coffee b/app/assets/javascripts/admin/directives/track_product.js.coffee index 3667794712..a4ea3865c0 100644 --- a/app/assets/javascripts/admin/directives/track_product.js.coffee +++ b/app/assets/javascripts/admin/directives/track_product.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnTrackProduct", ["DirtyProducts", (DirtyProducts) -> +angular.module("ofn.admin").directive "ofnTrackProduct", ["DirtyProducts", (DirtyProducts) -> require: "ngModel" link: (scope, element, attrs, ngModel) -> ngModel.$parsers.push (viewValue) -> diff --git a/app/assets/javascripts/admin/directives/track_variant.js.coffee b/app/assets/javascripts/admin/directives/track_variant.js.coffee index 189d5043fe..ab17ebcfa5 100644 --- a/app/assets/javascripts/admin/directives/track_variant.js.coffee +++ b/app/assets/javascripts/admin/directives/track_variant.js.coffee @@ -1,4 +1,4 @@ -Admin.directive "ofnTrackVariant", ["DirtyProducts", (DirtyProducts) -> +angular.module("ofn.admin").directive "ofnTrackVariant", ["DirtyProducts", (DirtyProducts) -> require: "ngModel" link: (scope, element, attrs, ngModel) -> ngModel.$parsers.push (viewValue) -> diff --git a/app/assets/javascripts/admin/filters/range_array.js.coffee b/app/assets/javascripts/admin/filters/range_array.js.coffee index 5056476f1b..be4a020442 100644 --- a/app/assets/javascripts/admin/filters/range_array.js.coffee +++ b/app/assets/javascripts/admin/filters/range_array.js.coffee @@ -1,4 +1,4 @@ -Admin.filter "rangeArray", -> +angular.module("ofn.admin").filter "rangeArray", -> return (input,start,end) -> input.push(i) for i in [start..end] input \ No newline at end of file diff --git a/app/assets/javascripts/admin/filters/select_filter.js.coffee b/app/assets/javascripts/admin/filters/select_filter.js.coffee index 562be954b2..2b03abd613 100644 --- a/app/assets/javascripts/admin/filters/select_filter.js.coffee +++ b/app/assets/javascripts/admin/filters/select_filter.js.coffee @@ -1,4 +1,4 @@ -Admin.filter "selectFilter", (blankOption) -> +angular.module("ofn.admin").filter "selectFilter", (blankOption) -> return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) -> filtered = [] filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) && diff --git a/app/assets/javascripts/admin/filters/variant_filter.js.coffee b/app/assets/javascripts/admin/filters/variant_filter.js.coffee index 039c4cc46f..ddbc0f2711 100644 --- a/app/assets/javascripts/admin/filters/variant_filter.js.coffee +++ b/app/assets/javascripts/admin/filters/variant_filter.js.coffee @@ -1,4 +1,4 @@ -Admin.filter "variantFilter", -> +angular.module("ofn.admin").filter "variantFilter", -> return (lineItems,selectedUnitsProduct,selectedUnitsVariant,sharedResource) -> filtered = [] filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedUnitsProduct,{}) || diff --git a/app/assets/javascripts/admin/products/products.js.coffee b/app/assets/javascripts/admin/products/products.js.coffee new file mode 100644 index 0000000000..e922d40a34 --- /dev/null +++ b/app/assets/javascripts/admin/products/products.js.coffee @@ -0,0 +1 @@ +angular.module("admin.products", []) \ No newline at end of file diff --git a/app/assets/javascripts/admin/products/units_controller.js.coffee b/app/assets/javascripts/admin/products/units_controller.js.coffee new file mode 100644 index 0000000000..9070648e21 --- /dev/null +++ b/app/assets/javascripts/admin/products/units_controller.js.coffee @@ -0,0 +1,46 @@ +angular.module("admin.products") + .controller "unitsCtrl", ($scope) -> + $scope.product = { master: {} } + + $scope.$watch -> + $scope.product.variant_unit_with_scale + , -> + if $scope.product.variant_unit_with_scale + match = $scope.product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) + if match + $scope.product.variant_unit = match[1] + $scope.product.variant_unit_scale = parseFloat(match[2]) + else + $scope.product.variant_unit = $scope.product.variant_unit_with_scale + $scope.product.variant_unit_scale = null + else + $scope.product.variant_unit = $scope.product.variant_unit_scale = null + + $scope.$watch -> + $scope.product.master.unit_value_with_description + , -> + if $scope.product.master.hasOwnProperty("unit_value_with_description") + match = $scope.product.master.unit_value_with_description.match(/^([\d\.]+(?= |$)|)( |)(.*)$/) + if match + $scope.product.master.unit_value = parseFloat(match[1]) + $scope.product.master.unit_value = null if isNaN($scope.product.master.unit_value) + $scope.product.master.unit_value *= $scope.product.variant_unit_scale if $scope.product.master.unit_value && $scope.product.variant_unit_scale + $scope.product.master.unit_description = match[3] + + $scope.variant_unit_options = [ + ["Weight (g)", "weight_1"], + ["Weight (kg)", "weight_1000"], + ["Weight (T)", "weight_1000000"], + ["Volume (mL)", "volume_0.001"], + ["Volume (L)", "volume_1"], + ["Volume (ML)", "volume_1000000"], + ["Items", "items"] + ] + + $scope.hasVariants = (product) -> + Object.keys(product.variants).length > 0 + + $scope.hasUnit = (product) -> + product.variant_unit_with_scale? + + \ No newline at end of file diff --git a/app/assets/javascripts/admin/services/blank_option.js.coffee b/app/assets/javascripts/admin/services/blank_option.js.coffee index 9913a6511d..42ff69a77b 100644 --- a/app/assets/javascripts/admin/services/blank_option.js.coffee +++ b/app/assets/javascripts/admin/services/blank_option.js.coffee @@ -1,2 +1,2 @@ -Admin.value "blankOption", -> +angular.module("ofn.admin").value "blankOption", -> { id: "0", name: "All" } \ No newline at end of file diff --git a/app/assets/javascripts/admin/services/confirm_handler.js.coffee b/app/assets/javascripts/admin/services/confirm_handler.js.coffee index 51b92848dc..88655e34e3 100644 --- a/app/assets/javascripts/admin/services/confirm_handler.js.coffee +++ b/app/assets/javascripts/admin/services/confirm_handler.js.coffee @@ -1,4 +1,4 @@ -Admin.factory "ofnConfirmHandler", (pendingChanges, $compile, $q) -> +angular.module("ofn.admin").factory "ofnConfirmHandler", (pendingChanges, $compile, $q) -> return (scope, callback) -> template = "
Unsaved changes currently exist, save now or ignore?
" dialogDiv = $compile(template)(scope) diff --git a/app/assets/javascripts/admin/services/data_fetcher.js.coffee b/app/assets/javascripts/admin/services/data_fetcher.js.coffee index 0227d26fc7..735e4cc6bb 100644 --- a/app/assets/javascripts/admin/services/data_fetcher.js.coffee +++ b/app/assets/javascripts/admin/services/data_fetcher.js.coffee @@ -1,4 +1,4 @@ -Admin.factory "dataFetcher", [ +angular.module("ofn.admin").factory "dataFetcher", [ "$http", "$q" ($http, $q) -> return (dataLocation) -> diff --git a/app/assets/javascripts/admin/services/data_submitter.js.coffee b/app/assets/javascripts/admin/services/data_submitter.js.coffee index 6a08ca2d33..7d121ec645 100644 --- a/app/assets/javascripts/admin/services/data_submitter.js.coffee +++ b/app/assets/javascripts/admin/services/data_submitter.js.coffee @@ -1,4 +1,4 @@ -Admin.factory "dataSubmitter", [ +angular.module("ofn.admin").factory "dataSubmitter", [ "$http", "$q", "switchClass" ($http, $q, switchClass) -> return (changeObj) -> diff --git a/app/assets/javascripts/admin/services/dirty_products.js.coffee b/app/assets/javascripts/admin/services/dirty_products.js.coffee index bb8614205e..16c10e1e34 100644 --- a/app/assets/javascripts/admin/services/dirty_products.js.coffee +++ b/app/assets/javascripts/admin/services/dirty_products.js.coffee @@ -1,4 +1,4 @@ -Admin.factory "DirtyProducts", ($parse) -> +angular.module("ofn.admin").factory "DirtyProducts", ($parse) -> # Temporary service to track changes in products on admin bulk product edit dirtyProducts = {} diff --git a/app/assets/javascripts/admin/services/pending_changes.js.coffee b/app/assets/javascripts/admin/services/pending_changes.js.coffee index df66900aa7..d72a4ac7bc 100644 --- a/app/assets/javascripts/admin/services/pending_changes.js.coffee +++ b/app/assets/javascripts/admin/services/pending_changes.js.coffee @@ -1,4 +1,4 @@ -Admin.factory "pendingChanges",[ +angular.module("ofn.admin").factory "pendingChanges",[ "dataSubmitter" (dataSubmitter) -> pendingChanges: {} diff --git a/app/assets/javascripts/admin/services/switch_class.js.coffee b/app/assets/javascripts/admin/services/switch_class.js.coffee index bdd61dac2e..e39c52d1f6 100644 --- a/app/assets/javascripts/admin/services/switch_class.js.coffee +++ b/app/assets/javascripts/admin/services/switch_class.js.coffee @@ -1,4 +1,4 @@ -Admin.factory "switchClass", [ +angular.module("ofn.admin").factory "switchClass", [ "$timeout" ($timeout) -> return (element,classToAdd,removeClasses,timeout) -> diff --git a/app/assets/javascripts/admin/services/taxons.js.coffee b/app/assets/javascripts/admin/services/taxons.js.coffee index 5e17dca657..1779ec3518 100644 --- a/app/assets/javascripts/admin/services/taxons.js.coffee +++ b/app/assets/javascripts/admin/services/taxons.js.coffee @@ -1,4 +1,4 @@ -Admin.factory "Taxons", ($resource) -> +angular.module("ofn.admin").factory "Taxons", ($resource) -> resource = $resource "/admin/taxons/search" return { diff --git a/app/assets/stylesheets/admin/dashboard_item.css.sass b/app/assets/stylesheets/admin/dashboard_item.css.sass index ca33dd99fb..e24d60b277 100644 --- a/app/assets/stylesheets/admin/dashboard_item.css.sass +++ b/app/assets/stylesheets/admin/dashboard_item.css.sass @@ -4,7 +4,23 @@ div.dashboard_item .centered text-align: center + .text-icon + margin-top: 8px + display: block + font-size: 16px + font-weight: bold + color: #fff + padding: 0px 6px + border-radius: 10px + &.green + background-color: #9fc820 + &.red + background-color: #DA5354 + &.orange + background-color: #DA7F52 + div.header + height: 50px border-radius: 6px 6px 0px 0px border: 1px solid #5498da position: relative @@ -26,16 +42,41 @@ div.dashboard_item h3 color: #DA7F52 - h3 - padding: 10px 5px 10px 3% + h3.alpha + height: 100% + padding: 10px 5px 0px 3% a border-radius: 0px 4px 0px 0px margin-left: 8px + height: 100% + padding: 15px 2px 0px 2px + + .tabs + height: 30px + border: solid #5498da + border-width: 0px 0px 1px 0px + margin-top: 3px + div.dashboard_tab + cursor: pointer + height: 30px + color: #fff + background-color: #5498da + padding: 5px 5px 0px 5px + text-align: center + font-weight: bold + border: solid #5498da + border-width: 1px 1px 0px 1px + &:hover + background-color: #9fc820 + &.selected + color: #5498da + background-color: #fff .list max-height: 250px overflow-y: auto + overflow-x: hidden .list-title border: solid #5498da @@ -50,10 +91,11 @@ div.dashboard_item .list-item border: solid #5498da border-width: 0px 1px 0px 1px + height: 38px span.alpha font-weight: bold margin-left: -3px - padding: 10px 2px 10px 5% + padding: 10px 2px 0px 5% span.omega padding-right: 13px margin-right: -3px @@ -94,10 +136,13 @@ div.dashboard_item color: #fff .icon-ok-sign color: #fff + .text-icon + &.green + color: #9fc820 + background-color: #fff a.button color: #fff - padding: 15px 15px font-size: 110% font-weight: bold text-align: center @@ -110,4 +155,5 @@ div.dashboard_item &:hover background-color: #9fc820 &.bottom - border-radius: 0px 0px 6px 6px \ No newline at end of file + border-radius: 0px 0px 6px 6px + padding: 15px 15px \ No newline at end of file diff --git a/app/assets/stylesheets/admin/sidebar-item.css.sass b/app/assets/stylesheets/admin/sidebar-item.css.sass index e3e23f85a4..fc19154e94 100644 --- a/app/assets/stylesheets/admin/sidebar-item.css.sass +++ b/app/assets/stylesheets/admin/sidebar-item.css.sass @@ -17,10 +17,22 @@ div.sidebar_item .list max-height: 400px overflow-y: auto - - .list-item + overflow-x: hidden border: solid #5498da border-width: 0px 1px 0px 1px + &.red + color: #DA5354 + border: solid #DA5354 + border-width: 0px 3px 0px 3px + .list-item + &.odd + background-color: #fcf6ef + &:hover + background-color: #9fc820 + a + color: #DA5354 + + .list-item span.alpha font-weight: bold margin-left: -3px @@ -29,16 +41,12 @@ div.sidebar_item max-width: 160px text-overflow: ellipsis span.omega - padding: 8px 13px 8px 0px + padding: 8px 18px 8px 0px margin-right: -3px text-align: right .icon-remove-sign color: #DA5354 font-size: 18px - &.red - color: #DA5354 - border: solid #DA5354 - border-width: 0px 3px 0px 3px &.even background-color: #fff &.odd diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index a72c6fdbd6..0b700ba596 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -123,6 +123,14 @@ class Enterprise < ActiveRecord::Base self.supplied_products.where('count_on_hand > 0').present? end + def supplied_and_active_products_on_hand + self.supplied_products.where('spree_products.count_on_hand > 0').active + end + + def active_products_in_order_cycles + self.supplied_and_active_products_on_hand.in_an_active_order_cycle + end + def to_param "#{id}-#{name.parameterize}" end diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index ba7cbc253d..0140586668 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -75,6 +75,12 @@ Spree::Product.class_eval do scope :in_order_cycle, lambda { |order_cycle| with_order_cycles_inner. merge(Exchange.outgoing). where('order_cycles.id = ?', order_cycle) } + + scope :in_an_active_order_cycle, lambda { with_order_cycles_inner. + merge(OrderCycle.active). + merge(Exchange.outgoing). + where('order_cycles.id IS NOT NULL') } + scope :managed_by, lambda { |user| if user.has_spree_role?('admin') scoped diff --git a/app/overrides/spree/admin/products/new/replace_form.html.haml.deface b/app/overrides/spree/admin/products/new/replace_form.html.haml.deface new file mode 100644 index 0000000000..c752744ee6 --- /dev/null +++ b/app/overrides/spree/admin/products/new/replace_form.html.haml.deface @@ -0,0 +1,56 @@ +/ replace "fieldset[data-hook='new_product']" + +%fieldset{ id: "new_product" } + %legend{align: "center"}= t(:new_product) + .row + = f.field_container :name do + = f.label :name, t(:name) + %span.required * + %br/ + = f.text_field :name, :class => 'fullwidth title' + = f.error_message_on :name + .row + .alpha.six.columns + = f.field_container :supplier do + = f.label :supplier + %span.required * + = f.collection_select(:supplier_id, Enterprise.is_primary_producer.managed_by(spree_current_user).by_name, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"}) + = f.error_message_on :supplier + .five.columns + = f.field_container :price do + = f.label :price, t(:price) + %span.required * + %br/ + = f.text_field :price, :class => 'fullwidth' + = f.error_message_on :price + .five.columns.omega + = f.field_container :on_hand do + = f.label :on_hand, t(:on_hand) + %span.required * + %br/ + = f.text_field :on_hand, :class => 'fullwidth' + = f.error_message_on :on_hand + .row{ 'ng-controller' => 'unitsCtrl' } + .six.columns.alpha + = f.label :variant_unit_with_scale, :units + %select.select2.fullwidth{ id: 'product_variant_unit_with_scale', 'ng-model' => 'product.variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' } + %option{'value' => '', 'ng-hide' => "hasUnit(product)"} + %input{ type: 'hidden', 'ng-value' => 'product.variant_unit', name: 'product[variant_unit]' } + %input{ type: 'hidden', 'ng-value' => 'product.variant_unit_scale', name: 'product[variant_unit_scale]' } + .five.columns + = f.label :product_unit_value_with_description, :value + %input.fullwidth{ id: 'product_unit_value_with_description', 'ng-model' => 'product.master.unit_value_with_description', :type => 'text', :placeholder => 'eg. 2', 'ng-disabled' => "!hasUnit(product)" } + %input{ type: 'hidden', 'ng-value' => 'product.master.unit_value', name: 'product[unit_value]' } + %input{ type: 'hidden', 'ng-value' => 'product.master.unit_description', name: 'product[unit_description]' } + .five.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" } + = f.label :product_variant_unit_name, :unit_name + %input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => 'eg. bunches', :type => 'text' } + #product-from-prototype.clearfix{"data-hook" => "product-from-prototype"} + = render :file => 'spree/admin/prototypes/show' if @prototype + = render :partial => 'spree/admin/shared/new_resource_links' + + +:javascript + angular.element(document.getElementById("new_product")).ready(function() { + angular.bootstrap(document.getElementById("new_product"), ['admin.products']); + }); \ No newline at end of file diff --git a/app/views/admin/enterprises/_sidebar.html.haml b/app/views/admin/enterprises/_sidebar.html.haml index 578612ec6f..0390cb289a 100644 --- a/app/views/admin/enterprises/_sidebar.html.haml +++ b/app/views/admin/enterprises/_sidebar.html.haml @@ -1,59 +1,63 @@ +- payment_methods_color = @payment_methods.count > 0 ? (@enterprise.payment_methods.count > 0 ? "blue" : "red") : "red" .sidebar_item.four.columns.alpha#payment_methods - .four.columns.alpha.header{ class: "#{@payment_methods.count > 0 ? "blue" : "red"}" } + .four.columns.alpha.header{ class: "#{payment_methods_color}" } %span.four.columns.alpha.centered Payment Methods - - if @payment_methods.count > 0 - .four.columns.alpha.list + .four.columns.alpha.list{ class: "#{payment_methods_color}" } + - if @payment_methods.count > 0 + -# = hidden_field_tag "enterprise[payment_method_ids][]", [] - @payment_methods.each do |payment_method| %a.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{edit_admin_payment_method_path(payment_method)}" } %span.three.columns.alpha = payment_method.name %span.one.column.omega - = f.check_box :payment_method_ids, { :multiple => true }, payment_method.id, nil - - else - .four.columns.alpha.list-item.red - %span.three.columns.alpha None Available - %span.one.column.omega - %span.icon-remove-sign - %a.four.columns.alpha.button{ href: "#{new_admin_payment_method_path}", class: "#{@payment_methods.count > 0 ? "blue" : "red"}" } + = f.check_box :payment_method_ids, { multiple: true }, payment_method.id, nil + - else + .four.columns.alpha.list-item + %span.three.columns.alpha None Available + %span.one.column.omega + %span.icon-remove-sign + %a.four.columns.alpha.button{ href: "#{new_admin_payment_method_path}", class: "#{payment_methods_color}" } CREATE NEW %span.icon-arrow-right +- shipping_methods_color = @shipping_methods.count > 0 ? (@enterprise.shipping_methods.count > 0 ? "blue" : "red") : "red" .sidebar_item.four.columns.alpha#shipping_methods - .four.columns.alpha.header{ class: "#{@shipping_methods.count > 0 ? "blue" : "red"}" } + .four.columns.alpha.header{ class: "#{shipping_methods_color}" } %span.four.columns.alpha.centered Shipping Methods - - if @shipping_methods.count > 0 - .four.columns.alpha.list + .four.columns.alpha.list{ class: "#{shipping_methods_color}" } + - if @shipping_methods.count > 0 - @shipping_methods.each do |shipping_method| %a.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{edit_admin_shipping_method_path(shipping_method)}" } %span.three.columns.alpha = shipping_method.name %span.one.column.omega = f.check_box :shipping_method_ids, { :multiple => true }, shipping_method.id, nil - - else - .four.columns.alpha.list-item.red - %span.three.columns.alpha None Available - %span.one.column.omega - %span.icon-remove-sign - %a.four.columns.alpha.button{ href: "#{new_admin_shipping_method_path}", class: "#{@payment_methods.count > 0 ? "blue" : "red"}" } + - else + .four.columns.alpha.list-item + %span.three.columns.alpha None Available + %span.one.column.omega + %span.icon-remove-sign + %a.four.columns.alpha.button{ href: "#{new_admin_shipping_method_path}", class: "#{shipping_methods_color}" } CREATE NEW %span.icon-arrow-right +- enterprise_fees_color = @enterprise_fees.count > 0 ? "blue" : "red" .sidebar_item.four.columns.alpha#enterprise_fees - .four.columns.alpha.header{ class: "#{@enterprise_fees.count > 0 ? "blue" : "red"}" } + .four.columns.alpha.header{ class: "#{enterprise_fees_color}" } %span.four.columns.alpha.centered Enterprise Fees - - if @enterprise_fees.count > 0 - .four.columns.alpha.list + .four.columns.alpha.list{ class: "#{enterprise_fees_color}" } + - if @enterprise_fees.count > 0 - @enterprise_fees.each do |enterprise_fee| %a.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{main_app.admin_enterprise_fees_path}" } %span.three.columns.alpha = enterprise_fee.name %span.one.column.omega   - - else - .four.columns.alpha.list-item.red - %span.three.columns.alpha None Available - %span.one.column.omega - %span.icon-remove-sign - %a.four.columns.alpha.button{ href: "#{main_app.admin_enterprise_fees_path}", class: "#{@enterprise_fees.count > 0 ? "blue" : "red"}" } + - else + .four.columns.alpha.list-item.red + %span.three.columns.alpha None Available + %span.one.column.omega + %span.icon-remove-sign + %a.four.columns.alpha.button{ href: "#{main_app.admin_enterprise_fees_path}", class: "#{enterprise_fees_color}" } CREATE NEW %span.icon-arrow-right \ No newline at end of file diff --git a/app/views/spree/admin/overview/_enterprises.html.haml b/app/views/spree/admin/overview/_enterprises.html.haml index 4042381502..85dc93c2ee 100644 --- a/app/views/spree/admin/overview/_enterprises.html.haml +++ b/app/views/spree/admin/overview/_enterprises.html.haml @@ -1,11 +1,15 @@ -%div.dashboard_item.sixteen.columns.alpha#enterprises +%div.dashboard_item.sixteen.columns.alpha#enterprises{ 'ng-app' => 'ofn.admin', 'ng-controller' => "enterprisesDashboardCtrl" } %div.header.sixteen.columns.alpha{ :class => "#{@enterprises.count > 0 ? "" : "red"}"} %h3.thirteen.columns.alpha My Enterprises - if @enterprises.any? - %a.three.columns.omega.icon-plus.button.blue{ href: "#{main_app.new_admin_enterprise_path}" } + %a.three.columns.omega.icon-plus.button.blue.white-bottom{ href: "#{main_app.new_admin_enterprise_path}" } CREATE NEW - else %a.with-tip{ title: "Enterprises are Producers and/or Hubs and are the basic unit of organisation within the Open Food Network." } What's this? + - if @enterprises.any? + %div.sixteen.columns.alpha.tabs + %div.dashboard_tab.eight.columns.alpha.blue{ ng: { class: "{selected: activeTab == 'hubs'}", click: "activeTab = 'hubs'" } } HUBS + %div.dashboard_tab.eight.columns.omega.blue{ ng: { class: "{selected: activeTab == 'producers'}", click: "activeTab = 'producers'" } } PRODUCERS - if @enterprises.empty? %div.sixteen.columns.alpha.list-item.red %span.text.fifteen.columns.alpha You don't have any enterprises yet. @@ -15,40 +19,69 @@ CREATE A NEW ENTERPRISE %span.icon-arrow-right - else - %div.sixteen.columns.alpha.list-title - %span.five.columns.alpha Name - %span.centered.three.columns Payment Methods - %span.centered.three.columns Shipping Methods - %span.centered.three.columns Enterprise Fees - %div.sixteen.columns.alpha.list - - @enterprises.each do |enterprise| - %a.sixteen.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{main_app.edit_admin_enterprise_path(enterprise)}" } - %span.five.columns.alpha - = enterprise.name - %span.symbol.three.columns.centered - - payment_method_count = enterprise.payment_methods.count - - if payment_method_count < 1 && enterprise.is_distributor - %span.icon-remove-sign.with-tip{ title: "#{enterprise.name} has no Payment Methods" } - - elsif enterprise.is_primary_producer - %span.icon-ok-sign.with-tip{ title: "Producers (like #{enterprise.name}) do not require Payment Methods." } - - else - %span.icon-ok-sign.with-tip{ title: "#{payment_method_count} Payment Method#{payment_method_count > 1 ? "s" : ""}" } - %span.symbol.three.columns.centered - - shipping_method_count = enterprise.shipping_methods.count - - if shipping_method_count < 1 && enterprise.is_distributor - %span.icon-remove-sign.with-tip{ title: "#{enterprise.name} has no Shipping Methods" } - - elsif enterprise.is_primary_producer - %span.icon-ok-sign.with-tip{ title: "Producers (like #{enterprise.name}) do not require Shipping Methods." } - -else - %span.icon-ok-sign.with-tip{ title: "#{shipping_method_count} Shipping Method#{shipping_method_count > 1 ? "s" : ""}" } - %span.symbol.three.columns.centered - - fee_count = enterprise.enterprise_fees.count - - if fee_count > 0 - %span.icon-ok-sign.with-tip{ title: "#{fee_count} Fee#{fee_count > 1 ? "s" : ""}" } - - else - %span.icon-warning-sign.with-tip{ title: "#{enterprise.name} has no Enterprise Fees" } - %span.two.columns.omega.right - %span.icon-arrow-right + %div.hubs_tab{ ng: { show: "activeTab == 'hubs'"} } + %div.sixteen.columns.alpha.list-title + %span.five.columns.alpha Name + %span.centered.three.columns Payment Methods + %span.centered.three.columns Shipping Methods + %span.centered.three.columns Enterprise Fees + %div.sixteen.columns.alpha.list + - @enterprises.is_distributor.each do |enterprise| + %a.sixteen.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{main_app.edit_admin_enterprise_path(enterprise)}" } + %span.five.columns.alpha + = enterprise.name + %span.symbol.three.columns.centered + - payment_method_count = enterprise.payment_methods.count + - if payment_method_count < 1 && enterprise.is_distributor + %span.icon-remove-sign.with-tip{ title: "#{enterprise.name} has no Payment Methods" } + - elsif enterprise.is_primary_producer + %span.icon-ok-sign.with-tip{ title: "Producers (like #{enterprise.name}) do not require Payment Methods." } + - else + %span.icon-ok-sign.with-tip{ title: "#{payment_method_count} Payment Method#{payment_method_count > 1 ? "s" : ""}" } + %span.symbol.three.columns.centered + - shipping_method_count = enterprise.shipping_methods.count + - if shipping_method_count < 1 && enterprise.is_distributor + %span.icon-remove-sign.with-tip{ title: "#{enterprise.name} has no Shipping Methods" } + - elsif enterprise.is_primary_producer + %span.icon-ok-sign.with-tip{ title: "Producers (like #{enterprise.name}) do not require Shipping Methods." } + -else + %span.icon-ok-sign.with-tip{ title: "#{shipping_method_count} Shipping Method#{shipping_method_count > 1 ? "s" : ""}" } + %span.symbol.three.columns.centered + - fee_count = enterprise.enterprise_fees.count + - if fee_count > 0 + %span.icon-ok-sign.with-tip{ title: "#{fee_count} Fee#{fee_count > 1 ? "s" : ""}" } + - else + %span.icon-warning-sign.with-tip{ title: "#{enterprise.name} has no Enterprise Fees" } + %span.two.columns.omega.right + %span.icon-arrow-right + %div.producers_tab{ ng: { show: "activeTab == 'producers'"} } + %div.list-title.sixteen.columns.alpha + %span.five.columns.alpha Name + %span.centered.three.columns Total Products + %span.centered.three.columns Active Products + %span.centered.three.columns Products in OCs + %div.sixteen.columns.alpha.list + - @enterprises.is_primary_producer.each do |enterprise| + %a.sixteen.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{main_app.edit_admin_enterprise_path(enterprise)}" } + %span.five.columns.alpha + = enterprise.name + %span.symbol.three.columns.centered + %span.one.column.alpha   + %span.text-icon.one.column.centered{ class: "#{enterprise.supplied_products.not_deleted.count > 0 ? "green" : "red" }" } + = enterprise.supplied_products.not_deleted.count + %span.one.column.omega   + %span.symbol.three.columns.centered + %span.one.column.alpha   + %span.text-icon.one.column.centered{ class: "#{enterprise.supplied_and_active_products_on_hand.count > 0 ? "green" : "red" }" } + = enterprise.supplied_and_active_products_on_hand.count + %span.one.column.omega   + %span.symbol.three.columns.centered + %span.one.column.alpha   + %span.text-icon.one.column.centered{ class: "#{enterprise.active_products_in_order_cycles.count > 0 ? "green" : "orange" }" } + = enterprise.active_products_in_order_cycles.count + %span.one.column.omega   + %span.two.columns.omega.right + %span.icon-arrow-right %a.sixteen.columns.alpha.button.bottom.blue{ href: "#{main_app.admin_enterprises_path}" } MANAGE MY ENTERPRISES %span.icon-arrow-right \ No newline at end of file diff --git a/app/views/spree/admin/shared/_tabs.html.erb b/app/views/spree/admin/shared/_tabs.html.erb index ab66dbf1de..2228d4ac7b 100644 --- a/app/views/spree/admin/shared/_tabs.html.erb +++ b/app/views/spree/admin/shared/_tabs.html.erb @@ -1,4 +1,4 @@ -<%= tab :overview, :route => :admin, :icon => 'icon-dashboard' %> +<%= tab :dashboard, :route => :admin, :icon => 'icon-dashboard' %> <%= tab :orders, :payments, :creditcard_payments, :shipments, :credit_cards, :return_authorizations, :url => admin_orders_path('q[s]' => 'completed_at desc'), :icon => 'icon-shopping-cart' %> <%= tab :products , :option_types, :properties, :prototypes, :variants, :product_properties, :taxons, :url => bulk_edit_admin_products_path, :icon => 'icon-th-large' %> <%= tab :reports, :icon => 'icon-file' %> diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index f375b8890a..d93bc78dd6 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -338,6 +338,16 @@ describe Enterprise do end end + describe "supplied_and_active_products_on_hand" do + it "find only active products which are in stock" do + supplier = create(:supplier_enterprise) + inactive_product = create(:product, supplier: supplier, on_hand: 1, available_on: Date.tomorrow) + out_of_stock_product = create(:product, supplier: supplier, on_hand: 0, available_on: Date.yesterday) + p1 = create(:product, supplier: supplier, on_hand: 1, available_on: Date.yesterday) + supplier.supplied_and_active_products_on_hand.should == [p1] + end + end + describe "finding variants distributed by the enterprise" do it "finds the master variant" do d = create(:distributor_enterprise) diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 6d90b70761..a5333b6d11 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -230,6 +230,20 @@ module Spree end end + describe "in_an_active_order_cycle" do + it "shows products in order cycle distribution" do + s = create(:supplier_enterprise) + d2 = create(:distributor_enterprise) + d3 = create(:distributor_enterprise) + p1 = create(:product) + p2 = create(:product) + p3 = create(:product) + oc2 = create(:simple_order_cycle, suppliers: [s], distributors: [d2], variants: [p2.master], orders_close_at: 1.day.ago) + oc2 = create(:simple_order_cycle, suppliers: [s], distributors: [d3], variants: [p3.master], orders_close_at: Date.tomorrow) + Product.in_an_active_order_cycle.should == [p3] + end + end + describe "access roles" do before(:each) do @e1 = create(:enterprise)