mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-12 18:36:49 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0ee4aab01 | ||
|
|
452593b6f1 |
66
.github/ISSUE_TEMPLATE.md
vendored
Normal file
66
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<!-- Provide a general summary of the issue in the Title above.
|
||||
|
||||
If your issue is not a bug, please use the Feature template instead:
|
||||
https://github.com/openfoodfoundation/openfoodnetwork/wiki/Feature-template
|
||||
|
||||
-->
|
||||
## Description
|
||||
<!-- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
|
||||
|
||||
|
||||
|
||||
## Expected Behavior
|
||||
<!-- Tell us what should happen -->
|
||||
|
||||
|
||||
|
||||
## Actual Behavior
|
||||
<!-- Tell us what happens instead -->
|
||||
|
||||
|
||||
|
||||
## Steps to Reproduce
|
||||
<!-- Provide an unambiguous set of steps to reproduce this bug -->
|
||||
<!-- Include code to reproduce if relevant -->
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## Animated Gif/Screenshot
|
||||
<!-- Provide a screenshot or brief animated gif reproducing the bug. Linux users can use
|
||||
[Peek](https://github.com/phw/peek#ubuntu) while Mac users can use [Recordit](http://recordit.co/) -->
|
||||
|
||||
|
||||
|
||||
## Context
|
||||
<!-- How has this bug affected you? What were you trying to accomplish? -->
|
||||
|
||||
|
||||
|
||||
## Severity
|
||||
<!-- Assign a label and explain the impact.
|
||||
|
||||
bug-s1: a critical feature is broken: checkout, payments, signup, login
|
||||
bug-s2: a non-critical feature is broken, no workaround
|
||||
bug-s3: a feature is broken but there is a workaround
|
||||
bug-s4: it's annoying, but you can use it
|
||||
bug-s5: we can live with it, only a few users impacted
|
||||
|
||||
https://github.com/openfoodfoundation/openfoodnetwork/wiki/Bug-severity
|
||||
-->
|
||||
|
||||
|
||||
|
||||
## Your Environment
|
||||
<!-- Include relevant details about the environment you experienced the bug in -->
|
||||
|
||||
* Version used:
|
||||
* Browser name and version:
|
||||
* Operating System and version (desktop or mobile):
|
||||
|
||||
## Possible Fix
|
||||
<!-- Not obligatory, but suggest a fix or reason for the bug -->
|
||||
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/bug_report.md
vendored
14
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -9,7 +9,6 @@ assignees: ''
|
||||
|
||||
## Description
|
||||
<!-- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
|
||||
<!-- How has this bug affected you? What were you trying to accomplish? -->
|
||||
|
||||
|
||||
## Expected Behavior
|
||||
@@ -23,8 +22,6 @@ assignees: ''
|
||||
## Steps to Reproduce
|
||||
<!-- Provide an unambiguous set of steps to reproduce this bug -->
|
||||
<!-- Include code to reproduce if relevant -->
|
||||
<!-- Include links -->
|
||||
<!-- Include user ID -->
|
||||
|
||||
1.
|
||||
2.
|
||||
@@ -32,11 +29,13 @@ assignees: ''
|
||||
4.
|
||||
|
||||
## Animated Gif/Screenshot
|
||||
<!-- Provide a screenshot or brief video reproducing the bug. -->
|
||||
<!-- Please try to have the dev tools opened on the network tab (press F12 to open the devtools of your browser -->
|
||||
<!-- Provide a screenshot or brief animated gif reproducing the bug. Linux users can use
|
||||
[Peek](https://github.com/phw/peek#ubuntu) while Mac users can use [Recordit](http://recordit.co/) -->
|
||||
|
||||
|
||||
## Context
|
||||
<!-- How has this bug affected you? What were you trying to accomplish? -->
|
||||
|
||||
## Workaround
|
||||
<!-- Include a workaround for this bug (if relevant) -->
|
||||
|
||||
## Severity
|
||||
<!-- Assign a label and explain the impact.
|
||||
@@ -56,6 +55,7 @@ https://github.com/openfoodfoundation/openfoodnetwork/wiki/Bug-severity
|
||||
* Version used:
|
||||
* Browser name and version:
|
||||
* Operating System and version (desktop or mobile):
|
||||
* OFN Platform instance where you discovered the bug, and which version of the software they are using.
|
||||
|
||||
## Possible Fix
|
||||
<!-- Not obligatory, but suggest a fix or reason for the bug -->
|
||||
|
||||
11
.github/ISSUE_TEMPLATE/story-template.md
vendored
11
.github/ISSUE_TEMPLATE/story-template.md
vendored
@@ -14,12 +14,5 @@ assignees: ''
|
||||
**- I want to be able to do:** (specify the desired behavior)
|
||||
(Link to others issues or resources to provide context > only if really necessary). -->
|
||||
|
||||
## Acceptance Criteria & Tests
|
||||
<!-- Document the outcomes that need to be achieved before this component can be considered complete.
|
||||
-->
|
||||
<!-- Provide an unambiguous set of steps a tester should do to validate the PR that will solve this issue -->
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
## Acceptance Criteria
|
||||
<!-- Document the outcomes that need to be achieved before this component can be considered complete. -->
|
||||
|
||||
@@ -110,6 +110,18 @@ Metrics/LineLength:
|
||||
- app/models/variant_override.rb
|
||||
- app/models/variant_override_set.rb
|
||||
- app/overrides/add_enterprise_fees_to_admin_configurations_menu.rb
|
||||
- app/serializers/api/admin/basic_enterprise_serializer.rb
|
||||
- app/serializers/api/admin/enterprise_fee_serializer.rb
|
||||
- app/serializers/api/admin/enterprise_serializer.rb
|
||||
- app/serializers/api/admin/exchange_serializer.rb
|
||||
- app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb
|
||||
- app/serializers/api/admin/index_enterprise_serializer.rb
|
||||
- app/serializers/api/admin/index_order_cycle_serializer.rb
|
||||
- app/serializers/api/admin/line_item_serializer.rb
|
||||
- app/serializers/api/admin/order_cycle_serializer.rb
|
||||
- app/serializers/api/admin/subscription_serializer.rb
|
||||
- app/serializers/api/admin/tag_rule_serializer.rb
|
||||
- app/serializers/api/admin/variant_override_serializer.rb
|
||||
- app/services/cart_service.rb
|
||||
- app/services/default_stock_location.rb
|
||||
- app/services/embedded_page_service.rb
|
||||
@@ -136,6 +148,7 @@ Metrics/LineLength:
|
||||
- lib/open_food_network/order_cycle_form_applicator.rb
|
||||
- lib/open_food_network/order_cycle_management_report.rb
|
||||
- lib/open_food_network/order_grouper.rb
|
||||
- lib/open_food_network/orders_and_fulfillments_report.rb
|
||||
- lib/open_food_network/payments_report.rb
|
||||
- lib/open_food_network/permalink_generator.rb
|
||||
- lib/open_food_network/products_cache.rb
|
||||
@@ -441,6 +454,7 @@ Metrics/AbcSize:
|
||||
- lib/open_food_network/order_cycle_form_applicator.rb
|
||||
- lib/open_food_network/order_cycle_management_report.rb
|
||||
- lib/open_food_network/order_cycle_permissions.rb
|
||||
- lib/open_food_network/orders_and_fulfillments_report.rb
|
||||
- lib/open_food_network/packing_report.rb
|
||||
- lib/open_food_network/payments_report.rb
|
||||
- lib/open_food_network/permissions.rb
|
||||
@@ -518,6 +532,7 @@ Metrics/CyclomaticComplexity:
|
||||
- lib/discourse/single_sign_on.rb
|
||||
- lib/open_food_network/bulk_coop_report.rb
|
||||
- lib/open_food_network/enterprise_issue_validator.rb
|
||||
- lib/open_food_network/orders_and_fulfillments_report.rb
|
||||
- lib/spree/core/controller_helpers/order_decorator.rb
|
||||
- lib/spree/core/controller_helpers/respond_with_decorator.rb
|
||||
- lib/spree/localized_number.rb
|
||||
@@ -542,6 +557,7 @@ Metrics/PerceivedComplexity:
|
||||
- lib/discourse/single_sign_on.rb
|
||||
- lib/open_food_network/bulk_coop_report.rb
|
||||
- lib/open_food_network/enterprise_issue_validator.rb
|
||||
- lib/open_food_network/orders_and_fulfillments_report.rb
|
||||
- lib/spree/core/controller_helpers/order_decorator.rb
|
||||
- lib/spree/core/controller_helpers/respond_with_decorator.rb
|
||||
- lib/spree/localized_number.rb
|
||||
@@ -611,6 +627,7 @@ Metrics/MethodLength:
|
||||
- lib/open_food_network/order_cycle_management_report.rb
|
||||
- lib/open_food_network/order_cycle_permissions.rb
|
||||
- lib/open_food_network/order_grouper.rb
|
||||
- lib/open_food_network/orders_and_fulfillments_report.rb
|
||||
- lib/open_food_network/packing_report.rb
|
||||
- lib/open_food_network/payments_report.rb
|
||||
- lib/open_food_network/permissions.rb
|
||||
@@ -654,6 +671,7 @@ Metrics/ClassLength:
|
||||
- lib/open_food_network/order_cycle_form_applicator.rb
|
||||
- lib/open_food_network/order_cycle_management_report.rb
|
||||
- lib/open_food_network/order_cycle_permissions.rb
|
||||
- lib/open_food_network/orders_and_fulfillments_report.rb
|
||||
- lib/open_food_network/packing_report.rb
|
||||
- lib/open_food_network/payments_report.rb
|
||||
- lib/open_food_network/permissions.rb
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.1.9
|
||||
2.1.5
|
||||
|
||||
@@ -6,7 +6,7 @@ RUN apt-get update && apt-get install -y curl git build-essential software-prope
|
||||
# Setup ENV variables
|
||||
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:$PATH
|
||||
ENV RBENV_ROOT /usr/local/src/rbenv
|
||||
ENV RUBY_VERSION 2.1.9
|
||||
ENV RUBY_VERSION 2.1.5
|
||||
ENV CONFIGURE_OPTS --disable-install-doc
|
||||
|
||||
# Rbenv & Ruby part
|
||||
|
||||
@@ -11,7 +11,7 @@ The following guides are located in the wiki and provide more OS-specific step-b
|
||||
### Dependencies
|
||||
|
||||
* Rails 3.2.x
|
||||
* Ruby 2.1.9
|
||||
* Ruby 2.1.5
|
||||
* PostgreSQL database
|
||||
* PhantomJS (for testing)
|
||||
* See Gemfile for a list of gems required
|
||||
|
||||
14
Gemfile
14
Gemfile
@@ -1,5 +1,5 @@
|
||||
source 'https://rubygems.org'
|
||||
ruby "2.1.9"
|
||||
ruby "2.1.5"
|
||||
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
||||
|
||||
gem 'i18n', '~> 0.6.11'
|
||||
@@ -39,7 +39,7 @@ gem 'activemerchant', '~> 1.78'
|
||||
gem 'devise', '~> 2.2.5'
|
||||
gem 'devise-encryptable', '0.2.0'
|
||||
gem 'jwt', '~> 2.2'
|
||||
gem 'oauth2', '~> 1.4.2' # Used for Stripe Connect
|
||||
gem 'oauth2', '~> 1.4.1' # Used for Stripe Connect
|
||||
|
||||
gem 'daemons'
|
||||
gem 'delayed_job_active_record'
|
||||
@@ -85,6 +85,7 @@ gem 'paperclip', '~> 3.4.1'
|
||||
gem 'rack-rewrite'
|
||||
gem 'rack-ssl', require: 'rack/ssl'
|
||||
gem 'roadie-rails', '~> 1.1.1'
|
||||
gem 'skylight', '< 2.0'
|
||||
gem 'spinjs-rails'
|
||||
|
||||
gem 'combine_pdf'
|
||||
@@ -104,10 +105,7 @@ group :assets do
|
||||
gem 'coffee-rails', '~> 3.2.1'
|
||||
gem 'compass-rails'
|
||||
|
||||
gem 'mini_racer', '0.1.15'
|
||||
# Previously we found that libv8 6.7.288.46.1 breakis the compilation of mini_racer.
|
||||
# Now we see that we need to set the version explicitly. Nothing else depends on libv8.
|
||||
gem 'libv8', '6.3.292.48.1'
|
||||
gem 'therubyracer', '=0.12.0'
|
||||
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
|
||||
@@ -159,6 +157,10 @@ end
|
||||
group :development do
|
||||
gem 'byebug', '~> 9.0.0' # 9.1 requires ruby 2.2
|
||||
gem 'debugger-linecache'
|
||||
gem 'guard'
|
||||
gem 'guard-livereload'
|
||||
gem 'guard-rails'
|
||||
gem 'guard-rspec', '~> 4.7.3'
|
||||
gem 'listen', '3.0.8' # 3.1.0 requires ruby 2.2
|
||||
gem "newrelic_rpm", "~> 3.0"
|
||||
gem 'pry-byebug', '>= 3.4.3'
|
||||
|
||||
102
Gemfile.lock
102
Gemfile.lock
@@ -164,7 +164,7 @@ GEM
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
blockenspiel (0.5.0)
|
||||
bugsnag (6.12.1)
|
||||
bugsnag (6.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.0.4)
|
||||
byebug (9.0.6)
|
||||
@@ -223,7 +223,7 @@ GEM
|
||||
activerecord (>= 3.2.0, < 5.0)
|
||||
fog (~> 1.0)
|
||||
rails (>= 3.2.0, < 5.0)
|
||||
ddtrace (0.28.0)
|
||||
ddtrace (0.26.0)
|
||||
msgpack
|
||||
debugger-linecache (1.2.0)
|
||||
deface (1.0.2)
|
||||
@@ -252,6 +252,9 @@ GEM
|
||||
diffy (3.3.0)
|
||||
docile (1.3.2)
|
||||
dry-inflector (0.1.2)
|
||||
em-websocket (0.5.1)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.2.7)
|
||||
excon (0.62.0)
|
||||
@@ -429,11 +432,34 @@ GEM
|
||||
ruby-progressbar (~> 1.4)
|
||||
geocoder (1.1.8)
|
||||
gmaps4rails (1.5.6)
|
||||
guard (2.15.0)
|
||||
formatador (>= 0.2.4)
|
||||
listen (>= 2.7, < 4.0)
|
||||
lumberjack (>= 1.0.12, < 2.0)
|
||||
nenv (~> 0.1)
|
||||
notiffany (~> 0.0)
|
||||
pry (>= 0.9.12)
|
||||
shellany (~> 0.0)
|
||||
thor (>= 0.18.1)
|
||||
guard-compat (1.2.1)
|
||||
guard-livereload (2.5.2)
|
||||
em-websocket (~> 0.5)
|
||||
guard (~> 2.8)
|
||||
guard-compat (~> 1.0)
|
||||
multi_json (~> 1.8)
|
||||
guard-rails (0.7.2)
|
||||
guard (~> 2.11)
|
||||
guard-compat (~> 1.0)
|
||||
guard-rspec (4.7.3)
|
||||
guard (~> 2.1)
|
||||
guard-compat (~> 1.1)
|
||||
rspec (>= 2.99.0, < 4.0)
|
||||
haml (4.0.7)
|
||||
tilt
|
||||
hashdiff (1.0.0)
|
||||
highline (1.6.18)
|
||||
hike (1.2.3)
|
||||
http_parser.rb (0.6.0)
|
||||
httparty (0.16.2)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (0.6.11)
|
||||
@@ -465,10 +491,11 @@ GEM
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
libv8 (6.3.292.48.1)
|
||||
libv8 (3.16.14.19)
|
||||
listen (3.0.8)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
lumberjack (1.0.13)
|
||||
mail (2.5.5)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
@@ -476,8 +503,6 @@ GEM
|
||||
mime-types (1.25.1)
|
||||
mini_mime (1.0.1)
|
||||
mini_portile2 (2.1.0)
|
||||
mini_racer (0.1.15)
|
||||
libv8 (~> 6.3)
|
||||
momentjs-rails (2.20.1)
|
||||
railties (>= 3.1)
|
||||
money (5.1.1)
|
||||
@@ -486,13 +511,17 @@ GEM
|
||||
multi_json (1.13.1)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
nenv (0.3.0)
|
||||
net-http-persistent (3.1.0)
|
||||
connection_pool (~> 2.2)
|
||||
newrelic_rpm (3.18.1.330)
|
||||
nokogiri (1.6.8.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
oauth2 (1.4.2)
|
||||
faraday (>= 0.8, < 2.0)
|
||||
notiffany (0.1.1)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
oauth2 (1.4.1)
|
||||
faraday (>= 0.8, < 0.16.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
@@ -581,6 +610,7 @@ GEM
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
redcarpet (3.5.0)
|
||||
ref (2.0.0)
|
||||
request_store (1.4.1)
|
||||
rack (>= 1.4)
|
||||
roadie (3.4.0)
|
||||
@@ -596,29 +626,29 @@ GEM
|
||||
nokogiri
|
||||
roo (>= 2.0.0beta1, < 3)
|
||||
spreadsheet (> 0.9.0)
|
||||
rspec (3.9.0)
|
||||
rspec-core (~> 3.9.0)
|
||||
rspec-expectations (~> 3.9.0)
|
||||
rspec-mocks (~> 3.9.0)
|
||||
rspec-core (3.9.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-expectations (3.9.0)
|
||||
rspec (3.8.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-core (3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-mocks (3.9.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-rails (3.9.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.9.0)
|
||||
rspec-expectations (~> 3.9.0)
|
||||
rspec-mocks (~> 3.9.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-retry (0.6.1)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.9.0)
|
||||
rspec-support (3.8.0)
|
||||
rubocop (0.57.2)
|
||||
jaro_winkler (~> 1.5.1)
|
||||
parallel (~> 1.10)
|
||||
@@ -630,7 +660,7 @@ GEM
|
||||
ruby-ole (1.2.12.1)
|
||||
ruby-progressbar (1.10.1)
|
||||
ruby-rc4 (0.1.5)
|
||||
rubyzip (1.3.0)
|
||||
rubyzip (1.2.2)
|
||||
safe_yaml (1.0.5)
|
||||
sass (3.3.14)
|
||||
sass-rails (3.2.6)
|
||||
@@ -643,9 +673,10 @@ GEM
|
||||
selenium-webdriver (3.141.0)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.2, >= 1.2.2)
|
||||
shellany (0.0.1)
|
||||
shoulda-matchers (2.8.0)
|
||||
activesupport (>= 3.0.0)
|
||||
simplecov (0.17.1)
|
||||
simplecov (0.17.0)
|
||||
docile (~> 1.1)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
@@ -654,6 +685,8 @@ GEM
|
||||
rack (~> 1.4)
|
||||
rack-protection (~> 1.4)
|
||||
tilt (>= 1.3, < 3)
|
||||
skylight (1.7.2)
|
||||
activesupport (>= 3.0.0)
|
||||
spinjs-rails (1.4)
|
||||
rails (>= 3.1)
|
||||
spreadsheet (1.1.7)
|
||||
@@ -671,6 +704,9 @@ GEM
|
||||
stripe (4.24.0)
|
||||
faraday (~> 0.13)
|
||||
net-http-persistent (~> 3.0)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.20.3)
|
||||
tilt (1.4.1)
|
||||
timecop (0.9.1)
|
||||
@@ -683,7 +719,7 @@ GEM
|
||||
railties (> 3.2.8, < 4.0.0)
|
||||
sprockets (>= 2.2.0)
|
||||
tzinfo (0.3.55)
|
||||
uglifier (4.2.0)
|
||||
uglifier (4.1.20)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.3.2)
|
||||
unicorn (5.5.1)
|
||||
@@ -703,7 +739,7 @@ GEM
|
||||
nokogiri (~> 1.6)
|
||||
rubyzip (~> 1.0)
|
||||
selenium-webdriver (~> 3.0)
|
||||
webmock (3.7.6)
|
||||
webmock (3.7.1)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
@@ -760,6 +796,10 @@ DEPENDENCIES
|
||||
fuubar (~> 2.4.1)
|
||||
geocoder
|
||||
gmaps4rails
|
||||
guard
|
||||
guard-livereload
|
||||
guard-rails
|
||||
guard-rspec (~> 4.7.3)
|
||||
haml
|
||||
i18n (~> 0.6.11)
|
||||
i18n-js (~> 3.3.0)
|
||||
@@ -771,13 +811,11 @@ DEPENDENCIES
|
||||
kaminari (~> 0.14.1)
|
||||
knapsack
|
||||
letter_opener (>= 1.4.1)
|
||||
libv8 (= 6.3.292.48.1)
|
||||
listen (= 3.0.8)
|
||||
mini_racer (= 0.1.15)
|
||||
momentjs-rails
|
||||
newrelic_rpm (~> 3.0)
|
||||
nokogiri (>= 1.6.7.1)
|
||||
oauth2 (~> 1.4.2)
|
||||
oauth2 (~> 1.4.1)
|
||||
ofn-qz!
|
||||
oj
|
||||
order_management!
|
||||
@@ -805,6 +843,7 @@ DEPENDENCIES
|
||||
shoulda-matchers
|
||||
simple_form!
|
||||
simplecov
|
||||
skylight (< 2.0)
|
||||
spinjs-rails
|
||||
spree_api!
|
||||
spree_backend!
|
||||
@@ -814,6 +853,7 @@ DEPENDENCIES
|
||||
spring (= 1.7.2)
|
||||
spring-commands-rspec
|
||||
stripe
|
||||
therubyracer (= 0.12.0)
|
||||
timecop
|
||||
truncate_html
|
||||
turbo-sprockets-rails3
|
||||
@@ -828,7 +868,7 @@ DEPENDENCIES
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.1.9p490
|
||||
ruby 2.1.5p273
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.2
|
||||
|
||||
11
Guardfile
Normal file
11
Guardfile
Normal file
@@ -0,0 +1,11 @@
|
||||
# A sample Guardfile
|
||||
# More info at https://github.com/guard/guard#readme
|
||||
|
||||
guard 'livereload' do
|
||||
watch(%r{app/views/.+\.(erb|haml|slim)$})
|
||||
watch(%r{app/helpers/.+\.rb})
|
||||
watch(%r{public/.+\.(css|js|html)})
|
||||
|
||||
# Rails Assets Pipeline
|
||||
watch(%r{(app|vendor)(/assets/\w+/(.+\.(css|js|html|png|jpg))).*}) { |m| "/assets/#{m[3]}" }
|
||||
end
|
||||
@@ -1,5 +1,6 @@
|
||||
[](https://semaphoreci.com/openfoodfoundation/openfoodnetwork-2)
|
||||
[](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork)
|
||||
[](https://oss.skylight.io/app/applications/EiXQ6sSKij8y)
|
||||
|
||||
# Open Food Network
|
||||
|
||||
@@ -35,7 +36,7 @@ We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. B
|
||||
Copyright (c) 2012 - 2019 Open Food Foundation, released under the AGPL licence.
|
||||
|
||||
[survey]: https://docs.google.com/a/eaterprises.com.au/forms/d/1zxR5vSiU9CigJ9cEaC8-eJLgYid8CR8er7PPH9Mc-30/edit#
|
||||
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/enQtNzY3NDEwNzM2MDM0LWFmNGRhNDUwYzNmNWNkYmFkMzgxNDg1OTg1ODNjNWY4Y2FhNDIwNmE4ZWI0OThiMGNmZjFkODczNGZiYTJmNWI
|
||||
[slack-invite]: https://openfoodnetwork.org/slack-invite
|
||||
[contributor-guide]: https://ofn-user-guide.gitbook.io/ofn-contributor-guide/who-are-we
|
||||
[ofn-install]: https://github.com/openfoodfoundation/ofn-install
|
||||
[super-admin-guide]: https://ofn-user-guide.gitbook.io/ofn-super-admin-guide
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
module Api
|
||||
class OrdersController < BaseController
|
||||
def show
|
||||
authorize! :read, order
|
||||
render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
|
||||
end
|
||||
|
||||
def index
|
||||
authorize! :admin, Spree::Order
|
||||
|
||||
@@ -24,12 +19,5 @@ module Api
|
||||
each_serializer: Api::Admin::OrderSerializer
|
||||
)
|
||||
end
|
||||
|
||||
def order
|
||||
@order ||= Spree::Order.
|
||||
where(number: params[:id]).
|
||||
includes(line_items: { variant: [:product, :stock_items, :default_price] }).
|
||||
first!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
module Api
|
||||
class ShipmentsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
before_filter :find_order
|
||||
before_filter :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
|
||||
|
||||
def create
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
@shipment = get_or_create_shipment(params[:stock_location_id])
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
@shipment.refresh_rates
|
||||
@shipment.save!
|
||||
|
||||
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :read, Spree::Shipment
|
||||
@shipment = @order.shipments.find_by_number!(params[:id])
|
||||
params[:shipment] ||= []
|
||||
unlock = params[:shipment].delete(:unlock)
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.adjustment.open
|
||||
end
|
||||
|
||||
@shipment.update_attributes(params[:shipment])
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.adjustment.close
|
||||
end
|
||||
|
||||
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def ready
|
||||
authorize! :read, Spree::Shipment
|
||||
unless @shipment.ready?
|
||||
if @shipment.can_ready?
|
||||
@shipment.ready!
|
||||
else
|
||||
render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") },
|
||||
status: :unprocessable_entity) && return
|
||||
end
|
||||
end
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def ship
|
||||
authorize! :read, Spree::Shipment
|
||||
unless @shipment.shipped?
|
||||
@shipment.ship!
|
||||
end
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def add
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def remove
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.remove(variant, quantity, @shipment)
|
||||
@shipment.reload if @shipment.persisted?
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_order
|
||||
@order = Spree::Order.find_by_number!(params[:order_id])
|
||||
authorize! :read, @order
|
||||
end
|
||||
|
||||
def find_and_update_shipment
|
||||
@shipment = @order.shipments.find_by_number!(params[:id])
|
||||
@shipment.update_attributes(params[:shipment])
|
||||
@shipment.reload
|
||||
end
|
||||
|
||||
def scoped_variant(variant_id)
|
||||
variant = Spree::Variant.find(variant_id)
|
||||
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
|
||||
variant
|
||||
end
|
||||
|
||||
def get_or_create_shipment(stock_location_id)
|
||||
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,12 +0,0 @@
|
||||
module Api
|
||||
class TaxonomiesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: :jstree
|
||||
|
||||
def jstree
|
||||
@taxonomy = Spree::Taxonomy.find(params[:id])
|
||||
render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,71 +0,0 @@
|
||||
module Api
|
||||
class TaxonsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: [:index, :show, :jstree]
|
||||
|
||||
def index
|
||||
if taxonomy
|
||||
@taxons = taxonomy.root.children
|
||||
else
|
||||
if params[:ids]
|
||||
@taxons = Spree::Taxon.where(id: params[:ids].split(","))
|
||||
else
|
||||
@taxons = Spree::Taxon.ransack(params[:q]).result
|
||||
end
|
||||
end
|
||||
render json: @taxons, each_serializer: Api::TaxonSerializer
|
||||
end
|
||||
|
||||
def jstree
|
||||
@taxon = taxon
|
||||
render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Taxon
|
||||
@taxon = Spree::Taxon.new(params[:taxon])
|
||||
@taxon.taxonomy_id = params[:taxonomy_id]
|
||||
taxonomy = Spree::Taxonomy.find_by_id(params[:taxonomy_id])
|
||||
|
||||
if taxonomy.nil?
|
||||
@taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api')
|
||||
invalid_resource!(@taxon) && return
|
||||
end
|
||||
|
||||
@taxon.parent_id = taxonomy.root.id unless params[:taxon][:parent_id]
|
||||
|
||||
if @taxon.save
|
||||
render json: @taxon, serializer: Api::TaxonSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Taxon
|
||||
if taxon.update_attributes(params[:taxon])
|
||||
render json: taxon, serializer: Api::TaxonSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Taxon
|
||||
taxon.destroy
|
||||
render json: taxon, serializer: Api::TaxonSerializer, status: :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def taxonomy
|
||||
return if params[:taxonomy_id].blank?
|
||||
@taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id])
|
||||
end
|
||||
|
||||
def taxon
|
||||
@taxon ||= taxonomy.taxons.find(params[:id])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -152,7 +152,7 @@ class CheckoutController < Spree::CheckoutController
|
||||
end
|
||||
|
||||
def update_failed
|
||||
current_order.updater.shipping_address_from_distributor
|
||||
clear_ship_address
|
||||
RestartCheckout.new(@order).call
|
||||
|
||||
respond_to do |format|
|
||||
@@ -165,6 +165,15 @@ class CheckoutController < Spree::CheckoutController
|
||||
end
|
||||
end
|
||||
|
||||
# When we have a pickup Shipping Method,
|
||||
# we clone the distributor address into ship_address before_save
|
||||
# We don't want this data in the form, so we clear it out
|
||||
def clear_ship_address
|
||||
unless current_order.shipping_method.andand.require_ship_address
|
||||
current_order.ship_address = Spree::Address.default
|
||||
end
|
||||
end
|
||||
|
||||
def load_order
|
||||
@order = current_order
|
||||
redirect_to(main_app.shop_path) && return unless @order && @order.checkout_allowed?
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class CountriesController < ResourceController
|
||||
def collection
|
||||
super.order(:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,35 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class GeneralSettingsController < Spree::Admin::BaseController
|
||||
def edit
|
||||
@preferences_general = [:site_name, :default_seo_title, :default_meta_keywords,
|
||||
:default_meta_description, :site_url, :bugherd_api_key]
|
||||
@preferences_security = [:allow_ssl_in_production,
|
||||
:allow_ssl_in_staging, :allow_ssl_in_development_and_test,
|
||||
:check_for_spree_alerts]
|
||||
@preferences_currency = [:display_currency, :hide_cents]
|
||||
end
|
||||
|
||||
def update
|
||||
params.each do |name, value|
|
||||
next unless Spree::Config.has_preference? name
|
||||
Spree::Config[name] = value
|
||||
end
|
||||
flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:general_settings))
|
||||
|
||||
redirect_to edit_admin_general_settings_path
|
||||
end
|
||||
|
||||
def dismiss_alert
|
||||
return unless request.xhr? && params[:alert_id]
|
||||
dismissed = Spree::Config[:dismissed_spree_alerts] || ''
|
||||
Spree::Config.set(dismissed_spree_alerts: dismissed.
|
||||
split(',').
|
||||
push(params[:alert_id]).
|
||||
join(','))
|
||||
filter_dismissed_alerts
|
||||
render nothing: true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
module Spree
|
||||
module Admin
|
||||
GeneralSettingsController.class_eval do
|
||||
end
|
||||
|
||||
module GeneralSettingsEditPreferences
|
||||
def edit
|
||||
super
|
||||
@preferences_general << :bugherd_api_key
|
||||
end
|
||||
end
|
||||
GeneralSettingsController.prepend(GeneralSettingsEditPreferences)
|
||||
end
|
||||
end
|
||||
@@ -1,79 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class ImageSettingsController < Spree::Admin::BaseController
|
||||
def edit
|
||||
@styles = ActiveSupport::JSON.decode(Spree::Config[:attachment_styles])
|
||||
@headers = ActiveSupport::JSON.decode(Spree::Config[:s3_headers])
|
||||
end
|
||||
|
||||
def update
|
||||
update_styles(params)
|
||||
update_headers(params) if Spree::Config[:use_s3]
|
||||
|
||||
Spree::Config.set(params[:preferences])
|
||||
update_paperclip_settings
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:success] = Spree.t(:image_settings_updated)
|
||||
redirect_to spree.edit_admin_image_settings_path
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_styles(params)
|
||||
if params[:new_attachment_styles].present?
|
||||
params[:new_attachment_styles].each do |_index, style|
|
||||
params[:attachment_styles][style[:name]] = style[:value] unless style[:value].empty?
|
||||
end
|
||||
end
|
||||
|
||||
styles = params[:attachment_styles]
|
||||
|
||||
Spree::Config[:attachment_styles] = ActiveSupport::JSON.encode(styles) unless styles.nil?
|
||||
end
|
||||
|
||||
def update_headers(params)
|
||||
if params[:new_s3_headers].present?
|
||||
params[:new_s3_headers].each do |_index, header|
|
||||
params[:s3_headers][header[:name]] = header[:value] unless header[:value].empty?
|
||||
end
|
||||
end
|
||||
|
||||
headers = params[:s3_headers]
|
||||
|
||||
Spree::Config[:s3_headers] = ActiveSupport::JSON.encode(headers) unless headers.nil?
|
||||
end
|
||||
|
||||
def update_paperclip_settings
|
||||
if Spree::Config[:use_s3]
|
||||
s3_creds = { access_key_id: Spree::Config[:s3_access_key],
|
||||
secret_access_key: Spree::Config[:s3_secret],
|
||||
bucket: Spree::Config[:s3_bucket] }
|
||||
Spree::Image.attachment_definitions[:attachment][:storage] = :s3
|
||||
Spree::Image.attachment_definitions[:attachment][:s3_credentials] = s3_creds
|
||||
Spree::Image.attachment_definitions[:attachment][:s3_headers] =
|
||||
ActiveSupport::JSON.decode(Spree::Config[:s3_headers])
|
||||
Spree::Image.attachment_definitions[:attachment][:bucket] = Spree::Config[:s3_bucket]
|
||||
else
|
||||
Spree::Image.attachment_definitions[:attachment].delete :storage
|
||||
end
|
||||
|
||||
Spree::Image.attachment_definitions[:attachment][:styles] =
|
||||
ActiveSupport::JSON.decode(Spree::Config[:attachment_styles]).symbolize_keys!
|
||||
Spree::Image.attachment_definitions[:attachment][:path] = Spree::Config[:attachment_path]
|
||||
Spree::Image.attachment_definitions[:attachment][:default_url] =
|
||||
Spree::Config[:attachment_default_url]
|
||||
Spree::Image.attachment_definitions[:attachment][:default_style] =
|
||||
Spree::Config[:attachment_default_style]
|
||||
|
||||
# Spree stores attachent definitions in JSON. This converts the style name and format to
|
||||
# strings. However, when paperclip encounters these, it doesn't recognise the format.
|
||||
# Here we solve that problem by converting format and style name to symbols.
|
||||
Spree::Image.reformat_styles
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
Spree::Admin::ImageSettingsController.class_eval do
|
||||
# Spree stores attachent definitions in JSON. This converts the style name and format to
|
||||
# strings. However, when paperclip encounters these, it doesn't recognise the format.
|
||||
# Here we solve that problem by converting format and style name to symbols.
|
||||
def update_paperclip_settings_with_format_styles
|
||||
update_paperclip_settings_without_format_styles
|
||||
Spree::Image.reformat_styles
|
||||
end
|
||||
|
||||
alias_method_chain :update_paperclip_settings, :format_styles
|
||||
end
|
||||
@@ -1,39 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class MailMethodsController < Spree::Admin::BaseController
|
||||
after_filter :initialize_mail_settings
|
||||
|
||||
def update
|
||||
if params[:smtp_password].blank?
|
||||
params.delete(:smtp_password)
|
||||
end
|
||||
|
||||
params.each do |name, value|
|
||||
next unless Spree::Config.has_preference? name
|
||||
Spree::Config[name] = value
|
||||
end
|
||||
|
||||
flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:mail_methods))
|
||||
render :edit
|
||||
end
|
||||
|
||||
def testmail
|
||||
if TestMailer.test_email(try_spree_current_user).deliver
|
||||
flash[:success] = Spree.t('admin.mail_methods.testmail.delivery_success')
|
||||
else
|
||||
flash[:error] = Spree.t('admin.mail_methods.testmail.delivery_error')
|
||||
end
|
||||
rescue StandardError => e
|
||||
flash[:error] = Spree.t('admin.mail_methods.testmail.error') % { e: e }
|
||||
ensure
|
||||
redirect_to edit_admin_mail_method_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize_mail_settings
|
||||
Spree::Core::MailSettings.init
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,6 +3,7 @@ require 'open_food_network/spree_api_key_loader'
|
||||
Spree::Admin::OrdersController.class_eval do
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
helper CheckoutHelper
|
||||
before_filter :load_spree_api_key, only: :bulk_management
|
||||
before_filter :load_order, only: %i[show edit update fire resend invoice print print_ticket]
|
||||
|
||||
before_filter :load_distribution_choices, only: [:new, :edit, :update]
|
||||
@@ -26,10 +27,6 @@ Spree::Admin::OrdersController.class_eval do
|
||||
# within the page then fetches the data it needs from Api::OrdersController
|
||||
end
|
||||
|
||||
def bulk_management
|
||||
load_spree_api_key
|
||||
end
|
||||
|
||||
def edit
|
||||
@order.shipments.map &:refresh_rates
|
||||
|
||||
|
||||
@@ -30,11 +30,6 @@ Spree::Admin::ProductsController.class_eval do
|
||||
@show_latest_import = params[:latest_import] || false
|
||||
end
|
||||
|
||||
def new
|
||||
@object.shipping_category = DefaultShippingCategory.find_or_create
|
||||
super
|
||||
end
|
||||
|
||||
def create
|
||||
delete_stock_params_and_set_after do
|
||||
super
|
||||
@@ -49,6 +44,8 @@ Spree::Admin::ProductsController.class_eval do
|
||||
delete_stock_params_and_set_after do
|
||||
super
|
||||
end
|
||||
|
||||
clear_variants_unit_description if @object.variant_unit == 'items'
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
@@ -193,4 +190,10 @@ Spree::Admin::ProductsController.class_eval do
|
||||
def set_product_master_variant_price_to_zero
|
||||
@product.price = 0 if @product.price.nil?
|
||||
end
|
||||
|
||||
def clear_variants_unit_description
|
||||
@object.variants.each do |variant|
|
||||
variant.update_attribute :unit_description, ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -126,8 +126,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
@include_blank = I18n.t(:all)
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new(permissions,
|
||||
params, render_content?)
|
||||
@report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new spree_current_user, params, render_content?
|
||||
@table = order_grouper_table
|
||||
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class ShippingCategoriesController < ResourceController
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,84 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class ShippingMethodsController < ResourceController
|
||||
before_filter :load_data, except: [:index]
|
||||
before_filter :set_shipping_category, only: [:create, :update]
|
||||
before_filter :set_zones, only: [:create, :update]
|
||||
before_filter :load_hubs, only: [:new, :edit, :create, :update]
|
||||
|
||||
# Sort shipping methods by distributor name
|
||||
def collection
|
||||
collection = super
|
||||
collection = collection.managed_by(spree_current_user).by_name
|
||||
|
||||
if params.key? :enterprise_id
|
||||
distributor = Enterprise.find params[:enterprise_id]
|
||||
collection = collection.for_distributor(distributor)
|
||||
end
|
||||
|
||||
collection
|
||||
end
|
||||
|
||||
def new
|
||||
@object.shipping_categories = [DefaultShippingCategory.find_or_create]
|
||||
super
|
||||
end
|
||||
|
||||
def destroy
|
||||
# Our reports are not adapted to soft deleted shipping_methods so here we prevent
|
||||
# the deletion (even soft) of shipping_methods that are referenced in orders
|
||||
if order = order_referenced_by_shipping_method
|
||||
flash[:error] = I18n.t(:shipping_method_destroy_error, number: order.number)
|
||||
redirect_to(collection_url) && return
|
||||
end
|
||||
|
||||
@object.touch :deleted_at
|
||||
flash[:success] = flash_message_for(@object, :successfully_removed)
|
||||
|
||||
respond_with(@object) do |format|
|
||||
format.html { redirect_to collection_url }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order_referenced_by_shipping_method
|
||||
Order.joins(shipments: :shipping_rates)
|
||||
.where( spree_shipping_rates: { shipping_method_id: @object } )
|
||||
.first
|
||||
end
|
||||
|
||||
def load_hubs
|
||||
# rubocop:disable Style/TernaryParentheses
|
||||
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.sort_by! do |d|
|
||||
[(@shipping_method.has_distributor? d) ? 0 : 1, d.name]
|
||||
end
|
||||
# rubocop:enable Style/TernaryParentheses
|
||||
end
|
||||
|
||||
def set_shipping_category
|
||||
return true if params["shipping_method"][:shipping_categories] == ""
|
||||
@shipping_method.shipping_categories =
|
||||
Spree::ShippingCategory.where(id: params["shipping_method"][:shipping_categories])
|
||||
@shipping_method.save
|
||||
params[:shipping_method].delete(:shipping_categories)
|
||||
end
|
||||
|
||||
def set_zones
|
||||
return true if params["shipping_method"][:zones] == ""
|
||||
@shipping_method.zones = Spree::Zone.where(id: params["shipping_method"][:zones])
|
||||
@shipping_method.save
|
||||
params[:shipping_method].delete(:zones)
|
||||
end
|
||||
|
||||
def location_after_save
|
||||
edit_admin_shipping_method_path(@shipping_method)
|
||||
end
|
||||
|
||||
def load_data
|
||||
@available_zones = Zone.order(:name)
|
||||
@calculators = ShippingMethod.calculators.sort_by(&:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
module Spree
|
||||
module Admin
|
||||
ShippingMethodsController.class_eval do
|
||||
before_filter :do_not_destroy_referenced_shipping_methods, only: :destroy
|
||||
before_filter :load_hubs, only: [:new, :edit, :create, :update]
|
||||
|
||||
# Sort shipping methods by distributor name
|
||||
def collection
|
||||
collection = super
|
||||
collection = collection.managed_by(spree_current_user).by_name
|
||||
|
||||
if params.key? :enterprise_id
|
||||
distributor = Enterprise.find params[:enterprise_id]
|
||||
collection = collection.for_distributor(distributor)
|
||||
end
|
||||
|
||||
collection
|
||||
end
|
||||
|
||||
# Spree allows soft deletes of shipping_methods but our reports are not adapted to that
|
||||
# Here we prevent the deletion (even soft) of shipping_methods that are referenced in orders
|
||||
def do_not_destroy_referenced_shipping_methods
|
||||
order = Order.joins(shipments: :shipping_rates)
|
||||
.where( spree_shipping_rates: { shipping_method_id: @object } )
|
||||
.first
|
||||
return unless order
|
||||
flash[:error] = I18n.t(:shipping_method_destroy_error, number: order.number)
|
||||
redirect_to(collection_url) && return
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_hubs
|
||||
# rubocop:disable Style/TernaryParentheses
|
||||
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.sort_by! do |d|
|
||||
[(@shipping_method.has_distributor? d) ? 0 : 1, d.name]
|
||||
end
|
||||
# rubocop:enable Style/TernaryParentheses
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,29 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class StatesController < ResourceController
|
||||
belongs_to 'spree/country'
|
||||
before_filter :load_data
|
||||
|
||||
def index
|
||||
respond_with(@collection) do |format|
|
||||
format.html
|
||||
format.js { render partial: 'state_list' }
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def location_after_save
|
||||
admin_country_states_url(@country)
|
||||
end
|
||||
|
||||
def collection
|
||||
super.order(:name)
|
||||
end
|
||||
|
||||
def load_data
|
||||
@countries = Country.order(:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class TaxCategoriesController < ResourceController
|
||||
def destroy
|
||||
if @object.destroy
|
||||
flash[:success] = flash_message_for(@object, :successfully_removed)
|
||||
respond_with(@object) do |format|
|
||||
format.html { redirect_to collection_url }
|
||||
format.js { render partial: "spree/admin/shared/destroy" }
|
||||
end
|
||||
else
|
||||
respond_with(@object) do |format|
|
||||
format.html { redirect_to collection_url }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,26 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class TaxRatesController < ResourceController
|
||||
before_filter :load_data
|
||||
|
||||
update.after :update_after
|
||||
create.after :create_after
|
||||
|
||||
private
|
||||
|
||||
def load_data
|
||||
@available_zones = Zone.order(:name)
|
||||
@available_categories = TaxCategory.order(:name)
|
||||
@calculators = TaxRate.calculators.sort_by(&:name)
|
||||
end
|
||||
|
||||
def update_after
|
||||
Rails.cache.delete('vat_rates')
|
||||
end
|
||||
|
||||
def create_after
|
||||
Rails.cache.delete('vat_rates')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,15 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class TaxSettingsController < Spree::Admin::BaseController
|
||||
def update
|
||||
Spree::Config.set(params[:preferences])
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
redirect_to edit_admin_tax_settings_path
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,21 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class TaxonomiesController < ResourceController
|
||||
respond_to :json, :only => [:get_children]
|
||||
|
||||
def get_children
|
||||
@taxons = Taxon.find(params[:parent_id]).children
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def location_after_save
|
||||
if @taxonomy.created_at == @taxonomy.updated_at
|
||||
edit_admin_taxonomy_url(@taxonomy)
|
||||
else
|
||||
admin_taxonomies_url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,118 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class TaxonsController < Spree::Admin::BaseController
|
||||
respond_to :html, :json, :js
|
||||
|
||||
def search
|
||||
if params[:ids]
|
||||
@taxons = Spree::Taxon.where(id: params[:ids].split(','))
|
||||
else
|
||||
@taxons = Spree::Taxon.limit(20).search(name_cont: params[:q]).result
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
||||
@taxon = @taxonomy.taxons.build(params[:taxon])
|
||||
if @taxon.save
|
||||
respond_with(@taxon) do |format|
|
||||
format.json { render json: @taxon.to_json }
|
||||
end
|
||||
else
|
||||
flash[:error] = Spree.t('errors.messages.could_not_create_taxon')
|
||||
respond_with(@taxon) do |format|
|
||||
format.html do
|
||||
if redirect_to @taxonomy
|
||||
edit_admin_taxonomy_url(@taxonomy)
|
||||
else
|
||||
admin_taxonomies_url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
||||
@taxon = @taxonomy.taxons.find(params[:id])
|
||||
@permalink_part = @taxon.permalink.split("/").last
|
||||
end
|
||||
|
||||
def update
|
||||
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
||||
@taxon = @taxonomy.taxons.find(params[:id])
|
||||
parent_id = params[:taxon][:parent_id]
|
||||
new_position = params[:taxon][:position]
|
||||
|
||||
if parent_id || new_position # taxon is being moved
|
||||
new_parent = parent_id.nil? ? @taxon.parent : Taxon.find(parent_id.to_i)
|
||||
new_position = new_position.nil? ? -1 : new_position.to_i
|
||||
|
||||
# Bellow is a very complicated way of finding where in nested set we
|
||||
# should actually move the taxon to achieve sane results,
|
||||
# JS is giving us the desired position, which was awesome for previous setup,
|
||||
# but now it's quite complicated to find where we should put it as we have
|
||||
# to differenciate between moving to the same branch, up down and into
|
||||
# first position.
|
||||
new_siblings = new_parent.children
|
||||
if new_position <= 0 && new_siblings.empty?
|
||||
@taxon.move_to_child_of(new_parent)
|
||||
elsif new_parent.id != @taxon.parent_id
|
||||
if new_position.zero?
|
||||
@taxon.move_to_left_of(new_siblings.first)
|
||||
else
|
||||
@taxon.move_to_right_of(new_siblings[new_position - 1])
|
||||
end
|
||||
elsif new_position < new_siblings.index(@taxon)
|
||||
@taxon.move_to_left_of(new_siblings[new_position]) # we move up
|
||||
else
|
||||
@taxon.move_to_right_of(new_siblings[new_position - 1]) # we move down
|
||||
end
|
||||
# Reset legacy position, if any extensions still rely on it
|
||||
new_parent.children.reload.each{ |t| t.update_column(:position, t.position) }
|
||||
|
||||
if parent_id
|
||||
@taxon.reload
|
||||
@taxon.set_permalink
|
||||
@taxon.save!
|
||||
@update_children = true
|
||||
end
|
||||
end
|
||||
|
||||
if params.key? "permalink_part"
|
||||
parent_permalink = @taxon.permalink.split("/")[0...-1].join("/")
|
||||
parent_permalink += "/" if parent_permalink.present?
|
||||
params[:taxon][:permalink] = parent_permalink + params[:permalink_part]
|
||||
end
|
||||
# check if we need to rename child taxons if parent name or permalink changes
|
||||
if params[:taxon][:name] != @taxon.name || params[:taxon][:permalink] != @taxon.permalink
|
||||
@update_children = true
|
||||
end
|
||||
|
||||
if @taxon.update_attributes(params[:taxon])
|
||||
flash[:success] = flash_message_for(@taxon, :successfully_updated)
|
||||
end
|
||||
|
||||
# rename child taxons
|
||||
if @update_children
|
||||
@taxon.descendants.each do |taxon|
|
||||
taxon.reload
|
||||
taxon.set_permalink
|
||||
taxon.save!
|
||||
end
|
||||
end
|
||||
|
||||
respond_with(@taxon) do |format|
|
||||
format.html { redirect_to edit_admin_taxonomy_url(@taxonomy) }
|
||||
format.json { render json: @taxon.to_json }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@taxon = Taxon.find(params[:id])
|
||||
@taxon.destroy
|
||||
respond_with(@taxon) { |format| format.json { render json: '' } }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -46,12 +46,7 @@ module Spree
|
||||
@user.spree_roles = roles.reject(&:blank?).collect{ |r| Spree::Role.find(r) }
|
||||
end
|
||||
|
||||
message = if new_email_unconfirmed?
|
||||
Spree.t(:email_updated)
|
||||
else
|
||||
Spree.t(:account_updated)
|
||||
end
|
||||
flash.now[:success] = message
|
||||
flash.now[:success] = Spree.t(:account_updated)
|
||||
end
|
||||
render :edit
|
||||
end
|
||||
@@ -131,10 +126,6 @@ module Spree
|
||||
def load_roles
|
||||
@roles = Spree::Role.scoped
|
||||
end
|
||||
|
||||
def new_email_unconfirmed?
|
||||
params[:user][:email] != @user.email
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
class ZonesController < ResourceController
|
||||
before_filter :load_data, except: [:index]
|
||||
|
||||
def new
|
||||
@zone.zone_members.build
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def collection
|
||||
params[:q] ||= {}
|
||||
params[:q][:s] ||= "ascend_by_name"
|
||||
@search = super.ransack(params[:q])
|
||||
@zones = @search.result.page(params[:page]).per(Spree::Config[:orders_per_page])
|
||||
end
|
||||
|
||||
def load_data
|
||||
@countries = Country.order(:name)
|
||||
@states = State.order(:name)
|
||||
@zones = Zone.order(:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
108
app/controllers/spree/api/shipments_controller.rb
Normal file
108
app/controllers/spree/api/shipments_controller.rb
Normal file
@@ -0,0 +1,108 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
module Spree
|
||||
module Api
|
||||
class ShipmentsController < Spree::Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
before_filter :find_order
|
||||
before_filter :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
|
||||
|
||||
def create
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
@shipment = get_or_create_shipment(params[:stock_location_id])
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
@shipment.refresh_rates
|
||||
@shipment.save!
|
||||
|
||||
respond_with(@shipment.reload, default_template: :show)
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :read, Shipment
|
||||
@shipment = @order.shipments.find_by_number!(params[:id])
|
||||
params[:shipment] ||= []
|
||||
unlock = params[:shipment].delete(:unlock)
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.adjustment.open
|
||||
end
|
||||
|
||||
@shipment.update_attributes(params[:shipment])
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.adjustment.close
|
||||
end
|
||||
|
||||
@shipment.reload
|
||||
respond_with(@shipment, default_template: :show)
|
||||
end
|
||||
|
||||
def ready
|
||||
authorize! :read, Shipment
|
||||
unless @shipment.ready?
|
||||
if @shipment.can_ready?
|
||||
@shipment.ready!
|
||||
else
|
||||
render "spree/api/shipments/cannot_ready_shipment", status: :unprocessable_entity
|
||||
return
|
||||
end
|
||||
end
|
||||
respond_with(@shipment, default_template: :show)
|
||||
end
|
||||
|
||||
def ship
|
||||
authorize! :read, Shipment
|
||||
unless @shipment.shipped?
|
||||
@shipment.ship!
|
||||
end
|
||||
respond_with(@shipment, default_template: :show)
|
||||
end
|
||||
|
||||
def add
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
respond_with(@shipment, default_template: :show)
|
||||
end
|
||||
|
||||
def remove
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.remove(variant, quantity, @shipment)
|
||||
@shipment.reload if @shipment.persisted?
|
||||
|
||||
respond_with(@shipment, default_template: :show)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_order
|
||||
@order = Spree::Order.find_by_number!(params[:order_id])
|
||||
authorize! :read, @order
|
||||
end
|
||||
|
||||
def find_and_update_shipment
|
||||
@shipment = @order.shipments.find_by_number!(params[:id])
|
||||
@shipment.update_attributes(params[:shipment])
|
||||
@shipment.reload
|
||||
end
|
||||
|
||||
def scoped_variant(variant_id)
|
||||
variant = Spree::Variant.find(variant_id)
|
||||
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
|
||||
variant
|
||||
end
|
||||
|
||||
def get_or_create_shipment(stock_location_id)
|
||||
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
75
app/controllers/spree/api/taxons_controller.rb
Normal file
75
app/controllers/spree/api/taxons_controller.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
module Spree
|
||||
module Api
|
||||
class TaxonsController < Spree::Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
if taxonomy
|
||||
@taxons = taxonomy.root.children
|
||||
else
|
||||
if params[:ids]
|
||||
@taxons = Taxon.where(id: params[:ids].split(","))
|
||||
else
|
||||
@taxons = Taxon.ransack(params[:q]).result
|
||||
end
|
||||
end
|
||||
respond_with(@taxons)
|
||||
end
|
||||
|
||||
def show
|
||||
@taxon = taxon
|
||||
respond_with(@taxon)
|
||||
end
|
||||
|
||||
def jstree
|
||||
show
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Taxon
|
||||
@taxon = Taxon.new(params[:taxon])
|
||||
@taxon.taxonomy_id = params[:taxonomy_id]
|
||||
taxonomy = Taxonomy.find_by_id(params[:taxonomy_id])
|
||||
|
||||
if taxonomy.nil?
|
||||
@taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api')
|
||||
invalid_resource!(@taxon) && return
|
||||
end
|
||||
|
||||
@taxon.parent_id = taxonomy.root.id unless params[:taxon][:parent_id]
|
||||
|
||||
if @taxon.save
|
||||
respond_with(@taxon, status: 201, default_template: :show)
|
||||
else
|
||||
invalid_resource!(@taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Taxon
|
||||
if taxon.update_attributes(params[:taxon])
|
||||
respond_with(taxon, status: 200, default_template: :show)
|
||||
else
|
||||
invalid_resource!(taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Taxon
|
||||
taxon.destroy
|
||||
respond_with(taxon, status: 204)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def taxonomy
|
||||
return if params[:taxonomy_id].blank?
|
||||
@taxonomy ||= Taxonomy.find(params[:taxonomy_id])
|
||||
end
|
||||
|
||||
def taxon
|
||||
@taxon ||= taxonomy.taxons.find(params[:id])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -38,6 +38,10 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def nav_bar
|
||||
render partial: 'spree/shared/nav_bar'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def accurate_title
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
module GeneralSettingsHelper
|
||||
def currency_options
|
||||
currencies = ::Money::Currency.table.map do |_code, details|
|
||||
iso = details[:iso_code]
|
||||
[iso, "#{details[:name]} (#{iso})"]
|
||||
end
|
||||
options_from_collection_for_select(currencies, :first, :last, Spree::Config[:currency])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
module Spree
|
||||
module Admin
|
||||
module TaxonsHelper
|
||||
def taxon_path(taxon)
|
||||
taxon.ancestors.reverse.collect(&:name).join( " >> ")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,43 +13,8 @@ module Calculator
|
||||
|
||||
def compute(object)
|
||||
line_items = line_items_for object
|
||||
(total_weight(line_items) * preferred_per_kg).round(2)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def total_weight(line_items)
|
||||
line_items.sum do |line_item|
|
||||
line_item_weight(line_item)
|
||||
end
|
||||
end
|
||||
|
||||
def line_item_weight(line_item)
|
||||
if line_item.final_weight_volume.present?
|
||||
weight_per_final_weight_volume(line_item)
|
||||
else
|
||||
weight_per_variant(line_item) * line_item.quantity
|
||||
end
|
||||
end
|
||||
|
||||
def weight_per_variant(line_item)
|
||||
line_item.variant.andand.weight || 0
|
||||
end
|
||||
|
||||
def weight_per_final_weight_volume(line_item)
|
||||
if line_item.variant.product.andand.variant_unit == 'weight'
|
||||
# Divided by 1000 because grams is the base weight unit and the calculator price is per_kg
|
||||
line_item.final_weight_volume / 1000.0
|
||||
else
|
||||
weight_per_variant(line_item) * quantity_implied_in_final_weight_volume(line_item)
|
||||
end
|
||||
end
|
||||
|
||||
# Example: 2 (line_item.quantity) wine glasses of 125mL (line_item.variant.unit_value)
|
||||
# Customer ends up getting 350mL (line_item.final_weight_volume) of wine
|
||||
# that represent 2.8 (quantity_implied_in_final_weight_volume) glasses of wine
|
||||
def quantity_implied_in_final_weight_volume(line_item)
|
||||
(1.0 * line_item.final_weight_volume / line_item.variant.unit_value).round(3)
|
||||
total_weight = line_items.sum { |li| ((li.variant.andand.weight || 0) * li.quantity) }
|
||||
total_weight * preferred_per_kg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,7 +19,7 @@ module OrderShipment
|
||||
#
|
||||
# @return [ShippingMethod]
|
||||
def shipping_method
|
||||
return if shipments.blank?
|
||||
return if shipments.empty?
|
||||
shipments.first.shipping_method
|
||||
end
|
||||
|
||||
|
||||
@@ -25,21 +25,36 @@ module VariantStock
|
||||
#
|
||||
# @return [Float|Integer]
|
||||
def on_hand
|
||||
warn_deprecation(__method__, '#total_on_hand')
|
||||
|
||||
total_on_hand
|
||||
end
|
||||
|
||||
# Sets the stock level of the variant.
|
||||
# This will only work if there is a stock item for the variant.
|
||||
# This will only work if `track_inventory_levels` config is set
|
||||
# and if there is a stock item for the variant.
|
||||
#
|
||||
# @raise [StandardError] when the variant has no stock item
|
||||
# @raise [StandardError] when the track_inventory_levels config key is not set
|
||||
# and when the variant has no stock item
|
||||
def on_hand=(new_level)
|
||||
warn_deprecation(__method__, '#total_on_hand')
|
||||
|
||||
error = 'Cannot set on_hand value when Spree::Config[:track_inventory_levels] is false'
|
||||
raise error unless Spree::Config.track_inventory_levels
|
||||
|
||||
raise_error_if_no_stock_item_available
|
||||
|
||||
overwrite_stock_levels(new_level)
|
||||
end
|
||||
|
||||
# Checks whether this variant is produced on demand.
|
||||
#
|
||||
# In Spree 2.0 this attribute is removed in favour of
|
||||
# track_inventory_levels only. It was initially introduced in
|
||||
# https://github.com/openfoodfoundation/spree/commit/20b5ad9835dca7f41a40ad16c7b45f987eea6dcc
|
||||
def on_demand
|
||||
warn_deprecation(__method__, 'StockItem#backorderable?')
|
||||
|
||||
# A variant that has not been saved yet, doesn't have a stock item
|
||||
# This provides a default value for variant.on_demand using Spree::StockLocation.backorderable_default
|
||||
return Spree::StockLocation.first.backorderable_default if stock_items.empty?
|
||||
@@ -54,6 +69,8 @@ module VariantStock
|
||||
#
|
||||
# @raise [StandardError] when the variant has no stock item yet
|
||||
def on_demand=(new_value)
|
||||
warn_deprecation(__method__, 'StockItem#backorderable=')
|
||||
|
||||
raise_error_if_no_stock_item_available
|
||||
|
||||
# There should be only one at the default stock location.
|
||||
@@ -72,6 +89,8 @@ module VariantStock
|
||||
# Here we depend only on variant.total_on_hand and variant.on_demand.
|
||||
# This way, variant_overrides only need to override variant.total_on_hand and variant.on_demand.
|
||||
def can_supply?(quantity)
|
||||
return true unless Spree::Config[:track_inventory_levels]
|
||||
|
||||
on_demand || total_on_hand >= quantity
|
||||
end
|
||||
|
||||
@@ -81,13 +100,13 @@ module VariantStock
|
||||
# Here we depend only on variant.total_on_hand and variant.on_demand.
|
||||
# This way, variant_overrides only need to override variant.total_on_hand and variant.on_demand.
|
||||
def fill_status(quantity)
|
||||
on_hand = if total_on_hand >= quantity || on_demand
|
||||
quantity
|
||||
else
|
||||
[0, total_on_hand].max
|
||||
end
|
||||
|
||||
backordered = 0
|
||||
if on_hand >= quantity
|
||||
on_hand = quantity
|
||||
backordered = 0
|
||||
else
|
||||
on_hand = [0, total_on_hand].max
|
||||
backordered = on_demand ? (quantity - on_hand) : 0
|
||||
end
|
||||
|
||||
[on_hand, backordered]
|
||||
end
|
||||
@@ -98,9 +117,6 @@ module VariantStock
|
||||
def move(quantity, originator = nil)
|
||||
raise_error_if_no_stock_item_available
|
||||
|
||||
# Don't change variant stock if variant is on_demand
|
||||
return if on_demand
|
||||
|
||||
# Creates a stock movement: it updates stock_item.count_on_hand and fills backorders
|
||||
#
|
||||
# This is the original Spree::StockLocation#move,
|
||||
@@ -139,4 +155,11 @@ module VariantStock
|
||||
def stock_item
|
||||
stock_items.first
|
||||
end
|
||||
|
||||
def warn_deprecation(method_name, new_method_name)
|
||||
ActiveSupport::Deprecation.warn(
|
||||
"`##{method_name}` is deprecated and will be removed. " \
|
||||
"Please use `#{new_method_name}` instead."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -207,15 +207,12 @@ class AbilityDecorator
|
||||
end
|
||||
|
||||
def add_order_management_abilities(user)
|
||||
# Enterprise User can only access orders that they are a distributor for
|
||||
can [:index, :create], Spree::Order
|
||||
can [:read, :update, :fire, :resend, :invoice, :print, :print_ticket], Spree::Order do |order|
|
||||
# We allow editing orders with a nil distributor as this state occurs
|
||||
# during the order creation process from the admin backend
|
||||
order.distributor.nil? ||
|
||||
# Enterprise User can access orders that they are a distributor for
|
||||
user.enterprises.include?(order.distributor) ||
|
||||
# Enterprise User can access orders that are placed inside a OC they coordinate
|
||||
order.order_cycle.andand.coordinated_by?(user)
|
||||
order.distributor.nil? || user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
|
||||
end
|
||||
can [:admin, :bulk_management, :managed], Spree::Order do
|
||||
user.admin? || user.enterprises.any?(&:is_distributor)
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
module Spree
|
||||
Price.class_eval do
|
||||
acts_as_paranoid without_default_scope: true
|
||||
|
||||
after_save :refresh_products_cache
|
||||
|
||||
# Allow prices to access associated soft-deleted variants.
|
||||
def variant
|
||||
Spree::Variant.unscoped { super }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_price
|
||||
|
||||
@@ -32,7 +32,7 @@ module Spree
|
||||
# NOTE: This is an override of spree's method, needed to allow orders
|
||||
# without line items (ie. user invoices) to not have inventory units
|
||||
def require_inventory
|
||||
return false unless line_items.count > 0 # This line altered
|
||||
return false unless Spree::Config[:track_inventory_levels] && line_items.count > 0 # This line altered
|
||||
order.completed? && !order.canceled?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -91,11 +91,6 @@ Spree::Variant.class_eval do
|
||||
can_supply?(quantity)
|
||||
end
|
||||
|
||||
# Allow variant to access associated soft-deleted prices.
|
||||
def default_price
|
||||
Spree::Price.unscoped { super }
|
||||
end
|
||||
|
||||
def price_with_fees(distributor, order_cycle)
|
||||
price + fees_for(distributor, order_cycle)
|
||||
end
|
||||
|
||||
@@ -10,11 +10,6 @@ class SubscriptionLineItem < ActiveRecord::Base
|
||||
(price_estimate || 0) * (quantity || 0)
|
||||
end
|
||||
|
||||
# Ensure SubscriptionLineItem always has access to soft-deleted Variant attribute
|
||||
def variant
|
||||
Spree::Variant.unscoped { super }
|
||||
end
|
||||
|
||||
# Used to calculators to estimate fees
|
||||
alias_method :amount, :total_estimate
|
||||
|
||||
|
||||
6
app/overrides/admin_tab.rb
Normal file
6
app/overrides/admin_tab.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
Deface::Override.new(virtual_path: "spree/layouts/admin",
|
||||
name: "user_admin_tabs",
|
||||
insert_bottom: "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
|
||||
partial: "spree/admin/users_tab",
|
||||
disabled: false,
|
||||
original: '031652cf5a054796022506622082ab6d2693699f')
|
||||
5
app/overrides/auth_admin_login_navigation_bar.rb
Normal file
5
app/overrides/auth_admin_login_navigation_bar.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
Deface::Override.new(virtual_path: "spree/layouts/admin",
|
||||
name: "auth_admin_login_navigation_bar",
|
||||
insert_top: "[data-hook='admin_login_navigation_bar'], #admin_login_navigation_bar[data-hook]",
|
||||
partial: "spree/layouts/admin/login_nav",
|
||||
original: '841227d0aedf7909d62237d8778df99100087715')
|
||||
6
app/overrides/auth_shared_login_bar.rb
Normal file
6
app/overrides/auth_shared_login_bar.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
Deface::Override.new(virtual_path: "spree/shared/_nav_bar",
|
||||
name: "auth_shared_login_bar",
|
||||
insert_before: "li#search-bar",
|
||||
partial: "spree/shared/login_bar",
|
||||
disabled: false,
|
||||
original: 'eb3fa668cd98b6a1c75c36420ef1b238a1fc55ac')
|
||||
3
app/overrides/remove_search_bar.rb
Normal file
3
app/overrides/remove_search_bar.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
Deface::Override.new(virtual_path: "spree/shared/_nav_bar",
|
||||
remove: "#search-bar",
|
||||
name: "search_removal")
|
||||
3
app/overrides/remove_side_bar.rb
Normal file
3
app/overrides/remove_side_bar.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
Deface::Override.new(virtual_path: "spree/shared/_sidebar",
|
||||
remove: "#sidebar",
|
||||
name: "sidebar_removal")
|
||||
5
app/overrides/set_auth_token_in_backend.rb
Normal file
5
app/overrides/set_auth_token_in_backend.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
Deface::Override.new(virtual_path: "spree/layouts/admin",
|
||||
insert_bottom: "[data-hook='admin_inside_head']",
|
||||
partial: "layouts/auth_token_script",
|
||||
name: "set_auth_token_in_backend",
|
||||
original: '6bc2c5de1c8f7542d033548557437c9fe4b3ba02')
|
||||
5
app/overrides/set_auth_token_in_frontend.rb
Normal file
5
app/overrides/set_auth_token_in_frontend.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
Deface::Override.new(virtual_path: "spree/layouts/spree_application",
|
||||
insert_bottom: "[data-hook='inside_head']",
|
||||
partial: "layouts/auth_token_script",
|
||||
name: "set_auth_token_in_frontend",
|
||||
original: '5659ac7dbf6ac6469907b005b85285b894677815')
|
||||
@@ -0,0 +1,5 @@
|
||||
<!-- surround_contents 'body' -->
|
||||
|
||||
<div <%= yield(:app_wrapper_attrs).strip.html_safe %>>
|
||||
<%= render_original %>
|
||||
</div>
|
||||
19
app/overrides/spree/shared/_footer/footer.html.haml.deface
Normal file
19
app/overrides/spree/shared/_footer/footer.html.haml.deface
Normal file
@@ -0,0 +1,19 @@
|
||||
/ replace "footer"
|
||||
|
||||
-#= render partial: "shared/footer"
|
||||
%footer
|
||||
%hr/
|
||||
|
||||
-#.row
|
||||
-#.seven.columns.offset-by-three
|
||||
-#%center
|
||||
-#%h1 What is open food network?
|
||||
-#%p
|
||||
-#%i
|
||||
-#Open food network is an online space in which people can connect with, trade and sell food directly with
|
||||
-#Australian farmers. We aim to reconnect people with their food.
|
||||
-#%hr/
|
||||
|
||||
-#.row
|
||||
-#.five.columns.secondary.offset-by-seven.secondary
|
||||
-#All rights reserved. © 2013 Open Food Foundation
|
||||
@@ -0,0 +1,8 @@
|
||||
/ replace "#logo"
|
||||
|
||||
%figure#logo.columns.eight
|
||||
- if 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
|
||||
@@ -0,0 +1,2 @@
|
||||
/ set_attributes '#top-nav-bar'
|
||||
/ attributes({:class => "columns eight"})
|
||||
@@ -0,0 +1,5 @@
|
||||
/ insert_before "#password-credentials"
|
||||
|
||||
- if @unconfirmed_email
|
||||
%p.alert-box
|
||||
= t('spree.users.show.unconfirmed_email', unconfirmed_email: @unconfirmed_email)
|
||||
@@ -4,11 +4,7 @@ class Api::AddressSerializer < ActiveModel::Serializer
|
||||
|
||||
attributes :id, :zipcode, :city, :state_name, :state_id,
|
||||
:phone, :firstname, :lastname, :address1, :address2, :city, :country_id,
|
||||
:zipcode, :country_name
|
||||
|
||||
def country_name
|
||||
object.country.andand.name
|
||||
end
|
||||
:zipcode
|
||||
|
||||
def state_name
|
||||
object.state.andand.abbr
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
module Api
|
||||
class AdjustmentSerializer < ActiveModel::Serializer
|
||||
attributes :id, :amount, :label, :eligible,
|
||||
:source_type, :source_id,
|
||||
:adjustable_type, :adjustable_id,
|
||||
:originator_type, :originator_id
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
class Api::Admin::BasicEnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category,
|
||||
:payment_method_ids, :shipping_method_ids, :producer_profile_only, :permalink
|
||||
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :payment_method_ids, :shipping_method_ids
|
||||
attributes :producer_profile_only, :permalink
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Api::Admin::CustomerSerializer < ActiveModel::Serializer
|
||||
attributes :id, :email, :enterprise_id, :user_id, :code, :tags, :tag_list, :name,
|
||||
:allow_charges, :default_card_present?
|
||||
attributes :id, :email, :enterprise_id, :user_id, :code, :tags, :tag_list, :name
|
||||
attributes :allow_charges, :default_card_present?
|
||||
|
||||
has_one :ship_address, serializer: Api::AddressSerializer
|
||||
has_one :bill_address, serializer: Api::AddressSerializer
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Api::Admin::EnterpriseFeeSerializer < ActiveModel::Serializer
|
||||
attributes :id, :enterprise_id, :fee_type, :name, :tax_category_id, :inherits_tax_category,
|
||||
:calculator_type, :enterprise_name, :calculator_description, :calculator_settings
|
||||
attributes :id, :enterprise_id, :fee_type, :name, :tax_category_id, :inherits_tax_category, :calculator_type
|
||||
attributes :enterprise_name, :calculator_description, :calculator_settings
|
||||
|
||||
def enterprise_name
|
||||
object.enterprise.andand.name
|
||||
@@ -16,9 +16,7 @@ class Api::Admin::EnterpriseFeeSerializer < ActiveModel::Serializer
|
||||
result = nil
|
||||
|
||||
options[:controller].__send__(:with_format, :html) do
|
||||
result = options[:controller].
|
||||
render_to_string(partial: 'admin/enterprise_fees/calculator_settings',
|
||||
locals: { enterprise_fee: object })
|
||||
result = options[:controller].render_to_string partial: 'admin/enterprise_fees/calculator_settings', locals: { enterprise_fee: object }
|
||||
end
|
||||
|
||||
result.gsub('[0]', '[{{ $index }}]').gsub('_0_', '_{{ $index }}_')
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :permalink,
|
||||
:payment_method_ids, :shipping_method_ids, :producer_profile_only, :long_description,
|
||||
:preferred_shopfront_message, :preferred_shopfront_closed_message,
|
||||
:preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order,
|
||||
:preferred_product_selection_from_inventory_only,
|
||||
:owner, :contact, :users, :tag_groups, :default_tag_group,
|
||||
:require_login, :allow_guest_orders, :allow_order_changes,
|
||||
:logo, :promo_image
|
||||
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :payment_method_ids, :shipping_method_ids
|
||||
attributes :producer_profile_only, :long_description, :permalink
|
||||
attributes :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order
|
||||
attributes :preferred_product_selection_from_inventory_only
|
||||
attributes :owner, :contact, :users, :tag_groups, :default_tag_group
|
||||
attributes :require_login, :allow_guest_orders, :allow_order_changes
|
||||
attributes :logo, :promo_image
|
||||
|
||||
has_one :owner, serializer: Api::Admin::UserSerializer
|
||||
has_many :users, serializer: Api::Admin::UserSerializer
|
||||
@@ -22,9 +21,7 @@ class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
|
||||
|
||||
def tag_groups
|
||||
object.tag_rules.prioritised.reject(&:is_default).each_with_object([]) do |tag_rule, tag_groups|
|
||||
tag_group = find_match(tag_groups, tag_rule.preferred_customer_tags.
|
||||
split(",").
|
||||
map{ |t| { text: t } })
|
||||
tag_group = find_match(tag_groups, tag_rule.preferred_customer_tags.split(",").map{ |t| { text: t } })
|
||||
if tag_group[:rules].empty?
|
||||
tag_groups << tag_group
|
||||
tag_group[:position] = tag_groups.count
|
||||
@@ -35,16 +32,13 @@ class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
|
||||
|
||||
def default_tag_group
|
||||
default_rules = object.tag_rules.select(&:is_default)
|
||||
serialized_rules =
|
||||
ActiveModel::ArraySerializer.new(default_rules,
|
||||
each_serializer: Api::Admin::TagRuleSerializer)
|
||||
serialized_rules = ActiveModel::ArraySerializer.new(default_rules, each_serializer: Api::Admin::TagRuleSerializer)
|
||||
{ tags: [], rules: serialized_rules }
|
||||
end
|
||||
|
||||
def find_match(tag_groups, tags)
|
||||
tag_groups.each do |tag_group|
|
||||
return tag_group if tag_group[:tags].length == tags.length &&
|
||||
(tag_group[:tags] & tags) == tag_group[:tags]
|
||||
return tag_group if tag_group[:tags].length == tags.length && (tag_group[:tags] & tags) == tag_group[:tags]
|
||||
end
|
||||
{ tags: tags, rules: [] }
|
||||
end
|
||||
@@ -62,7 +56,7 @@ class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
|
||||
# # medium: LOGO_MEDIUM_URL
|
||||
# # }
|
||||
def attachment_urls(attachment, versions)
|
||||
return unless attachment.file?
|
||||
return unless attachment.exists?
|
||||
|
||||
versions.each_with_object({}) do |version, urls|
|
||||
urls[version] = attachment.url(version)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
class Api::Admin::ExchangeSerializer < ActiveModel::Serializer
|
||||
attributes :id, :sender_id, :receiver_id, :incoming, :variants,
|
||||
:receival_instructions, :pickup_time, :pickup_instructions,
|
||||
:tags, :tag_list
|
||||
attributes :id, :sender_id, :receiver_id, :incoming, :variants, :receival_instructions, :pickup_time, :pickup_instructions
|
||||
attributes :tags, :tag_list
|
||||
|
||||
has_many :enterprise_fees, serializer: Api::Admin::BasicEnterpriseFeeSerializer
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
require 'open_food_network/enterprise_issue_validator'
|
||||
|
||||
class Api::Admin::ForOrderCycle::EnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :managed, :supplied_products,
|
||||
:issues_summary_supplier, :issues_summary_distributor,
|
||||
:is_primary_producer, :is_distributor, :sells
|
||||
attributes :id, :name, :managed, :supplied_products
|
||||
attributes :issues_summary_supplier, :issues_summary_distributor
|
||||
attributes :is_primary_producer, :is_distributor, :sells
|
||||
|
||||
def issues_summary_supplier
|
||||
issues =
|
||||
OpenFoodNetwork::EnterpriseIssueValidator.
|
||||
new(object).
|
||||
issues_summary(confirmation_only: true)
|
||||
|
||||
issues = OpenFoodNetwork::EnterpriseIssueValidator.new(object).issues_summary confirmation_only: true
|
||||
if issues.nil? && products.empty?
|
||||
issues = "no products in inventory"
|
||||
end
|
||||
@@ -27,8 +23,7 @@ class Api::Admin::ForOrderCycle::EnterpriseSerializer < ActiveModel::Serializer
|
||||
|
||||
def supplied_products
|
||||
serializer = Api::Admin::ForOrderCycle::SuppliedProductSerializer
|
||||
ActiveModel::ArraySerializer.new(products, each_serializer: serializer,
|
||||
order_cycle: order_cycle)
|
||||
ActiveModel::ArraySerializer.new(products, each_serializer: serializer, order_cycle: order_cycle)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
require 'open_food_network/enterprise_issue_validator'
|
||||
|
||||
class Api::Admin::IndexEnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :permalink, :is_primary_producer, :sells, :producer_profile_only, :owned,
|
||||
:edit_path, :issues, :warnings
|
||||
attributes :name, :id, :permalink, :is_primary_producer, :sells, :producer_profile_only, :owned, :edit_path
|
||||
|
||||
attributes :issues, :warnings
|
||||
|
||||
def owned
|
||||
return true if options[:spree_current_user].admin?
|
||||
|
||||
@@ -5,9 +5,9 @@ module Api
|
||||
class IndexOrderCycleSerializer < ActiveModel::Serializer
|
||||
include OrderCyclesHelper
|
||||
|
||||
attributes :id, :name, :orders_open_at, :orders_close_at, :status, :variant_count, :deletable,
|
||||
:coordinator, :producers, :shops, :viewing_as_coordinator,
|
||||
:edit_path, :clone_path, :delete_path, :subscriptions_count
|
||||
attributes :id, :name, :orders_open_at, :orders_close_at, :status, :variant_count, :deletable
|
||||
attributes :coordinator, :producers, :shops, :viewing_as_coordinator
|
||||
attributes :edit_path, :clone_path, :delete_path, :subscriptions_count
|
||||
|
||||
has_many :schedules, serializer: Api::Admin::IdNameSerializer
|
||||
|
||||
@@ -68,10 +68,7 @@ module Api
|
||||
private
|
||||
|
||||
def visible_enterprises
|
||||
@visible_enterprises ||=
|
||||
OpenFoodNetwork::OrderCyclePermissions.
|
||||
new(options[:current_user], object).
|
||||
visible_enterprises
|
||||
@visible_enterprises ||= OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object).visible_enterprises
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
class Api::Admin::LineItemSerializer < ActiveModel::Serializer
|
||||
attributes :id, :quantity, :max_quantity, :price, :supplier, :final_weight_volume,
|
||||
:units_product, :units_variant
|
||||
attributes :id, :quantity, :max_quantity, :price, :supplier, :final_weight_volume, :units_product, :units_variant
|
||||
|
||||
has_one :order, serializer: Api::Admin::IdSerializer
|
||||
|
||||
@@ -21,8 +20,7 @@ class Api::Admin::LineItemSerializer < ActiveModel::Serializer
|
||||
end
|
||||
|
||||
def max_quantity
|
||||
return object.quantity unless object.max_quantity.present? &&
|
||||
object.max_quantity > object.quantity
|
||||
return object.quantity unless object.max_quantity.present? && object.max_quantity > object.quantity
|
||||
object.max_quantity
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
require 'open_food_network/order_cycle_permissions'
|
||||
|
||||
class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :orders_open_at, :orders_close_at, :coordinator_id, :exchanges,
|
||||
:editable_variants_for_incoming_exchanges, :editable_variants_for_outgoing_exchanges,
|
||||
:visible_variants_for_outgoing_exchanges,
|
||||
:viewing_as_coordinator, :schedule_ids, :subscriptions_count
|
||||
attributes :id, :name, :orders_open_at, :orders_close_at, :coordinator_id, :exchanges
|
||||
attributes :editable_variants_for_incoming_exchanges, :editable_variants_for_outgoing_exchanges
|
||||
attributes :visible_variants_for_outgoing_exchanges
|
||||
attributes :viewing_as_coordinator, :schedule_ids, :subscriptions_count
|
||||
|
||||
has_many :coordinator_fees, serializer: Api::IdSerializer
|
||||
|
||||
@@ -25,14 +25,8 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
|
||||
end
|
||||
|
||||
def exchanges
|
||||
scoped_exchanges =
|
||||
OpenFoodNetwork::OrderCyclePermissions.
|
||||
new(options[:current_user], object).
|
||||
visible_exchanges.by_enterprise_name
|
||||
|
||||
ActiveModel::ArraySerializer.
|
||||
new(scoped_exchanges, each_serializer: Api::Admin::ExchangeSerializer,
|
||||
current_user: options[:current_user])
|
||||
scoped_exchanges = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object).visible_exchanges.by_enterprise_name
|
||||
ActiveModel::ArraySerializer.new(scoped_exchanges, each_serializer: Api::Admin::ExchangeSerializer, current_user: options[:current_user])
|
||||
end
|
||||
|
||||
def editable_variants_for_incoming_exchanges
|
||||
@@ -72,13 +66,9 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
|
||||
# for shops. We need this here to allow hubs to restrict visible variants to only those in
|
||||
# their inventory if they so choose
|
||||
variants = if enterprise.prefers_product_selection_from_inventory_only?
|
||||
permissions.
|
||||
visible_variants_for_outgoing_exchanges_to(enterprise).
|
||||
visible_for(enterprise)
|
||||
permissions.visible_variants_for_outgoing_exchanges_to(enterprise).visible_for(enterprise)
|
||||
else
|
||||
permissions.
|
||||
visible_variants_for_outgoing_exchanges_to(enterprise).
|
||||
not_hidden_for(enterprise)
|
||||
permissions.visible_variants_for_outgoing_exchanges_to(enterprise).not_hidden_for(enterprise)
|
||||
end.pluck(:id)
|
||||
visible[enterprise.id] = variants if variants.any?
|
||||
end
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
class Api::Admin::OrderSerializer < ActiveModel::Serializer
|
||||
attributes :id, :number, :user_id, :full_name, :email, :phone, :completed_at, :display_total,
|
||||
:edit_path, :state, :payment_state, :shipment_state,
|
||||
:payments_path, :ship_path, :ready_to_ship, :created_at,
|
||||
:distributor_name, :special_instructions, :payment_capture_path,
|
||||
:item_total, :adjustment_total, :payment_total, :total
|
||||
attributes :id, :number, :full_name, :email, :phone, :completed_at, :display_total
|
||||
attributes :edit_path, :state, :payment_state, :shipment_state
|
||||
attributes :payments_path, :ship_path, :ready_to_ship, :created_at
|
||||
attributes :distributor_name, :special_instructions, :payment_capture_path
|
||||
|
||||
has_one :distributor, serializer: Api::Admin::IdSerializer
|
||||
has_one :order_cycle, serializer: Api::Admin::IdSerializer
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
module Api
|
||||
module Admin
|
||||
class SubscriptionSerializer < ActiveModel::Serializer
|
||||
attributes :id, :shop_id, :customer_id, :schedule_id, :payment_method_id, :shipping_method_id,
|
||||
:begins_at, :ends_at,
|
||||
:customer_email, :schedule_name, :edit_path, :canceled_at, :paused_at, :state,
|
||||
:shipping_fee_estimate, :payment_fee_estimate
|
||||
attributes :id, :shop_id, :customer_id, :schedule_id, :payment_method_id, :shipping_method_id, :begins_at, :ends_at
|
||||
attributes :customer_email, :schedule_name, :edit_path, :canceled_at, :paused_at, :state
|
||||
attributes :shipping_fee_estimate, :payment_fee_estimate
|
||||
|
||||
has_many :subscription_line_items, serializer: Api::Admin::SubscriptionLineItemSerializer
|
||||
has_many :closed_proxy_orders, serializer: Api::Admin::ProxyOrderSerializer
|
||||
|
||||
@@ -16,8 +16,7 @@ module Api::Admin::TagRule
|
||||
end
|
||||
|
||||
class FilterShippingMethodsSerializer < BaseSerializer
|
||||
attributes :preferred_matched_shipping_methods_visibility, :preferred_shipping_method_tags,
|
||||
:shipping_method_tags
|
||||
attributes :preferred_matched_shipping_methods_visibility, :preferred_shipping_method_tags, :shipping_method_tags
|
||||
|
||||
def shipping_method_tags
|
||||
object.preferred_shipping_method_tags.split(",")
|
||||
@@ -25,8 +24,7 @@ module Api::Admin::TagRule
|
||||
end
|
||||
|
||||
class FilterPaymentMethodsSerializer < BaseSerializer
|
||||
attributes :preferred_matched_payment_methods_visibility, :preferred_payment_method_tags,
|
||||
:payment_method_tags
|
||||
attributes :preferred_matched_payment_methods_visibility, :preferred_payment_method_tags, :payment_method_tags
|
||||
|
||||
def payment_method_tags
|
||||
object.preferred_payment_method_tags.split(",")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Api::Admin::VariantOverrideSerializer < ActiveModel::Serializer
|
||||
attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand, :default_stock,
|
||||
:resettable, :tag_list, :tags, :import_date
|
||||
attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand, :default_stock, :resettable
|
||||
attributes :tag_list, :tags, :import_date
|
||||
|
||||
def tag_list
|
||||
object.tag_list.join(",")
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class Api::Admin::VariantSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :producer_name, :image, :sku, :import_date,
|
||||
:options_text, :unit_value, :unit_description, :unit_to_display,
|
||||
:display_as, :display_name, :name_to_display,
|
||||
:price, :on_demand, :on_hand, :in_stock, :stock_location_id, :stock_location_name
|
||||
attributes :id, :name, :producer_name, :image, :sku, :import_date
|
||||
attributes :options_text, :unit_value, :unit_description, :unit_to_display
|
||||
attributes :display_as, :display_name, :name_to_display
|
||||
attributes :price, :on_demand, :on_hand, :in_stock, :stock_location_id, :stock_location_name
|
||||
|
||||
has_many :variant_overrides
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
module Api
|
||||
class OrderDetailedSerializer < Api::Admin::OrderSerializer
|
||||
has_one :shipping_method, serializer: Api::ShippingMethodSerializer
|
||||
has_one :ship_address, serializer: Api::AddressSerializer
|
||||
has_one :bill_address, serializer: Api::AddressSerializer
|
||||
|
||||
has_many :line_items, serializer: Api::LineItemSerializer
|
||||
has_many :adjustments, serializer: Api::AdjustmentSerializer
|
||||
|
||||
has_many :payments, serializer: Api::PaymentSerializer
|
||||
end
|
||||
end
|
||||
@@ -1,9 +1,9 @@
|
||||
module Api
|
||||
class OrderSerializer < ActiveModel::Serializer
|
||||
attributes :number, :completed_at, :total, :state, :shipment_state, :payment_state,
|
||||
:outstanding_balance, :payments, :path, :cancel_path,
|
||||
:changes_allowed, :changes_allowed_until, :item_count,
|
||||
:shop_id
|
||||
attributes :number, :completed_at, :total, :state, :shipment_state, :payment_state
|
||||
attributes :outstanding_balance, :payments, :path, :cancel_path
|
||||
attributes :changes_allowed, :changes_allowed_until, :item_count
|
||||
attributes :shop_id
|
||||
|
||||
has_many :payments, serializer: Api::PaymentSerializer
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module Api
|
||||
class PaymentSerializer < ActiveModel::Serializer
|
||||
attributes :amount, :updated_at, :payment_method, :state
|
||||
|
||||
def payment_method
|
||||
object.payment_method.try(:name)
|
||||
end
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
module Api
|
||||
class ShipmentSerializer < ActiveModel::Serializer
|
||||
attributes :id, :tracking, :number, :order_id, :cost, :shipped_at, :stock_location_name, :state
|
||||
|
||||
def order_id
|
||||
object.order.number
|
||||
end
|
||||
|
||||
def stock_location_name
|
||||
object.stock_location.name
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
module Api
|
||||
class TaxonJstreeAttributeSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name
|
||||
end
|
||||
end
|
||||
@@ -1,18 +0,0 @@
|
||||
module Api
|
||||
class TaxonJstreeSerializer < ActiveModel::Serializer
|
||||
attributes :data, :state
|
||||
has_one :attr, serializer: TaxonJstreeAttributeSerializer
|
||||
|
||||
def data
|
||||
object.name
|
||||
end
|
||||
|
||||
def attr
|
||||
object
|
||||
end
|
||||
|
||||
def state
|
||||
"closed"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,7 @@ class Api::TaxonSerializer < ActiveModel::Serializer
|
||||
cached
|
||||
delegate :cache_key, to: :object
|
||||
|
||||
attributes :id, :name, :permalink, :icon, :pretty_name, :position, :parent_id, :taxonomy_id
|
||||
attributes :id, :name, :permalink, :icon
|
||||
|
||||
def icon
|
||||
object.icon(:original)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class Api::VariantSerializer < ActiveModel::Serializer
|
||||
attributes :id, :is_master, :product_name, :sku,
|
||||
:options_text, :unit_value, :unit_description, :unit_to_display,
|
||||
:display_as, :display_name, :name_to_display,
|
||||
:price, :on_demand, :on_hand, :fees, :price_with_fees,
|
||||
:tag_list
|
||||
attributes :id, :is_master, :product_name, :sku
|
||||
attributes :options_text, :unit_value, :unit_description, :unit_to_display
|
||||
attributes :display_as, :display_name, :name_to_display
|
||||
attributes :price, :on_demand, :on_hand, :fees, :price_with_fees
|
||||
attributes :tag_list
|
||||
|
||||
delegate :price, to: :object
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# Encapsulates the concept of default stock location in creation of a product or a shipping method.
|
||||
|
||||
class DefaultShippingCategory
|
||||
NAME = 'Default'.freeze
|
||||
|
||||
def self.create!
|
||||
Spree::ShippingCategory.create!(name: NAME)
|
||||
end
|
||||
|
||||
def self.find_or_create
|
||||
Spree::ShippingCategory.find_or_create_by_name(NAME)
|
||||
end
|
||||
end
|
||||
@@ -73,9 +73,7 @@ class EmbeddedPageService
|
||||
|
||||
def current_referer
|
||||
return if @request.referer.blank?
|
||||
uri = URI(@request.referer)
|
||||
return if uri.host.blank?
|
||||
uri.host.downcase
|
||||
URI(@request.referer).host.downcase
|
||||
end
|
||||
|
||||
def current_referer_without_www
|
||||
|
||||
@@ -1,75 +1,41 @@
|
||||
# Returns a (paginatable) AR object for the products or variants in stock for a given shop and OC.
|
||||
# The stock-checking includes on_demand and stock level overrides from variant_overrides.
|
||||
# Finds valid products distributed by a particular distributor in an order cycle
|
||||
#
|
||||
# If a product without variants is added to an order cycle, and then some
|
||||
# variants are added to that product, but not the order cycle, then the master
|
||||
# variant should not available for customers to purchase. This class filters
|
||||
# out such products so that the customer cannot purchase them.
|
||||
class OrderCycleDistributedProducts
|
||||
def initialize(distributor, order_cycle)
|
||||
@distributor = distributor
|
||||
def initialize(order_cycle, distributor)
|
||||
@order_cycle = order_cycle
|
||||
@distributor = distributor
|
||||
end
|
||||
|
||||
def products_relation
|
||||
Spree::Product.where(id: stocked_products)
|
||||
end
|
||||
# Returns an ActiveRecord relation without invalid products. Check
|
||||
# #valid_products_distributed_by for details
|
||||
#
|
||||
# @return [ActiveRecord::Relation<Spree::Product>]
|
||||
def relation
|
||||
variants = order_cycle.variants_distributed_by(distributor)
|
||||
products = variants.map(&:product).uniq
|
||||
|
||||
def variants_relation
|
||||
@order_cycle.
|
||||
variants_distributed_by(@distributor).
|
||||
merge(stocked_variants_and_overrides)
|
||||
valid_products = products.reject do |product|
|
||||
product_has_only_obsolete_master_in_distribution?(product, variants)
|
||||
end
|
||||
product_ids = valid_products.map(&:id)
|
||||
|
||||
Spree::Product.where(id: product_ids)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stocked_products
|
||||
@order_cycle.
|
||||
variants_distributed_by(@distributor).
|
||||
merge(stocked_variants_and_overrides).
|
||||
select("DISTINCT spree_variants.product_id")
|
||||
end
|
||||
attr_reader :order_cycle, :distributor
|
||||
|
||||
def stocked_variants_and_overrides
|
||||
Spree::Variant.
|
||||
joins("LEFT OUTER JOIN variant_overrides ON variant_overrides.variant_id = spree_variants.id
|
||||
AND variant_overrides.hub_id = #{@distributor.id}").
|
||||
joins(:stock_items).
|
||||
where(query_stock_with_overrides)
|
||||
end
|
||||
|
||||
def query_stock_with_overrides
|
||||
"( #{variant_not_overriden} AND ( #{variant_on_demand} OR #{variant_in_stock} ) )
|
||||
OR ( #{variant_overriden} AND ( #{override_on_demand} OR #{override_in_stock} ) )
|
||||
OR ( #{variant_overriden} AND ( #{override_on_demand_null} AND #{variant_on_demand} ) )
|
||||
OR ( #{variant_overriden} AND ( #{override_on_demand_null}
|
||||
AND #{variant_not_on_demand} AND #{variant_in_stock} ) )"
|
||||
end
|
||||
|
||||
def variant_not_overriden
|
||||
"variant_overrides.id IS NULL"
|
||||
end
|
||||
|
||||
def variant_overriden
|
||||
"variant_overrides.id IS NOT NULL"
|
||||
end
|
||||
|
||||
def variant_in_stock
|
||||
"spree_stock_items.count_on_hand > 0"
|
||||
end
|
||||
|
||||
def variant_on_demand
|
||||
"spree_stock_items.backorderable IS TRUE"
|
||||
end
|
||||
|
||||
def variant_not_on_demand
|
||||
"spree_stock_items.backorderable IS FALSE"
|
||||
end
|
||||
|
||||
def override_on_demand
|
||||
"variant_overrides.on_demand IS TRUE"
|
||||
end
|
||||
|
||||
def override_in_stock
|
||||
"variant_overrides.count_on_hand > 0"
|
||||
end
|
||||
|
||||
def override_on_demand_null
|
||||
"variant_overrides.on_demand IS NULL"
|
||||
# If a product without variants is added to an order cycle, and then some variants are added
|
||||
# to that product, but not the order cycle, then the master variant should not available for
|
||||
# customers to purchase.
|
||||
def product_has_only_obsolete_master_in_distribution?(product, distributed_variants)
|
||||
product.has_variants? &&
|
||||
distributed_variants.include?(product.master) &&
|
||||
(product.variants & distributed_variants).empty?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,8 +9,8 @@ class SubscriptionValidator
|
||||
|
||||
attr_reader :subscription
|
||||
|
||||
validates :shop, :customer, :schedule, :shipping_method, :payment_method, presence: true
|
||||
validates :bill_address, :ship_address, :begins_at, presence: true
|
||||
validates_presence_of :shop, :customer, :schedule, :shipping_method, :payment_method
|
||||
validates_presence_of :bill_address, :ship_address, :begins_at
|
||||
validate :shipping_method_allowed?
|
||||
validate :payment_method_allowed?
|
||||
validate :payment_method_type_allowed?
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
%h1.page-title
|
||||
=t :customers
|
||||
|
||||
- content_for :main_ng_app_name do
|
||||
= "admin.customers"
|
||||
- content_for :app_wrapper_attrs do
|
||||
= "ng-app='admin.customers'"
|
||||
|
||||
- content_for :page_actions do
|
||||
%li
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
= t('.editing')
|
||||
= @enterprise.name
|
||||
|
||||
- content_for :main_ng_app_name do
|
||||
= "admin.enterprises"
|
||||
- content_for :app_wrapper_attrs do
|
||||
= "ng-app='admin.enterprises'"
|
||||
|
||||
- content_for :page_actions do
|
||||
%li= select :enterprise, :id, options_for_select(editable_enterprises.collect {|e| [e.name, e.id, {:'data-url' => "#{main_app.edit_admin_enterprise_path(e.permalink)}", :'ng-selected' => "selected==#{e.id}"}]}, @enterprise.id ), {}, {:'enterprise-switcher' => '', 'data-initial' => "#{@enterprise.id}", :'ng-init' => "selected='#{@enterprise.id}'", :'ng-model' => 'selected', :id => 'enterprise_switcher', :class => 'select2'}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- content_for :page_title do
|
||||
= t('.title')
|
||||
|
||||
- content_for :main_ng_app_name do
|
||||
= "admin.enterprises"
|
||||
- content_for :app_wrapper_attrs do
|
||||
= "ng-app='admin.enterprises'"
|
||||
|
||||
- content_for :page_actions do
|
||||
= render 'admin/shared/user_guide_link'
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
- content_for :page_actions do
|
||||
%li= button_link_to t('.back_link'), main_app.admin_enterprises_path, icon: 'icon-arrow-left'
|
||||
|
||||
- content_for :main_ng_app_name do
|
||||
= "admin.enterprises"
|
||||
- content_for :app_wrapper_attrs do
|
||||
= "ng-app='admin.enterprises'"
|
||||
|
||||
= admin_inject_available_countries(module: 'admin.enterprises')
|
||||
= admin_inject_json "admin.enterprises", "defaultCountryID", Spree::Config[:default_country_id]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
= content_for :page_title do
|
||||
= t :admin_order_cycles
|
||||
|
||||
- content_for :main_ng_app_name do
|
||||
= "admin.orderCycles"
|
||||
- content_for :app_wrapper_attrs do
|
||||
= "ng-app='admin.orderCycles'"
|
||||
|
||||
= content_for :page_actions do
|
||||
- if subscriptions_enabled?
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- content_for :page_title do
|
||||
= t('admin.subscriptions.subscriptions')
|
||||
|
||||
- content_for :main_ng_app_name do
|
||||
= "admin.subscriptions"
|
||||
- content_for :app_wrapper_attrs do
|
||||
= "ng-app='admin.subscriptions'"
|
||||
|
||||
- content_for :page_actions do
|
||||
%li
|
||||
|
||||
@@ -146,3 +146,13 @@
|
||||
= t '.footer_data_text_without_privacy_policy_html', {cookies_policy: cookies_policy_link.html_safe }
|
||||
.medium-2.columns.text-center
|
||||
/ Placeholder
|
||||
-if ENV['SKYLIGHT_PUBLIC_DASHBOARD_URL'].present?
|
||||
.row
|
||||
.small-12.medium-8.medium-offset-2.columns.text-center
|
||||
%hr.hr-light
|
||||
%br
|
||||
|
||||
.row
|
||||
.small-12.medium-8.medium-offset-2.columns.text-center
|
||||
.text.small
|
||||
= t '.footer_skylight_dashboard_html', {dashboard: link_to('Skylight', ENV['SKYLIGHT_PUBLIC_DASHBOARD_URL'], target: "_blank")}
|
||||
|
||||
2
app/views/spree/admin/_users_tab.html.haml
Normal file
2
app/views/spree/admin/_users_tab.html.haml
Normal file
@@ -0,0 +1,2 @@
|
||||
- if can? :admin, Spree::User
|
||||
= tab(:users, url: spree.admin_users_path, icon: 'icon-user')
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
- content_for :page_title do
|
||||
%i.icon-arrow-right
|
||||
= t(:adjustments)
|
||||
= Spree.t(:adjustments)
|
||||
|
||||
- content_for :page_actions do
|
||||
%li= button_link_to t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus'
|
||||
%li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
|
||||
%li= button_link_to Spree.t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus'
|
||||
%li= button_link_to Spree.t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
= render :partial => 'adjustments_table'
|
||||
|
||||
= button_link_to t(:continue), @order.cart? ? new_admin_order_payment_url(@order) : admin_orders_url, :icon => 'icon-arrow-right'
|
||||
= button_link_to Spree.t(:continue), @order.cart? ? new_admin_order_payment_url(@order) : admin_orders_url, :icon => 'icon-arrow-right'
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
.row
|
||||
.alpha.four.columns
|
||||
.field
|
||||
= f.label :name, t("spree.name")
|
||||
= f.text_field :name, class: 'fullwidth'
|
||||
.four.columns
|
||||
.field
|
||||
= f.label :iso_name, t("spree.iso_name")
|
||||
= f.text_field :iso_name, class: 'fullwidth'
|
||||
.omega.four.columns
|
||||
.field.checkbox
|
||||
%label
|
||||
= f.check_box :states_required
|
||||
= t("spree.states_required")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user