mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-15 19:06:50 +00:00
Compare commits
258 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab9bc7b1dc | ||
|
|
cf4ccc268a | ||
|
|
7af17242f9 | ||
|
|
eb5e411a8e | ||
|
|
bdeca54377 | ||
|
|
20d59cf5a5 | ||
|
|
8b241f058b | ||
|
|
cb28843af1 | ||
|
|
d684a88697 | ||
|
|
d0f66a6053 | ||
|
|
d2fbf9f14d | ||
|
|
8d3f25bb39 | ||
|
|
abaaf05631 | ||
|
|
dd8c769ea9 | ||
|
|
864c9ec1da | ||
|
|
b0cfa6a17c | ||
|
|
51258b242c | ||
|
|
1a44e74a9d | ||
|
|
efbf2c7ffa | ||
|
|
6365434a94 | ||
|
|
d9f90be38a | ||
|
|
008b43b1fc | ||
|
|
5609354136 | ||
|
|
d9e8ce2f0e | ||
|
|
cce65aa462 | ||
|
|
44511b8b61 | ||
|
|
eb413ccc84 | ||
|
|
6cd6b751c8 | ||
|
|
af95181245 | ||
|
|
36fa4896ed | ||
|
|
7c723c04b6 | ||
|
|
c85d5b86eb | ||
|
|
1a97df1d21 | ||
|
|
a5716cf2c2 | ||
|
|
b4e990a081 | ||
|
|
eccd97fc28 | ||
|
|
c4d4d10873 | ||
|
|
1e5e009735 | ||
|
|
ea96759306 | ||
|
|
d967905b83 | ||
|
|
f698408d40 | ||
|
|
75b0b290ae | ||
|
|
21b18a8cc5 | ||
|
|
91bf588bcc | ||
|
|
a8de4dc039 | ||
|
|
c7cf9695bc | ||
|
|
b9a0579397 | ||
|
|
de6abc3464 | ||
|
|
881313edf9 | ||
|
|
381bfd383b | ||
|
|
266d6ef834 | ||
|
|
1e18f773f5 | ||
|
|
41792395aa | ||
|
|
98ff895f5f | ||
|
|
c3c1573f54 | ||
|
|
a0af22350d | ||
|
|
e3b660abb9 | ||
|
|
9a86e41942 | ||
|
|
b5ce056d06 | ||
|
|
574a215525 | ||
|
|
2cdab7af25 | ||
|
|
235bb009e8 | ||
|
|
dfb855bd14 | ||
|
|
9395f6c808 | ||
|
|
53fa71d1f3 | ||
|
|
61c08997a1 | ||
|
|
dd61034908 | ||
|
|
ec22f4c09f | ||
|
|
54894fb222 | ||
|
|
11f59c9f59 | ||
|
|
27a730ef6c | ||
|
|
10e5d09416 | ||
|
|
3b4d73760b | ||
|
|
89199ef30a | ||
|
|
67c77cea81 | ||
|
|
cc7d6cde1d | ||
|
|
0b636c1d89 | ||
|
|
2b9fef6aec | ||
|
|
3aa30af199 | ||
|
|
0212351d32 | ||
|
|
29653a5595 | ||
|
|
e6368af757 | ||
|
|
2c80be7e9e | ||
|
|
d194e74eda | ||
|
|
3f61a5412c | ||
|
|
0f3723a923 | ||
|
|
bbca674937 | ||
|
|
623882a2a1 | ||
|
|
371f966f63 | ||
|
|
be55f461d0 | ||
|
|
e6591be55c | ||
|
|
5b6bff1691 | ||
|
|
db2e5e7558 | ||
|
|
4867f45ee1 | ||
|
|
47b08269d6 | ||
|
|
76f234ee4d | ||
|
|
163035dcad | ||
|
|
503bd8f5dd | ||
|
|
6e800341c3 | ||
|
|
b097a62c7a | ||
|
|
cfa281478a | ||
|
|
f64684dc48 | ||
|
|
397697d17c | ||
|
|
c940a34ec9 | ||
|
|
fc63d8719c | ||
|
|
7ba366e2a6 | ||
|
|
b26c46d7db | ||
|
|
72a568ffad | ||
|
|
3ea7ff766a | ||
|
|
3d491d7b5e | ||
|
|
1710c8726e | ||
|
|
2a8ba0bf42 | ||
|
|
3279003fd3 | ||
|
|
f2a35e219e | ||
|
|
39c5f8febe | ||
|
|
87b1ab9a1a | ||
|
|
85b8adb1aa | ||
|
|
e8818c5191 | ||
|
|
c91699a11e | ||
|
|
8d6c8791bb | ||
|
|
31054c7bf4 | ||
|
|
5563d23beb | ||
|
|
8de6f983a2 | ||
|
|
53594b3a0f | ||
|
|
f8619092bd | ||
|
|
2c2352cd4e | ||
|
|
12bfb9301a | ||
|
|
ba0d4c2111 | ||
|
|
4eee86a240 | ||
|
|
587e4ae86d | ||
|
|
60c246f104 | ||
|
|
87842ecaf5 | ||
|
|
2ba632456f | ||
|
|
3beff77164 | ||
|
|
69fd3f0b60 | ||
|
|
ff4bd449a2 | ||
|
|
379b702b9b | ||
|
|
fa4741eb65 | ||
|
|
1f7aec0c1d | ||
|
|
122cf6c065 | ||
|
|
9daf7e3955 | ||
|
|
a3df4bf026 | ||
|
|
fdde55f631 | ||
|
|
f8153c07b1 | ||
|
|
eade689070 | ||
|
|
a522242e7a | ||
|
|
e05d64a0b4 | ||
|
|
985887334f | ||
|
|
3aa06ee1e4 | ||
|
|
3ab961a7e2 | ||
|
|
60b7a571c5 | ||
|
|
f8ca24c5cd | ||
|
|
f58219eb3d | ||
|
|
4554c0555d | ||
|
|
176db78e64 | ||
|
|
98063dae60 | ||
|
|
c01d45e3af | ||
|
|
d5c2abdd7e | ||
|
|
a7b723af93 | ||
|
|
6a29b830c2 | ||
|
|
8e83c6679a | ||
|
|
a0f0b3c93b | ||
|
|
ecd7b16ef5 | ||
|
|
718a5911a3 | ||
|
|
bbac5aa803 | ||
|
|
346a4e71d0 | ||
|
|
f83ceae5d1 | ||
|
|
08afcac1e5 | ||
|
|
9496987da6 | ||
|
|
224864a8d8 | ||
|
|
b9248d3e2c | ||
|
|
903bd21577 | ||
|
|
87686848bc | ||
|
|
32a898b6a2 | ||
|
|
636ed2ad0d | ||
|
|
1d61e91afd | ||
|
|
6b5a1255f8 | ||
|
|
12dc0b93aa | ||
|
|
5503760ce3 | ||
|
|
9fa5a9e766 | ||
|
|
a62f48441d | ||
|
|
5c09ebf138 | ||
|
|
ee5ab22501 | ||
|
|
ad1f837c44 | ||
|
|
dcb24cf06c | ||
|
|
b73619d168 | ||
|
|
dde1a27d3a | ||
|
|
57e838898f | ||
|
|
773a5480e9 | ||
|
|
0fdf313424 | ||
|
|
46aee6f77c | ||
|
|
ca558a4ecc | ||
|
|
edcef02017 | ||
|
|
211e9c33a7 | ||
|
|
2293623d2c | ||
|
|
9e51b19f98 | ||
|
|
90ba1d2198 | ||
|
|
78877f591b | ||
|
|
f292be8c92 | ||
|
|
755adf4287 | ||
|
|
9547f91f46 | ||
|
|
30601b9203 | ||
|
|
504a053693 | ||
|
|
148333467f | ||
|
|
242fb49276 | ||
|
|
37dbd376e9 | ||
|
|
b641de6ec9 | ||
|
|
313843d798 | ||
|
|
1b51ea0e3a | ||
|
|
f2e3d298fa | ||
|
|
e19aaf6be8 | ||
|
|
28b2dd40dd | ||
|
|
c9bbe80738 | ||
|
|
0f7b880409 | ||
|
|
78a8f8c1bb | ||
|
|
b1b1aa5b1e | ||
|
|
a7c2a73fa8 | ||
|
|
fce7714994 | ||
|
|
7ca9670073 | ||
|
|
22f6ece83f | ||
|
|
a7bb04b890 | ||
|
|
4c586d1b7e | ||
|
|
7ea143d19a | ||
|
|
25189d190b | ||
|
|
91b35d068c | ||
|
|
8d9f8beff3 | ||
|
|
c0a7d22a50 | ||
|
|
fafbfe8735 | ||
|
|
6fddb491db | ||
|
|
5ea3733c8a | ||
|
|
7ac888ae00 | ||
|
|
ed4d78bca8 | ||
|
|
d99a54accf | ||
|
|
fd363ff6c2 | ||
|
|
fcd9653a79 | ||
|
|
8e42f29bde | ||
|
|
a25bf32156 | ||
|
|
7a5c56cbca | ||
|
|
cbae7dcc8e | ||
|
|
d93a8b6428 | ||
|
|
7a48d7fe22 | ||
|
|
87b092fdf7 | ||
|
|
0d9a0919e5 | ||
|
|
c1aa2f9b33 | ||
|
|
650e35c13e | ||
|
|
71de15b3e4 | ||
|
|
4dc0701213 | ||
|
|
3e5dfda324 | ||
|
|
13cbbcef40 | ||
|
|
949808e839 | ||
|
|
02a276b9c9 | ||
|
|
9f1a773a58 | ||
|
|
0e510998a4 | ||
|
|
3b9657eb17 | ||
|
|
9956b967f0 | ||
|
|
9310bc902a | ||
|
|
9798b05a24 | ||
|
|
586753015b |
2
.mailmap
Normal file
2
.mailmap
Normal file
@@ -0,0 +1,2 @@
|
||||
Rob Harrington <oeoeaio@gmail.com>
|
||||
Laura Summers <summerscope@gmail.com>
|
||||
5
Gemfile
5
Gemfile
@@ -1,12 +1,13 @@
|
||||
source 'https://rubygems.org'
|
||||
ruby "1.9.3"
|
||||
|
||||
gem 'rails', '3.2.19'
|
||||
gem 'rails', '3.2.21'
|
||||
gem 'rails-i18n', '~> 3.0.0'
|
||||
gem 'i18n', '~> 0.6.11'
|
||||
|
||||
gem 'pg'
|
||||
gem 'spree', :github => 'openfoodfoundation/spree', :branch => '1-3-stable'
|
||||
gem 'spree_i18n', :github => 'spree/spree_i18n'
|
||||
gem 'spree_i18n', :github => 'spree/spree_i18n', :branch => '1-3-stable'
|
||||
gem 'spree_auth_devise', :github => 'spree/spree_auth_devise', :branch => '1-3-stable'
|
||||
|
||||
# Waiting on merge of PR #117
|
||||
|
||||
93
Gemfile.lock
93
Gemfile.lock
@@ -86,11 +86,13 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/spree_i18n.git
|
||||
revision: a96bee02340e008e60549295a4f09e047fd2e628
|
||||
revision: 752eb67204e9c5a4e22b62591a8fd55fe2285e43
|
||||
branch: 1-3-stable
|
||||
specs:
|
||||
spree_i18n (1.0.0)
|
||||
i18n (~> 0.5)
|
||||
spree (~> 1.1)
|
||||
rails-i18n
|
||||
spree_core (>= 1.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/willrjmarshall/foundation_rails_helper.git
|
||||
@@ -105,12 +107,12 @@ GIT
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.19)
|
||||
actionpack (= 3.2.19)
|
||||
actionmailer (3.2.21)
|
||||
actionpack (= 3.2.21)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (3.2.19)
|
||||
activemodel (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
actionpack (3.2.21)
|
||||
activemodel (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
@@ -121,29 +123,23 @@ GEM
|
||||
active_link_to (1.0.0)
|
||||
active_model_serializers (0.8.1)
|
||||
activemodel (>= 3.0)
|
||||
active_utils (2.2.3)
|
||||
activesupport (>= 2.3.11)
|
||||
i18n
|
||||
activemerchant (1.44.1)
|
||||
active_utils (~> 2.2.0)
|
||||
activemerchant (1.46.0)
|
||||
activesupport (>= 3.2.14, < 5.0.0)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
json (~> 1.7)
|
||||
nokogiri (~> 1.4)
|
||||
offsite_payments (~> 2.0.0)
|
||||
activemodel (3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
activemodel (3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.19)
|
||||
activemodel (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
activerecord (3.2.21)
|
||||
activemodel (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.19)
|
||||
activemodel (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
activesupport (3.2.19)
|
||||
activeresource (3.2.21)
|
||||
activemodel (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
activesupport (3.2.21)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
multi_json (~> 1.0)
|
||||
acts_as_list (0.1.4)
|
||||
@@ -185,7 +181,7 @@ GEM
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.4)
|
||||
cocaine (0.5.5)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
@@ -195,7 +191,7 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.3.3)
|
||||
colorize (0.7.3)
|
||||
colorize (0.7.5)
|
||||
columnize (0.3.6)
|
||||
comfortable_mexican_sofa (1.6.24)
|
||||
active_link_to (~> 1.0.0)
|
||||
@@ -308,7 +304,7 @@ GEM
|
||||
jquery-rails (2.2.2)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.1)
|
||||
json (1.8.2)
|
||||
json_spec (1.1.1)
|
||||
multi_json (~> 1.0)
|
||||
rspec (~> 2.0)
|
||||
@@ -329,9 +325,9 @@ GEM
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
method_source (0.8.1)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.6.1)
|
||||
mini_portile (0.6.2)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
money (5.1.1)
|
||||
@@ -342,16 +338,8 @@ GEM
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.6.8)
|
||||
newrelic_rpm (3.6.7.152)
|
||||
nokogiri (1.6.4.1)
|
||||
nokogiri (1.6.6.2)
|
||||
mini_portile (~> 0.6.0)
|
||||
offsite_payments (2.0.1)
|
||||
active_utils (~> 2.2.0)
|
||||
activesupport (>= 3.2.14, < 5.0.0)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (~> 0.5)
|
||||
json (~> 1.7)
|
||||
money (< 7.0.0)
|
||||
nokogiri (~> 1.4)
|
||||
oj (2.1.2)
|
||||
orm_adapter (0.5.0)
|
||||
paperclip (3.5.4)
|
||||
@@ -390,28 +378,28 @@ GEM
|
||||
rack
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.19)
|
||||
actionmailer (= 3.2.19)
|
||||
actionpack (= 3.2.19)
|
||||
activerecord (= 3.2.19)
|
||||
activeresource (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
rails (3.2.21)
|
||||
actionmailer (= 3.2.21)
|
||||
actionpack (= 3.2.21)
|
||||
activerecord (= 3.2.21)
|
||||
activeresource (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.19)
|
||||
railties (= 3.2.21)
|
||||
rails-i18n (3.0.1)
|
||||
i18n (~> 0.5)
|
||||
rails (>= 3.0.0, < 4.0.0)
|
||||
railties (3.2.19)
|
||||
actionpack (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
railties (3.2.21)
|
||||
actionpack (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
raindrops (0.9.0)
|
||||
rake (10.3.2)
|
||||
rake (10.4.2)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -493,7 +481,7 @@ GEM
|
||||
sprockets (>= 2.0.0)
|
||||
turn (0.8.3)
|
||||
ansi
|
||||
tzinfo (0.3.42)
|
||||
tzinfo (0.3.43)
|
||||
uglifier (1.2.4)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (>= 1.0.2)
|
||||
@@ -521,7 +509,7 @@ GEM
|
||||
xml-simple (1.1.4)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
zeus (0.13.3)
|
||||
zeus (0.15.4)
|
||||
method_source (>= 0.6.7)
|
||||
|
||||
PLATFORMS
|
||||
@@ -561,6 +549,7 @@ DEPENDENCIES
|
||||
guard-rspec
|
||||
guard-zeus
|
||||
haml
|
||||
i18n (~> 0.6.11)
|
||||
immigrant
|
||||
jquery-rails
|
||||
json_spec
|
||||
@@ -575,7 +564,7 @@ DEPENDENCIES
|
||||
rabl
|
||||
rack-livereload
|
||||
rack-ssl
|
||||
rails (= 3.2.19)
|
||||
rails (= 3.2.21)
|
||||
rails-i18n (~> 3.0.0)
|
||||
representative_view
|
||||
roadie-rails (~> 1.0.3)
|
||||
|
||||
@@ -53,14 +53,10 @@ Configure the site:
|
||||
cp config/application.yml.example config/application.yml
|
||||
edit config/application.yml
|
||||
|
||||
Create the development and test databases, using the settings specified in `config/database.yml`:
|
||||
Create the development and test databases, using the settings specified in `config/database.yml`, and populate them with a schema and seed data:
|
||||
|
||||
rake db:setup
|
||||
|
||||
Then load the schema and some seed data with the following command:
|
||||
|
||||
rake db:schema:load db:seed
|
||||
|
||||
Load some default data for your environment:
|
||||
|
||||
rake openfoodnetwork:dev:load_sample_data
|
||||
@@ -99,4 +95,4 @@ usage instructions.
|
||||
|
||||
## Licence
|
||||
|
||||
Copyright (c) 2012 - 2013 Open Food Foundation, released under the AGPL licence.
|
||||
Copyright (c) 2012 - 2015 Open Food Foundation, released under the AGPL licence.
|
||||
|
||||
BIN
app/assets/images/noimage/group.png
Normal file
BIN
app/assets/images/noimage/group.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
app/assets/images/open-food-network-beta-black.png
Normal file
BIN
app/assets/images/open-food-network-beta-black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -19,6 +19,7 @@
|
||||
//= require ../shared/ng-infinite-scroll.min.js
|
||||
//= require ./admin
|
||||
//= require ./enterprises/enterprises
|
||||
//= require ./enterprise_groups/enterprise_groups
|
||||
//= require ./payment_methods/payment_methods
|
||||
//= require ./products/products
|
||||
//= require ./shipping_methods/shipping_methods
|
||||
|
||||
@@ -17,7 +17,7 @@ angular.module("ofn.admin").controller "AdminVariantOverridesCtrl", ($scope, $ti
|
||||
|
||||
|
||||
$scope.fetchProducts = ->
|
||||
url = "/api/products/distributable?page=::page::;per_page=100"
|
||||
url = "/api/products/overridable?page=::page::;per_page=100"
|
||||
PagedFetcher.fetch url, (data) => $scope.addProducts data.products
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
angular.module("admin.enterprise_groups")
|
||||
.controller "enterpriseGroupCtrl", ($scope, SideMenu) ->
|
||||
$scope.menu = SideMenu
|
||||
@@ -0,0 +1,15 @@
|
||||
angular.module("admin.enterprise_groups")
|
||||
.controller "sideMenuCtrl", ($scope, SideMenu) ->
|
||||
$scope.menu = SideMenu
|
||||
$scope.select = SideMenu.select
|
||||
|
||||
$scope.menu.setItems [
|
||||
{ name: 'Primary Details', icon_class: "icon-user" }
|
||||
{ name: 'Users', icon_class: "icon-user" }
|
||||
{ name: 'About', icon_class: "icon-pencil" }
|
||||
{ name: 'Images', icon_class: "icon-picture" }
|
||||
{ name: 'Contact', icon_class: "icon-phone" }
|
||||
{ name: 'Web', icon_class: "icon-globe" }
|
||||
]
|
||||
|
||||
$scope.select(0)
|
||||
@@ -0,0 +1 @@
|
||||
angular.module("admin.enterprise_groups", ["admin.side_menu", "admin.users"])
|
||||
@@ -1,12 +1,12 @@
|
||||
angular.module("admin.enterprises")
|
||||
.controller "enterpriseCtrl", ($scope, NavigationCheck, Enterprise, EnterprisePaymentMethods, EnterpriseShippingMethods, SideMenu) ->
|
||||
$scope.Enterprise = Enterprise.enterprise
|
||||
console.log Enterprise
|
||||
$scope.PaymentMethods = EnterprisePaymentMethods.paymentMethods
|
||||
$scope.ShippingMethods = EnterpriseShippingMethods.shippingMethods
|
||||
$scope.navClear = NavigationCheck.clear
|
||||
$scope.pristineEmail = $scope.Enterprise.email
|
||||
$scope.menu = SideMenu
|
||||
$scope.newManager = { id: '', email: 'Add a manager...' }
|
||||
|
||||
# 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,
|
||||
@@ -17,3 +17,18 @@ angular.module("admin.enterprises")
|
||||
|
||||
# Register the NavigationCheck callback
|
||||
NavigationCheck.register(enterpriseNavCallback)
|
||||
|
||||
$scope.removeManager = (manager) ->
|
||||
if manager.id?
|
||||
for i, user of $scope.Enterprise.users when user.id == manager.id
|
||||
$scope.Enterprise.users.splice i, 1
|
||||
|
||||
$scope.addManager = (manager) ->
|
||||
if manager.id? and manager.email?
|
||||
manager =
|
||||
id: manager.id
|
||||
email: manager.email
|
||||
if (user for user in $scope.Enterprise.users when user.id == manager.id).length == 0
|
||||
$scope.Enterprise.users.push manager
|
||||
else
|
||||
alert "#{manager.email} is already a manager!"
|
||||
|
||||
@@ -5,7 +5,8 @@ angular.module("admin.enterprises")
|
||||
$scope.select = SideMenu.select
|
||||
|
||||
$scope.menu.setItems [
|
||||
{ name: 'Primary Details', icon_class: "icon-user" }
|
||||
{ name: 'Primary Details', icon_class: "icon-home" }
|
||||
{ name: 'Users', icon_class: "icon-user" }
|
||||
{ name: 'Address', icon_class: "icon-map-marker" }
|
||||
{ name: 'Contact', icon_class: "icon-phone" }
|
||||
{ name: 'Social', icon_class: "icon-twitter" }
|
||||
@@ -38,4 +39,3 @@ angular.module("admin.enterprises")
|
||||
|
||||
$scope.showShopPreferences = ->
|
||||
$scope.Enterprise.sells != "none"
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
angular.module('admin.order_cycles', ['ngResource'])
|
||||
.controller('AdminCreateOrderCycleCtrl', ['$scope', 'OrderCycle', 'Enterprise', 'EnterpriseFee', ($scope, OrderCycle, Enterprise, EnterpriseFee) ->
|
||||
.controller('AdminCreateOrderCycleCtrl', ['$scope', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'ocInstance', ($scope, OrderCycle, Enterprise, EnterpriseFee, ocInstance) ->
|
||||
$scope.enterprises = Enterprise.index()
|
||||
$scope.supplied_products = Enterprise.supplied_products
|
||||
$scope.enterprise_fees = EnterpriseFee.index()
|
||||
|
||||
$scope.order_cycle = OrderCycle.order_cycle
|
||||
$scope.order_cycle.coordinator_id = ocInstance.coordinator_id
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded
|
||||
|
||||
@@ -5,6 +5,7 @@ angular.module("ofn.admin").factory 'EnterpriseRelationships', ($http, enterpris
|
||||
'add_to_order_cycle'
|
||||
'manage_products'
|
||||
'edit_profile'
|
||||
'create_variant_overrides'
|
||||
]
|
||||
|
||||
constructor: ->
|
||||
@@ -28,3 +29,4 @@ angular.module("ofn.admin").factory 'EnterpriseRelationships', ($http, enterpris
|
||||
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"
|
||||
when "create_variant_overrides" then "to override variant details"
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
angular.module("admin.users").directive "ofnUserAutocomplete", ($http) ->
|
||||
angular.module("admin.users").directive "userSelect", ->
|
||||
scope:
|
||||
user: '&userSelect'
|
||||
model: '=ngModel'
|
||||
link: (scope,element,attrs) ->
|
||||
setTimeout ->
|
||||
element.select2
|
||||
multiple: false
|
||||
initSelection: (element, callback) ->
|
||||
callback { id: element.val(), email: attrs.email }
|
||||
callback {id: scope.user().id, email: scope.user().email}
|
||||
ajax:
|
||||
url: Spree.routes.user_search
|
||||
url: '/admin/search/known_users'
|
||||
datatype: 'json'
|
||||
data:(term, page) ->
|
||||
{ q: term }
|
||||
@@ -15,4 +18,6 @@ angular.module("admin.users").directive "ofnUserAutocomplete", ($http) ->
|
||||
formatResult: (user) ->
|
||||
user.email
|
||||
formatSelection: (user) ->
|
||||
user.email
|
||||
scope.$apply ->
|
||||
scope.model = user if scope.model?
|
||||
user.email
|
||||
@@ -11,9 +11,9 @@ $ ->
|
||||
|
||||
# Temporarily handles the cart showing stuff
|
||||
$(document).ready ->
|
||||
$('#cart_adjustments').hide()
|
||||
$('.cart_adjustment').hide()
|
||||
|
||||
$('th.cart-adjustment-header a').click ->
|
||||
$('#cart_adjustments').toggle()
|
||||
$('td.cart-adjustments a').click ->
|
||||
$('.cart_adjustment').toggle()
|
||||
$(this).html('Item Handling Fees (included in item totals)')
|
||||
false
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Darkswarm.controller "GroupEnterpriseNodeCtrl", ($scope, CurrentHub) ->
|
||||
|
||||
$scope.active = false
|
||||
|
||||
$scope.toggle = ->
|
||||
$scope.active = !$scope.active
|
||||
|
||||
$scope.open = ->
|
||||
$scope.active
|
||||
|
||||
$scope.current = ->
|
||||
$scope.hub.id is CurrentHub.hub.id
|
||||
@@ -0,0 +1,13 @@
|
||||
Darkswarm.controller "GroupEnterprisesCtrl", ($scope, Enterprises, Search, FilterSelectorsService) ->
|
||||
$scope.Enterprises = Enterprises
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.query = Search.search()
|
||||
$scope.activeTaxons = []
|
||||
$scope.show_profiles = false
|
||||
$scope.filtersActive = false
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
Search.search query
|
||||
@@ -1,3 +1,3 @@
|
||||
Darkswarm.controller "MapCtrl", ($scope, MapConfiguration, OfnMap)->
|
||||
$scope.OfnMap = OfnMap
|
||||
$scope.map = MapConfiguration.options
|
||||
$scope.map = angular.copy MapConfiguration.options
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
Darkswarm.controller "TabsCtrl", ($scope, $rootScope, $location, OrderCycle) ->
|
||||
Darkswarm.controller "TabsCtrl", ($scope, $rootScope, $location) ->
|
||||
# Return active if supplied path matches url hash path.
|
||||
$scope.active = (path)->
|
||||
$location.hash() == path
|
||||
|
||||
# Toggle tab selected status by setting the url hash path.
|
||||
# Select tab by setting the url hash path.
|
||||
$scope.select = (path)->
|
||||
$location.hash path
|
||||
|
||||
# Toggle tab selected status by setting the url hash path.
|
||||
$scope.toggle = (path)->
|
||||
if $scope.active(path)
|
||||
$location.hash ""
|
||||
else
|
||||
|
||||
@@ -8,6 +8,6 @@ Darkswarm.directive "ofnEmptiesCart", (CurrentHub, Cart, Navigation, storage) ->
|
||||
if CurrentHub.hub?.id and CurrentHub.hub.id isnt scope.hub.id and !Cart.empty()
|
||||
elm.bind 'click', (ev)->
|
||||
ev.preventDefault()
|
||||
if confirm "Are you sure? This will change your selected Hub and remove any items in you shopping cart."
|
||||
if confirm "Are you sure? This will change your selected Hub and remove any items in your shopping cart."
|
||||
storage.clearAll() # One day this will have to be moar GRANULAR
|
||||
Navigation.go scope.hub.path
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Darkswarm.directive "linkToService", ->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
scope: {
|
||||
ref: '='
|
||||
service: '='
|
||||
}
|
||||
template: '<a href="{{ref | ext_url: service}}" target="_blank" ng-show="ref"></a>'
|
||||
@@ -0,0 +1,7 @@
|
||||
Darkswarm.filter "ext_url", ->
|
||||
urlPattern = /^https?:\/\//
|
||||
(url, prefix) ->
|
||||
if !url || url.match(urlPattern)
|
||||
url
|
||||
else
|
||||
prefix + url
|
||||
@@ -1,9 +1,10 @@
|
||||
Darkswarm.filter 'shipping', ()->
|
||||
Darkswarm.filter 'shipping', ()->
|
||||
(objects, options)->
|
||||
objects ||= []
|
||||
options ?= null
|
||||
|
||||
if options.pickup and !options.delivery
|
||||
|
||||
if !options
|
||||
objects
|
||||
else if options.pickup and !options.delivery
|
||||
objects.filter (obj)->
|
||||
obj.pickup
|
||||
else if options.delivery and !options.pickup
|
||||
|
||||
@@ -8,6 +8,7 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
|
||||
for line_item in @line_items
|
||||
line_item.variant.line_item = line_item
|
||||
Variants.register line_item.variant
|
||||
line_item.variant.extended_name = @extendedVariantName(line_item.variant)
|
||||
|
||||
orderChanged: =>
|
||||
@unsaved()
|
||||
@@ -63,8 +64,17 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
|
||||
@create_line_item(variant) unless exists
|
||||
|
||||
create_line_item: (variant)->
|
||||
variant.extended_name = @extendedVariantName(variant)
|
||||
variant.line_item =
|
||||
variant: variant
|
||||
quantity: null
|
||||
max_quantity: null
|
||||
@line_items.push variant.line_item
|
||||
@line_items.push variant.line_item
|
||||
|
||||
extendedVariantName: (variant) =>
|
||||
if variant.product_name == variant.name_to_display
|
||||
variant.product_name
|
||||
else
|
||||
name = "#{variant.product_name} - #{variant.name_to_display}"
|
||||
name += " (#{variant.options_text})" if variant.options_text
|
||||
name
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
font-size: 120%
|
||||
cursor: pointer
|
||||
text-transform: uppercase
|
||||
&.odd
|
||||
&:nth-child(odd)
|
||||
background-color: #ebf3fb
|
||||
&.even
|
||||
&:nth-child(even)
|
||||
background-color: #ffffff
|
||||
&:hover
|
||||
background-color: #eaf0f5
|
||||
|
||||
3
app/assets/stylesheets/admin/variant_overrides.css.sass
Normal file
3
app/assets/stylesheets/admin/variant_overrides.css.sass
Normal file
@@ -0,0 +1,3 @@
|
||||
.variant-override-unit
|
||||
float: right
|
||||
font-style: italic
|
||||
@@ -75,7 +75,7 @@ ordercycle
|
||||
|
||||
|
||||
button.graph-button
|
||||
z-index: 9999999
|
||||
// z-index: 9999999
|
||||
border: 1px solid transparent
|
||||
padding: 0
|
||||
margin: 0
|
||||
|
||||
@@ -23,4 +23,5 @@ $disabled-v-dark: #808080
|
||||
$med-grey: #666
|
||||
$med-drk-grey: #444
|
||||
$dark-grey: #333
|
||||
$light-grey: #ddd
|
||||
$black: #000
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
@import branding
|
||||
@import animations
|
||||
|
||||
.order-summary
|
||||
background-color: #e1f0f5
|
||||
padding: 1em
|
||||
width: 100%
|
||||
|
||||
checkout
|
||||
display: block
|
||||
|
||||
@@ -55,7 +60,6 @@ checkout
|
||||
text-align: left
|
||||
|
||||
// Logic to swap out up / down accordion icons
|
||||
|
||||
//Foundation overrides
|
||||
dd > a
|
||||
@include csstrans
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import branding
|
||||
@import mixins
|
||||
|
||||
// Search page
|
||||
#groups
|
||||
background-color: $clr-brick-light
|
||||
background-image: url("/assets/groups.svg")
|
||||
@@ -8,35 +9,97 @@
|
||||
background-repeat: no-repeat
|
||||
padding-bottom: 20px
|
||||
|
||||
a > .group-name
|
||||
&:hover, &:focus, &:active
|
||||
text-decoration: underline
|
||||
|
||||
.groups-icons
|
||||
text-align: right
|
||||
a
|
||||
font-size: 1.5em
|
||||
|
||||
.groups-header
|
||||
border: 2px solid $clr-brick-light-bright
|
||||
@include border-radius-mixed(0.5em, 0.5em, 0, 0)
|
||||
margin: -1rem 0 1rem
|
||||
padding: 1rem 0.9375rem
|
||||
@media screen and (min-width: 640px)
|
||||
border: 0 none
|
||||
@include border-radius(0)
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
.group
|
||||
padding-bottom: 40px
|
||||
hr
|
||||
border-bottom: 10px solid white
|
||||
outline: 0
|
||||
border-top: 0
|
||||
margin: 0
|
||||
padding-bottom: 0.5em
|
||||
.row div
|
||||
font-size: 110%
|
||||
.row a
|
||||
vertical-align: middle
|
||||
.ofn-i_035-groups
|
||||
font-size: 120%
|
||||
vertical-align: middle
|
||||
|
||||
// Individual Page
|
||||
#group-page
|
||||
.group-logo, .group-header
|
||||
text-align: center
|
||||
.group-logo
|
||||
padding-bottom: 1em
|
||||
max-height: 200px
|
||||
.group-name
|
||||
border-bottom: 1px solid #ccc
|
||||
@media screen and (min-width: 768px)
|
||||
.group-logo, .group-header
|
||||
text-align: left
|
||||
.group-logo
|
||||
max-height: 120px
|
||||
float: left
|
||||
padding-right: 1em
|
||||
background-color: white
|
||||
|
||||
.group-hero
|
||||
position: relative
|
||||
padding: 0
|
||||
border: 10px solid white
|
||||
background: white
|
||||
// Tabs
|
||||
.tabs dd a // Mobile first
|
||||
padding: 0.25rem 0.45rem 0rem
|
||||
font-size: 0.75rem
|
||||
border: none
|
||||
margin-bottom: -2px
|
||||
margin-right: 2px
|
||||
text-transform: capitalize
|
||||
@include avenir
|
||||
@include border-radius(1em 0.25em 0 0)
|
||||
@include gradient($disabled-light, $disabled-bright)
|
||||
@media screen and (min-width: 768px)
|
||||
.tabs dd a
|
||||
padding: 0.5rem 1rem 0.25em
|
||||
font-size: 0.875rem
|
||||
@include border-radius(1.5em 0.25em 0 0)
|
||||
@media screen and (min-width: 1024px)
|
||||
.tabs dd a
|
||||
padding: 0.75rem 1.5rem 0.5em
|
||||
font-size: 1rem
|
||||
@include border-radius(2em 0.25em 0 0)
|
||||
.tabs dd.active a
|
||||
@include gradient(white, white)
|
||||
margin-bottom: -1px
|
||||
border-top: 1px solid $light-grey
|
||||
border-left: 1px solid $light-grey
|
||||
border-right: 1px solid $light-grey
|
||||
border-bottom: 0
|
||||
.tabs-content
|
||||
border-top: 1px solid $light-grey
|
||||
border-left: 1px solid $light-grey
|
||||
border-right: 1px solid $light-grey
|
||||
border-bottom: 1px solid $light-grey
|
||||
padding: 1.5em
|
||||
|
||||
h3.group-name
|
||||
margin-top: 0.5em
|
||||
margin-bottom: 0.15em
|
||||
|
||||
img.group-logo
|
||||
max-width: 220px
|
||||
max-height: 86px
|
||||
float: right
|
||||
padding-top: 10px
|
||||
|
||||
|
||||
img.group-hero-img
|
||||
background-color: black
|
||||
width: 100%
|
||||
height: inherit
|
||||
max-height: 260px
|
||||
min-height: 120px
|
||||
overflow: hidden
|
||||
// Producers tab
|
||||
.producers
|
||||
background-image: none
|
||||
.active_table .active_table_node a.is_distributor, .active_table .active_table_node a.is_distributor i.ofn-i_059-producer
|
||||
color: $clr-turquoise
|
||||
// Hubs tab
|
||||
.hubs
|
||||
background-image: none
|
||||
padding-top: 0
|
||||
padding-bottom: 0
|
||||
|
||||
@@ -120,5 +120,21 @@
|
||||
background-repeat: no-repeat
|
||||
background-size: 100% auto
|
||||
|
||||
|
||||
@mixin gradient($gradient-clr1, $gradient-clr2)
|
||||
background: $gradient-clr1
|
||||
// Old browsers
|
||||
background: -moz-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
|
||||
// FF3.6+
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, $gradient-clr1), color-stop(100%, $gradient-clr2))
|
||||
// Chrome,Safari4+
|
||||
background: -webkit-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
|
||||
// Chrome10+,Safari5.1+
|
||||
background: -o-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
|
||||
// Opera 11.10+
|
||||
background: -ms-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
|
||||
// IE10+
|
||||
background: linear-gradient(to bottom, $gradient-clr1 0%, $gradient-clr2 100%)
|
||||
// W3C
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$gradient-clr1', endColorstr='$gradient-clr2',GradientType=0 )
|
||||
// IE6-8
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
color: $disabled-dark
|
||||
border-bottom: 1px solid $disabled-dark
|
||||
border-bottom: 1px solid $light-grey
|
||||
margin-top: 0.75rem
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
@@ -67,8 +67,8 @@
|
||||
margin-bottom: 0.5rem
|
||||
overflow-y: scroll
|
||||
overflow-x: hidden
|
||||
border-bottom: 1px solid #999
|
||||
@include box-shadow(0 2px 2px -2px #999)
|
||||
border-bottom: 1px solid $light-grey
|
||||
@include box-shadow(0 2px 2px -2px $light-grey)
|
||||
|
||||
.enterprise-logo, img
|
||||
float: left
|
||||
|
||||
@@ -36,10 +36,22 @@
|
||||
li.product-cart
|
||||
border-top: 1px solid #424242
|
||||
|
||||
// Shopping cart
|
||||
#cart-detail
|
||||
.cart-item-delete
|
||||
a.delete
|
||||
font-size: 1.125em
|
||||
|
||||
.item-thumb-image
|
||||
display: none
|
||||
@media screen and (min-width: 640px)
|
||||
display: inline-block
|
||||
float: left
|
||||
padding-right: 0.5em
|
||||
width: 36px
|
||||
height: 36px
|
||||
|
||||
|
||||
|
||||
#edit-cart
|
||||
button, .button
|
||||
|
||||
@@ -16,27 +16,45 @@
|
||||
@font-face
|
||||
font-family: 'AvenirMed'
|
||||
src: url("/AvenirLTStd-Medium.otf") format("opentype")
|
||||
|
||||
body
|
||||
font-family: 'Open Sans', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif
|
||||
|
||||
$font-helvetica: "Helvetica Neue", "HelveticaNeue", "Helvetica", Helvetica, Arial, sans-serif
|
||||
|
||||
a
|
||||
color: $clr-brick
|
||||
&:hover
|
||||
&:hover, &:focus, &:active
|
||||
text-decoration: none
|
||||
color: $clr-brick-bright
|
||||
|
||||
.text-big
|
||||
font-size: 1.5rem
|
||||
font-weight: 300
|
||||
|
||||
small, .small
|
||||
font-size: 0.75rem
|
||||
|
||||
.text-small
|
||||
font-size: 0.875rem
|
||||
margin-bottom: 0.5rem
|
||||
font-family: $font-helvetica
|
||||
&, & *
|
||||
font-size: 0.875rem
|
||||
|
||||
.text-normal
|
||||
font-weight: 400
|
||||
font-family: $font-helvetica
|
||||
|
||||
.text-skinny
|
||||
font-weight: 300
|
||||
font-family: $font-helvetica
|
||||
|
||||
.word-wrap
|
||||
word-wrap: break-word
|
||||
|
||||
.pre-wrap
|
||||
white-space: pre-wrap
|
||||
|
||||
.pre-line
|
||||
white-space: pre-line
|
||||
|
||||
.light
|
||||
color: #999
|
||||
@@ -81,6 +99,9 @@ ul.check-list
|
||||
.light-grey
|
||||
color: #666666
|
||||
|
||||
.pad
|
||||
padding: 1em
|
||||
|
||||
.pad-top
|
||||
padding-top: 1em
|
||||
|
||||
|
||||
@@ -56,6 +56,23 @@ table.social
|
||||
table.order-summary
|
||||
border-collapse: separate
|
||||
border-spacing: 0px 10px
|
||||
tbody tr td
|
||||
padding-left: 5px
|
||||
padding-right: 5px
|
||||
thead tr th
|
||||
background-color: #f2f2f2
|
||||
border-bottom: 1px solid black
|
||||
padding-left: 5px
|
||||
padding-right: 5px
|
||||
h4
|
||||
margin-top: 15px
|
||||
tfoot
|
||||
tr:first-child td
|
||||
border-top: 1px solid black
|
||||
padding-top: 5px
|
||||
tr td
|
||||
padding-left: 5px
|
||||
padding-right: 5px
|
||||
|
||||
.social .soc-btn
|
||||
padding: 3px 7px
|
||||
@@ -245,6 +262,10 @@ ul
|
||||
tr td
|
||||
padding: 15px
|
||||
|
||||
.pad
|
||||
tr td
|
||||
padding: 15px
|
||||
|
||||
.column-wrap
|
||||
padding: 0!important
|
||||
margin: 0 auto
|
||||
|
||||
@@ -59,6 +59,7 @@ module Admin
|
||||
|
||||
def load_data
|
||||
@calculators = EnterpriseFee.calculators.sort_by(&:name)
|
||||
@tax_categories = Spree::TaxCategory.order('is_default DESC, name ASC')
|
||||
end
|
||||
|
||||
def collection
|
||||
|
||||
@@ -1,22 +1,50 @@
|
||||
module Admin
|
||||
class EnterpriseGroupsController < ResourceController
|
||||
before_filter :load_data, except: :index
|
||||
before_filter :load_object_data, only: [:new, :edit, :create, :update]
|
||||
|
||||
def index
|
||||
@enterprise_groups = @enterprise_groups.managed_by(spree_current_user)
|
||||
end
|
||||
|
||||
def move_up
|
||||
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
|
||||
@enterprise_group.move_higher
|
||||
EnterpriseGroup.with_isolation_level_serializable do
|
||||
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
|
||||
@enterprise_group.move_higher
|
||||
end
|
||||
redirect_to main_app.admin_enterprise_groups_path
|
||||
end
|
||||
|
||||
def move_down
|
||||
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
|
||||
@enterprise_group.move_lower
|
||||
EnterpriseGroup.with_isolation_level_serializable do
|
||||
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
|
||||
@enterprise_group.move_lower
|
||||
end
|
||||
redirect_to main_app.admin_enterprise_groups_path
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def build_resource_with_address
|
||||
enterprise_group = build_resource_without_address
|
||||
enterprise_group.address = Spree::Address.new
|
||||
enterprise_group.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id])
|
||||
enterprise_group
|
||||
end
|
||||
alias_method_chain :build_resource, :address
|
||||
|
||||
private
|
||||
|
||||
def load_data
|
||||
@countries = Spree::Country.order(:name)
|
||||
@enterprises = Enterprise.activated
|
||||
end
|
||||
|
||||
def load_object_data
|
||||
@owner_email = @enterprise_group.andand.owner.andand.email || ""
|
||||
end
|
||||
|
||||
|
||||
def collection
|
||||
EnterpriseGroup.by_position
|
||||
end
|
||||
|
||||
@@ -7,10 +7,14 @@ module Admin
|
||||
before_filter :check_can_change_sells, only: :update
|
||||
before_filter :check_can_change_bulk_sells, only: :bulk_update
|
||||
before_filter :override_owner, only: :create
|
||||
before_filter :override_sells, only: :create
|
||||
before_filter :check_can_change_owner, only: :update
|
||||
before_filter :check_can_change_bulk_owner, only: :bulk_update
|
||||
before_filter :check_can_change_managers, only: :update
|
||||
|
||||
|
||||
helper 'spree/products'
|
||||
include ActionView::Helpers::TextHelper
|
||||
include OrderCyclesHelper
|
||||
|
||||
def for_order_cycle
|
||||
@@ -44,10 +48,20 @@ module Admin
|
||||
|
||||
def bulk_update
|
||||
@enterprise_set = EnterpriseSet.new(collection, params[:enterprise_set])
|
||||
touched_enterprises = @enterprise_set.collection.select(&:changed?)
|
||||
if @enterprise_set.save
|
||||
flash[:success] = 'Enterprises updated successfully'
|
||||
flash[:success] = "Enterprises updated successfully"
|
||||
|
||||
# 18-3-2015: It seems that the form for this action sometimes loads bogus values for
|
||||
# the 'sells' field, and submitting that form results in a bunch of enterprises with
|
||||
# values that have mysteriously changed. This statement is here to help debug that
|
||||
# issue, and should be removed (along with its display in index.html.haml) when the
|
||||
# issue has been resolved.
|
||||
flash[:action] = "Updated #{pluralize(touched_enterprises.count, 'enterprise')}: #{touched_enterprises.map(&:name).join(', ')}"
|
||||
|
||||
redirect_to main_app.admin_enterprises_path
|
||||
else
|
||||
@enterprise_set.collection.select! { |e| touched_enterprises.include? e }
|
||||
flash[:error] = 'Update failed'
|
||||
render :index
|
||||
end
|
||||
@@ -116,6 +130,13 @@ module Admin
|
||||
params[:enterprise][:owner_id] = spree_current_user.id unless spree_current_user.admin?
|
||||
end
|
||||
|
||||
def override_sells
|
||||
unless spree_current_user.admin?
|
||||
has_hub = spree_current_user.enterprises.is_hub.any?
|
||||
params[:enterprise][:sells] = has_hub ? 'any' : 'none'
|
||||
end
|
||||
end
|
||||
|
||||
def check_can_change_owner
|
||||
unless ( spree_current_user == @enterprise.owner ) || spree_current_user.admin?
|
||||
params[:enterprise].delete :owner_id
|
||||
@@ -130,6 +151,12 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def check_can_change_managers
|
||||
unless ( spree_current_user == @enterprise.owner ) || spree_current_user.admin?
|
||||
params[:enterprise].delete :user_ids
|
||||
end
|
||||
end
|
||||
|
||||
# Overriding method on Spree's resource controller
|
||||
def location_after_save
|
||||
if params[:enterprise].key? :producer_properties_attributes
|
||||
|
||||
@@ -6,6 +6,7 @@ module Admin
|
||||
include OrderCyclesHelper
|
||||
|
||||
before_filter :load_order_cycle_set, :only => :index
|
||||
before_filter :require_coordinator, only: :new
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
@@ -85,5 +86,23 @@ module Admin
|
||||
def load_order_cycle_set
|
||||
@order_cycle_set = OrderCycleSet.new :collection => collection
|
||||
end
|
||||
|
||||
def require_coordinator
|
||||
if params[:coordinator_id] && @order_cycle.coordinator = order_cycle_coordinating_enterprises.find_by_id(params[:coordinator_id])
|
||||
return
|
||||
end
|
||||
|
||||
available_coordinators = order_cycle_coordinating_enterprises.select(&:confirmed?)
|
||||
case available_coordinators.count
|
||||
when 0
|
||||
flash[:error] = "None of your enterprises have permission to coordinate an order cycle"
|
||||
redirect_to main_app.admin_order_cycles_path
|
||||
when 1
|
||||
@order_cycle.coordinator = available_coordinators.first
|
||||
else
|
||||
flash[:error] = "You don't have permission to create an order cycle coordinated by that enterprise" if params[:coordinator_id]
|
||||
render :set_coordinator
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,22 +2,19 @@ require 'open_food_network/spree_api_key_loader'
|
||||
|
||||
module Admin
|
||||
class VariantOverridesController < ResourceController
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
include OrderCyclesHelper
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
|
||||
before_filter :load_spree_api_key, only: :index
|
||||
before_filter :load_data
|
||||
|
||||
def index
|
||||
@hubs = order_cycle_hub_enterprises(without_validation: true)
|
||||
@producers = order_cycle_producer_enterprises
|
||||
@hub_permissions = OpenFoodNetwork::Permissions.new(spree_current_user).
|
||||
order_cycle_enterprises_per_hub
|
||||
@variant_overrides = VariantOverride.for_hubs(@hubs)
|
||||
end
|
||||
|
||||
|
||||
def bulk_update
|
||||
collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }]
|
||||
vo_set = VariantOverrideSet.new collection_attributes: collection_hash
|
||||
vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash
|
||||
|
||||
# Ensure we're authorised to update all variant overrides
|
||||
vo_set.collection.each { |vo| authorize! :update, vo }
|
||||
@@ -35,6 +32,20 @@ module Admin
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def load_data
|
||||
@hubs = order_cycle_hub_enterprises
|
||||
|
||||
# Used in JS to look up the name of the producer of each product
|
||||
@producers = OpenFoodNetwork::Permissions.new(spree_current_user).
|
||||
variant_override_producers
|
||||
|
||||
@hub_permissions = OpenFoodNetwork::Permissions.new(spree_current_user).
|
||||
variant_override_enterprises_per_hub
|
||||
@variant_overrides = VariantOverride.for_hubs(@hubs)
|
||||
end
|
||||
|
||||
def collection
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,9 @@ class EnterprisesController < BaseController
|
||||
layout "darkswarm"
|
||||
helper Spree::ProductsHelper
|
||||
include OrderCyclesHelper
|
||||
|
||||
# These prepended filters are in the reverse order of execution
|
||||
prepend_before_filter :load_active_distributors, :set_order_cycles, :require_distributor_chosen, :reset_order, only: :shop
|
||||
before_filter :clean_permalink, only: :check_permalink
|
||||
|
||||
respond_to :js, only: :permalink_checker
|
||||
@@ -56,26 +59,6 @@ class EnterprisesController < BaseController
|
||||
end
|
||||
end
|
||||
|
||||
def shop
|
||||
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
|
||||
order.empty!
|
||||
order.set_order_cycle! nil
|
||||
end
|
||||
|
||||
order.distributor = distributor
|
||||
|
||||
order_cycle_options = OrderCycle.active.with_distributor(distributor)
|
||||
order.order_cycle = order_cycle_options.first if order_cycle_options.count == 1
|
||||
order.save!
|
||||
|
||||
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]
|
||||
|
||||
@@ -92,4 +75,20 @@ class EnterprisesController < BaseController
|
||||
def clean_permalink
|
||||
params[:permalink] = params[:permalink].parameterize
|
||||
end
|
||||
|
||||
def reset_order
|
||||
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
|
||||
order.empty!
|
||||
order.set_order_cycle! nil
|
||||
end
|
||||
|
||||
order.distributor = distributor
|
||||
|
||||
order_cycle_options = OrderCycle.active.with_distributor(distributor)
|
||||
order.order_cycle = order_cycle_options.first if order_cycle_options.count == 1
|
||||
order.save!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,4 +5,8 @@ class GroupsController < BaseController
|
||||
def index
|
||||
@groups = EnterpriseGroup.on_front_page.by_position
|
||||
end
|
||||
|
||||
def show
|
||||
@group = EnterpriseGroup.find params[:id]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ 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'
|
||||
require 'open_food_network/sales_tax_report'
|
||||
|
||||
Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
@@ -27,7 +28,8 @@ Spree::Admin::ReportsController.class_eval do
|
||||
["Addresses", :addresses]
|
||||
],
|
||||
order_cycle_management: [
|
||||
["Payment Methods Report", :payment_methods_report]
|
||||
["Payment Methods Report", :payment_methods],
|
||||
["Delivery Report", :delivery]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -58,7 +60,6 @@ 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
|
||||
|
||||
@@ -68,14 +69,13 @@ Spree::Admin::ReportsController.class_eval do
|
||||
@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
|
||||
params[:q] = {} unless params[:q]
|
||||
params[:q] ||= {}
|
||||
|
||||
if params[:q][:completed_at_gt].blank?
|
||||
params[:q][:completed_at_gt] = Time.zone.now.beginning_of_month
|
||||
@@ -102,9 +102,39 @@ Spree::Admin::ReportsController.class_eval do
|
||||
send_data csv_string, :filename => "orders_and_distributors_#{timestamp}.csv"
|
||||
end
|
||||
end
|
||||
|
||||
def sales_tax
|
||||
params[:q] ||= {}
|
||||
|
||||
if params[:q][:completed_at_gt].blank?
|
||||
params[:q][:completed_at_gt] = Time.zone.now.beginning_of_month
|
||||
else
|
||||
params[:q][:completed_at_gt] = Time.zone.parse(params[:q][:completed_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
|
||||
end
|
||||
|
||||
if params[:q] && !params[:q][:completed_at_lt].blank?
|
||||
params[:q][:completed_at_lt] = Time.zone.parse(params[:q][:completed_at_lt]).end_of_day rescue ""
|
||||
end
|
||||
params[:q][:meta_sort] ||= "completed_at.desc"
|
||||
|
||||
@search = Spree::Order.complete.not_state(:canceled).managed_by(spree_current_user).search(params[:q])
|
||||
orders = @search.result
|
||||
@distributors = Enterprise.is_distributor.managed_by(spree_current_user)
|
||||
|
||||
@report = OpenFoodNetwork::SalesTaxReport.new orders
|
||||
unless params[:csv]
|
||||
render :html => @report
|
||||
else
|
||||
csv_string = CSV.generate do |csv|
|
||||
csv << @report.header
|
||||
@report.table.each { |row| csv << row }
|
||||
end
|
||||
send_data csv_string, :filename => "sales_tax.csv"
|
||||
end
|
||||
end
|
||||
|
||||
def bulk_coop
|
||||
params[:q] = {} unless params[:q]
|
||||
params[:q] ||= {}
|
||||
|
||||
if params[:q][:completed_at_gt].blank?
|
||||
params[:q][:completed_at_gt] = Time.zone.now.beginning_of_month
|
||||
@@ -257,7 +287,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
end
|
||||
|
||||
def payments
|
||||
params[:q] = {} unless params[:q]
|
||||
params[:q] ||= {}
|
||||
|
||||
if params[:q][:completed_at_gt].blank?
|
||||
params[:q][:completed_at_gt] = Time.zone.now.beginning_of_month
|
||||
@@ -641,7 +671,8 @@ Spree::Admin::ReportsController.class_eval do
|
||||
: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" },
|
||||
:order_cycle_management => {:name => "Order Cycle Management", :description => ''}
|
||||
:order_cycle_management => {:name => "Order Cycle Management", :description => ''},
|
||||
:sales_tax => { :name => "Sales Tax", :description => "Sales Tax For Orders" }
|
||||
}
|
||||
# Return only reports the user is authorized to view.
|
||||
reports.select { |action| can? action, :report }
|
||||
|
||||
18
app/controllers/spree/admin/search_controller_decorator.rb
Normal file
18
app/controllers/spree/admin/search_controller_decorator.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
Spree::Admin::SearchController.class_eval do
|
||||
def known_users
|
||||
if exact_match = Spree.user_class.find_by_email(params[:q])
|
||||
@users = [exact_match]
|
||||
else
|
||||
@users = spree_current_user.known_users.ransack({
|
||||
:m => 'or',
|
||||
:email_start => params[:q],
|
||||
:ship_address_firstname_start => params[:q],
|
||||
:ship_address_lastname_start => params[:q],
|
||||
:bill_address_firstname_start => params[:q],
|
||||
:bill_address_lastname_start => params[:q]
|
||||
}).result.limit(10)
|
||||
end
|
||||
render :users
|
||||
|
||||
end
|
||||
end
|
||||
@@ -17,21 +17,25 @@ Spree::Api::ProductsController.class_eval do
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
|
||||
render text: { products: ActiveModel::ArraySerializer.new(@products, each_serializer: Spree::Api::ProductSerializer), pages: @products.num_pages }.to_json
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def distributable
|
||||
producers = OpenFoodNetwork::Permissions.new(current_api_user).
|
||||
order_cycle_enterprises.is_primary_producer.by_name
|
||||
|
||||
@products = Spree::Product.scoped.
|
||||
merge(product_scope).
|
||||
where(supplier_id: producers).
|
||||
by_producer.by_name.
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
@products = paged_products_for_producers producers
|
||||
|
||||
render text: { products: ActiveModel::ArraySerializer.new(@products, each_serializer: Spree::Api::ProductSerializer), pages: @products.num_pages }.to_json
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def overridable
|
||||
producers = OpenFoodNetwork::Permissions.new(current_api_user).
|
||||
variant_override_producers.by_name
|
||||
|
||||
@products = paged_products_for_producers producers
|
||||
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def soft_delete
|
||||
@@ -60,4 +64,17 @@ Spree::Api::ProductsController.class_eval do
|
||||
scope.includes(:master)
|
||||
end
|
||||
|
||||
def paged_products_for_producers(producers)
|
||||
Spree::Product.scoped.
|
||||
merge(product_scope).
|
||||
where(supplier_id: producers).
|
||||
by_producer.by_name.
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
end
|
||||
|
||||
def render_paged_products(products)
|
||||
render text: { products: ActiveModel::ArraySerializer.new(products, each_serializer: Spree::Api::ProductSerializer), pages: products.num_pages }.to_json
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -62,6 +62,10 @@ module Admin
|
||||
admin_inject_json_ams_array "ofn.admin", "variantOverrides", @variant_overrides, Api::Admin::VariantOverrideSerializer
|
||||
end
|
||||
|
||||
def admin_inject_order_cycle_instance
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: 'admin.order_cycles', name: 'ocInstance', json: "{coordinator_id: '#{@order_cycle.coordinator.id}'}"}
|
||||
end
|
||||
|
||||
def admin_inject_spree_api_key
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: 'ofn.admin', name: 'SpreeApiKey', json: "'#{@spree_api_key.to_s}'"}
|
||||
end
|
||||
|
||||
@@ -1,2 +1,23 @@
|
||||
module GroupsHelper
|
||||
|
||||
def link_to_service(baseurl, name, html_options = {})
|
||||
return if name.blank?
|
||||
html_options = html_options.merge target: '_blank'
|
||||
link_to ext_url(baseurl, name), html_options do
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def ext_url(prefix, url)
|
||||
if url =~ /^https?:\/\//i
|
||||
url
|
||||
else
|
||||
prefix + url
|
||||
end
|
||||
end
|
||||
|
||||
def strip_url(url)
|
||||
url.andand.sub(/^https?:\/\//i, '')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -3,6 +3,10 @@ module OrderCyclesHelper
|
||||
@current_order_cycle ||= current_order(false).andand.order_cycle
|
||||
end
|
||||
|
||||
def order_cycle_permitted_in(enterprises)
|
||||
enterprises.merge(order_cycle_permitted_enterprises)
|
||||
end
|
||||
|
||||
def order_cycle_permitted_enterprises
|
||||
OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises
|
||||
end
|
||||
@@ -11,33 +15,24 @@ module OrderCyclesHelper
|
||||
order_cycle_permitted_enterprises.is_primary_producer.by_name
|
||||
end
|
||||
|
||||
def order_cycle_producer_enterprise_options
|
||||
validated_enterprise_options order_cycle_producer_enterprises, confirmed: true
|
||||
end
|
||||
|
||||
def order_cycle_coordinating_enterprises
|
||||
order_cycle_permitted_enterprises.is_distributor.by_name
|
||||
end
|
||||
|
||||
def order_cycle_hub_enterprises(options={})
|
||||
enterprises = order_cycle_permitted_enterprises.is_distributor.by_name
|
||||
def order_cycle_coordinating_enterprise_options
|
||||
validated_enterprise_options order_cycle_coordinating_enterprises, confirmed: true
|
||||
end
|
||||
|
||||
if options[:without_validation]
|
||||
enterprises
|
||||
else
|
||||
enterprises.map do |e|
|
||||
disabled_message = nil
|
||||
if e.shipping_methods.empty? && e.payment_methods.available.empty?
|
||||
disabled_message = 'no shipping or payment methods'
|
||||
elsif e.shipping_methods.empty?
|
||||
disabled_message = 'no shipping methods'
|
||||
elsif e.payment_methods.available.empty?
|
||||
disabled_message = 'no payment methods'
|
||||
end
|
||||
def order_cycle_hub_enterprises
|
||||
order_cycle_permitted_enterprises.is_hub.by_name
|
||||
end
|
||||
|
||||
if disabled_message
|
||||
["#{e.name} (#{disabled_message})", e.id, {disabled: true}]
|
||||
else
|
||||
[e.name, e.id]
|
||||
end
|
||||
end
|
||||
end
|
||||
def order_cycle_hub_enterprise_options
|
||||
validated_enterprise_options order_cycle_hub_enterprises, confirmed: true, shipping_and_payment_methods: true
|
||||
end
|
||||
|
||||
def order_cycle_status_class(order_cycle)
|
||||
@@ -68,8 +63,12 @@ module OrderCyclesHelper
|
||||
OrderCycle.active.with_distributor(@distributor).present?
|
||||
end
|
||||
|
||||
def order_cycles_simple_view
|
||||
@order_cycles_simple_view ||= !OpenFoodNetwork::Permissions.new(spree_current_user).can_manage_complex_order_cycles?
|
||||
def order_cycles_simple_index
|
||||
@order_cycles_simple_index ||= !OpenFoodNetwork::Permissions.new(spree_current_user).can_manage_complex_order_cycles?
|
||||
end
|
||||
|
||||
def order_cycles_simple_form
|
||||
@order_cycles_simple_form ||= @order_cycle.coordinator.sells == 'own'
|
||||
end
|
||||
|
||||
def order_cycles_enabled?
|
||||
@@ -80,4 +79,28 @@ module OrderCyclesHelper
|
||||
order_cycle.exchanges.to_enterprises(current_distributor).outgoing.first.pickup_time
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validated_enterprise_options(enterprises, options={})
|
||||
enterprises.map do |e|
|
||||
disabled_message = nil
|
||||
if options[:shipping_and_payment_methods] && (e.shipping_methods.empty? || e.payment_methods.available.empty?)
|
||||
if e.shipping_methods.empty? && e.payment_methods.available.empty?
|
||||
disabled_message = 'no shipping or payment methods'
|
||||
elsif e.shipping_methods.empty?
|
||||
disabled_message = 'no shipping methods'
|
||||
elsif e.payment_methods.available.empty?
|
||||
disabled_message = 'no payment methods'
|
||||
end
|
||||
elsif options[:confirmed] && !e.confirmed?
|
||||
disabled_message = 'unconfirmed'
|
||||
end
|
||||
|
||||
if disabled_message
|
||||
["#{e.name} (#{disabled_message})", e.id, {disabled: true}]
|
||||
else
|
||||
[e.name, e.id]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
9
app/helpers/spree/base_helper_decorator.rb
Normal file
9
app/helpers/spree/base_helper_decorator.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
module Spree
|
||||
module BaseHelper
|
||||
# human readable list of variant options
|
||||
# Override: Do not show out of stock text
|
||||
def variant_options(v, options={})
|
||||
v.options_text
|
||||
end
|
||||
end
|
||||
end
|
||||
7
app/models/customer.rb
Normal file
7
app/models/customer.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class Customer < ActiveRecord::Base
|
||||
belongs_to :enterprise
|
||||
|
||||
validates :code, presence: true, uniqueness: {scope: :enterprise_id}
|
||||
validates :email, presence: true
|
||||
validates :enterprise_id, presence: true
|
||||
end
|
||||
@@ -68,7 +68,7 @@ class Enterprise < ActiveRecord::Base
|
||||
before_validation :set_unused_address_fields
|
||||
after_validation :geocode_address
|
||||
|
||||
after_create :relate_to_owners_hubs
|
||||
after_create :relate_to_owners_enterprises
|
||||
# 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? }
|
||||
@@ -253,6 +253,10 @@ class Enterprise < ActiveRecord::Base
|
||||
self.sells != "none"
|
||||
end
|
||||
|
||||
def is_hub
|
||||
self.sells == 'any'
|
||||
end
|
||||
|
||||
# Simplify enterprise categories for frontend logic and icons, and maybe other things.
|
||||
def category
|
||||
# Make this crazy logic human readable so we can argue about it sanely.
|
||||
@@ -365,15 +369,34 @@ class Enterprise < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def relate_to_owners_hubs
|
||||
hubs = owner.owned_enterprises.is_hub.where('enterprises.id != ?', self)
|
||||
def relate_to_owners_enterprises
|
||||
# When a new producer is created, it grants permissions to all pre-existing hubs
|
||||
# When a new hub is created,
|
||||
# - it grants permissions to all pre-existing hubs
|
||||
# - all producers grant permission to it
|
||||
|
||||
hubs.each do |hub|
|
||||
enterprises = owner.owned_enterprises.where('enterprises.id != ?', self)
|
||||
|
||||
# We grant permissions to all pre-existing hubs
|
||||
enterprises.is_hub.each do |enterprise|
|
||||
EnterpriseRelationship.create!(parent: self,
|
||||
child: hub,
|
||||
child: enterprise,
|
||||
permissions_list: [:add_to_order_cycle,
|
||||
:manage_products,
|
||||
:edit_profile])
|
||||
:edit_profile,
|
||||
:create_variant_overrides])
|
||||
end
|
||||
|
||||
# All pre-existing producers grant permission to new hubs
|
||||
if is_hub
|
||||
enterprises.is_primary_producer.each do |enterprise|
|
||||
EnterpriseRelationship.create!(parent: enterprise,
|
||||
child: self,
|
||||
permissions_list: [:add_to_order_cycle,
|
||||
:manage_products,
|
||||
:edit_profile,
|
||||
:create_variant_overrides])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
class EnterpriseFee < ActiveRecord::Base
|
||||
belongs_to :enterprise
|
||||
belongs_to :tax_category, class_name: 'Spree::TaxCategory', foreign_key: 'tax_category_id'
|
||||
has_and_belongs_to_many :order_cycles, join_table: 'coordinator_fees'
|
||||
has_many :exchange_fees, dependent: :destroy
|
||||
has_many :exchanges, through: :exchange_fees
|
||||
@@ -8,7 +9,7 @@ class EnterpriseFee < ActiveRecord::Base
|
||||
|
||||
calculated_adjustments
|
||||
|
||||
attr_accessible :enterprise_id, :fee_type, :name, :calculator_type
|
||||
attr_accessible :enterprise_id, :fee_type, :name, :tax_category_id, :calculator_type
|
||||
|
||||
FEE_TYPES = %w(packing transport admin sales fundraising)
|
||||
PER_ORDER_CALCULATORS = ['Spree::Calculator::FlatRate', 'Spree::Calculator::FlexiRate']
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
require 'open_food_network/locking'
|
||||
|
||||
class EnterpriseGroup < ActiveRecord::Base
|
||||
acts_as_list
|
||||
|
||||
has_and_belongs_to_many :enterprises
|
||||
belongs_to :owner, class_name: 'Spree::User', foreign_key: :owner_id, inverse_of: :owned_groups
|
||||
belongs_to :address, :class_name => 'Spree::Address'
|
||||
accepts_nested_attributes_for :address
|
||||
validates :address, presence: true, associated: true
|
||||
before_validation :set_undefined_address_fields
|
||||
before_validation :set_unused_address_fields
|
||||
after_find :unset_undefined_address_fields
|
||||
after_save :unset_undefined_address_fields
|
||||
|
||||
validates :name, presence: true
|
||||
validates :description, presence: true
|
||||
|
||||
attr_accessible :name, :description, :long_description, :on_front_page, :enterprise_ids
|
||||
attr_accessible :owner_id
|
||||
attr_accessible :logo, :promo_image
|
||||
attr_accessible :address_attributes
|
||||
attr_accessible :email, :website, :facebook, :instagram, :linkedin, :twitter
|
||||
|
||||
delegate :phone, :address1, :address2, :city, :zipcode, :state, :country, :to => :address
|
||||
|
||||
has_attached_file :logo,
|
||||
styles: {medium: "100x100"},
|
||||
@@ -28,4 +43,32 @@ class EnterpriseGroup < ActiveRecord::Base
|
||||
|
||||
scope :by_position, order('position ASC')
|
||||
scope :on_front_page, where(on_front_page: true)
|
||||
scope :managed_by, lambda { |user|
|
||||
if user.has_spree_role?('admin')
|
||||
scoped
|
||||
else
|
||||
where('owner_id = ?', user.id)
|
||||
end
|
||||
}
|
||||
|
||||
def set_unused_address_fields
|
||||
address.firstname = address.lastname = 'unused' if address.present?
|
||||
end
|
||||
|
||||
def set_undefined_address_fields
|
||||
return unless address.present?
|
||||
address.phone.present? || address.phone = 'undefined'
|
||||
address.address1.present? || address.address1 = 'undefined'
|
||||
address.city.present? || address.city = 'undefined'
|
||||
address.zipcode.present? || address.zipcode = 'undefined'
|
||||
end
|
||||
|
||||
def unset_undefined_address_fields
|
||||
return unless address.present?
|
||||
address.phone.sub!(/^undefined$/, '')
|
||||
address.address1.sub!(/^undefined$/, '')
|
||||
address.city.sub!(/^undefined$/, '')
|
||||
address.zipcode.sub!(/^undefined$/, '')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -15,6 +15,7 @@ class EnterpriseRelationship < ActiveRecord::Base
|
||||
}
|
||||
|
||||
scope :permitting, ->(enterprises) { where('child_id IN (?)', enterprises) }
|
||||
scope :permitted_by, ->(enterprises) { where('parent_id IN (?)', enterprises) }
|
||||
|
||||
scope :with_permission, ->(permission) {
|
||||
joins(:permissions).
|
||||
|
||||
@@ -6,6 +6,7 @@ class AbilityDecorator
|
||||
def initialize(user)
|
||||
add_base_abilities user if is_new_user? user
|
||||
add_enterprise_management_abilities user if can_manage_enterprises? user
|
||||
add_group_management_abilities user if can_manage_groups? user
|
||||
add_product_management_abilities user if can_manage_products? user
|
||||
add_order_management_abilities user if can_manage_orders? user
|
||||
add_relationship_management_abilities user if can_manage_relationships? user
|
||||
@@ -21,6 +22,11 @@ class AbilityDecorator
|
||||
user.enterprises.present?
|
||||
end
|
||||
|
||||
# Users can manage a group if they have one.
|
||||
def can_manage_groups?(user)
|
||||
user.owned_groups.present?
|
||||
end
|
||||
|
||||
# Users can manage products if they have an enterprise that is not a profile.
|
||||
def can_manage_products?(user)
|
||||
can_manage_enterprises?(user) &&
|
||||
@@ -41,6 +47,14 @@ class AbilityDecorator
|
||||
can [:create], Enterprise
|
||||
end
|
||||
|
||||
def add_group_management_abilities(user)
|
||||
can [:admin, :index], :overview
|
||||
can [:admin, :index], EnterpriseGroup
|
||||
can [:read, :edit, :update], EnterpriseGroup do |group|
|
||||
user.owned_groups.include? group
|
||||
end
|
||||
end
|
||||
|
||||
def add_enterprise_management_abilities(user)
|
||||
# Spree performs authorize! on (:create, nil) when creating a new order from admin, and also (:search, nil)
|
||||
# when searching for variants to add to the order
|
||||
@@ -63,6 +77,8 @@ class AbilityDecorator
|
||||
can [:admin, :read, :edit, :bulk_update, :destroy], EnterpriseFee do |enterprise_fee|
|
||||
user.enterprises.include? enterprise_fee.enterprise
|
||||
end
|
||||
|
||||
can [:admin, :known_users], :search
|
||||
end
|
||||
|
||||
def add_product_management_abilities(user)
|
||||
@@ -78,9 +94,15 @@ class AbilityDecorator
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :update, :bulk_update], VariantOverride do |vo|
|
||||
OpenFoodNetwork::Permissions.new(user).
|
||||
hub_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
order_cycle_enterprises.is_distributor.
|
||||
include? vo.hub
|
||||
|
||||
producer_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_producers.
|
||||
include? vo.variant.product.supplier
|
||||
|
||||
hub_auth && producer_auth
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], Spree::ProductProperty
|
||||
@@ -131,7 +153,7 @@ class AbilityDecorator
|
||||
end
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :bulk_coop, :payments, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management], :report
|
||||
can [:admin, :index, :customers, :group_buys, :bulk_coop, :sales_tax, :payments, :orders_and_distributors, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management], :report
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -3,5 +3,17 @@ module Spree
|
||||
has_one :metadata, class_name: 'AdjustmentMetadata', dependent: :destroy
|
||||
|
||||
scope :enterprise_fee, where(originator_type: 'EnterpriseFee')
|
||||
scope :included_tax, where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem')
|
||||
|
||||
attr_accessible :included_tax
|
||||
|
||||
def set_included_tax!(rate)
|
||||
tax = amount - (amount / (1 + rate))
|
||||
set_absolute_included_tax! tax
|
||||
end
|
||||
|
||||
def set_absolute_included_tax!(tax)
|
||||
update_attributes! included_tax: tax.round(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
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.
|
||||
# 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
|
||||
# Tax Preferences
|
||||
preference :products_require_tax_category, :boolean, default: false
|
||||
preference :shipping_tax_rate, :decimal, default: 0
|
||||
end
|
||||
|
||||
7
app/models/spree/money_decorator.rb
Normal file
7
app/models/spree/money_decorator.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
Spree::Money.class_eval do
|
||||
|
||||
# return the currency symbol (on it's own) for the current default currency
|
||||
def self.currency_symbol
|
||||
Money.new(0, Spree::Config[:currency]).symbol
|
||||
end
|
||||
end
|
||||
@@ -68,7 +68,7 @@ Spree::Order.class_eval do
|
||||
|
||||
scope :with_payment_method_name, lambda { |payment_method_name|
|
||||
joins(:payments => :payment_method).
|
||||
where('spree_payment_methods.name = ?', payment_method_name).
|
||||
where('spree_payment_methods.name IN (?)', payment_method_name).
|
||||
select('DISTINCT spree_orders.*')
|
||||
}
|
||||
|
||||
|
||||
11
app/models/spree/shipment_decorator.rb
Normal file
11
app/models/spree/shipment_decorator.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
module Spree
|
||||
Shipment.class_eval do
|
||||
def ensure_correct_adjustment_with_included_tax
|
||||
ensure_correct_adjustment_without_included_tax
|
||||
|
||||
adjustment.set_included_tax! Config.shipping_tax_rate if Config.shipment_inc_vat
|
||||
end
|
||||
|
||||
alias_method_chain :ensure_correct_adjustment, :included_tax
|
||||
end
|
||||
end
|
||||
3
app/models/spree/shipping_category_decorator.rb
Normal file
3
app/models/spree/shipping_category_decorator.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
Spree::ShippingCategory.class_eval do
|
||||
attr_accessible :temperature_controlled
|
||||
end
|
||||
12
app/models/spree/tax_rate_decorator.rb
Normal file
12
app/models/spree/tax_rate_decorator.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
Spree::TaxRate.class_eval do
|
||||
def adjust_with_included_tax(order)
|
||||
adjust_without_included_tax(order)
|
||||
|
||||
order.reload
|
||||
(order.adjustments.tax + order.price_adjustments).each do |a|
|
||||
a.set_absolute_included_tax! a.amount
|
||||
end
|
||||
end
|
||||
|
||||
alias_method_chain :adjust, :included_tax
|
||||
end
|
||||
@@ -2,6 +2,7 @@ Spree.user_class.class_eval do
|
||||
has_many :enterprise_roles, :dependent => :destroy
|
||||
has_many :enterprises, through: :enterprise_roles
|
||||
has_many :owned_enterprises, class_name: 'Enterprise', foreign_key: :owner_id, inverse_of: :owner
|
||||
has_many :owned_groups, class_name: 'EnterpriseGroup', foreign_key: :owner_id, inverse_of: :owner
|
||||
has_one :cart
|
||||
|
||||
accepts_nested_attributes_for :enterprise_roles, :allow_destroy => true
|
||||
@@ -11,6 +12,16 @@ Spree.user_class.class_eval do
|
||||
|
||||
validate :limit_owned_enterprises
|
||||
|
||||
def known_users
|
||||
if admin?
|
||||
Spree::User.scoped
|
||||
else
|
||||
Spree::User
|
||||
.includes(:enterprises)
|
||||
.where("enterprises.id IN (SELECT enterprise_id FROM enterprise_roles WHERE user_id = ?)", id)
|
||||
end
|
||||
end
|
||||
|
||||
def build_enterprise_roles
|
||||
Enterprise.all.each do |enterprise|
|
||||
unless self.enterprise_roles.find_by_enterprise_id enterprise.id
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class VariantOverrideSet < ModelSet
|
||||
def initialize(attributes={})
|
||||
super(VariantOverride, VariantOverride.all, attributes, nil,
|
||||
def initialize(collection, attributes={})
|
||||
super(VariantOverride, collection, attributes, nil,
|
||||
proc { |attrs| attrs['price'].blank? && attrs['count_on_hand'].blank? } )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
Deface::Override.new(:virtual_path => "spree/admin/shared/_configuration_menu",
|
||||
:name => "add_enterprise_groups_to_admin_configurations_menu",
|
||||
:insert_bottom => "[data-hook='admin_configurations_sidebar_menu']",
|
||||
:text => "<li><%= link_to 'Enterprise Groups', main_app.admin_enterprise_groups_path %></li>",
|
||||
:partial => 'enterprise_groups/admin_configurations_menu',
|
||||
:original => '')
|
||||
@@ -1,5 +0,0 @@
|
||||
Deface::Override.new(:virtual_path => "spree/layouts/admin",
|
||||
:name => "add_enterprises_admin_tab",
|
||||
:insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
|
||||
:text => "<%= tab :enterprises, :url => main_app.admin_enterprises_path %>",
|
||||
:original => '6999548b86c700f2cc5d4f9d297c94b3617fd981')
|
||||
@@ -1,5 +0,0 @@
|
||||
Deface::Override.new(:virtual_path => "spree/layouts/admin",
|
||||
:name => "add_order_cycles_admin_tab",
|
||||
:insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
|
||||
:text => "<%= tab :order_cycles, :url => main_app.admin_order_cycles_path %>",
|
||||
:original => 'd4e321201ecb543e92192a031c8896a45dde3576')
|
||||
@@ -1,5 +0,0 @@
|
||||
Deface::Override.new(:virtual_path => "spree/shared/_order_details",
|
||||
:replace => "[data-hook='order_item_description']",
|
||||
:partial => "spree/orders/order_item_description",
|
||||
:name => "order_item_description",
|
||||
:original => '1729abc5f441607b09cc0d44843a8dfd660ac5e0')
|
||||
@@ -1,3 +1,3 @@
|
||||
/ insert_bottom "[data-hook='admin_product_sub_tabs']"
|
||||
|
||||
= tab :overrides, url: main_app.admin_variant_overrides_path, match_path: '/variant_overrides'
|
||||
= tab :variant_overrides, label: "Overrides", url: main_app.admin_variant_overrides_path, match_path: '/variant_overrides'
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/ insert_bottom "div[data-hook='admin_shipping_category_form_fields']"
|
||||
|
||||
%div.field.align-center{"data-hook" => "name"}
|
||||
= f.label :temperature_controlled, t(:temperature_controlled)
|
||||
= f.check_box :temperature_controlled
|
||||
@@ -0,0 +1,5 @@
|
||||
/ insert_after "[data-hook='category_row'] td:first-child"
|
||||
|
||||
%td.align-center
|
||||
= shipping_category.temperature_controlled ? 'Yes' : 'No'
|
||||
%br/
|
||||
@@ -0,0 +1,4 @@
|
||||
/ insert_after "[data-hook='categories_header'] th:first-child"
|
||||
|
||||
%th
|
||||
Temperature Controlled
|
||||
@@ -0,0 +1,5 @@
|
||||
/ insert_after "[data-hook='shipment_vat']"
|
||||
|
||||
.field.align-center{ "data-hook" => "shipping_tax_rate" }
|
||||
= number_field_tag "preferences[shipping_tax_rate]", Spree::Config[:shipping_tax_rate].to_f, in: 0.0..1.0, step: 0.01
|
||||
= label_tag nil, t(:shipping_tax_rate)
|
||||
@@ -0,0 +1,2 @@
|
||||
/ insert_bottom "[data-hook='admin_tabs'], #admin_tabs[data-hook]"
|
||||
= tab :enterprises, :url => main_app.admin_enterprises_path
|
||||
@@ -0,0 +1,2 @@
|
||||
/ insert_bottom "[data-hook='admin_tabs'], #admin_tabs[data-hook]"
|
||||
= tab :enterprise_groups, :url => main_app.admin_enterprise_groups_path, label: 'groups'
|
||||
@@ -0,0 +1,2 @@
|
||||
/ insert_bottom "[data-hook='admin_tabs'], #admin_tabs[data-hook]"
|
||||
= tab :order_cycles, :url => main_app.admin_order_cycles_path
|
||||
@@ -3,7 +3,7 @@ class EnterpriseFeePresenter
|
||||
@controller, @enterprise_fee, @index = controller, enterprise_fee, index
|
||||
end
|
||||
|
||||
delegate :id, :enterprise_id, :fee_type, :name, :calculator_type, :to => :enterprise_fee
|
||||
delegate :id, :enterprise_id, :fee_type, :name, :tax_category_id, :calculator_type, :to => :enterprise_fee
|
||||
|
||||
def enterprise_fee
|
||||
@enterprise_fee
|
||||
|
||||
@@ -2,4 +2,8 @@ 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, :permalink
|
||||
attributes :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order
|
||||
end
|
||||
attributes :owner, :users
|
||||
|
||||
has_one :owner, serializer: Api::Admin::UserSerializer
|
||||
has_many :users, serializer: Api::Admin::UserSerializer
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Api::VariantSerializer < ActiveModel::Serializer
|
||||
attributes :id, :is_master, :count_on_hand, :name_to_display, :unit_to_display,
|
||||
:on_demand, :price, :fees, :price_with_fees
|
||||
:options_text, :on_demand, :price, :fees, :price_with_fees, :product_name
|
||||
|
||||
def price_with_fees
|
||||
object.price_with_fees(options[:current_distributor], options[:current_order_cycle])
|
||||
@@ -13,4 +13,9 @@ class Api::VariantSerializer < ActiveModel::Serializer
|
||||
def fees
|
||||
object.fees_by_type_for(options[:current_distributor], options[:current_order_cycle])
|
||||
end
|
||||
|
||||
def product_name
|
||||
object.product.name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Spree::Api::VariantSerializer < ActiveModel::Serializer
|
||||
attributes :id, :options_text, :unit_value, :unit_description, :on_demand, :display_as, :display_name
|
||||
attributes :id, :options_text, :unit_value, :unit_description, :unit_to_display, :on_demand, :display_as, :display_name, :name_to_display
|
||||
attributes :on_hand, :price
|
||||
|
||||
def on_hand
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
%th Enterprise
|
||||
%th Fee Type
|
||||
%th Name
|
||||
%th Tax Category
|
||||
%th Calculator
|
||||
%th Calculator values
|
||||
%th.actions
|
||||
@@ -21,9 +22,10 @@
|
||||
%tr{'ng-repeat' => 'enterprise_fee in enterprise_fees | filter:query'}
|
||||
%td
|
||||
= f.ng_hidden_field :id
|
||||
= f.ng_collection_select :enterprise_id, @enterprises, :id, :name, 'enterprise_fee.enterprise_id', :include_blank => true
|
||||
= f.ng_collection_select :enterprise_id, @enterprises, :id, :name, 'enterprise_fee.enterprise_id', include_blank: true
|
||||
%td= f.ng_select :fee_type, enterprise_fee_type_options, 'enterprise_fee.fee_type'
|
||||
%td= f.ng_text_field :name, { placeholder: 'e.g. packing fee' }
|
||||
%td= f.ng_collection_select :tax_category_id, @tax_categories, :id, :name, 'enterprise_fee.tax_category_id', include_blank: true
|
||||
%td= f.ng_collection_select :calculator_type, @calculators, :name, :description, 'enterprise_fee.calculator_type', {'class' => 'calculator_type', 'ng-model' => 'calculatorType', 'spree-ensure-calculator-preferences-match-type' => "1"}
|
||||
%td{'ng-bind-html-unsafe-compiled' => 'enterprise_fee.calculator_settings'}
|
||||
%td.actions{'spree-delete-resource' => "1"}
|
||||
|
||||
@@ -4,6 +4,7 @@ r.list_of :enterprise_fees, @presented_collection do
|
||||
r.element :enterprise_name
|
||||
r.element :fee_type
|
||||
r.element :name
|
||||
r.element :tax_category_id
|
||||
r.element :calculator_type
|
||||
r.element :calculator_description
|
||||
r.element :calculator_settings if @include_calculators
|
||||
|
||||
@@ -1,43 +1,16 @@
|
||||
= f.field_container :name do
|
||||
= f.label :name
|
||||
%br/
|
||||
= f.text_field :name
|
||||
= render 'spree/shared/error_messages', target: @enterprise
|
||||
|
||||
= f.field_container :description do
|
||||
= f.label :description
|
||||
%br/
|
||||
= f.text_field :description
|
||||
|
||||
= f.field_container :long_description do
|
||||
= f.label :long_description
|
||||
%br/
|
||||
= f.text_area :long_description
|
||||
|
||||
= f.field_container :on_front_page do
|
||||
= f.label :on_front_page, 'On front page?'
|
||||
%br/
|
||||
= f.check_box :on_front_page
|
||||
|
||||
= f.field_container :enterprise_ids do
|
||||
= f.label :enterprise_ids, 'Enterprises'
|
||||
%br/
|
||||
= f.collection_select :enterprise_ids, Enterprise.all, :id, :name, {}, {class: "select2 fullwidth", multiple: true}
|
||||
|
||||
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :logo, class: 'with-tip', 'data-powertip' => 'This is the logo'
|
||||
.with-tip{'data-powertip' => 'This is the logo'}
|
||||
%a What's this?
|
||||
.omega.eight.columns
|
||||
= image_tag @object.logo.url if @object.logo.present?
|
||||
= f.file_field :logo
|
||||
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :promo_image, class: 'with-tip', 'data-powertip' => 'This image is displayed at the top of the Group profile'
|
||||
.with-tip{'data-powertip' => 'This image is displayed at the top of the Group profile'}
|
||||
%a What's this?
|
||||
.omega.eight.columns
|
||||
= image_tag @object.promo_image.url if @object.promo_image.present?
|
||||
= f.file_field :promo_image
|
||||
= form_for [main_app, :admin, @enterprise_group] do |f|
|
||||
.row{ ng: {app: 'admin.enterprise_groups', controller: 'enterpriseGroupCtrl'} }
|
||||
.sixteen.columns.alpha
|
||||
.four.columns.alpha
|
||||
= render 'admin/shared/side_menu'
|
||||
.one.column
|
||||
.eleven.columns.omega.fullwidth_inputs
|
||||
= render 'form_primary_details', f: f
|
||||
= render 'form_users', f: f
|
||||
= render 'form_about', f: f
|
||||
= render 'form_images', f: f
|
||||
= render 'form_address', f: f
|
||||
= render 'form_web', f: f
|
||||
= render "spree/admin/shared/#{action}_resource_links"
|
||||
|
||||
6
app/views/admin/enterprise_groups/_form_about.html.haml
Normal file
6
app/views/admin/enterprise_groups/_form_about.html.haml
Normal file
@@ -0,0 +1,6 @@
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='About'" } }
|
||||
%legend About
|
||||
= f.field_container :long_description do
|
||||
= f.label :long_description
|
||||
%br/
|
||||
= f.text_area :long_description
|
||||
41
app/views/admin/enterprise_groups/_form_address.html.haml
Normal file
41
app/views/admin/enterprise_groups/_form_address.html.haml
Normal file
@@ -0,0 +1,41 @@
|
||||
= f.fields_for :address do |af|
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='Contact'" } }
|
||||
%legend Contact
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= af.label :phone
|
||||
.omega.eight.columns
|
||||
= af.text_field :phone, { placeholder: "eg. 98 7654 3210"}
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :email
|
||||
.omega.eight.columns
|
||||
= f.text_field :email
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= af.label :address1
|
||||
.eight.columns.omega
|
||||
= af.text_field :address1, { placeholder: "eg. 123 High Street"}
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= af.label :address2
|
||||
.eight.columns.omega
|
||||
= af.text_field :address2
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= af.label :city, 'Suburb'
|
||||
\/
|
||||
= af.label :zipcode, 'Postcode'
|
||||
.four.columns
|
||||
= af.text_field :city, { placeholder: "eg. Northcote"}
|
||||
.four.columns.omega
|
||||
= af.text_field :zipcode, { placeholder: "eg. 3070"}
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= af.label :state_id, 'State'
|
||||
\/
|
||||
= af.label :country_id, 'Country'
|
||||
.four.columns
|
||||
= af.collection_select :state_id, af.object.country.states, :id, :name, {}, :class => "select2 fullwidth"
|
||||
.four.columns.omega
|
||||
= af.collection_select :country_id, available_countries, :id, :name, {}, :class => "select2 fullwidth"
|
||||
18
app/views/admin/enterprise_groups/_form_images.html.haml
Normal file
18
app/views/admin/enterprise_groups/_form_images.html.haml
Normal file
@@ -0,0 +1,18 @@
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='Images'" } }
|
||||
%legend Images
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :logo, class: 'with-tip', 'data-powertip' => 'This is the logo'
|
||||
.with-tip{'data-powertip' => 'This is the logo'}
|
||||
%a What's this?
|
||||
.omega.eight.columns
|
||||
= image_tag @object.logo.url if @object.logo.present?
|
||||
= f.file_field :logo
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :promo_image, class: 'with-tip', 'data-powertip' => 'This image is displayed at the top of the Group profile'
|
||||
.with-tip{'data-powertip' => 'This image is displayed at the top of the Group profile'}
|
||||
%a What's this?
|
||||
.omega.eight.columns
|
||||
= image_tag @object.promo_image.url if @object.promo_image.present?
|
||||
= f.file_field :promo_image
|
||||
@@ -0,0 +1,21 @@
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='Primary Details'" } }
|
||||
%legend Primary Details
|
||||
= f.field_container :name do
|
||||
= f.label :name
|
||||
%br/
|
||||
= f.text_field :name
|
||||
|
||||
= f.field_container :description do
|
||||
= f.label :description
|
||||
%br/
|
||||
= f.text_field :description
|
||||
|
||||
= f.field_container :on_front_page do
|
||||
= f.label :on_front_page, 'On front page?'
|
||||
%br/
|
||||
= f.check_box :on_front_page
|
||||
|
||||
= f.field_container :enterprise_ids do
|
||||
= f.label :enterprise_ids, 'Enterprises'
|
||||
%br/
|
||||
= f.collection_select :enterprise_ids, @enterprises, :id, :name, {}, {class: "select2 fullwidth", multiple: true}
|
||||
14
app/views/admin/enterprise_groups/_form_users.html.haml
Normal file
14
app/views/admin/enterprise_groups/_form_users.html.haml
Normal file
@@ -0,0 +1,14 @@
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='Users'" } }
|
||||
%legend Users
|
||||
.row
|
||||
.three.columns.alpha
|
||||
=f.label :owner_id, 'Owner'
|
||||
.with-tip{'data-powertip' => "The primary user responsible for this group."}
|
||||
%a What's this?
|
||||
.eight.columns.omega
|
||||
- if spree_current_user.admin?
|
||||
= f.hidden_field :owner_id,
|
||||
class: "select2 fullwidth",
|
||||
'user-select' => "{id:'#{@enterprise_group.owner.andand.id}', email:'#{@enterprise_group.owner.andand.email}'}"
|
||||
- else
|
||||
= @enterprise_group.owner.andand.email
|
||||
27
app/views/admin/enterprise_groups/_form_web.html.haml
Normal file
27
app/views/admin/enterprise_groups/_form_web.html.haml
Normal file
@@ -0,0 +1,27 @@
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='Web'" } }
|
||||
%legend Web Resources
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :website
|
||||
.omega.eight.columns
|
||||
= f.text_field :website, { placeholder: "eg. www.truffles.com"}
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :facebook, 'Facebook'
|
||||
.omega.eight.columns
|
||||
= f.text_field :facebook
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :instagram, 'Instagram'
|
||||
.omega.eight.columns
|
||||
= f.text_field :instagram
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :linkedin, 'LinkedIn'
|
||||
.omega.eight.columns
|
||||
= f.text_field :linkedin
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :twitter
|
||||
.omega.eight.columns
|
||||
= f.text_field :twitter, { placeholder: "eg. @the_prof" }
|
||||
@@ -1,5 +1,3 @@
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise }
|
||||
|
||||
= form_for [main_app, :admin, @enterprise_group] do |f|
|
||||
= render :partial => 'form', :locals => { :f => f }
|
||||
= render :partial => 'spree/admin/shared/edit_resource_links'
|
||||
= render 'admin/enterprise_groups/form', action: 'edit'
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
- if spree_current_user.admin?
|
||||
%th Owner
|
||||
%th On front page?
|
||||
%th Enterprises
|
||||
%th.actions
|
||||
@@ -17,14 +19,18 @@
|
||||
- @enterprise_groups.each do |enterprise_group|
|
||||
%tr
|
||||
%td.name= enterprise_group.name
|
||||
- if spree_current_user.admin?
|
||||
%td= enterprise_group.owner.andand.email || ""
|
||||
%td= enterprise_group.on_front_page ? 'Y' : 'N'
|
||||
%td= enterprise_group.enterprises.map(&:name).join ', '
|
||||
%td.actions
|
||||
= link_to '', main_app.edit_admin_enterprise_group_path(enterprise_group), class: 'edit-enterprise-group icon-edit no-text'
|
||||
= link_to_delete enterprise_group, no_text: true
|
||||
|
||||
- if enterprise_group.last?
|
||||
.blank-action
|
||||
- else
|
||||
= link_to_with_icon 'icon-arrow-down', '', main_app.admin_enterprise_group_move_down_path(enterprise_group), class: 'move-down no-text'
|
||||
= link_to_with_icon 'icon-arrow-up', '', main_app.admin_enterprise_group_move_up_path(enterprise_group), class: 'move-up no-text' unless enterprise_group.first?
|
||||
- if spree_current_user.admin?
|
||||
- if enterprise_group.last?
|
||||
.blank-action
|
||||
- else
|
||||
= link_to_with_icon 'icon-arrow-down', '', main_app.admin_enterprise_group_move_down_path(enterprise_group), class: 'move-down no-text'
|
||||
- if !enterprise_group.first?
|
||||
= link_to_with_icon 'icon-arrow-up', '', main_app.admin_enterprise_group_move_up_path(enterprise_group), class: 'move-up no-text'
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise }
|
||||
|
||||
= form_for [main_app, :admin, @enterprise_group] do |f|
|
||||
= render :partial => 'form', :locals => { :f => f }
|
||||
= render :partial => 'spree/admin/shared/new_resource_links'
|
||||
= render 'admin/enterprise_groups/form', action: 'new'
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
%legend Primary Details
|
||||
= render 'admin/enterprises/form/primary_details', f: f
|
||||
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='Users'" } }
|
||||
%legend Users
|
||||
= render 'admin/enterprises/form/users', f: f
|
||||
|
||||
= f.fields_for :address do |af|
|
||||
%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='Address'" } }
|
||||
%legend Address
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
%a What's this?
|
||||
.nine.columns.omega
|
||||
- owner_email = @enterprise.andand.owner.andand.email || ""
|
||||
= f.hidden_field :owner_id, class: "select2 fullwidth", 'ofn-user-autocomplete' => true, email: owner_email
|
||||
= f.hidden_field :owner_id, class: "select2 fullwidth", 'user-select' => 'Enterprise.owner'
|
||||
.row
|
||||
.three.columns.alpha
|
||||
%label Primary Producer?
|
||||
@@ -102,4 +102,4 @@
|
||||
|
||||
.row
|
||||
.twelve.columns.alpha
|
||||
= render partial: "spree/admin/shared/new_resource_links"
|
||||
= render partial: "spree/admin/shared/new_resource_links"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
.four.columns.alpha
|
||||
= render 'side_menu'
|
||||
= render 'admin/shared/side_menu'
|
||||
.one.column
|
||||
.eleven.columns.omega.fullwidth_inputs
|
||||
= render 'form', f: f
|
||||
|
||||
@@ -14,16 +14,6 @@
|
||||
|
||||
.eight.columns.omega
|
||||
= f.collection_select :group_ids, EnterpriseGroup.all, :id, :name, {}, class: "select2 fullwidth", multiple: true, placeholder: "Start typing to search available groups..."
|
||||
- if spree_current_user.admin?
|
||||
.row
|
||||
.three.columns.alpha
|
||||
=f.label :owner_id, 'Owner'
|
||||
%span.required *
|
||||
.with-tip{'data-powertip' => "The primary user responsible for this enterprise."}
|
||||
%a What's this?
|
||||
.eight.columns
|
||||
- owner_email = @enterprise.andand.owner.andand.email || ""
|
||||
= f.hidden_field :owner_id, class: "select2 fullwidth", 'ofn-user-autocomplete' => true, email: owner_email
|
||||
|
||||
.row
|
||||
.three.columns.alpha
|
||||
@@ -86,4 +76,4 @@
|
||||
%a What's this?
|
||||
.eight.columns.omega
|
||||
= surround spree.root_url, "/shop" do
|
||||
{{Enterprise.permalink}}
|
||||
{{Enterprise.permalink}}
|
||||
|
||||
42
app/views/admin/enterprises/form/_users.html.haml
Normal file
42
app/views/admin/enterprises/form/_users.html.haml
Normal file
@@ -0,0 +1,42 @@
|
||||
- owner_email = @enterprise.andand.owner.andand.email || ""
|
||||
- full_permissions = (spree_current_user.admin? || spree_current_user == @enterprise.andand.owner)
|
||||
|
||||
.row
|
||||
.three.columns.alpha
|
||||
=f.label :owner_id, 'Owner'
|
||||
- if full_permissions
|
||||
%span.required *
|
||||
.with-tip{'data-powertip' => "The primary user responsible for this enterprise."}
|
||||
%a What's this?
|
||||
.eight.columns.omega
|
||||
- if full_permissions
|
||||
= f.hidden_field :owner_id, class: "select2 fullwidth", 'user-select' => 'Enterprise.owner'
|
||||
- else
|
||||
= owner_email
|
||||
|
||||
.row
|
||||
.three.columns.alpha
|
||||
=f.label :user_ids, 'Managers'
|
||||
- if full_permissions
|
||||
%span.required *
|
||||
.with-tip{'data-powertip' => "The other users with permission to manage this enterprise."}
|
||||
%a What's this?
|
||||
.eight.columns.omega
|
||||
- if full_permissions
|
||||
%table
|
||||
%tr
|
||||
%td
|
||||
- # Ignore this input in the submit
|
||||
= hidden_field_tag :ignored, :new_manager, class: "select2 fullwidth", 'user-select' => 'newManager', 'ng-model' => 'newManager'
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'addManager(newManager)', :class => "icon-plus no-text" }
|
||||
%tr.animate-repeat{ ng: { repeat: 'manager in Enterprise.users' }}
|
||||
%td
|
||||
= hidden_field_tag "enterprise[user_ids][]", nil, multiple: true, 'ng-value' => 'manager.id'
|
||||
{{ manager.email }}
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'removeManager(manager)', :class => "icon-trash no-text" }
|
||||
- else
|
||||
- @enterprise.users.each do |manager|
|
||||
= manager.email
|
||||
%br
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise_set }
|
||||
|
||||
-# For purposes of debugging bulk_update. See Admin/Enterprises#bulk_update.
|
||||
- if flash[:action]
|
||||
%p= flash[:action]
|
||||
|
||||
= form_for @enterprise_set, url: main_app.bulk_update_admin_enterprises_path do |f|
|
||||
%table#listing_enterprises.index
|
||||
%colgroup
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user