mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-13 18:46:49 +00:00
Compare commits
183 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9163b0c1ad | ||
|
|
fd9f65f1b6 | ||
|
|
713999c1d8 | ||
|
|
21db56ce6c | ||
|
|
adbe127e76 | ||
|
|
3c4ad4121f | ||
|
|
8e8f38e484 | ||
|
|
b429be707c | ||
|
|
4829e59663 | ||
|
|
d12fdd23fb | ||
|
|
b0a29801b6 | ||
|
|
6ebd58b67d | ||
|
|
0791cc3c2a | ||
|
|
76acbb6159 | ||
|
|
d7ea81e821 | ||
|
|
9245af6a8f | ||
|
|
36430d3bad | ||
|
|
7520552fd7 | ||
|
|
6991e5e6b1 | ||
|
|
42d6695264 | ||
|
|
4d26b3d648 | ||
|
|
177181cd75 | ||
|
|
4baa205cf9 | ||
|
|
60313f7a6a | ||
|
|
3e5ea3fe63 | ||
|
|
b98c01b280 | ||
|
|
ff624e83eb | ||
|
|
48dc85cfc2 | ||
|
|
a0990c107f | ||
|
|
585c061fb0 | ||
|
|
83726eba63 | ||
|
|
7ad9fdf0be | ||
|
|
6b10a4a775 | ||
|
|
4088bdc236 | ||
|
|
9b78963d5a | ||
|
|
3ec3441cfa | ||
|
|
39889390ef | ||
|
|
c3659612ed | ||
|
|
7a6cd98646 | ||
|
|
9286c82b43 | ||
|
|
c330e49a7f | ||
|
|
e2268e53bb | ||
|
|
9f0aeb5adf | ||
|
|
41e42c78c4 | ||
|
|
1753432f36 | ||
|
|
0f8809abfc | ||
|
|
1d80bee595 | ||
|
|
d04e843315 | ||
|
|
c0eb902eef | ||
|
|
2c307f09c3 | ||
|
|
23fc428d95 | ||
|
|
3bd77c74a5 | ||
|
|
8334ff736b | ||
|
|
51687b5c2c | ||
|
|
21108b34b6 | ||
|
|
2a21889216 | ||
|
|
b451b94fd1 | ||
|
|
d2d3a577ea | ||
|
|
b3e67fa164 | ||
|
|
ac34da4f24 | ||
|
|
d2277999cc | ||
|
|
cdd6c2daf2 | ||
|
|
4a881a5aa5 | ||
|
|
d5d218c450 | ||
|
|
f8622be21d | ||
|
|
676e7cb4d6 | ||
|
|
1dfbc88813 | ||
|
|
9db1c4c708 | ||
|
|
25a734b208 | ||
|
|
47a8731b8e | ||
|
|
932604bd69 | ||
|
|
4d7871a0bb | ||
|
|
51c8891fac | ||
|
|
9b258e075b | ||
|
|
891a9b06a8 | ||
|
|
b5879d51ac | ||
|
|
dcc04ea538 | ||
|
|
83754a01ef | ||
|
|
2d82f76a43 | ||
|
|
d5437e1508 | ||
|
|
f0bd9c1065 | ||
|
|
642de2f65f | ||
|
|
f6e9c9494c | ||
|
|
90ad2e2b7d | ||
|
|
cfb69ae7d2 | ||
|
|
a93a824b83 | ||
|
|
2170c7ede1 | ||
|
|
06cf914119 | ||
|
|
307cc313df | ||
|
|
0431e0048c | ||
|
|
20bde803c8 | ||
|
|
6b43354386 | ||
|
|
494bb1f3b4 | ||
|
|
d52b6b34e3 | ||
|
|
4583e29ae3 | ||
|
|
a4d4622521 | ||
|
|
20f650b472 | ||
|
|
e013e1fe00 | ||
|
|
d40ffeef52 | ||
|
|
6200390369 | ||
|
|
e9f32f5329 | ||
|
|
27bc845b0b | ||
|
|
22cb8b7a71 | ||
|
|
c6db1d440c | ||
|
|
bc448e5156 | ||
|
|
6a42f62eb2 | ||
|
|
8db09d9590 | ||
|
|
7e55262ce9 | ||
|
|
bbc887a692 | ||
|
|
6f36c0463c | ||
|
|
592ac7856a | ||
|
|
261dea37e9 | ||
|
|
80c507cc66 | ||
|
|
1ad13f0359 | ||
|
|
532041c07b | ||
|
|
05bd0c4168 | ||
|
|
51b0d7e0eb | ||
|
|
d2e0d4f44a | ||
|
|
ab26902e4e | ||
|
|
6adb4194c2 | ||
|
|
b6f29c778e | ||
|
|
4839c00d62 | ||
|
|
a438216189 | ||
|
|
29f9b3bbd7 | ||
|
|
ac59665e3c | ||
|
|
e4efda2f96 | ||
|
|
a9b91bc52a | ||
|
|
f90ee33c89 | ||
|
|
087ccb52f9 | ||
|
|
4bf8716786 | ||
|
|
c0030ddb13 | ||
|
|
370133b875 | ||
|
|
6863dd75ef | ||
|
|
fafdb29fcb | ||
|
|
85882a73ff | ||
|
|
2bad590ef4 | ||
|
|
c3995ee4d5 | ||
|
|
94684e9963 | ||
|
|
1e1a070b2b | ||
|
|
d50f8dcd01 | ||
|
|
813ef463a2 | ||
|
|
72118f4e2e | ||
|
|
e9f04c3c15 | ||
|
|
6e0576235d | ||
|
|
27d646c0e8 | ||
|
|
0151ecbb32 | ||
|
|
d548515684 | ||
|
|
343af1f1e0 | ||
|
|
3b58d99abc | ||
|
|
4a30f27b3d | ||
|
|
c4b45bdbbf | ||
|
|
b0f5d0170c | ||
|
|
5fcb2982fa | ||
|
|
ead84aa9ff | ||
|
|
1d3800696e | ||
|
|
f5ee9ba2f3 | ||
|
|
e6eecd3ae2 | ||
|
|
0832a8f63d | ||
|
|
23c7715929 | ||
|
|
2ea7bdbec6 | ||
|
|
6c300431d2 | ||
|
|
91c500417b | ||
|
|
7e49bd634e | ||
|
|
eeae72352b | ||
|
|
079781576b | ||
|
|
f878e18037 | ||
|
|
633a8a49e2 | ||
|
|
a5ae1c490c | ||
|
|
c2c51a5531 | ||
|
|
35c27bf516 | ||
|
|
e4d1ae7548 | ||
|
|
4f153714a8 | ||
|
|
451dd3966f | ||
|
|
c3829ae64f | ||
|
|
b81bf60dc2 | ||
|
|
cc0da142b7 | ||
|
|
03b59eae75 | ||
|
|
e89184de02 | ||
|
|
cc3959467d | ||
|
|
15f29f4c8e | ||
|
|
932d571d2c | ||
|
|
9a5ee81431 | ||
|
|
6f6ae309c6 |
3
Gemfile
3
Gemfile
@@ -21,7 +21,7 @@ gem 'comfortable_mexican_sofa'
|
||||
gem 'simple_form', :github => 'RohanM/simple_form'
|
||||
|
||||
gem 'unicorn'
|
||||
gem 'angularjs-rails'
|
||||
gem 'angularjs-rails', '1.2.13'
|
||||
gem 'bugsnag'
|
||||
gem 'newrelic_rpm'
|
||||
gem 'haml'
|
||||
@@ -78,6 +78,7 @@ gem 'jquery-rails'
|
||||
group :test, :development do
|
||||
# Pretty printed test output
|
||||
gem 'turn', '~> 0.8.3', :require => false
|
||||
gem 'fuubar'
|
||||
gem 'rspec-rails'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'factory_girl_rails', :require => false
|
||||
|
||||
@@ -269,6 +269,9 @@ GEM
|
||||
railties (>= 3.1.0)
|
||||
sass (>= 3.2.0)
|
||||
fssm (0.2.10)
|
||||
fuubar (1.3.3)
|
||||
rspec (>= 2.14.0, < 3.1.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
geocoder (1.1.8)
|
||||
gmaps4rails (1.5.6)
|
||||
guard (2.2.4)
|
||||
@@ -449,6 +452,7 @@ GEM
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
ruby-hmac (0.4.0)
|
||||
ruby-progressbar (1.7.1)
|
||||
safe_yaml (0.9.5)
|
||||
sass (3.2.19)
|
||||
sass-rails (3.2.6)
|
||||
@@ -528,7 +532,7 @@ DEPENDENCIES
|
||||
andand
|
||||
angular-rails-templates
|
||||
angularjs-file-upload-rails (~> 1.1.0)
|
||||
angularjs-rails
|
||||
angularjs-rails (= 1.2.13)
|
||||
awesome_print
|
||||
aws-sdk
|
||||
bugsnag
|
||||
@@ -548,6 +552,7 @@ DEPENDENCIES
|
||||
foundation-icons-sass-rails
|
||||
foundation-rails
|
||||
foundation_rails_helper!
|
||||
fuubar
|
||||
geocoder
|
||||
gmaps4rails
|
||||
guard
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 44 KiB |
55
app/assets/images/spinning-circles.svg
Executable file
55
app/assets/images/spinning-circles.svg
Executable file
@@ -0,0 +1,55 @@
|
||||
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
|
||||
<svg width="58" height="58" viewBox="0 0 58 58" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(2 1)" stroke="#0096ad" stroke-width="1.5">
|
||||
<circle cx="42.601" cy="11.462" r="5" fill-opacity="1" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="1;0;0;0;0;0;0;0" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
<circle cx="49.063" cy="27.063" r="5" fill-opacity="0" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="0;1;0;0;0;0;0;0" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
<circle cx="42.601" cy="42.663" r="5" fill-opacity="0" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="0;0;1;0;0;0;0;0" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
<circle cx="27" cy="49.125" r="5" fill-opacity="0" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="0;0;0;1;0;0;0;0" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
<circle cx="11.399" cy="42.663" r="5" fill-opacity="0" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="0;0;0;0;1;0;0;0" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
<circle cx="4.938" cy="27.063" r="5" fill-opacity="0" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="0;0;0;0;0;1;0;0" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
<circle cx="11.399" cy="11.462" r="5" fill-opacity="0" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="0;0;0;0;0;0;1;0" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
<circle cx="27" cy="5" r="5" fill-opacity="0" fill="#0096ad">
|
||||
<animate attributeName="fill-opacity"
|
||||
begin="0s" dur="1.3s"
|
||||
values="0;0;0;0;0;0;0;1" calcMode="linear"
|
||||
repeatCount="indefinite" />
|
||||
</circle>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -1,68 +1,19 @@
|
||||
angular.module("admin.enterprises")
|
||||
.controller "enterpriseCtrl", ($scope, NavigationCheck, Enterprise, PaymentMethods, ShippingMethods, SideMenu) ->
|
||||
.controller "enterpriseCtrl", ($scope, NavigationCheck, Enterprise, EnterprisePaymentMethods, EnterpriseShippingMethods, SideMenu) ->
|
||||
$scope.Enterprise = Enterprise.enterprise
|
||||
$scope.PaymentMethods = PaymentMethods.paymentMethods
|
||||
$scope.ShippingMethods = ShippingMethods.shippingMethods
|
||||
console.log Enterprise
|
||||
$scope.PaymentMethods = EnterprisePaymentMethods.paymentMethods
|
||||
$scope.ShippingMethods = EnterpriseShippingMethods.shippingMethods
|
||||
$scope.navClear = NavigationCheck.clear
|
||||
# htmlVariable is used by textAngular wysiwyg for the long descrtiption.
|
||||
$scope.pristineEmail = $scope.Enterprise.email
|
||||
$scope.menu = SideMenu
|
||||
|
||||
# Provide a callback for generating warning messages displayed before leaving the page. This is passed in
|
||||
# from a directive "nav-check" in the page - if we pass it here it will be called in the test suite,
|
||||
# and on all new uses of this contoller, and we might not want that .
|
||||
$scope.enterpriseNavCallback = ->
|
||||
if $scope.enterprise.$dirty
|
||||
enterpriseNavCallback = ->
|
||||
if $scope.Enterprise.$dirty
|
||||
"Your changes to the enterprise are not saved yet."
|
||||
|
||||
for payment_method in $scope.PaymentMethods
|
||||
payment_method.selected = payment_method.id in $scope.Enterprise.payment_method_ids
|
||||
|
||||
$scope.paymentMethodsColor = ->
|
||||
if $scope.PaymentMethods.length > 0
|
||||
if $scope.selectedPaymentMethodsCount() > 0 then "blue" else "red"
|
||||
else
|
||||
"red"
|
||||
|
||||
$scope.selectedPaymentMethodsCount = ->
|
||||
$scope.PaymentMethods.reduce (count, payment_method) ->
|
||||
count++ if payment_method.selected
|
||||
count
|
||||
, 0
|
||||
|
||||
for shipping_method in $scope.ShippingMethods
|
||||
shipping_method.selected = shipping_method.id in $scope.Enterprise.shipping_method_ids
|
||||
|
||||
$scope.shippingMethodsColor = ->
|
||||
if $scope.ShippingMethods.length > 0
|
||||
if $scope.selectedShippingMethodsCount() > 0 then "blue" else "red"
|
||||
else
|
||||
"red"
|
||||
|
||||
$scope.selectedShippingMethodsCount = ->
|
||||
$scope.ShippingMethods.reduce (count, shipping_method) ->
|
||||
count++ if shipping_method.selected
|
||||
count
|
||||
, 0
|
||||
|
||||
$scope.$watch "Enterprise.is_primary_producer", (newValue, oldValue) ->
|
||||
if !newValue && $scope.Enterprise.sells == "none"
|
||||
$scope.menu.hide_item_by_name('Enterprise Fees')
|
||||
else
|
||||
$scope.menu.show_item_by_name('Enterprise Fees')
|
||||
|
||||
|
||||
$scope.$watch "Enterprise.sells", (newValue, oldValue) ->
|
||||
if newValue == "none"
|
||||
$scope.menu.hide_item_by_name('Shipping Methods')
|
||||
$scope.menu.hide_item_by_name('Payment Methods')
|
||||
$scope.menu.hide_item_by_name('Shop Preferences')
|
||||
if $scope.Enterprise.is_primary_producer
|
||||
$scope.menu.show_item_by_name('Enterprise Fees')
|
||||
else
|
||||
$scope.menu.hide_item_by_name('Enterprise Fees')
|
||||
else
|
||||
$scope.menu.show_item_by_name('Shipping Methods')
|
||||
$scope.menu.show_item_by_name('Payment Methods')
|
||||
$scope.menu.show_item_by_name('Shop Preferences')
|
||||
$scope.menu.show_item_by_name('Enterprise Fees')
|
||||
# Register the NavigationCheck callback
|
||||
NavigationCheck.register(enterpriseNavCallback)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
angular.module("admin.enterprises")
|
||||
.controller "permalinkCtrl", ($scope, PermalinkChecker) ->
|
||||
# locals
|
||||
initialPermalink = $scope.Enterprise.permalink
|
||||
pendingRequest = null
|
||||
|
||||
# variables on $scope
|
||||
$scope.availablility = ""
|
||||
$scope.checking = false
|
||||
|
||||
$scope.$watch "Enterprise.permalink", (newValue, oldValue) ->
|
||||
$scope.checking = true
|
||||
pendingRequest = PermalinkChecker.check(newValue)
|
||||
|
||||
pendingRequest.then (data) ->
|
||||
if data.permalink == initialPermalink
|
||||
$scope.availability = ""
|
||||
else
|
||||
$scope.availability = data.available
|
||||
$scope.Enterprise.permalink = data.permalink
|
||||
$scope.checking = false
|
||||
, (data) ->
|
||||
# Do nothing (this is hopefully an aborted request)
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module("admin.enterprises")
|
||||
.controller "sideMenuCtrl", ($scope, Enterprise, SideMenu) ->
|
||||
.controller "sideMenuCtrl", ($scope, $parse, Enterprise, SideMenu, enterprisePermissions) ->
|
||||
$scope.Enterprise = Enterprise.enterprise
|
||||
$scope.menu = SideMenu
|
||||
$scope.select = SideMenu.select
|
||||
@@ -12,10 +12,30 @@ angular.module("admin.enterprises")
|
||||
{ name: 'About', icon_class: "icon-pencil" }
|
||||
{ name: 'Business Details', icon_class: "icon-briefcase" }
|
||||
{ name: 'Images', icon_class: "icon-picture" }
|
||||
{ name: "Shipping Methods", icon_class: "icon-truck" }
|
||||
{ name: "Payment Methods", icon_class: "icon-money" }
|
||||
{ name: "Enterprise Fees", icon_class: "icon-tasks" }
|
||||
{ name: "Shop Preferences", icon_class: "icon-shopping-cart" }
|
||||
{ name: "Shipping Methods", icon_class: "icon-truck", show: "showShippingMethods()" }
|
||||
{ name: "Payment Methods", icon_class: "icon-money", show: "showPaymentMethods()" }
|
||||
{ name: "Enterprise Fees", icon_class: "icon-tasks", show: "showEnterpriseFees()" }
|
||||
{ name: "Shop Preferences", icon_class: "icon-shopping-cart", show: "showShopPreferences()" }
|
||||
]
|
||||
|
||||
$scope.select(0)
|
||||
|
||||
|
||||
$scope.showItem = (item) ->
|
||||
if item.show?
|
||||
$parse(item.show)($scope)
|
||||
else
|
||||
true
|
||||
|
||||
$scope.showShippingMethods = ->
|
||||
enterprisePermissions.can_manage_shipping_methods && $scope.Enterprise.sells != "none"
|
||||
|
||||
$scope.showPaymentMethods = ->
|
||||
enterprisePermissions.can_manage_payment_methods && $scope.Enterprise.sells != "none"
|
||||
|
||||
$scope.showEnterpriseFees = ->
|
||||
enterprisePermissions.can_manage_enterprise_fees && ($scope.Enterprise.sells != "none" || $scope.Enterprise.is_primary_producer)
|
||||
|
||||
$scope.showShopPreferences = ->
|
||||
$scope.Enterprise.sells != "none"
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
angular.module("admin.enterprises")
|
||||
.factory "EnterprisePaymentMethods", (Enterprise, PaymentMethods) ->
|
||||
new class EnterprisePaymentMethods
|
||||
paymentMethods: PaymentMethods.paymentMethods
|
||||
|
||||
constructor: ->
|
||||
for payment_method in @paymentMethods
|
||||
payment_method.selected = payment_method.id in Enterprise.enterprise.payment_method_ids
|
||||
|
||||
displayColor: ->
|
||||
if @paymentMethods.length > 0 && @selectedCount() > 0
|
||||
"blue"
|
||||
else
|
||||
"red"
|
||||
|
||||
selectedCount: ->
|
||||
@paymentMethods.reduce (count, payment_method) ->
|
||||
count++ if payment_method.selected
|
||||
count
|
||||
, 0
|
||||
@@ -0,0 +1,20 @@
|
||||
angular.module("admin.enterprises")
|
||||
.factory "EnterpriseShippingMethods", (Enterprise, ShippingMethods) ->
|
||||
new class EnterpriseShippingMethods
|
||||
shippingMethods: ShippingMethods.shippingMethods
|
||||
|
||||
constructor: ->
|
||||
for shipping_method in @shippingMethods
|
||||
shipping_method.selected = shipping_method.id in Enterprise.enterprise.shipping_method_ids
|
||||
|
||||
displayColor: ->
|
||||
if @shippingMethods.length > 0 && @selectedCount() > 0
|
||||
"blue"
|
||||
else
|
||||
"red"
|
||||
|
||||
selectedCount: ->
|
||||
@shippingMethods.reduce (count, shipping_method) ->
|
||||
count++ if shipping_method.selected
|
||||
count
|
||||
, 0
|
||||
@@ -0,0 +1,36 @@
|
||||
angular.module("admin.enterprises").factory 'PermalinkChecker', ($q, $http) ->
|
||||
new class PermalinkChecker
|
||||
deferredRequest: null
|
||||
deferredAbort: null
|
||||
|
||||
check: (permalink) =>
|
||||
@abort(@deferredAbort) if @deferredRequest && @deferredRequest.promise
|
||||
@deferredRequest = deferredRequest = $q.defer()
|
||||
@deferredAbort = deferredAbort = $q.defer()
|
||||
request = $http(
|
||||
method: "GET"
|
||||
url: "/enterprises/check_permalink?permalink=#{permalink}"
|
||||
headers:
|
||||
Accept: 'application/javascript'
|
||||
timeout: deferredAbort.promise
|
||||
)
|
||||
.success( (data) =>
|
||||
deferredRequest.resolve
|
||||
permalink: data
|
||||
available: "Available"
|
||||
).error (data,status) =>
|
||||
if status == 409
|
||||
deferredRequest.resolve
|
||||
permalink: data
|
||||
available: "Unavailable"
|
||||
else
|
||||
# Something went wrong or request was aborted
|
||||
deferredRequest.reject()
|
||||
|
||||
deferredRequest.promise.finally ->
|
||||
request = deferredRequest.promise = null;
|
||||
|
||||
deferredRequest.promise
|
||||
|
||||
abort: (deferredAbort) ->
|
||||
deferredAbort.resolve()
|
||||
@@ -74,7 +74,8 @@ angular.module('admin.order_cycles', ['ngResource'])
|
||||
$scope.removeDistributionOfVariant = (variant_id) ->
|
||||
OrderCycle.removeDistributionOfVariant(variant_id)
|
||||
|
||||
$scope.submit = ->
|
||||
$scope.submit = (event) ->
|
||||
event.preventDefault()
|
||||
OrderCycle.create()
|
||||
])
|
||||
|
||||
@@ -154,7 +155,8 @@ angular.module('admin.order_cycles', ['ngResource'])
|
||||
$scope.removeDistributionOfVariant = (variant_id) ->
|
||||
OrderCycle.removeDistributionOfVariant(variant_id)
|
||||
|
||||
$scope.submit = ->
|
||||
$scope.submit = (event) ->
|
||||
event.preventDefault()
|
||||
OrderCycle.update()
|
||||
])
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ angular.module('admin.order_cycles').controller "AdminSimpleCreateOrderCycleCtrl
|
||||
$scope.enterpriseFeesForEnterprise = (enterprise_id) ->
|
||||
EnterpriseFee.forEnterprise(parseInt(enterprise_id))
|
||||
|
||||
$scope.submit = ->
|
||||
$scope.submit = (event) ->
|
||||
event.preventDefault()
|
||||
OrderCycle.mirrorIncomingToOutgoingProducts()
|
||||
OrderCycle.create()
|
||||
|
||||
@@ -32,6 +32,7 @@ angular.module('admin.order_cycles').controller "AdminSimpleEditOrderCycleCtrl",
|
||||
$event.preventDefault()
|
||||
OrderCycle.removeCoordinatorFee(index)
|
||||
|
||||
$scope.submit = ->
|
||||
$scope.submit = (event) ->
|
||||
event.preventDefault()
|
||||
OrderCycle.mirrorIncomingToOutgoingProducts()
|
||||
OrderCycle.update()
|
||||
|
||||
@@ -87,20 +87,21 @@ angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window)
|
||||
load: (order_cycle_id, callback=null) ->
|
||||
service = this
|
||||
OrderCycle.get {order_cycle_id: order_cycle_id}, (oc) ->
|
||||
angular.extend(service.order_cycle, oc)
|
||||
service.order_cycle.incoming_exchanges = []
|
||||
service.order_cycle.outgoing_exchanges = []
|
||||
for exchange in service.order_cycle.exchanges
|
||||
if exchange.incoming
|
||||
angular.extend(exchange, {enterprise_id: exchange.sender_id, active: true})
|
||||
delete(exchange.receiver_id)
|
||||
service.order_cycle.incoming_exchanges.push(exchange)
|
||||
|
||||
else
|
||||
angular.extend(exchange, {enterprise_id: exchange.receiver_id, active: true})
|
||||
delete(exchange.sender_id)
|
||||
service.order_cycle.outgoing_exchanges.push(exchange)
|
||||
|
||||
delete oc.$promise
|
||||
delete oc.$resolved
|
||||
angular.extend(service.order_cycle, oc)
|
||||
service.order_cycle.incoming_exchanges = []
|
||||
service.order_cycle.outgoing_exchanges = []
|
||||
for exchange in service.order_cycle.exchanges
|
||||
if exchange.incoming
|
||||
angular.extend(exchange, {enterprise_id: exchange.sender_id, active: true})
|
||||
delete(exchange.receiver_id)
|
||||
service.order_cycle.incoming_exchanges.push(exchange)
|
||||
else
|
||||
angular.extend(exchange, {enterprise_id: exchange.receiver_id, active: true})
|
||||
delete(exchange.sender_id)
|
||||
service.order_cycle.outgoing_exchanges.push(exchange)
|
||||
|
||||
delete(service.order_cycle.exchanges)
|
||||
service.loaded = true
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ angular.module("admin.payment_methods")
|
||||
.factory "PaymentMethods", (paymentMethods) ->
|
||||
new class PaymentMethods
|
||||
paymentMethods: paymentMethods
|
||||
|
||||
|
||||
findByID: (id) ->
|
||||
for paymentMethod in @paymentMethods
|
||||
return paymentMethod if paymentMethod.id is id
|
||||
|
||||
@@ -4,6 +4,7 @@ angular.module("ofn.admin").factory 'EnterpriseRelationships', ($http, enterpris
|
||||
all_permissions: [
|
||||
'add_to_order_cycle'
|
||||
'manage_products'
|
||||
'edit_profile'
|
||||
]
|
||||
|
||||
constructor: ->
|
||||
@@ -26,3 +27,4 @@ angular.module("ofn.admin").factory 'EnterpriseRelationships', ($http, enterpris
|
||||
switch permission
|
||||
when "add_to_order_cycle" then "to add to order cycle"
|
||||
when "manage_products" then "to manage products"
|
||||
when "edit_profile" then "to edit profile"
|
||||
|
||||
@@ -2,7 +2,7 @@ angular.module("admin.shipping_methods")
|
||||
.factory "ShippingMethods", (shippingMethods) ->
|
||||
new class ShippingMethods
|
||||
shippingMethods: shippingMethods
|
||||
|
||||
|
||||
findByID: (id) ->
|
||||
for shippingMethod in @shippingMethods
|
||||
return shippingMethod if shippingMethod.id is id
|
||||
|
||||
@@ -13,7 +13,7 @@ angular.module("admin.taxons").factory "Taxons", (taxons, $filter) ->
|
||||
|
||||
# For finding multiple Taxons represented by comma delimited string
|
||||
findByIDs: (ids) ->
|
||||
@taxonsByID[taxon_id] for taxon_id in ids.split(",")
|
||||
@taxonsByID[taxon_id] for taxon_id in ids.split(",") when @taxonsByID[taxon_id]
|
||||
|
||||
findByTerm: (term) ->
|
||||
$filter('filter')(@taxons, term)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
angular.module("admin.utils").directive "navCheckCallback", (NavigationCheck)->
|
||||
restrict: 'A'
|
||||
scope:
|
||||
navCheckCallback: '&'
|
||||
link: (scope,element,attributes) ->
|
||||
# Provide a callback, otherwise this default will be used:
|
||||
callback = scope.navCheckCallback()
|
||||
callback ||= ->
|
||||
"You will lose any unsaved work!"
|
||||
NavigationCheck.register(callback)
|
||||
@@ -4,7 +4,7 @@ Darkswarm.controller "CheckoutCtrl", ($scope, storage, Checkout, CurrentUser, Cu
|
||||
|
||||
# Bind to local storage
|
||||
$scope.fieldsToBind = ["bill_address", "email", "payment_method_id", "shipping_method_id", "ship_address"]
|
||||
prefix = "order_#{Checkout.order.id}#{CurrentUser?.id}#{CurrentHub.hub.id}"
|
||||
prefix = "order_#{Checkout.order.id}#{CurrentUser.id or ""}#{CurrentHub.hub.id}"
|
||||
|
||||
for field in $scope.fieldsToBind
|
||||
storage.bind $scope, "Checkout.order.#{field}",
|
||||
@@ -16,7 +16,7 @@ Darkswarm.controller "CheckoutCtrl", ($scope, storage, Checkout, CurrentUser, Cu
|
||||
$scope.order = Checkout.order # Ordering is important
|
||||
$scope.secrets = Checkout.secrets
|
||||
|
||||
$scope.enabled = !!CurrentUser
|
||||
$scope.enabled = !!CurrentUser.id?
|
||||
|
||||
$scope.purchase = (event, form) ->
|
||||
event.preventDefault()
|
||||
|
||||
@@ -43,6 +43,11 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
|
||||
@line_items.filter (li)->
|
||||
li.quantity > 0
|
||||
|
||||
total_item_count: =>
|
||||
@line_items_present().reduce (sum,li) ->
|
||||
sum = sum + li.quantity
|
||||
, 0
|
||||
|
||||
empty: =>
|
||||
@line_items_present().length == 0
|
||||
|
||||
@@ -62,4 +67,4 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
|
||||
variant: variant
|
||||
quantity: null
|
||||
max_quantity: null
|
||||
@line_items.push variant.line_item
|
||||
@line_items.push variant.line_item
|
||||
@@ -1,7 +1,4 @@
|
||||
Darkswarm.factory 'CurrentUser', (user)-> # This is for the current user
|
||||
if user and !$.isEmptyObject(user)
|
||||
new class CurrentUser
|
||||
constructor: ->
|
||||
@[k] = v for k, v of user
|
||||
else
|
||||
undefined
|
||||
new class CurrentUser
|
||||
constructor: ->
|
||||
@[k] = v for k, v of user if user and !$.isEmptyObject(user)
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
Darkswarm.factory 'HashNavigation', ($location) ->
|
||||
new class HashNavigation
|
||||
hash: null
|
||||
hash: null
|
||||
|
||||
constructor: ->
|
||||
# Make sure we have a path as hashes
|
||||
# dont seem to work so well without them
|
||||
$location.path("") if !$location.path()
|
||||
|
||||
active: (hash)->
|
||||
$location.hash() == hash
|
||||
$location.hash() == hash
|
||||
|
||||
navigate: (hash)->
|
||||
@hash = hash
|
||||
|
||||
@@ -12,22 +12,22 @@
|
||||
%li.cost
|
||||
.right {{ variant.price | localizeCurrency }}
|
||||
Item cost
|
||||
%li{"bo-if" => "variant.fees.admin"}
|
||||
%li.admin-fee{"bo-if" => "variant.fees.admin"}
|
||||
.right {{ variant.fees.admin | localizeCurrency }}
|
||||
Admin fee
|
||||
%li{"bo-if" => "variant.fees.sales"}
|
||||
%li.sales-fee{"bo-if" => "variant.fees.sales"}
|
||||
.right {{ variant.fees.sales | localizeCurrency }}
|
||||
Sales fee
|
||||
%li{"bo-if" => "variant.fees.packing"}
|
||||
%li.packing-fee{"bo-if" => "variant.fees.packing"}
|
||||
.right {{ variant.fees.packing | localizeCurrency }}
|
||||
Packing fee
|
||||
%li{"bo-if" => "variant.fees.transport"}
|
||||
%li.transport-fee{"bo-if" => "variant.fees.transport"}
|
||||
.right {{ variant.fees.transport | localizeCurrency }}
|
||||
Transport fee
|
||||
%li{"bo-if" => "variant.fees.fundraising"}
|
||||
%li.fundraising-fee{"bo-if" => "variant.fees.fundraising"}
|
||||
.right {{ variant.fees.fundraising | localizeCurrency }}
|
||||
Fundraising fee
|
||||
%li
|
||||
%li.total
|
||||
%strong
|
||||
.right = {{ variant.price_with_fees | localizeCurrency }}
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
%button.graph-button{"ng-class" => "{open: tt_isOpen}"}
|
||||
%i.ofn-i_058-graph
|
||||
/ %i.ofn-i_058-graph
|
||||
|
||||
@@ -40,6 +40,6 @@
|
||||
.message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } }
|
||||
Your logo will appear here for review once uploaded
|
||||
.loading{ ng: { hide: "!imageUploader.isUploading" } }
|
||||
%img.spinner{ src: "/assets/loading.gif" }
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
%br/
|
||||
Uploading...
|
||||
|
||||
@@ -38,6 +38,6 @@
|
||||
.message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } }
|
||||
Your logo will appear here for review once uploaded
|
||||
.loading{ ng: { hide: "!imageUploader.isUploading" } }
|
||||
%img.spinner{ src: "/assets/loading.gif" }
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
%br/
|
||||
Uploading...
|
||||
|
||||
@@ -58,5 +58,5 @@
|
||||
|
||||
.small-12.medium-2.large-2.columns.total-price.text-right
|
||||
.table-cell
|
||||
%strong
|
||||
%strong{"ng-class" => "{filled: variant.totalPrice()}"}
|
||||
{{ variant.totalPrice() | localizeCurrency }}
|
||||
|
||||
14
app/assets/stylesheets/admin/enterprise_console.css.scss
Normal file
14
app/assets/stylesheets/admin/enterprise_console.css.scss
Normal file
@@ -0,0 +1,14 @@
|
||||
span.unavailable, span.available {
|
||||
font-weight: bold;
|
||||
i {
|
||||
font-size: 150%;
|
||||
}
|
||||
}
|
||||
|
||||
span.available {
|
||||
color: #9fc820;
|
||||
}
|
||||
|
||||
span.unavailable {
|
||||
color: #DA5354;
|
||||
}
|
||||
@@ -77,44 +77,36 @@ ordercycle
|
||||
button.graph-button
|
||||
z-index: 9999999
|
||||
border: 1px solid transparent
|
||||
@include box-shadow(none)
|
||||
padding: 0
|
||||
margin: 0
|
||||
@include border-radius(999rem)
|
||||
display: inline
|
||||
background-color: rgba(255,255,255,0.5)
|
||||
padding: 5px
|
||||
@media all and (max-width: 768px)
|
||||
display: none
|
||||
// Hide for small
|
||||
|
||||
&:hover, &:active, &:focus
|
||||
background-color: rgba(255,255,255,1)
|
||||
i.ofn-i_058-graph
|
||||
color: $clr-brick-bright
|
||||
|
||||
i.ofn-i_058-graph
|
||||
padding: 4px
|
||||
@include box-shadow(none)
|
||||
@include border-radius(999rem)
|
||||
&:before
|
||||
@include icon-font
|
||||
content: '\e639'
|
||||
color: #999
|
||||
margin: 0
|
||||
padding: 0
|
||||
font-size: 1rem
|
||||
|
||||
@media all and (max-width: 640px)
|
||||
padding: 3px
|
||||
i.ofn-i_058-graph
|
||||
font-size: 0.75rem
|
||||
&:focus
|
||||
border: 1px solid #e0e0e0
|
||||
background-color: rgba(255,255,255,1)
|
||||
&:before
|
||||
color: #666
|
||||
&:hover, &:active
|
||||
background-color: rgba(255,255,255,1)
|
||||
border: 1px solid transparent
|
||||
&:before
|
||||
color: $clr-brick-bright
|
||||
@media all and (max-width: 768px)
|
||||
// Hide for small
|
||||
display: none
|
||||
|
||||
button.graph-button.open
|
||||
@include box-shadow(inset 0 1px 1px 0 rgba(0,0,0,0.35))
|
||||
border: 1px solid #999
|
||||
|
||||
&:hover, &:active, &:focus
|
||||
background-color: rgba(255,255,255,1)
|
||||
i.ofn-i_058-graph
|
||||
color: $clr-brick-bright
|
||||
|
||||
i.ofn-i_058-graph
|
||||
color: $clr-brick
|
||||
|
||||
border: 1px solid transparent
|
||||
background-color: $clr-brick-bright
|
||||
&:before
|
||||
content: '\e608'
|
||||
color: white
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import branding.css.sass
|
||||
@import animations.sass
|
||||
|
||||
.darkswarm
|
||||
products
|
||||
@@ -71,9 +72,14 @@
|
||||
// Total price
|
||||
.total-price
|
||||
padding-left: 0rem
|
||||
color: $disabled-med
|
||||
.filled
|
||||
color: $med-drk-grey
|
||||
@media all and (max-width: 640px)
|
||||
background: #777
|
||||
color: white
|
||||
color: $disabled-med
|
||||
.filled
|
||||
color: white
|
||||
.table-cell
|
||||
height: 27px
|
||||
|
||||
@@ -97,17 +103,19 @@
|
||||
@media all and (max-width: 768px)
|
||||
padding-left: 4.9375rem
|
||||
@media all and (max-width: 640px)
|
||||
padding-left: 4.5rem
|
||||
@media all and (max-width:480px)
|
||||
padding-left: 0.9375rem
|
||||
small
|
||||
font-size: 80%
|
||||
h3
|
||||
font-size: 1.5rem
|
||||
margin: 0
|
||||
h3 a
|
||||
color: #222
|
||||
i
|
||||
@include csstrans
|
||||
font-size: 0.6em
|
||||
&:hover, &:focus, &:active
|
||||
color: black
|
||||
|
||||
|
||||
|
||||
color: $clr-brick
|
||||
i
|
||||
font-size: 0.8em
|
||||
|
||||
|
||||
@@ -1,26 +1,59 @@
|
||||
@import branding
|
||||
@import animations.sass
|
||||
|
||||
.darkswarm
|
||||
products
|
||||
product
|
||||
.product-thumb
|
||||
@include csstrans
|
||||
position: absolute
|
||||
top: 3px
|
||||
top: 2px
|
||||
left: 0px
|
||||
width: 7rem
|
||||
height: 7rem
|
||||
outline: 1px solid $disabled-bright
|
||||
float: left
|
||||
display: block
|
||||
z-index: 999999
|
||||
background-color: white
|
||||
overflow: hidden
|
||||
|
||||
i
|
||||
@include csstrans
|
||||
transition-delay: 150ms
|
||||
position: absolute
|
||||
left: 45%
|
||||
top: 45%
|
||||
z-index: 99999
|
||||
color: white
|
||||
font-size: 1rem
|
||||
opacity: 0
|
||||
img
|
||||
@include csstrans
|
||||
opacity: 1
|
||||
@include transform-scale(scale(1))
|
||||
|
||||
&:hover, &:focus, &:active
|
||||
background-color: $clr-brick
|
||||
i
|
||||
left: 32%
|
||||
top: 30%
|
||||
font-size: 3rem
|
||||
opacity: 1
|
||||
img
|
||||
opacity: 0.5
|
||||
@include transform-scale(scale(1.1))
|
||||
|
||||
@media all and (max-width: 768px)
|
||||
top: 2px
|
||||
width: 4rem
|
||||
height: 4rem
|
||||
|
||||
@media all and (max-width: 480px)
|
||||
&:hover, &:focus, &:active
|
||||
i
|
||||
left: 30%
|
||||
top: 30%
|
||||
font-size: 2rem
|
||||
@media all and (max-width: 640px)
|
||||
display: none
|
||||
width: 0rem
|
||||
height: 0rem
|
||||
height: 0rem
|
||||
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
margin-top: -1.1rem
|
||||
padding-top: 0.25rem
|
||||
z-index: 999999
|
||||
|
||||
@media all and (max-width: 768px)
|
||||
margin-top: -0.85rem
|
||||
@media all and (max-width: 480px)
|
||||
background-size: 28px 32px
|
||||
min-height: 32px
|
||||
width: 28px
|
||||
|
||||
render-svg
|
||||
svg
|
||||
@@ -19,3 +20,12 @@
|
||||
height: 24px
|
||||
path
|
||||
fill: #999
|
||||
|
||||
@media all and (max-width: 768px)
|
||||
margin-top: -0.85rem
|
||||
|
||||
@media all and (max-width: 480px)
|
||||
render-svg
|
||||
svg
|
||||
width: 18px
|
||||
height: 18px
|
||||
|
||||
@@ -66,10 +66,8 @@ products .filter-box
|
||||
table-layout: fixed
|
||||
text-transform: capitalize
|
||||
overflow: visible
|
||||
// width: 100%
|
||||
// height: 2rem
|
||||
line-height: 1
|
||||
color: #444
|
||||
color: $med-drk-grey
|
||||
font-size: 0.875rem
|
||||
span
|
||||
display: table-cell
|
||||
|
||||
@@ -51,6 +51,21 @@
|
||||
100%
|
||||
opacity: 1
|
||||
|
||||
@-webkit-keyframes spin
|
||||
0%
|
||||
-webkit-transform: rotate(0deg)
|
||||
transform: rotate(0deg)
|
||||
100%
|
||||
-webkit-transform: rotate(359deg)
|
||||
transform: rotate(359deg)
|
||||
@keyframes spin
|
||||
0%
|
||||
-webkit-transform: rotate(0deg)
|
||||
transform: rotate(0deg)
|
||||
100%
|
||||
-webkit-transform: rotate(359deg)
|
||||
transform: rotate(359deg)
|
||||
|
||||
// ANIMATION CLASSES
|
||||
|
||||
.fade
|
||||
|
||||
@@ -21,5 +21,6 @@ $disabled-med: #b3b3b3
|
||||
$disabled-dark: #999
|
||||
$disabled-v-dark: #808080
|
||||
$med-grey: #666
|
||||
$med-drk-grey: #444
|
||||
$dark-grey: #333
|
||||
$black: #000
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
@import branding
|
||||
|
||||
.product-img
|
||||
border-bottom: 40px white solid
|
||||
border-top: 20px white solid
|
||||
border-left: 20px white solid
|
||||
border-right: 20px white solid
|
||||
padding: 5px
|
||||
margin-bottom: 10px
|
||||
outline: 1px solid #ccc
|
||||
@include box-shadow(0 1px 2px 1px rgba(0,0,0,0.25))
|
||||
@include box-shadow(0 1px 2px 1px rgba(0,0,0,0.15))
|
||||
|
||||
.hero-img
|
||||
outline: 1px solid $disabled-bright
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
nav
|
||||
@include textpress
|
||||
|
||||
.joyride-tip-guide .button
|
||||
text-shadow: none
|
||||
|
||||
// Default overrides - big menu
|
||||
|
||||
.top-bar-section ul li.ofn-logo > a
|
||||
display: table-cell
|
||||
vertical-align: middle
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import mixins
|
||||
@import animations
|
||||
@import variables
|
||||
@import branding
|
||||
@import big-input
|
||||
@@ -25,6 +26,21 @@
|
||||
.add_to_cart
|
||||
margin-top: 2rem
|
||||
|
||||
form
|
||||
input.small.button.primary.right.add_to_cart
|
||||
&.dirty
|
||||
padding-left: 3.2rem
|
||||
i.cart-spinner
|
||||
position: absolute
|
||||
top: 14px
|
||||
right: 146px
|
||||
color: white
|
||||
font-size: 1.2em
|
||||
// Necessary to be below Z index of cart popover:
|
||||
z-index: 98
|
||||
-webkit-animation: spin 2s infinite linear
|
||||
animation: spin 2s infinite linear
|
||||
|
||||
product
|
||||
@include csstrans
|
||||
border-bottom: 1px solid #e5e5e5
|
||||
@@ -33,7 +49,7 @@
|
||||
margin-bottom: 20px !important
|
||||
position: relative
|
||||
display: block
|
||||
color: #444
|
||||
color: $med-drk-grey
|
||||
|
||||
&:hover, &:focus, &:active
|
||||
border-bottom: 1px solid $clr-brick-med-bright
|
||||
@@ -62,12 +78,14 @@
|
||||
@media all and (max-width: 640px)
|
||||
padding-right: 0.25rem
|
||||
|
||||
i.ofn-i_056-bulk, i.ofn-i_036-producers
|
||||
i.ofn-i_056-bulk
|
||||
font-size: 1rem
|
||||
padding-right: 0rem
|
||||
|
||||
i.ofn-i_036-producers
|
||||
padding-left: 0.5rem
|
||||
padding-left: 0.2rem
|
||||
padding-right: 0rem
|
||||
font-size: 0.8rem
|
||||
|
||||
.shopfront_message, .shopfront_closed_message
|
||||
padding: 15px
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module Admin
|
||||
class EnterprisesController < ResourceController
|
||||
before_filter :load_enterprise_set, :only => :index
|
||||
before_filter :load_countries, :except => :index
|
||||
before_filter :load_countries, :except => [:index, :set_sells, :check_permalink]
|
||||
before_filter :load_methods_and_fees, :only => [:new, :edit, :update, :create]
|
||||
before_filter :load_taxons, :only => [:new, :edit, :update, :create]
|
||||
before_filter :check_can_change_sells, only: :update
|
||||
@@ -18,7 +18,7 @@ module Admin
|
||||
end
|
||||
|
||||
def set_sells
|
||||
enterprise = Enterprise.find(params[:id])
|
||||
enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
|
||||
attributes = { sells: params[:sells] }
|
||||
attributes[:producer_profile_only] = params[:sells] == "none" && !!params[:producer_profile_only]
|
||||
attributes[:shop_trial_start_date] = Time.now if params[:sells] == "own"
|
||||
@@ -53,7 +53,6 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
def build_resource_with_address
|
||||
@@ -64,6 +63,11 @@ module Admin
|
||||
end
|
||||
alias_method_chain :build_resource, :address
|
||||
|
||||
# Overriding method on Spree's resource controller,
|
||||
# so that resources are found using permalink
|
||||
def find_resource
|
||||
Enterprise.find_by_permalink(params[:id])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -76,8 +80,10 @@ module Admin
|
||||
end
|
||||
|
||||
def collection
|
||||
# TODO was ordered with is_distributor DESC as well, not sure why or how we want ot sort this now
|
||||
Enterprise.managed_by(spree_current_user).order('is_primary_producer ASC, name')
|
||||
# TODO was ordered with is_distributor DESC as well, not sure why or how we want to sort this now
|
||||
OpenFoodNetwork::Permissions.new(spree_current_user).
|
||||
editable_enterprises.
|
||||
order('is_primary_producer ASC, name')
|
||||
end
|
||||
|
||||
def collection_actions
|
||||
|
||||
@@ -12,7 +12,7 @@ module Admin
|
||||
end
|
||||
|
||||
def load_enterprise
|
||||
@enterprise = Enterprise.find params[:enterprise_id]
|
||||
@enterprise = Enterprise.find_by_permalink params[:enterprise_id]
|
||||
end
|
||||
|
||||
def load_properties
|
||||
|
||||
@@ -29,7 +29,7 @@ module Api
|
||||
end
|
||||
|
||||
def update
|
||||
@enterprise = Enterprise.find(params[:id])
|
||||
@enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
|
||||
authorize! :update, @enterprise
|
||||
|
||||
if @enterprise.update_attributes(params[:enterprise])
|
||||
@@ -40,7 +40,7 @@ module Api
|
||||
end
|
||||
|
||||
def update_image
|
||||
@enterprise = Enterprise.find(params[:id])
|
||||
@enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
|
||||
authorize! :update, @enterprise
|
||||
|
||||
if params[:logo] && @enterprise.update_attributes( { logo: params[:logo] } )
|
||||
|
||||
@@ -11,8 +11,19 @@ class BaseController < ApplicationController
|
||||
include Spree::ProductsHelper
|
||||
|
||||
before_filter :check_order_cycle_expiry
|
||||
|
||||
|
||||
def load_active_distributors
|
||||
@active_distributors ||= Enterprise.distributors_with_active_order_cycles
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_order_cycles
|
||||
@order_cycles = OrderCycle.with_distributor(@distributor).active
|
||||
|
||||
# And default to the only order cycle if there's only the one
|
||||
if @order_cycles.count == 1
|
||||
current_order(true).set_order_cycle! @order_cycles.first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
class EnterprisesController < BaseController
|
||||
layout "darkswarm"
|
||||
helper Spree::ProductsHelper
|
||||
include OrderCyclesHelper
|
||||
before_filter :clean_permalink, only: :check_permalink
|
||||
|
||||
respond_to :js, only: :permalink_checker
|
||||
|
||||
def index
|
||||
@enterprises = Enterprise.all
|
||||
@@ -24,7 +28,7 @@ class EnterprisesController < BaseController
|
||||
end
|
||||
|
||||
def show
|
||||
@enterprise = Enterprise.find params[:id]
|
||||
@enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
|
||||
|
||||
# User can view this page if they've already chosen their distributor, or if this page
|
||||
# is for a supplier, they may use it to select a distributor that sells this supplier's
|
||||
@@ -53,7 +57,7 @@ class EnterprisesController < BaseController
|
||||
end
|
||||
|
||||
def shop
|
||||
distributor = Enterprise.is_distributor.find params[:id]
|
||||
distributor = Enterprise.is_distributor.find_by_permalink(params[:id]) || Enterprise.is_distributor.find(params[:id])
|
||||
order = current_order(true)
|
||||
|
||||
if order.distributor and order.distributor != distributor
|
||||
@@ -67,6 +71,25 @@ class EnterprisesController < BaseController
|
||||
order.order_cycle = order_cycle_options.first if order_cycle_options.count == 1
|
||||
order.save!
|
||||
|
||||
redirect_to main_app.shop_path
|
||||
require_distributor_chosen
|
||||
set_order_cycles
|
||||
load_active_distributors
|
||||
end
|
||||
|
||||
def check_permalink
|
||||
return render text: params[:permalink], status: 409 if Enterprise.find_by_permalink params[:permalink]
|
||||
|
||||
path = Rails.application.routes.recognize_path( "/#{ params[:permalink].to_s }" )
|
||||
if path && path[:controller] == "cms_content"
|
||||
render text: params[:permalink], status: 200
|
||||
else
|
||||
render text: params[:permalink], status: 409
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def clean_permalink
|
||||
params[:permalink] = params[:permalink].parameterize
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ module OpenFoodNetwork
|
||||
|
||||
def add_variant
|
||||
@cart = Cart.find(params[:cart_id])
|
||||
distributor = Enterprise.find(params[:distributor_id])
|
||||
distributor = Enterprise.find_by_permalink(params[:distributor_id])
|
||||
order_cycle = OrderCycle.find(params[:order_cycle_id]) if params[:order_cycle_id]
|
||||
|
||||
if @cart.add_variant params[:variant_id], params[:quantity], distributor, order_cycle, current_currency
|
||||
@@ -36,4 +36,4 @@ module OpenFoodNetwork
|
||||
Spree::Config[:currency]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
require 'open_food_network/scope_product_to_hub'
|
||||
|
||||
class ShopController < BaseController
|
||||
layout "darkswarm"
|
||||
before_filter :require_distributor_chosen
|
||||
before_filter :set_order_cycles
|
||||
before_filter :load_active_distributors
|
||||
|
||||
def show
|
||||
redirect_to main_app.enterprise_shop_path(current_distributor)
|
||||
end
|
||||
|
||||
def products
|
||||
@@ -34,20 +36,14 @@ class ShopController < BaseController
|
||||
|
||||
private
|
||||
|
||||
def set_order_cycles
|
||||
@order_cycles = OrderCycle.with_distributor(@distributor).active
|
||||
|
||||
# And default to the only order cycle if there's only the one
|
||||
if @order_cycles.count == 1
|
||||
current_order(true).set_order_cycle! @order_cycles.first
|
||||
end
|
||||
end
|
||||
|
||||
def products_for_shop
|
||||
current_order_cycle.andand
|
||||
.valid_products_distributed_by(current_distributor).andand
|
||||
.order(taxon_order).andand
|
||||
.select { |p| !p.deleted? && p.has_stock_for_distribution?(current_order_cycle, current_distributor) }
|
||||
if current_order_cycle
|
||||
current_order_cycle.
|
||||
valid_products_distributed_by(current_distributor).
|
||||
order(taxon_order).
|
||||
each { |p| p.scope_to_hub current_distributor }.
|
||||
select { |p| !p.deleted? && p.has_stock_for_distribution?(current_order_cycle, current_distributor) }
|
||||
end
|
||||
end
|
||||
|
||||
def taxon_order
|
||||
|
||||
@@ -5,9 +5,12 @@ require 'open_food_network/group_buy_report'
|
||||
require 'open_food_network/order_grouper'
|
||||
require 'open_food_network/customers_report'
|
||||
require 'open_food_network/users_and_enterprises_report'
|
||||
require 'open_food_network/order_cycle_management_report'
|
||||
|
||||
Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
include Spree::ReportsHelper
|
||||
|
||||
REPORT_TYPES = {
|
||||
orders_and_fulfillment: [
|
||||
['Order Cycle Supplier Totals',:order_cycle_supplier_totals],
|
||||
@@ -22,11 +25,14 @@ Spree::Admin::ReportsController.class_eval do
|
||||
customers: [
|
||||
["Mailing List", :mailing_list],
|
||||
["Addresses", :addresses]
|
||||
],
|
||||
order_cycle_management: [
|
||||
["Payment Methods Report", :payment_methods_report]
|
||||
]
|
||||
}
|
||||
|
||||
# Fetches user's distributors, suppliers and order_cycles
|
||||
before_filter :load_data, only: [:customers, :products_and_inventory]
|
||||
before_filter :load_data, only: [:customers, :products_and_inventory, :order_cycle_management]
|
||||
|
||||
# Render a partial for orders and fulfillment description
|
||||
respond_override :index => { :html => { :success => lambda {
|
||||
@@ -36,6 +42,8 @@ Spree::Admin::ReportsController.class_eval do
|
||||
render_to_string(partial: 'products_and_inventory_description', layout: false, locals: {report_types: REPORT_TYPES[:products_and_inventory]}).html_safe
|
||||
@reports[:customers][:description] =
|
||||
render_to_string(partial: 'customers_description', layout: false, locals: {report_types: REPORT_TYPES[:customers]}).html_safe
|
||||
@reports[:order_cycle_management][:description] =
|
||||
render_to_string(partial: 'order_cycle_management_description', layout: false, locals: {report_types: REPORT_TYPES[:order_cycle_management]}).html_safe
|
||||
} } }
|
||||
|
||||
|
||||
@@ -50,8 +58,20 @@ Spree::Admin::ReportsController.class_eval do
|
||||
@report_types = REPORT_TYPES[:customers]
|
||||
@report_type = params[:report_type]
|
||||
@report = OpenFoodNetwork::CustomersReport.new spree_current_user, params
|
||||
|
||||
render_report(@report.header, @report.table, params[:csv], "customers_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
render_report(@report.header, @report.table, params[:csv], "customers.csv")
|
||||
def order_cycle_management
|
||||
@report_types = REPORT_TYPES[:order_cycle_management]
|
||||
@report_type = params[:report_type]
|
||||
@report = OpenFoodNetwork::OrderCycleManagementReport.new spree_current_user, params
|
||||
|
||||
@search = Spree::Order.complete.not_state(:canceled).managed_by(spree_current_user).search(params[:q])
|
||||
|
||||
@orders = @search.result
|
||||
|
||||
render_report(@report.header, @report.table, params[:csv], "order_cycle_management_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def orders_and_distributors
|
||||
@@ -79,7 +99,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
csv << @report.header
|
||||
@report.table.each { |row| csv << row }
|
||||
end
|
||||
send_data csv_string, :filename => "orders_and_distributors.csv"
|
||||
send_data csv_string, :filename => "orders_and_distributors_#{timestamp}.csv"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -231,7 +251,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
@header = header
|
||||
@table = order_grouper.table(@line_items)
|
||||
csv_file_name = "bulk_coop.csv"
|
||||
csv_file_name = "bulk_coop_#{timestamp}.csv"
|
||||
|
||||
render_report(@header, @table, params[:csv], csv_file_name)
|
||||
end
|
||||
@@ -262,7 +282,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
when "payments_by_payment_type"
|
||||
table_items = payments
|
||||
|
||||
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
|
||||
header = ["Payment State", "Distributor", "Payment Type", "Total (#{currency_symbol})"]
|
||||
|
||||
columns = [ proc { |payments| payments.first.order.payment_state },
|
||||
proc { |payments| payments.first.order.distributor.name },
|
||||
@@ -279,7 +299,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
when "itemised_payment_totals"
|
||||
table_items = orders
|
||||
|
||||
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Outstanding Balance ($)", "Total ($)"]
|
||||
header = ["Payment State", "Distributor", "Product Total (#{currency_symbol})", "Shipping Total (#{currency_symbol})", "Outstanding Balance (#{currency_symbol})", "Total (#{currency_symbol})"]
|
||||
|
||||
columns = [ proc { |orders| orders.first.payment_state },
|
||||
proc { |orders| orders.first.distributor.name },
|
||||
@@ -296,7 +316,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
when "payment_totals"
|
||||
table_items = orders
|
||||
|
||||
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Total ($)", "EFT ($)", "PayPal ($)", "Outstanding Balance ($)"]
|
||||
header = ["Payment State", "Distributor", "Product Total (#{currency_symbol})", "Shipping Total (#{currency_symbol})", "Total (#{currency_symbol})", "EFT (#{currency_symbol})", "PayPal (#{currency_symbol})", "Outstanding Balance (#{currency_symbol})"]
|
||||
|
||||
columns = [ proc { |orders| orders.first.payment_state },
|
||||
proc { |orders| orders.first.distributor.name },
|
||||
@@ -315,7 +335,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
else
|
||||
table_items = payments
|
||||
|
||||
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
|
||||
header = ["Payment State", "Distributor", "Payment Type", "Total (#{currency_symbol})"]
|
||||
|
||||
columns = [ proc { |payments| payments.first.order.payment_state },
|
||||
proc { |payments| payments.first.order.distributor.name },
|
||||
@@ -335,7 +355,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
@header = header
|
||||
@table = order_grouper.table(table_items)
|
||||
csv_file_name = "payments.csv"
|
||||
csv_file_name = "payments_#{timestamp}.csv"
|
||||
|
||||
render_report(@header, @table, params[:csv], csv_file_name)
|
||||
|
||||
@@ -475,7 +495,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
table_items = @line_items
|
||||
@include_blank = 'All'
|
||||
|
||||
header = ["Hub", "Customer", "Email", "Phone", "Producer", "Product", "Variant", "Amount", "Item ($)", "Item + Fees ($)", "Dist ($)", "Ship ($)", "Total ($)", "Paid?",
|
||||
header = ["Hub", "Customer", "Email", "Phone", "Producer", "Product", "Variant", "Amount", "Item (#{currency_symbol})", "Item + Fees (#{currency_symbol})", "Dist (#{currency_symbol})", "Ship (#{currency_symbol})", "Total (#{currency_symbol})", "Paid?",
|
||||
"Shipping", "Delivery?", "Ship street", "Ship street 2", "Ship city", "Ship postcode", "Ship state", "Order notes"]
|
||||
|
||||
rsa = proc { |line_items| line_items.first.order.shipping_method.andand.require_ship_address }
|
||||
@@ -567,7 +587,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
@header = header
|
||||
@table = order_grouper.table(table_items)
|
||||
csv_file_name = "#{__method__}.csv"
|
||||
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
|
||||
|
||||
render_report(@header, @table, params[:csv], csv_file_name)
|
||||
|
||||
@@ -576,13 +596,13 @@ Spree::Admin::ReportsController.class_eval do
|
||||
def products_and_inventory
|
||||
@report_types = REPORT_TYPES[:products_and_inventory]
|
||||
@report = OpenFoodNetwork::ProductsAndInventoryReport.new spree_current_user, params
|
||||
render_report(@report.header, @report.table, params[:csv], "products_and_inventory.csv")
|
||||
render_report(@report.header, @report.table, params[:csv], "products_and_inventory_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def users_and_enterprises
|
||||
# @report_types = REPORT_TYPES[:users_and_enterprises]
|
||||
@report = OpenFoodNetwork::UsersAndEnterprisesReport.new params
|
||||
render_report(@report.header, @report.table, params[:csv], "users_and_enterprises.csv")
|
||||
render_report(@report.header, @report.table, params[:csv], "users_and_enterprises_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def render_report (header, table, create_csv, csv_file_name)
|
||||
@@ -620,7 +640,8 @@ Spree::Admin::ReportsController.class_eval do
|
||||
:customers => {:name => "Customers", :description => 'Customer details'},
|
||||
:products_and_inventory => {:name => "Products & Inventory", :description => ''},
|
||||
:sales_total => { :name => "Sales Total", :description => "Sales Total For All Orders" },
|
||||
:users_and_enterprises => { :name => "Users & Enterprises", :description => "Enterprise Ownership & Status" }
|
||||
:users_and_enterprises => { :name => "Users & Enterprises", :description => "Enterprise Ownership & Status" },
|
||||
:order_cycle_management => {:name => "Order Cycle Management", :description => ''}
|
||||
}
|
||||
# Return only reports the user is authorized to view.
|
||||
reports.select { |action| can? action, :report }
|
||||
@@ -634,4 +655,8 @@ Spree::Admin::ReportsController.class_eval do
|
||||
end
|
||||
total_units.round(3)
|
||||
end
|
||||
|
||||
def timestamp
|
||||
Time.now.strftime("%Y%m%d")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,25 +33,6 @@ Spree::OrdersController.class_eval do
|
||||
end
|
||||
end
|
||||
|
||||
def select_distributor
|
||||
distributor = Enterprise.is_distributor.find params[:id]
|
||||
|
||||
order = current_order(true)
|
||||
order.distributor = distributor
|
||||
order.save!
|
||||
|
||||
redirect_to main_app.enterprise_path(distributor)
|
||||
end
|
||||
|
||||
def deselect_distributor
|
||||
order = current_order(true)
|
||||
|
||||
order.distributor = nil
|
||||
order.save!
|
||||
|
||||
redirect_to root_path
|
||||
end
|
||||
|
||||
def update_distribution
|
||||
@order = current_order(true)
|
||||
|
||||
|
||||
@@ -33,6 +33,15 @@ module Admin
|
||||
admin_inject_json_ams_array "ofn.admin", "producers", @producers, Api::Admin::IdNameSerializer
|
||||
end
|
||||
|
||||
def admin_inject_enterprise_permissions
|
||||
permissions =
|
||||
{can_manage_shipping_methods: can?(:manage_shipping_methods, @enterprise),
|
||||
can_manage_payment_methods: can?(:manage_payment_methods, @enterprise),
|
||||
can_manage_enterprise_fees: can?(:manage_enterprise_fees, @enterprise)}
|
||||
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: "admin.enterprises", name: "enterprisePermissions", json: permissions.to_json}
|
||||
end
|
||||
|
||||
def admin_inject_hub_permissions
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: "ofn.admin", name: "hubPermissions", json: @hub_permissions.to_json}
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'spree/money_decorator'
|
||||
|
||||
module Spree
|
||||
module ReportsHelper
|
||||
def report_order_cycle_options(order_cycles)
|
||||
@@ -7,5 +9,17 @@ module Spree
|
||||
[ "#{oc.name} (#{orders_open_at} - #{orders_close_at})".html_safe, oc.id ]
|
||||
end
|
||||
end
|
||||
|
||||
def report_payment_method_options(orders)
|
||||
orders.map { |o| o.payments.first.payment_method.andand.name }.uniq
|
||||
end
|
||||
|
||||
def report_shipping_method_options(orders)
|
||||
orders.map { |o| o.shipping_method.andand.name }.uniq
|
||||
end
|
||||
|
||||
def currency_symbol
|
||||
Spree::Money.currency_symbol
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,20 +56,25 @@ class Enterprise < ActiveRecord::Base
|
||||
validates :address, presence: true, associated: true
|
||||
validates :email, presence: true
|
||||
validates_presence_of :owner
|
||||
validates :permalink, uniqueness: true, presence: true
|
||||
validate :shopfront_taxons
|
||||
validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? }
|
||||
validates_length_of :description, :maximum => 255
|
||||
|
||||
before_save :confirmation_check, if: lambda{ email_changed? }
|
||||
before_save :confirmation_check, if: lambda { email_changed? }
|
||||
|
||||
before_validation :initialize_permalink, if: lambda { permalink.nil? }
|
||||
before_validation :ensure_owner_is_manager, if: lambda { owner_id_changed? && !owner_id.nil? }
|
||||
before_validation :set_unused_address_fields
|
||||
after_validation :geocode_address
|
||||
|
||||
after_create :relate_to_owners_hubs
|
||||
# TODO: Later versions of devise have a dedicated after_confirmation callback, so use that
|
||||
after_update :welcome_after_confirm, if: lambda { confirmation_token_changed? && confirmation_token.nil? }
|
||||
after_create :send_welcome_email, if: lambda { email_is_known? }
|
||||
|
||||
after_rollback :restore_permalink
|
||||
|
||||
scope :by_name, order('name')
|
||||
scope :visible, where(:visible => true)
|
||||
scope :confirmed, where('confirmed_at IS NOT NULL')
|
||||
@@ -93,6 +98,7 @@ class Enterprise < ActiveRecord::Base
|
||||
}
|
||||
scope :is_primary_producer, where(:is_primary_producer => true)
|
||||
scope :is_distributor, where('sells != ?', 'none')
|
||||
scope :is_hub, where(sells: 'any')
|
||||
scope :supplying_variant_in, lambda { |variants| joins(:supplied_products => :variants_including_master).where('spree_variants.id IN (?)', variants).select('DISTINCT enterprises.*') }
|
||||
scope :with_supplied_active_products_on_hand, lambda {
|
||||
joins(:supplied_products)
|
||||
@@ -199,7 +205,7 @@ class Enterprise < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def to_param
|
||||
"#{id}-#{name.parameterize}"
|
||||
permalink
|
||||
end
|
||||
|
||||
def relatives
|
||||
@@ -290,6 +296,22 @@ class Enterprise < ActiveRecord::Base
|
||||
shipping_methods.any? && payment_methods.available.any?
|
||||
end
|
||||
|
||||
def self.find_available_permalink(test_permalink)
|
||||
test_permalink = test_permalink.parameterize
|
||||
test_permalink = "my-enterprise" if test_permalink.blank?
|
||||
existing = Enterprise.select(:permalink).order(:permalink).where("permalink LIKE ?", "#{test_permalink}%").map(&:permalink)
|
||||
if existing.empty?
|
||||
test_permalink
|
||||
else
|
||||
used_indices = existing.map do |p|
|
||||
p.slice!(/^#{test_permalink}/)
|
||||
p.match(/^\d+$/).to_s.to_i
|
||||
end.select{ |p| p }
|
||||
options = (1..existing.length).to_a - used_indices
|
||||
test_permalink + options.first.to_s
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def devise_mailer
|
||||
@@ -330,7 +352,7 @@ class Enterprise < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def geocode_address
|
||||
address.geocode if address.changed?
|
||||
address.geocode if address.andand.changed?
|
||||
end
|
||||
|
||||
def ensure_owner_is_manager
|
||||
@@ -343,9 +365,30 @@ class Enterprise < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def relate_to_owners_hubs
|
||||
hubs = owner.owned_enterprises.is_hub.where('enterprises.id != ?', self)
|
||||
|
||||
hubs.each do |hub|
|
||||
EnterpriseRelationship.create!(parent: self,
|
||||
child: hub,
|
||||
permissions_list: [:add_to_order_cycle,
|
||||
:manage_products,
|
||||
:edit_profile])
|
||||
end
|
||||
end
|
||||
|
||||
def shopfront_taxons
|
||||
unless preferred_shopfront_taxon_order =~ /\A((\d+,)*\d+)?\z/
|
||||
errors.add(:shopfront_category_ordering, "must contain a list of taxons.")
|
||||
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?
|
||||
end
|
||||
|
||||
def initialize_permalink
|
||||
self.permalink = Enterprise.find_available_permalink(name)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -52,6 +52,9 @@ class AbilityDecorator
|
||||
|
||||
can [:admin, :index, :create], Enterprise
|
||||
can [:read, :edit, :update, :bulk_update, :set_sells, :resend_confirmation], Enterprise do |enterprise|
|
||||
OpenFoodNetwork::Permissions.new(user).editable_enterprises.include? enterprise
|
||||
end
|
||||
can [:manage_payment_methods, :manage_shipping_methods, :manage_enterprise_fees], Enterprise do |enterprise|
|
||||
user.enterprises.include? enterprise
|
||||
end
|
||||
|
||||
@@ -128,7 +131,7 @@ class AbilityDecorator
|
||||
end
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :group_buys, :bulk_coop, :payments, :orders_and_distributors, :orders_and_fulfillment, :products_and_inventory], :report
|
||||
can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :bulk_coop, :payments, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management], :report
|
||||
end
|
||||
|
||||
|
||||
|
||||
9
app/models/spree/app_configuration_decorator.rb
Normal file
9
app/models/spree/app_configuration_decorator.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
Spree::AppConfiguration.class_eval do
|
||||
# This file decorates the existing preferences file defined by Spree.
|
||||
# It allows us to add our own global configuration variables, which
|
||||
# we can allow to be modified in the UI by adding appropriate form
|
||||
# elements to existing or new configuration pages.
|
||||
|
||||
# Tax Preferences
|
||||
preference :products_require_tax_category, :boolean, default: false
|
||||
end
|
||||
15
app/models/spree/inventory_unit_decorator.rb
Normal file
15
app/models/spree/inventory_unit_decorator.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module Spree
|
||||
InventoryUnit.class_eval do
|
||||
def self.assign_opening_inventory(order)
|
||||
return [] unless order.completed?
|
||||
|
||||
#increase inventory to meet initial requirements
|
||||
order.line_items.each do |line_item|
|
||||
# Scope variant to hub so that stock levels may be subtracted from VariantOverride.
|
||||
line_item.variant.scope_to_hub order.distributor
|
||||
|
||||
increase(order, line_item.variant, line_item.quantity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -26,7 +26,7 @@ Spree::LineItem.class_eval do
|
||||
def price_with_adjustments
|
||||
# EnterpriseFee#create_locked_adjustment applies adjustments on line items to their parent order,
|
||||
# so line_item.adjustments returns an empty array
|
||||
price + order.adjustments.where(source_id: id).sum(&:amount) / quantity
|
||||
(price + order.adjustments.where(source_id: id).sum(&:amount) / quantity).round(2)
|
||||
end
|
||||
|
||||
def single_display_amount_with_adjustments
|
||||
@@ -34,9 +34,9 @@ Spree::LineItem.class_eval do
|
||||
end
|
||||
|
||||
def amount_with_adjustments
|
||||
# EnterpriseFee#create_locked_adjustment applies adjustments on line items to their parent order,
|
||||
# so line_item.adjustments returns an empty array
|
||||
amount + order.adjustments.where(source_id: id).sum(&:amount)
|
||||
# We calculate from price_with_adjustments here rather than building our own value because
|
||||
# rounding errors can produce discrepencies of $0.01.
|
||||
price_with_adjustments * quantity
|
||||
end
|
||||
|
||||
def display_amount_with_adjustments
|
||||
|
||||
@@ -66,6 +66,12 @@ Spree::Order.class_eval do
|
||||
where("state != ?", state)
|
||||
}
|
||||
|
||||
scope :with_payment_method_name, lambda { |payment_method_name|
|
||||
joins(:payments => :payment_method).
|
||||
where('spree_payment_methods.name = ?', payment_method_name).
|
||||
select('DISTINCT spree_orders.*')
|
||||
}
|
||||
|
||||
|
||||
# -- Methods
|
||||
def products_available_from_new_distribution
|
||||
@@ -95,6 +101,7 @@ Spree::Order.class_eval do
|
||||
|
||||
# Overridden to support max_quantity
|
||||
def add_variant(variant, quantity = 1, max_quantity = nil, currency = nil)
|
||||
line_items(:reload)
|
||||
current_item = find_line_item_by_variant(variant)
|
||||
if current_item
|
||||
Bugsnag.notify(RuntimeError.new("Order populator weirdness"), {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
Spree::OrderPopulator.class_eval do
|
||||
def populate(from_hash, overwrite = false)
|
||||
@distributor, @order_cycle = distributor_and_order_cycle
|
||||
@@ -31,6 +33,7 @@ Spree::OrderPopulator.class_eval do
|
||||
def attempt_cart_add(variant_id, quantity, max_quantity = nil)
|
||||
quantity = quantity.to_i
|
||||
variant = Spree::Variant.find(variant_id)
|
||||
variant.scope_to_hub @distributor
|
||||
if quantity > 0
|
||||
if check_stock_levels(variant, quantity) &&
|
||||
check_order_cycle_provided_for(variant) &&
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
require 'open_food_network/scope_product_to_hub'
|
||||
|
||||
Spree::Product.class_eval do
|
||||
include OpenFoodNetwork::ProductScopableToHub
|
||||
|
||||
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
|
||||
# don't specify dependent => destroy on this association, it is not called. See:
|
||||
# https://github.com/rails/rails/issues/7618
|
||||
@@ -20,7 +24,8 @@ Spree::Product.class_eval do
|
||||
validates_associated :master, message: "^Price and On Hand must be valid"
|
||||
validates_presence_of :supplier
|
||||
validates :primary_taxon, presence: { message: "^Product Category can't be blank" }
|
||||
|
||||
validates :tax_category_id, presence: { message: "^Tax Category can't be blank" }, if: "Spree::Config.products_require_tax_category"
|
||||
|
||||
validates_presence_of :variant_unit, if: :has_variants?
|
||||
validates_presence_of :variant_unit_scale,
|
||||
if: -> p { %w(weight volume).include? p.variant_unit }
|
||||
@@ -128,10 +133,6 @@ Spree::Product.class_eval do
|
||||
self.product_distributions.find_by_distributor_id(distributor)
|
||||
end
|
||||
|
||||
def variants_for(order_cycle, distributor)
|
||||
self.variants.where('spree_variants.id IN (?)', order_cycle.variants_distributed_by(distributor))
|
||||
end
|
||||
|
||||
# overriding to check self.on_demand as well
|
||||
def has_stock?
|
||||
has_variants? ? variants.any?(&:in_stock?) : (on_demand || master.in_stock?)
|
||||
@@ -141,7 +142,7 @@ Spree::Product.class_eval do
|
||||
# This product has stock for a distribution if it is available on-demand
|
||||
# or if one of its variants in the distribution is in stock
|
||||
(!has_variants? && on_demand) ||
|
||||
variants_distributed_by(order_cycle, distributor).any? { |v| v.in_stock? }
|
||||
variants_distributed_by(order_cycle, distributor).any?(&:in_stock?)
|
||||
end
|
||||
|
||||
def variants_distributed_by(order_cycle, distributor)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
require 'open_food_network/enterprise_fee_calculator'
|
||||
require 'open_food_network/option_value_namer'
|
||||
|
||||
Spree::Variant.class_eval do
|
||||
include OpenFoodNetwork::VariantScopableToHub
|
||||
|
||||
has_many :exchange_variants, dependent: :destroy
|
||||
has_many :exchanges, through: :exchange_variants
|
||||
|
||||
@@ -9,12 +12,12 @@ Spree::Variant.class_eval do
|
||||
accepts_nested_attributes_for :images
|
||||
|
||||
validates_presence_of :unit_value,
|
||||
if: -> v { %w(weight volume).include? v.product.andand.variant_unit },
|
||||
unless: :is_master
|
||||
if: -> v { %w(weight volume).include? v.product.andand.variant_unit },
|
||||
unless: :is_master
|
||||
|
||||
validates_presence_of :unit_description,
|
||||
if: -> v { v.product.andand.variant_unit.present? && v.unit_value.nil? },
|
||||
unless: :is_master
|
||||
if: -> v { v.product.andand.variant_unit.present? && v.unit_value.nil? },
|
||||
unless: :is_master
|
||||
|
||||
before_validation :update_weight_from_unit_value, if: -> v { v.product.present? }
|
||||
after_save :update_units
|
||||
@@ -39,6 +42,10 @@ Spree::Variant.class_eval do
|
||||
select('DISTINCT spree_variants.*')
|
||||
}
|
||||
|
||||
scope :for_distribution, lambda { |order_cycle, distributor|
|
||||
where('spree_variants.id IN (?)', order_cycle.variants_distributed_by(distributor))
|
||||
}
|
||||
|
||||
|
||||
def price_with_fees(distributor, order_cycle)
|
||||
price + fees_for(distributor, order_cycle)
|
||||
|
||||
@@ -8,7 +8,37 @@ class VariantOverride < ActiveRecord::Base
|
||||
where(hub_id: hubs)
|
||||
}
|
||||
|
||||
def self.price_for(variant, hub)
|
||||
VariantOverride.where(variant_id: variant, hub_id: hub).first.andand.price
|
||||
def self.price_for(hub, variant)
|
||||
self.for(hub, variant).andand.price
|
||||
end
|
||||
|
||||
def self.count_on_hand_for(hub, variant)
|
||||
self.for(hub, variant).andand.count_on_hand
|
||||
end
|
||||
|
||||
def self.stock_overridden?(hub, variant)
|
||||
count_on_hand_for(hub, variant).present?
|
||||
end
|
||||
|
||||
def self.decrement_stock!(hub, variant, quantity)
|
||||
vo = self.for(hub, variant)
|
||||
|
||||
if vo.nil?
|
||||
Bugsnag.notify RuntimeError.new "Attempting to decrement stock level for a variant without a VariantOverride."
|
||||
|
||||
elsif vo.count_on_hand.blank?
|
||||
Bugsnag.notify RuntimeError.new "Attempting to decrement stock level on a VariantOverride without a count_on_hand specified."
|
||||
|
||||
else
|
||||
vo.decrement! :count_on_hand, quantity
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def self.for(hub, variant)
|
||||
VariantOverride.where(variant_id: variant, hub_id: hub).first
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -52,6 +52,16 @@
|
||||
%br/
|
||||
= f.text_field :on_hand, class: 'fullwidth'
|
||||
= f.error_message_on :on_hand
|
||||
.twelve.columns.alpha
|
||||
.six.columns.alpha
|
||||
.three.columns
|
||||
- if Spree::TaxCategory.any?
|
||||
= render 'spree/admin/products/tax_category_form', f: f
|
||||
- else
|
||||
|
||||
.three.columns.omega
|
||||
= render 'spree/admin/products/shipping_category_form', f: f
|
||||
|
||||
.twelve.columns.alpha
|
||||
= f.field_container :description do
|
||||
= f.label :product_description, t(:product_description)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/ insert_before "[data-hook='shipment_vat']"
|
||||
|
||||
%div.field.align-center{ "data-hook" => "products_require_tax_category" }
|
||||
= hidden_field_tag 'preferences[products_require_tax_category]', '0'
|
||||
= check_box_tag 'preferences[products_require_tax_category]', '1', Spree::Config[:products_require_tax_category]
|
||||
= label_tag nil, t(:products_require_tax_category)
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
%figure#logo.columns.eight
|
||||
- if current_distributor
|
||||
%h1= link_to current_distributor.name, main_app.shop_enterprise_path(current_distributor)
|
||||
%h1= link_to current_distributor.name, main_app.enterprise_shop_path(current_distributor)
|
||||
.change-location= link_to 'Change Location', root_path
|
||||
- else
|
||||
%h1= link_to "OPEN FOOD NETWORK", root_path
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :payment_method_ids, :shipping_method_ids
|
||||
attributes :producer_profile_only, :email, :long_description
|
||||
attributes :producer_profile_only, :email, :long_description, :permalink
|
||||
attributes :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order
|
||||
end
|
||||
@@ -69,10 +69,8 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
|
||||
object.promo_image(:large) if object.promo_image.exists?
|
||||
end
|
||||
|
||||
# TODO when ActiveSerializers supports URL helpers
|
||||
# Then refactor. See readme https://github.com/rails-api/active_model_serializers
|
||||
def path
|
||||
"/enterprises/#{object.to_param}/shop"
|
||||
enterprise_shop_path(object)
|
||||
end
|
||||
|
||||
# Map svg icons.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
class Api::ProductSerializer < ActiveModel::Serializer
|
||||
# TODO
|
||||
# Prices can't be cached? How?
|
||||
@@ -41,6 +43,13 @@ class Api::CachedProductSerializer < ActiveModel::Serializer
|
||||
has_one :master, serializer: Api::VariantSerializer
|
||||
|
||||
def variants
|
||||
object.variants_for(options[:current_order_cycle], options[:current_distributor]).in_stock
|
||||
# We use the in_stock? method here instead of the in_stock scope because we need to
|
||||
# look up the stock as overridden by VariantOverrides, and the scope method is not affected
|
||||
# by them.
|
||||
|
||||
object.variants.
|
||||
for_distribution(options[:current_order_cycle], options[:current_distributor]).
|
||||
each { |v| v.scope_to_hub options[:current_distributor] }.
|
||||
select(&:in_stock?)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
= link_to_with_icon('icon-edit', 'Edit Profile', main_app.edit_admin_enterprise_path(enterprise), class: 'edit')
|
||||
%br/
|
||||
|
||||
= link_to_delete_enterprise enterprise
|
||||
%br/
|
||||
- if can? :destroy, enterprise
|
||||
= link_to_delete_enterprise enterprise
|
||||
%br/
|
||||
|
||||
- if enterprise.is_primary_producer
|
||||
= link_to_with_icon 'icon-dashboard', 'Properties', main_app.admin_enterprise_producer_properties_path(enterprise_id: enterprise.id)
|
||||
= link_to_with_icon 'icon-dashboard', 'Properties', main_app.admin_enterprise_producer_properties_path(enterprise_id: enterprise)
|
||||
(#{enterprise.producer_properties.count})
|
||||
%br/
|
||||
|
||||
- if enterprise.is_distributor
|
||||
- if can? :admin, Spree::PaymentMethod
|
||||
- if can?(:admin, Spree::PaymentMethod) && can?(:manage_payment_methods, enterprise)
|
||||
= link_to_with_icon 'icon-chevron-right', 'Payment Methods', spree.admin_payment_methods_path(enterprise_id: enterprise.id)
|
||||
(#{enterprise.payment_methods.count})
|
||||
- if enterprise.payment_methods.count == 0
|
||||
%span.icon-exclamation-sign.with-tip{"data-powertip" => "This enterprise has no payment methods", style: "font-size: 16px;color: #DA5354"}
|
||||
%br/
|
||||
|
||||
- if can? :admin, Spree::ShippingMethod
|
||||
- if can?(:admin, Spree::ShippingMethod) && can?(:manage_shipping_methods, enterprise)
|
||||
= link_to_with_icon 'icon-plane', 'Shipping Methods', spree.admin_shipping_methods_path(enterprise_id: enterprise.id)
|
||||
(#{enterprise.shipping_methods.count})
|
||||
- if enterprise.shipping_methods.count == 0
|
||||
%span.icon-exclamation-sign.with-tip{"data-powertip" => "This enterprise has shipping methods", style: "font-size: 16px;color: #DA5354"}
|
||||
%br/
|
||||
|
||||
- if can? :admin, EnterpriseFee
|
||||
- if can?(:admin, EnterpriseFee) && can?(:manage_enterprise_fees, enterprise)
|
||||
= link_to_with_icon 'icon-money', 'Enterprise Fees', main_app.admin_enterprise_fees_path(enterprise_id: enterprise.id)
|
||||
(#{enterprise.enterprise_fees.count})
|
||||
- if enterprise.enterprise_fees.count == 0
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
= admin_inject_enterprise
|
||||
= admin_inject_taxons
|
||||
= admin_inject_payment_methods
|
||||
= admin_inject_shipping_methods
|
||||
= admin_inject_shipping_methods
|
||||
= admin_inject_enterprise_permissions
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
-# Not all inputs are ng inputs, they don't make the form dirty on change.
|
||||
-# Not all inputs are ng inputs, they don't make the ng-form dirty on change.
|
||||
-# ng-change is only valid for inputs, not for a form.
|
||||
-# So we use onchange and have to get the scope to access the ng controller
|
||||
-# The nav-check-callback is warning on leave if the form is dirty.
|
||||
= form_for [main_app, :admin, @enterprise], html: { name: "enterprise",
|
||||
"ng-app" => 'admin.enterprises',
|
||||
"ng-submit" => "navClear()",
|
||||
"ng-controller" => 'enterpriseCtrl',
|
||||
"nav-check-callback" => 'enterpriseNavCallback',
|
||||
'onchange' => 'angular.element(enterprise).scope().enterprise.$setDirty()',
|
||||
} do |f|
|
||||
.row
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
%a.menu_item{ href: "", id: "{{ item.name.toLowerCase().replace(' ', '_') }}",
|
||||
ng: { repeat: '(index,item) in menu.items | filter:{visible:true}',
|
||||
click: 'select(index)',
|
||||
show: 'showItem(item)',
|
||||
class: '{ selected: item.selected}',
|
||||
'class-odd' => "'odd'",
|
||||
'class-even' => "'even'" } }
|
||||
%i{ class: "{{item.icon_class}}" }
|
||||
%span {{ item.name }}
|
||||
%span {{ item.name }}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
- if can? :admin, EnterpriseFee
|
||||
= render 'sidebar_enterprise_fees', f: f
|
||||
- if can? :admin, Spree::PaymentMethod
|
||||
= render 'sidebar_payment_methods', f: f
|
||||
- if can? :admin, Spree::ShippingMethod
|
||||
= render 'sidebar_shipping_methods', f: f
|
||||
@@ -1,20 +0,0 @@
|
||||
- enterprise_fees_color = @enterprise_fees.count > 0 ? "blue" : "red"
|
||||
.sidebar_item.four.columns.alpha#enterprise_fees{ ng: { show: 'Enterprise.category != "producer_hub"' } }
|
||||
.four.columns.alpha.header{ class: "#{enterprise_fees_color}" }
|
||||
%span.four.columns.alpha.centered Enterprise Fees
|
||||
.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_color}" }
|
||||
CREATE NEW
|
||||
%span.icon-arrow-right
|
||||
@@ -1,24 +0,0 @@
|
||||
.sidebar_item.four.columns.alpha#payment_methods{ ng: { show: 'Enterprise.sells != "none"' } }
|
||||
.four.columns.alpha.header{ ng: { class: "paymentMethodsColor()" } }
|
||||
%span.four.columns.alpha.centered Payment Methods
|
||||
.four.columns.alpha.list{ ng: { class: "paymentMethodsColor()" } }
|
||||
- if @payment_methods.count > 0
|
||||
-# = hidden_field_tag "enterprise[payment_method_ids][]", []
|
||||
- @payment_methods.each do |payment_method|
|
||||
%span.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", ng: { controller: 'paymentMethodCtrl', init: "findPaymentMethodByID(#{payment_method.id})" } }
|
||||
%span.four.columns
|
||||
%span.three.columns.alpha
|
||||
%label
|
||||
= f.check_box :payment_method_ids, { multiple: true, 'ng-model' => 'PaymentMethod.selected' }, payment_method.id, nil
|
||||
= payment_method.name
|
||||
%a.one.columns.omega{ href: "#{edit_admin_payment_method_path(payment_method)}" }
|
||||
%span.icon-arrow-right
|
||||
- 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}", ng: { class: "paymentMethodsColor()" } }
|
||||
CREATE NEW
|
||||
%span.icon-arrow-right
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
.sidebar_item.four.columns.alpha#shipping_methods{ ng: { show: 'Enterprise.sells != "none"' } }
|
||||
.four.columns.alpha.header{ ng: { class: "shippingMethodsColor()" } }
|
||||
%span.four.columns.alpha.centered Shipping Methods
|
||||
.four.columns.alpha.list{ ng: { class: "shippingMethodsColor()" } }
|
||||
- if @shipping_methods.count > 0
|
||||
- @shipping_methods.each do |shipping_method|
|
||||
%span.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", ng: { controller: 'shippingMethodCtrl', init: "findShippingMethodByID(#{shipping_method.id})" } }
|
||||
%span.four.columns
|
||||
%span.three.columns.alpha
|
||||
%label
|
||||
= f.check_box :shipping_method_ids, { :multiple => true, 'ng-model' => 'ShippingMethod.selected' }, shipping_method.id, nil
|
||||
= shipping_method.name
|
||||
%a.one.columns.omega{ href: "#{edit_admin_shipping_method_path(shipping_method)}" }
|
||||
%span.one.column.alpha.icon-arrow-right
|
||||
- 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}", ng: { class: "shippingMethodsColor()" } }
|
||||
CREATE NEW
|
||||
%span.icon-arrow-right
|
||||
|
||||
@@ -66,10 +66,24 @@
|
||||
= f.radio_button :visible, false
|
||||
|
||||
= f.label :visible, "Not Visible", :value => "false"
|
||||
.row{ ng: { show: "Enterprise.sells == 'own' || Enterprise.sells == 'any'" } }
|
||||
.three.columns.alpha
|
||||
%label Link to shop front
|
||||
.with-tip{'data-powertip' => "A direct link to your shopfront on the Open Food Network."}
|
||||
%a What's this?
|
||||
.eight.columns.omega
|
||||
= main_app.shop_enterprise_url(@enterprise)
|
||||
.permalink{ ng: { controller: "permalinkCtrl" } }
|
||||
.row{ ng: { show: "Enterprise.sells == 'own' || Enterprise.sells == 'any'" } }
|
||||
.three.columns.alpha
|
||||
= f.label :permalink, 'Permalink (no spaces)'
|
||||
.with-tip{'data-powertip' => "This permalink is used to create the url to your shop: #{spree.root_url}your-shop-name/shop"}
|
||||
%a What's this?
|
||||
.six.columns
|
||||
= f.text_field :permalink, { 'ng-model' => "Enterprise.permalink", placeholder: "eg. your-shop-name", 'ng-model-options' => "{ updateOn: 'default blur', debounce: {'default': 300, 'blur': 0} }" }
|
||||
.two.columns.omega
|
||||
%img.spinner{ src: "/assets/loading.gif", width: "30px", ng: { show: "checking" } }
|
||||
%span{ ng: { class: 'availability.toLowerCase()', hide: "checking" } }
|
||||
{{ availability }}
|
||||
%i{ ng: { class: "{'icon-ok-sign': availability == 'Available', 'icon-remove-sign': availability == 'Unavailable'}" } }
|
||||
.row{ ng: { show: "Enterprise.sells == 'own' || Enterprise.sells == 'any'" } }
|
||||
.three.columns.alpha
|
||||
%label Link to shop front
|
||||
.with-tip{'data-powertip' => "A direct link to your shopfront on the Open Food Network."}
|
||||
%a What's this?
|
||||
.eight.columns.omega
|
||||
= surround spree.root_url, "/shop" do
|
||||
{{Enterprise.permalink}}
|
||||
@@ -8,7 +8,7 @@
|
||||
.exchange-product-details
|
||||
.supplier {{ product.supplier_name }}
|
||||
%label
|
||||
= check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants', 'ng-disabled' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
= check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants.length > 0', 'ng-disabled' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
{{ product.name }}
|
||||
.exchange-product-variant{'ng-repeat' => 'variant in product.variants | filter:variantSuppliedToOrderCycle'}
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
|
||||
.exchange-product-details
|
||||
%label
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants', 'ng-disabled' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'ofn-sync-distributions' => '{{ product.master_id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants.length > 0', 'ng-disabled' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'ofn-sync-distributions' => '{{ product.master_id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
{{ product.name }}
|
||||
|
||||
-# When the master variant is in the order cycle but the product has variants, we want to
|
||||
-# be able to remove the master variant, since it serves no purpose. Display a checkbox to do so.
|
||||
.exchange-product-variant{'ng-show' => 'exchange.variants[product.master_id] && product.variants'}
|
||||
.exchange-product-variant{'ng-show' => 'exchange.variants[product.master_id] && product.variants.length > 0'}
|
||||
%label
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-model' => 'exchange.variants[product.master_id]', 'ofn-sync-distributions' => '{{ product.master_id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
Obsolete master
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
- ng_controller = order_cycles_simple_view ? 'AdminSimpleEditOrderCycleCtrl' : 'AdminEditOrderCycleCtrl'
|
||||
|
||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.order_cycles', 'ng-controller' => ng_controller, 'ng-submit' => 'submit()'} do |f|
|
||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.order_cycles', 'ng-controller' => ng_controller, 'ng-submit' => 'submit($event)'} do |f|
|
||||
- if order_cycles_simple_view
|
||||
= render 'simple_form', f: f
|
||||
- else
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
- ng_controller = order_cycles_simple_view ? 'AdminSimpleCreateOrderCycleCtrl' : 'AdminCreateOrderCycleCtrl'
|
||||
|
||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.order_cycles', 'ng-controller' => ng_controller, 'ng-submit' => 'submit()'} do |f|
|
||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.order_cycles', 'ng-controller' => ng_controller, 'ng-submit' => 'submit($event)'} do |f|
|
||||
- if order_cycles_simple_view
|
||||
= render 'simple_form', f: f
|
||||
- else
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
-# Shop URL
|
||||
-# %td
|
||||
-# %td
|
||||
-# %a{:href => "#{ main_app.shop_enterprise_url(@enterprise) }", :target => "_blank"}
|
||||
-# = main_app.shop_enterprise_url(@enterprise)
|
||||
-# %a{:href => "#{ main_app.enterprise_shop_url(@enterprise) }", :target => "_blank"}
|
||||
-# = main_app.enterprise_shop_url(@enterprise)
|
||||
-# %tr
|
||||
-# %td
|
||||
-# %tr
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
%ul#supplier-distributors
|
||||
- if @distributors.delete @enterprise
|
||||
%li= link_to "Buy direct from the farm", shop_enterprise_path(@enterprise), {class: distributor_link_class(@enterprise)}
|
||||
%li= link_to "Buy direct from the farm", enterprise_shop_path(@enterprise), {class: distributor_link_class(@enterprise)}
|
||||
|
||||
- @distributors.each do |distributor|
|
||||
%li= render partial: "shared/distributor", object: distributor
|
||||
|
||||
@@ -5,7 +5,7 @@ child suppliers: :producers do
|
||||
attributes :id
|
||||
end
|
||||
node :path do |enterprise|
|
||||
main_app.shop_enterprise_path(enterprise)
|
||||
main_app.enterprise_shop_path(enterprise)
|
||||
end
|
||||
node :pickup do |hub|
|
||||
hub.shipping_methods.where(:require_ship_address => false).present?
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
-#.row
|
||||
-#.panel
|
||||
-#%p
|
||||
-#%strong= link_to "Manage my account", account_path
|
||||
-#%strong= link_to "Manage my account", account_path
|
||||
-#- if enterprise_user?
|
||||
-#%strong= link_to "Enterprise admin", admin_path
|
||||
-#%strong= link_to "Enterprise admin", admin_path
|
||||
-#- if order = last_completed_order
|
||||
-#%dl
|
||||
-#%dt Current Hub:
|
||||
@@ -13,8 +13,8 @@
|
||||
-#%dt Last hub:
|
||||
-#%dd
|
||||
-#- if order.distributor != current_distributor
|
||||
-#= link_to "#{order.distributor.name}".html_safe, "",
|
||||
-#= link_to "#{order.distributor.name}".html_safe, "",
|
||||
-#{class: distributor_link_class(order.distributor),
|
||||
-#"ng-click" => "emptyCart('#{main_app.shop_enterprise_path(order.distributor)}', $event)"}
|
||||
-#"ng-click" => "emptyCart('#{main_app.enterprise_shop_path(order.distributor)}', $event)"}
|
||||
-#- else
|
||||
-#= order.distributor.name
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
= succeed ',' do
|
||||
= link_to "<strong>#{distributor.name}</strong>".html_safe, shop_enterprise_path(distributor), {class: distributor_link_class(distributor)}
|
||||
= link_to "<strong>#{distributor.name}</strong>".html_safe, enterprise_shop_path(distributor), {class: distributor_link_class(distributor)}
|
||||
%span.secondary= distributor.city
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
%span.cart-span{"ng-controller" => "CartCtrl", "ng-class" => "{ dirty: Cart.dirty }"}
|
||||
%span.cart-span{"ng-controller" => "CartCtrl", "ng-class" => "{ dirty: Cart.dirty || Cart.empty() }"}
|
||||
%a#cart.icon{cart: true}
|
||||
%span.nav-branded
|
||||
%span.nav-branded
|
||||
%i.ofn-i_027-shopping-cart
|
||||
%span
|
||||
{{ Cart.line_items_present().length }}
|
||||
{{ Cart.total_item_count() }}
|
||||
items
|
||||
|
||||
.joyride-tip-guide{"ng-class" => "{ in: open }", "ng-show" => "open"}
|
||||
@@ -12,7 +12,7 @@
|
||||
%h5 Your shopping cart
|
||||
%ul
|
||||
%li.product-cart{"ng-repeat" => "line_item in Cart.line_items_present()",
|
||||
"ng-controller" => "LineItemCtrl"}
|
||||
"ng-controller" => "LineItemCtrl", "id" => "cart-variant-{{ line_item.variant.id }}"}
|
||||
.row
|
||||
.columns.small-7
|
||||
%small
|
||||
@@ -20,22 +20,24 @@
|
||||
%em {{ line_item.variant.unit_to_display }}
|
||||
.columns.small-3.text-right
|
||||
%small
|
||||
{{line_item.quantity}}
|
||||
%span.quantity {{ line_item.quantity }}
|
||||
%i.ofn-i_009-close
|
||||
{{ line_item.variant.price_with_fees | localizeCurrency }}
|
||||
|
||||
%span.price {{ line_item.variant.price_with_fees | localizeCurrency }}
|
||||
|
||||
.columns.small-2
|
||||
%small
|
||||
\=
|
||||
%strong
|
||||
.right {{ line_item.variant.totalPrice() | localizeCurrency }}
|
||||
%strong
|
||||
.total-price.right {{ line_item.variant.totalPrice() | localizeCurrency }}
|
||||
|
||||
%li.total-cart{"ng-show" => "Cart.line_items_present().length > 0"}
|
||||
.row
|
||||
.columns.small-6
|
||||
%em Total:
|
||||
%em Total:
|
||||
.columns.small-6.text-right
|
||||
%strong {{ Cart.total() | localizeCurrency }}
|
||||
%strong {{ Cart.total() | localizeCurrency }}
|
||||
|
||||
.text-right
|
||||
%a.button.primary.small{href: checkout_path, "ng-disabled" => "Cart.dirty"} Quick checkout
|
||||
%a.button.secondary.tiny.add_to_cart{ href: cart_path, type: :submit, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }" }
|
||||
{{ Cart.dirty ? 'Updating cart...' : (Cart.empty() ? 'Cart empty' : 'Edit your cart' ) }}
|
||||
%a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} Checkout now
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
collection @products
|
||||
attributes :id, :name, :permalink, :count_on_hand, :on_demand, :group_buy
|
||||
|
||||
node do |product|
|
||||
{
|
||||
notes: strip_tags(product.notes),
|
||||
description: strip_tags(product.description),
|
||||
price: product.master.price_with_fees(current_distributor, current_order_cycle)
|
||||
}
|
||||
end
|
||||
|
||||
child :supplier => :supplier do
|
||||
attributes :id
|
||||
end
|
||||
|
||||
child :primary_taxon => :primary_taxon do
|
||||
extends 'json/taxon'
|
||||
end
|
||||
|
||||
child :master => :master do
|
||||
attributes :id, :is_master, :count_on_hand, :name_to_display, :unit_to_display, :count_on_hand, :on_demand
|
||||
child :images => :images do
|
||||
attributes :id, :alt
|
||||
node do |img|
|
||||
{:small_url => img.attachment.url(:small, false),
|
||||
:large_url => img.attachment.url(:large, false)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
node :variants do |product|
|
||||
product.variants_for(current_order_cycle, current_distributor).in_stock.map do |v|
|
||||
{id: v.id,
|
||||
is_master: v.is_master,
|
||||
count_on_hand: v.count_on_hand,
|
||||
name_to_display: v.name_to_display,
|
||||
unit_to_display: v.unit_to_display,
|
||||
on_demand: v.on_demand,
|
||||
price: v.price_with_fees(current_distributor, current_order_cycle),
|
||||
images: v.images.map { |i| {id: i.id, alt: i.alt, small_url: i.attachment.url(:small, false)} }
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
child :taxons => :taxons do |taxon|
|
||||
attributes :id
|
||||
end
|
||||
|
||||
child :properties => :properties do |property|
|
||||
attributes :name, :presentation
|
||||
end
|
||||
@@ -12,24 +12,24 @@
|
||||
|
||||
%form{action: cart_path}
|
||||
.small-12.medium-4.large-3.columns
|
||||
%input.button.primary.right.add_to_cart{type: :submit, value: "Your shopping cart",
|
||||
"ng-disabled" => "Cart.dirty"}
|
||||
%i.ofn-i_011-spinner.cart-spinner{"ng-show" => "Cart.dirty"}
|
||||
%input.small.button.primary.right.add_to_cart{type: :submit, value: "{{ Cart.dirty ? 'Updating cart...' : (Cart.empty() ? 'Cart empty' : 'Edit your cart' ) }}", "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }" }
|
||||
|
||||
%div.pad-top{bindonce: true}
|
||||
%product.animate-repeat{"ng-controller" => "ProductNodeCtrl",
|
||||
"ng-repeat" => "product in filteredProducts = (Products.products | products:query | taxons:activeTaxons) track by product.id "}
|
||||
"ng-repeat" => "product in filteredProducts = (Products.products | products:query | taxons:activeTaxons) track by product.id ", "id" => "product-{{ product.id }}"}
|
||||
|
||||
= render partial: "shop/products/summary"
|
||||
%shop-variant{variant: 'product.master', "bo-if" => "!product.hasVariants"}
|
||||
%shop-variant{variant: 'variant', "ng-repeat" => "variant in product.variants track by variant.id"}
|
||||
%shop-variant{variant: 'product.master', "bo-if" => "!product.hasVariants", "id" => "variant-{{ product.master.id }}"}
|
||||
%shop-variant{variant: 'variant', "ng-repeat" => "variant in product.variants track by variant.id", "id" => "variant-{{ variant.id }}"}
|
||||
|
||||
%product{"ng-show" => "Products.loading"}
|
||||
.row.summary
|
||||
.small-12.columns.text-center
|
||||
Loading products
|
||||
Loading products...
|
||||
.row
|
||||
.small-12.columns.text-center
|
||||
%img.spinner{ src: "/assets/loading.gif" }
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
|
||||
%div{"ng-show" => "filteredProducts.length == 0 && !Products.loading"}
|
||||
.row.summary
|
||||
@@ -41,6 +41,6 @@
|
||||
.row
|
||||
.small-12.columns
|
||||
%form{action: cart_path}
|
||||
%input.button.primary.right.add_to_cart{type: :submit, value: "Your shopping cart",
|
||||
"ng-disabled" => "Cart.dirty"}
|
||||
%i.ofn-i_011-spinner.cart-spinner{"ng-show" => "Cart.dirty"}
|
||||
%input.small.button.primary.right.add_to_cart{type: :submit, value: "{{ Cart.dirty ? 'Updating cart...' : (Cart.empty() ? 'Cart empty' : 'Edit your cart' ) }}", "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }" }
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
.product-thumb
|
||||
%a{"ng-click" => "triggerProductModal()"}
|
||||
%i.ofn-i_057-expand
|
||||
%img{"bo-src" => "product.primaryImageOrMissing", "ng-click" => "triggerProductModal()"}
|
||||
|
||||
.row.summary
|
||||
.small-9.medium-10.large-11.columns.summary-header
|
||||
.small-10.medium-10.large-11.columns.summary-header
|
||||
%h3
|
||||
%a{"ng-click" => "triggerProductModal()"}
|
||||
{{ product.name }}
|
||||
|
||||
%em from
|
||||
%span
|
||||
%enterprise-modal
|
||||
%i.ofn-i_036-producers
|
||||
{{ enterprise.name }}
|
||||
|
||||
.small-3.medium-2.large-1.columns.text-center
|
||||
%i.ofn-i_057-expand
|
||||
%small
|
||||
%em from
|
||||
%span
|
||||
%enterprise-modal
|
||||
%i.ofn-i_036-producers
|
||||
{{ enterprise.name }}
|
||||
.small-2.medium-2.large-1.columns.text-center
|
||||
.taxon-flag
|
||||
%render-svg{path: "{{product.primary_taxon.icon}}"}
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
%span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }}
|
||||
%span{ :class => 'two columns omega' } {{column.name }}
|
||||
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'loading' }
|
||||
%img.spinner{ src: "/assets/loading.gif" }
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
%h1 LOADING ORDERS
|
||||
%div{ :class => "sixteen columns alpha", 'ng-show' => '!loading && filteredLineItems.length == 0'}
|
||||
%h1#no_results No orders found.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
= f.field_container :shipping_categories do
|
||||
= f.label :shipping_category_id, t(:shipping_category)
|
||||
= f.collection_select(:shipping_category_id, Spree::ShippingCategory.all, :id, :name, {:include_blank => true}, {:class => 'select2 fullwidth'})
|
||||
= f.error_message_on :shipping_category_id
|
||||
@@ -0,0 +1,6 @@
|
||||
= f.field_container :tax_category_id do
|
||||
= f.label :tax_category_id, t(:tax_category)
|
||||
%span.required *
|
||||
%br
|
||||
= f.collection_select(:tax_category_id, Spree::TaxCategory.all, :id, :name, {:include_blank => Spree::TaxCategory.count > 1}, {:class => "select2 fullwidth"})
|
||||
= f.error_message_on :tax_category_id
|
||||
@@ -2,7 +2,7 @@
|
||||
{{ api_error_msg }}
|
||||
|
||||
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'loading' }
|
||||
%img.spinner{ src: "/assets/loading.gif" }
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
%h1 LOADING PRODUCTS
|
||||
|
||||
%div.sixteen.columns.alpha{ 'ng-show' => '!loading && filteredProducts.length == 0 && query.length==0' }
|
||||
|
||||
9
app/views/spree/admin/reports/_date_range_form.html.haml
Normal file
9
app/views/spree/admin/reports/_date_range_form.html.haml
Normal file
@@ -0,0 +1,9 @@
|
||||
.row.date-range-filter
|
||||
= label_tag nil, t(:date_range)
|
||||
%br
|
||||
= label_tag nil, t(:start), :class => 'inline'
|
||||
= f.text_field :completed_at_gt, :class => 'datetimepicker datepicker-from'
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= f.text_field :completed_at_lt, :class => 'datetimepicker datepicker-to'
|
||||
= label_tag nil, t(:end), :class => 'inline'
|
||||
@@ -0,0 +1,4 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_types.each do |report_type|
|
||||
%li
|
||||
= link_to report_type[0], "#{order_cycle_management_admin_reports_url}?report_type=#{report_type[1]}"
|
||||
@@ -1,26 +1,19 @@
|
||||
= form_for @search, :url => spree.bulk_coop_admin_reports_path do |f|
|
||||
= label_tag nil, t(:date_range)
|
||||
%br
|
||||
.date-range-filter
|
||||
%div{"class" => "left sub-field"}
|
||||
= f.text_field :completed_at_gt, :class => 'datepicker'
|
||||
%br
|
||||
= label_tag nil, t(:start), :class => 'sub'
|
||||
%div{"class" => "right sub-field"}
|
||||
= f.text_field :completed_at_lt, :class => 'datepicker'
|
||||
%br
|
||||
= label_tag nil, t(:stop)
|
||||
%br
|
||||
= label_tag nil, "Distributor: "
|
||||
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, :include_blank => 'All')
|
||||
%br
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
.row
|
||||
.four.columns.alpha
|
||||
= label_tag nil, "Distributor: "
|
||||
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => 'All'}, {:class => "select2 fullwidth"})
|
||||
= label_tag nil, "Report Type: "
|
||||
%br
|
||||
= select_tag(:report_type, options_for_select([['Bulk Co-op - Totals by Supplier',:bulk_coop_supplier_report],['Bulk Co-op - Allocation',:bulk_coop_allocation],['Bulk Co-op - Packing Sheets',:bulk_coop_packing_sheets],['Bulk Co-op - Customer Payments',:bulk_coop_customer_payments]], @report_type))
|
||||
%br
|
||||
%br
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, "Download as csv"
|
||||
%br
|
||||
%br
|
||||
= button t(:search)
|
||||
%br
|
||||
%br
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
= form_tag spree.customers_admin_reports_url do |f|
|
||||
%br
|
||||
= label_tag nil, "Distributor: "
|
||||
= select_tag(:distributor_id,
|
||||
options_from_collection_for_select(@distributors, :id, :name, params[:distributor_id]),
|
||||
:include_blank => true)
|
||||
.row
|
||||
.four.columns.alpha
|
||||
= label_tag nil, "Distributor: "
|
||||
= select_tag(:distributor_id,
|
||||
options_from_collection_for_select(@distributors, :id, :name, params[:distributor_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
%br
|
||||
= label_tag nil, "Supplier: "
|
||||
= select_tag(:supplier_id,
|
||||
options_from_collection_for_select(@suppliers, :id, :name, params[:supplier_id]),
|
||||
:include_blank => true)
|
||||
.four.columns
|
||||
= label_tag nil, "Supplier: "
|
||||
= select_tag(:supplier_id,
|
||||
options_from_collection_for_select(@suppliers, :id, :name, params[:supplier_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
%br
|
||||
= label_tag nil, "Order Cycle: "
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@order_cycles), params[:order_cycle_id]),
|
||||
include_blank: true)
|
||||
.six.columns
|
||||
= label_tag nil, "Order Cycle: "
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@order_cycles), params[:order_cycle_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
%br
|
||||
= label_tag nil, "Report Type: "
|
||||
= select_tag(:report_type, options_for_select(@report_types, @report_type))
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
= form_tag spree.order_cycle_management_admin_reports_url do |f|
|
||||
%br
|
||||
= label_tag nil, "Order Cycle: "
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@order_cycles), params[:order_cycle_id]),
|
||||
include_blank: true)
|
||||
%br
|
||||
%br
|
||||
= label_tag nil, "Payment Methods (hold Ctrl to select multiple payment methods)"
|
||||
%br
|
||||
|
||||
= select_tag(:payment_method_name,
|
||||
options_for_select(report_payment_method_options(@orders), params[:payment_method_name]),
|
||||
multiple: true, include_blank: true, size: 10)
|
||||
%br
|
||||
%br
|
||||
= label_tag nil, "Shipping Method: "
|
||||
= select_tag(:shipping_method_name,
|
||||
options_for_select(report_shipping_method_options(@orders), params[:shipping_method_name]),
|
||||
include_blank: true)
|
||||
%br
|
||||
%br
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, "Download as csv"
|
||||
%br
|
||||
%br
|
||||
= button t(:search)
|
||||
|
||||
%br
|
||||
%br
|
||||
%table#listing_order_payment_methods.index
|
||||
%thead
|
||||
%tr{'data-hook' => "orders_header"}
|
||||
- @report.header.each do |heading|
|
||||
%th=heading
|
||||
%tbody
|
||||
- @report.table.each do |row|
|
||||
%tr
|
||||
- row.each do |column|
|
||||
%td= column
|
||||
- if @report.table.empty?
|
||||
%tr
|
||||
%td{:colspan => "2"}= t(:none)
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
= form_for @search, :url => spree.orders_and_distributors_admin_reports_path do |s|
|
||||
= label_tag nil, t(:date_range)
|
||||
%br
|
||||
.date-range-filter
|
||||
%div{"class" => "left sub-field"}
|
||||
= s.text_field :completed_at_gt, :class => 'datepicker'
|
||||
%br
|
||||
= label_tag nil, t(:start), :class => 'sub'
|
||||
%div{"class" => "right sub-field"}
|
||||
= s.text_field :completed_at_lt, :class => 'datepicker'
|
||||
%br
|
||||
= label_tag nil, t(:stop)
|
||||
= form_for @search, :url => spree.orders_and_distributors_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, "Download as csv"
|
||||
%br
|
||||
= button t(:search)
|
||||
|
||||
%br
|
||||
%br
|
||||
%table#listing_orders.index
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user