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)