From 8dbe4accaf8c6ec78ca4e58cd03ed68be7a603b3 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Wed, 27 Feb 2019 16:27:34 +0000 Subject: [PATCH 001/507] Upgrade to the spree branch 2-1-0-stable and rails 4.0.0 --- Gemfile | 46 +-- Gemfile.lock | 347 +++++++++--------- .../spree/paypal_controller_decorator.rb | 45 --- app/helpers/application_helper.rb | 2 +- app/models/enterprise.rb | 2 +- config/initializers/rack_rewrite.rb | 4 +- config/initializers/simple_form.rb | 138 ------- 7 files changed, 197 insertions(+), 387 deletions(-) delete mode 100644 app/controllers/spree/paypal_controller_decorator.rb delete mode 100644 config/initializers/simple_form.rb diff --git a/Gemfile b/Gemfile index aa468612b3..322c12ea3c 100644 --- a/Gemfile +++ b/Gemfile @@ -4,13 +4,12 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" } gem 'i18n', '~> 0.6.11' gem 'i18n-js', '~> 3.6.0' -gem 'rails', '~> 3.2.22' -gem 'rails-i18n', '~> 3.0.0' +gem 'rails', '~> 4.0.0' +# gem 'rails-i18n', '~> 4.0' gem 'rails_safe_tasks', '~> 1.0' gem "activerecord-import" -# Patched version. See http://rubysec.com/advisories/CVE-2015-5312/. -gem 'nokogiri', '>= 1.6.7.1' +gem 'nokogiri', '~> 1.6.8.1' gem "order_management", path: "./engines/order_management" gem 'web', path: './engines/web' @@ -21,22 +20,23 @@ gem 'pg', '~> 0.21.0' # OFN-maintained and patched version of Spree v2.0.4. See # https://github.com/openfoodfoundation/openfoodnetwork/wiki/Tech-Doc:-OFN's-Spree-fork%F0%9F%8D%B4 # for details. -gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-0-4-stable' +gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-1-0-stable' gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable' +gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-1-stable', ref: '1c436c738d0f086b2ca0f75a977ac16bc6cb98b9' # Our branch contains two changes # - Pass customer email and phone number to PayPal (merged to upstream master) # - Change type of password from string to password to hide it in the form -gem 'spree_paypal_express', github: "openfoodfoundation/better_spree_paypal_express", branch: "2-0-stable" +# gem 'spree_paypal_express', github: "openfoodfoundation/better_spree_paypal_express", branch: "2-0-stable" gem 'stripe' # We need at least this version to have Digicert's root certificate # which is needed for Pin Payments (and possibly others). -gem 'activemerchant', '~> 1.78' +gem 'activemerchant', '~> 1.78.0' -gem 'devise', '~> 2.2.5' -gem 'devise-encryptable', '0.2.0' +gem 'devise', '~> 3.0.1' +gem 'devise-encryptable' gem 'jwt', '~> 2.2' gem 'oauth2', '~> 1.4.4' # Used for Stripe Connect @@ -46,7 +46,7 @@ gem 'delayed_job_web' # Fix bug in simple_form preventing collection_check_boxes usage within form_for block # When merged, revert to upstream gem -gem 'simple_form', github: 'RohanM/simple_form' +# gem 'simple_form', github: 'RohanM/simple_form' # Spree's default pagination gem (locked to the current version used by Spree) # We use it's methods in OFN code as well, so this is a direct dependency @@ -60,20 +60,21 @@ gem 'db2fog' gem 'haml' gem 'rabl' gem 'redcarpet' -gem 'sass', "~> 3.3" -gem 'sass-rails', '~> 3.2.3', groups: [:default, :assets] +#gem 'sass', "~> 3.3" +gem 'sass-rails', groups: [:default, :assets] gem 'truncate_html' gem 'unicorn' # AMS is pinned to 0.8.4 because 0.9.x is a complete re-write, as is 0.10.x # Once Rails is updated to 5.x we should bump directly to 0.10.x gem "active_model_serializers", "0.8.4" +gem 'activerecord-session_store' gem 'acts-as-taggable-on', '~> 3.4' gem 'angularjs-file-upload-rails', '~> 2.4.1' gem 'blockenspiel' gem 'custom_error_message', github: 'jeremydurham/custom-err-msg' gem 'dalli' -gem 'deface', '1.0.2' +gem 'deface' gem 'diffy' gem 'figaro' gem 'geocoder' @@ -81,6 +82,7 @@ gem 'gmaps4rails' gem 'oj' gem 'paper_trail', '~> 5.2.3' gem 'paperclip', '~> 3.4.1' +gem 'protected_attributes' gem 'rack-rewrite' gem 'rack-ssl', require: 'rack/ssl' gem 'roadie-rails', '~> 1.3.0' @@ -101,7 +103,7 @@ gem 'test-unit', '~> 3.3' # Gems used only for assets and not required # in production environments by default. group :assets do - gem 'coffee-rails', '~> 3.2.1' + gem 'coffee-rails', '~> 4.0.0' gem 'compass-rails' gem 'mini_racer', '0.2.9' @@ -111,18 +113,18 @@ group :assets do gem 'angular-rails-templates', '~> 0.3.0' gem 'foundation-icons-sass-rails' gem 'momentjs-rails' - gem 'turbo-sprockets-rails3' + # gem 'turbo-sprockets-rails3' end -gem "foundation-rails" -gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: "rails3" +gem 'foundation-rails', '= 5.5.2.1' +gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: 'rails3' gem 'jquery-migrate-rails' gem 'jquery-rails', '3.0.4' gem 'jquery-ui-rails', '~> 4.0.0' gem 'select2-rails', '~> 3.4.7' -gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', ref: '60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c' +# gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', ref: '60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c' group :production, :staging do gem 'ddtrace' @@ -134,8 +136,8 @@ group :test, :development do gem 'awesome_print' gem 'capybara', '>= 2.18.0' # 3.0 requires nokogiri 1.8 gem 'database_cleaner', '0.7.1', require: false - gem "factory_bot_rails", require: false - gem 'fuubar', '~> 2.5.0' + gem "factory_bot_rails", '4.8.2', require: false + gem 'fuubar', '~> 2.4.1' gem 'json_spec', '~> 1.1.4' gem 'knapsack' gem 'letter_opener', '>= 1.4.1' @@ -162,8 +164,8 @@ group :development do gem 'pry-byebug', '>= 3.4.3' gem 'rubocop' gem 'rubocop-rails' - gem 'spring', '1.7.2' - gem 'spring-commands-rspec' + #gem 'spring' + #gem 'spring-commands-rspec' # 1.0.9 fixed openssl issues on macOS https://github.com/eventmachine/eventmachine/issues/602 # While we don't require this gem directly, no dependents forced the upgrade to a version diff --git a/Gemfile.lock b/Gemfile.lock index 7a0d3c5f64..79f00de2e5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,59 +1,54 @@ -GIT - remote: https://github.com/RohanM/simple_form.git - revision: 45f08a213b40f3d4bda5f5398db841137587160a - specs: - simple_form (2.0.2) - actionpack (~> 3.0) - activemodel (~> 3.0) - GIT remote: https://github.com/jeremydurham/custom-err-msg.git revision: 3a8ec9dddc7a5b0aab7c69a6060596de300c68f4 specs: custom_error_message (1.1.1) -GIT - remote: https://github.com/openfoodfoundation/better_spree_paypal_express.git - revision: 27ad7165ea4c6e8c5f120b42b676cb9c2c272100 - branch: 2-0-stable - specs: - spree_paypal_express (2.0.3) - paypal-sdk-merchant (= 1.106.1) - spree_core (~> 2.0.3) - -GIT - remote: https://github.com/openfoodfoundation/ofn-qz.git - revision: 60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c - ref: 60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c - specs: - ofn-qz (0.1.0) - railties (~> 3.1) - GIT remote: https://github.com/openfoodfoundation/spree.git - revision: 8a8585a43cd04d1a50dc65227f337a91b18d66d5 - branch: 2-0-4-stable + revision: 95d3ccb32f2e4016d0fc73f39446d1739da56c50 + branch: 2-1-0-stable specs: - spree_core (2.0.4) - activemerchant (~> 1.34) + spree_core (2.1.0) + activemerchant (= 1.78.0) acts_as_list (= 0.2.0) - awesome_nested_set (= 2.1.5) - aws-sdk (~> 1.11.1) + awesome_nested_set (~> 3.0.0.rc.1) + aws-sdk (= 1.11.1) cancan (~> 1.6.10) - deface (>= 0.9.1) + deface (>= 1.0.0.rc3) ffaker (~> 1.16) highline (= 1.6.18) httparty (~> 0.11) json (>= 1.7.7) kaminari (~> 0.14.1) money (= 5.1.1) - paperclip (~> 3.0) - paranoia (~> 1.3) - rails (~> 3.2.14) - ransack (= 0.7.2) + paperclip (~> 3.4.1) + paranoia (~> 2.0) + rails (~> 4.0.0) + ransack (= 1.0.0) state_machine (= 1.2.0) stringex (~> 1.5.1) truncate_html (= 0.9.2) + spree_frontend (2.1.0) + canonical-rails + jquery-rails (~> 3.0.0) + spree_api (= 2.1.0) + spree_core (= 2.1.0) + stringex (~> 1.5.1) + +GIT + remote: https://github.com/spree/spree_auth_devise.git + revision: 1c436c738d0f086b2ca0f75a977ac16bc6cb98b9 + ref: 1c436c738d0f086b2ca0f75a977ac16bc6cb98b9 + branch: 2-1-stable + specs: + spree_auth_devise (2.1.0) + cancan (~> 1.6.7) + devise (~> 3.0.1) + devise-encryptable (= 0.1.2) + spree_backend (~> 2.1.0.beta) + spree_core (~> 2.1.0.beta) + spree_frontend (~> 2.1.0.beta) GIT remote: https://github.com/spree/spree_i18n.git @@ -89,19 +84,15 @@ GEM remote: https://rubygems.org/ specs: CFPropertyList (2.3.6) - actionmailer (3.2.22.5) - actionpack (= 3.2.22.5) - mail (~> 2.5.4) - actionpack (3.2.22.5) - activemodel (= 3.2.22.5) - activesupport (= 3.2.22.5) - builder (~> 3.0.0) + actionmailer (4.0.13) + actionpack (= 4.0.13) + mail (~> 2.5, >= 2.5.4) + actionpack (4.0.13) + activesupport (= 4.0.13) + builder (~> 3.1.0) erubis (~> 2.7.0) - journey (~> 1.0.4) - rack (~> 1.4.5) - rack-cache (~> 1.2) - rack-test (~> 0.6.1) - sprockets (~> 2.2.1) + rack (~> 1.5.2) + rack-test (~> 0.6.2) active_model_serializers (0.8.4) activemodel (>= 3.0) activemerchant (1.78.0) @@ -109,24 +100,31 @@ GEM builder (>= 2.1.2, < 4.0.0) i18n (>= 0.6.9) nokogiri (~> 1.4) - activemodel (3.2.22.5) - activesupport (= 3.2.22.5) - builder (~> 3.0.0) - activerecord (3.2.22.5) - activemodel (= 3.2.22.5) - activesupport (= 3.2.22.5) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activerecord-import (1.0.4) + activemodel (4.0.13) + activesupport (= 4.0.13) + builder (~> 3.1.0) + activerecord (4.0.13) + activemodel (= 4.0.13) + activerecord-deprecated_finders (~> 1.0.2) + activesupport (= 4.0.13) + arel (~> 4.0.0) + activerecord-deprecated_finders (1.0.4) + activerecord-import (1.0.3) activerecord (>= 3.2) activerecord-postgresql-adapter (0.0.1) pg - activeresource (3.2.22.5) - activemodel (= 3.2.22.5) - activesupport (= 3.2.22.5) - activesupport (3.2.22.5) - i18n (~> 0.6, >= 0.6.4) - multi_json (~> 1.0) + activerecord-session_store (1.1.3) + actionpack (>= 4.0) + activerecord (>= 4.0) + multi_json (~> 1.11, >= 1.11.2) + rack (>= 1.5.2, < 3) + railties (>= 4.0) + activesupport (4.0.13) + i18n (~> 0.6, >= 0.6.9) + minitest (~> 4.2) + multi_json (~> 1.3) + thread_safe (~> 0.1) + tzinfo (~> 0.3.37) acts-as-taggable-on (3.5.0) activerecord (>= 3.2, < 5) acts_as_list (0.2.0) @@ -140,11 +138,11 @@ GEM tilt angularjs-file-upload-rails (2.4.1) angularjs-rails (1.5.5) - arel (3.0.3) + arel (4.0.2) ast (2.4.0) atomic (1.1.101) - awesome_nested_set (2.1.5) - activerecord (>= 3.0.0) + awesome_nested_set (3.0.3) + activerecord (>= 4.0.0, < 5) awesome_print (1.8.0) aws-sdk (1.11.1) json (~> 1.4) @@ -156,9 +154,11 @@ GEM blockenspiel (0.5.0) bugsnag (6.13.0) concurrent-ruby (~> 1.0) - builder (3.0.4) + builder (3.1.4) byebug (9.0.6) cancan (1.6.10) + canonical-rails (0.1.0) + rails (>= 3.1, < 5.1) capybara (2.18.0) addressable mini_mime (>= 0.1.3) @@ -168,18 +168,18 @@ GEM xpath (>= 2.0, < 4.0) childprocess (3.0.0) chronic (0.10.2) - chunky_png (1.3.10) + chunky_png (1.3.11) climate_control (0.2.0) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) coderay (1.1.2) - coffee-rails (3.2.2) + coffee-rails (4.0.1) coffee-script (>= 2.2.0) - railties (~> 3.2.0) + railties (>= 4.0.0, < 5.0) coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.10.0) + coffee-script-source (1.12.2) colorize (0.8.1) combine_pdf (1.0.16) ruby-rc4 (>= 0.1.5) @@ -202,7 +202,7 @@ GEM concurrent-ruby (1.1.5) crack (0.4.3) safe_yaml (~> 1.0.0) - css_parser (1.7.0) + css_parser (1.7.1) addressable daemons (1.3.1) dalli (2.7.10) @@ -229,12 +229,12 @@ GEM delayed_job (> 2.0.3) rack-protection (>= 1.5.5) sinatra (>= 1.4.4) - devise (2.2.8) + devise (3.0.4) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.1) - railties (~> 3.1) - warden (~> 1.2.1) - devise-encryptable (0.2.0) + railties (>= 3.2.6, < 5) + warden (~> 1.2.3) + devise-encryptable (0.1.2) devise (>= 2.1.0) diff-lcs (1.3) diffy (3.3.0) @@ -244,14 +244,14 @@ GEM eventmachine (1.2.7) excon (0.71.1) execjs (2.7.0) - factory_bot (4.10.0) + factory_bot (4.8.2) activesupport (>= 3.0.0) - factory_bot_rails (4.10.0) - factory_bot (~> 4.10.0) + factory_bot_rails (4.8.2) + factory_bot (~> 4.8.2) railties (>= 3.0.0) faraday (1.0.0) multipart-post (>= 1.2, < 3) - ffaker (1.22.1) + ffaker (1.32.1) ffi (1.11.3) figaro (1.1.1) thor (~> 0.14) @@ -291,7 +291,7 @@ GEM fog-xml (~> 0.1.1) ipaddress (~> 0.5) json (>= 1.8, < 2.0) - fog-aliyun (0.3.2) + fog-aliyun (0.3.5) fog-core fog-json ipaddress (~> 0.8) @@ -349,8 +349,8 @@ GEM multi_json (~> 1.10) fog-local (0.6.0) fog-core (>= 1.27, < 3.0) - fog-openstack (0.1.25) - fog-core (~> 1.40) + fog-openstack (0.3.10) + fog-core (>= 1.45, <= 2.1.0) fog-json (>= 1.0) ipaddress (>= 0.8) fog-powerdns (0.2.0) @@ -394,12 +394,13 @@ GEM fog-voxel (0.1.0) fog-core fog-xml - fog-vsphere (2.3.0) + fog-vsphere (3.2.1) fog-core - rbvmomi (~> 1.9) - fog-xenserver (0.3.0) + rbvmomi (>= 1.9, < 3) + fog-xenserver (1.0.0) fog-core fog-xml + xmlrpc fog-xml (0.1.3) fog-core nokogiri (>= 1.5.11, < 2.0.0) @@ -412,17 +413,19 @@ GEM foundation-rails (5.5.2.1) railties (>= 3.1.0) sass (>= 3.3.0, < 3.5) - fuubar (2.5.0) + fuubar (2.4.1) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) - geocoder (1.1.8) - gmaps4rails (1.5.6) - haml (4.0.7) + geocoder (1.5.2) + gmaps4rails (2.1.2) + haml (5.1.2) + temple (>= 0.8.0) tilt hashdiff (1.0.0) highline (1.6.18) hike (1.2.3) - httparty (0.16.2) + httparty (0.17.3) + mime-types (~> 3.0) multi_xml (>= 0.5.2) i18n (0.6.11) i18n-js (3.6.0) @@ -431,7 +434,6 @@ GEM activerecord (>= 3.0) ipaddress (0.8.3) jaro_winkler (1.5.4) - journey (1.0.4) jquery-migrate-rails (1.2.1) jquery-rails (3.0.4) railties (>= 3.0, < 5.0) @@ -454,15 +456,17 @@ GEM letter_opener (1.7.0) launchy (~> 2.2) libv8 (7.3.492.27.1) - mail (2.5.5) - mime-types (~> 1.16) - treetop (~> 1.4.8) + mail (2.7.1) + mini_mime (>= 0.1.1) method_source (0.9.2) - mime-types (1.25.1) - mini_mime (1.0.1) + mime-types (3.3) + mime-types-data (~> 3.2015) + mime-types-data (3.2019.1009) + mini_mime (1.0.2) mini_portile2 (2.1.0) mini_racer (0.2.9) libv8 (>= 6.9.411) + minitest (4.7.5) momentjs-rails (2.20.1) railties (>= 3.1) money (5.1.1) @@ -481,6 +485,7 @@ GEM multi_xml (~> 0.5) rack (>= 1.2, < 3) oj (3.10.2) + optimist (3.0.0) orm_adapter (0.5.0) paper_trail (5.2.3) activerecord (>= 3.0, < 6.0) @@ -492,20 +497,17 @@ GEM cocaine (~> 0.5.0) mime-types parallel (1.19.1) - paranoia (1.3.4) - activerecord (~> 3.1) + paranoia (2.4.2) + activerecord (>= 4.0, < 6.1) parser (2.7.0.2) ast (~> 2.4.0) - paypal-sdk-core (0.2.10) - multi_json (~> 1.0) - xml-simple - paypal-sdk-merchant (1.106.1) - paypal-sdk-core (~> 0.2.3) pg (0.21.0) - polyamorous (0.5.0) - activerecord (~> 3.0) + polyamorous (0.6.4) + activerecord (>= 3.0) polyglot (0.3.5) power_assert (1.1.5) + protected_attributes (1.1.4) + activemodel (>= 4.0.1, < 5.0) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -515,54 +517,48 @@ GEM public_suffix (4.0.3) rabl (0.8.4) activesupport (>= 2.3.14) - rack (1.4.7) - rack-cache (1.9.0) - rack (>= 0.4) + rack (1.5.5) rack-mini-profiler (1.1.6) rack (>= 1.2.0) rack-protection (1.5.5) rack rack-rewrite (1.5.1) - rack-ssl (1.3.4) + rack-ssl (1.4.1) rack rack-test (0.6.3) rack (>= 1.0) - rails (3.2.22.5) - actionmailer (= 3.2.22.5) - actionpack (= 3.2.22.5) - activerecord (= 3.2.22.5) - activeresource (= 3.2.22.5) - activesupport (= 3.2.22.5) - bundler (~> 1.0) - railties (= 3.2.22.5) - rails-i18n (3.0.1) - i18n (~> 0.5) - rails (>= 3.0.0, < 4.0.0) + rails (4.0.13) + actionmailer (= 4.0.13) + actionpack (= 4.0.13) + activerecord (= 4.0.13) + activesupport (= 4.0.13) + bundler (>= 1.3.0, < 2.0) + railties (= 4.0.13) + sprockets-rails (~> 2.0) + rails-i18n (4.0.5) + i18n (~> 0.6) + railties (~> 4.0) rails_safe_tasks (1.0.0) - railties (3.2.22.5) - actionpack (= 3.2.22.5) - activesupport (= 3.2.22.5) - rack-ssl (~> 1.3.2) + railties (4.0.13) + actionpack (= 4.0.13) + activesupport (= 4.0.13) rake (>= 0.8.7) - rdoc (~> 3.4) - thor (>= 0.14.6, < 2.0) + thor (>= 0.18.1, < 2.0) rainbow (3.0.0) raindrops (0.19.1) - rake (13.0.0) - ransack (0.7.2) - actionpack (~> 3.0) - activerecord (~> 3.0) - polyamorous (~> 0.5.0) + rake (13.0.1) + ransack (1.0.0) + actionpack (>= 3.0) + activerecord (>= 3.0) + polyamorous (~> 0.6.0) rb-fsevent (0.10.3) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - rbvmomi (1.13.0) + rb-inotify (0.10.0) + ffi (~> 1.0) + rbvmomi (2.2.0) builder (~> 3.0) json (>= 1.8) nokogiri (~> 1.5) - trollop (~> 2.1) - rdoc (3.12.2) - json (~> 1.4) + optimist (~> 3.0) redcarpet (3.5.0) request_store (1.4.1) rack (>= 1.4) @@ -610,58 +606,57 @@ GEM rubocop-rails (2.4.2) rack (>= 1.1) rubocop (>= 0.72.0) + ruby-ole (1.2.12.2) ruby-progressbar (1.10.1) ruby-rc4 (0.1.5) rubyzip (1.3.0) safe_yaml (1.0.5) - sass (3.3.14) - sass-rails (3.2.6) - railties (~> 3.2.0) - sass (>= 3.1.10) - tilt (~> 1.3) + sass (3.4.25) + sass-rails (5.0.7) + railties (>= 4.0.0, < 6) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) select2-rails (3.4.9) sass-rails thor (~> 0.14) selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) - shoulda-matchers (2.8.0) - activesupport (>= 3.0.0) + shoulda-matchers (3.1.3) + activesupport (>= 4.0.0) simplecov (0.17.1) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) - sinatra (1.4.6) - rack (~> 1.4) + sinatra (1.4.8) + rack (~> 1.5) rack-protection (~> 1.4) tilt (>= 1.3, < 3) spinjs-rails (1.4) rails (>= 3.1) - spring (1.7.2) - spring-commands-rspec (1.0.4) - spring (>= 0.9.1) - sprockets (2.2.3) + sprockets (2.12.5) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) + sprockets-rails (2.3.3) + actionpack (>= 3.0) + activesupport (>= 3.0) + sprockets (>= 2.8, < 4.0) state_machine (1.2.0) stringex (1.5.1) stripe (5.11.0) test-unit (3.3.5) + temple (0.8.2) power_assert thor (0.20.3) + thread_safe (0.3.6) tilt (1.4.1) timecop (0.9.1) - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) - trollop (2.9.9) truncate_html (0.9.2) - turbo-sprockets-rails3 (0.3.14) - railties (> 3.2.8, < 4.0.0) - sprockets (>= 2.2.0) tzinfo (0.3.56) uglifier (4.2.0) execjs (>= 0.3.0, < 3) @@ -683,11 +678,13 @@ GEM addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - whenever (0.11.0) + whenever (1.0.0) chronic (>= 0.6.3) - wicked_pdf (1.1.0) + wicked_pdf (1.4.0) + activesupport wkhtmltopdf-binary (0.12.5) xml-simple (1.1.5) + xmlrpc (0.3.0) xpath (2.1.0) nokogiri (~> 1.3) @@ -696,9 +693,10 @@ PLATFORMS DEPENDENCIES active_model_serializers (= 0.8.4) - activemerchant (~> 1.78) + activemerchant (~> 1.78.0) activerecord-import activerecord-postgresql-adapter + activerecord-session_store acts-as-taggable-on (~> 3.4) andand angular-rails-templates (~> 0.3.0) @@ -711,7 +709,7 @@ DEPENDENCIES bugsnag byebug (~> 9.0.0) capybara (>= 2.18.0) - coffee-rails (~> 3.2.1) + coffee-rails (~> 4.0.0) combine_pdf compass-rails custom_error_message! @@ -721,20 +719,20 @@ DEPENDENCIES db2fog ddtrace debugger-linecache - deface (= 1.0.2) + deface delayed_job_active_record delayed_job_web - devise (~> 2.2.5) - devise-encryptable (= 0.2.0) + devise (~> 3.0.1) + devise-encryptable diffy eventmachine (>= 1.2.3) - factory_bot_rails + factory_bot_rails (= 4.8.2) figaro foreigner foundation-icons-sass-rails - foundation-rails + foundation-rails (= 5.5.2.1) foundation_rails_helper! - fuubar (~> 2.5.0) + fuubar (~> 2.4.1) geocoder gmaps4rails haml @@ -752,21 +750,20 @@ DEPENDENCIES mini_racer (= 0.2.9) momentjs-rails newrelic_rpm (~> 3.0) - nokogiri (>= 1.6.7.1) + nokogiri (~> 1.6.8.1) oauth2 (~> 1.4.4) - ofn-qz! oj order_management! paper_trail (~> 5.2.3) paperclip (~> 3.4.1) pg (~> 0.21.0) + protected_attributes pry-byebug (>= 3.4.3) rabl rack-mini-profiler (< 2.0.0) rack-rewrite rack-ssl - rails (~> 3.2.22) - rails-i18n (~> 3.0.0) + rails (~> 4.0.0) rails_safe_tasks (~> 1.0) redcarpet roadie-rails (~> 1.3.0) @@ -775,24 +772,18 @@ DEPENDENCIES rspec-retry rubocop rubocop-rails - sass (~> 3.3) sass-rails (~> 3.2.3) select2-rails (~> 3.4.7) selenium-webdriver shoulda-matchers - simple_form! simplecov spinjs-rails spree_core! spree_i18n! - spree_paypal_express! - spring (= 1.7.2) - spring-commands-rspec stripe test-unit (~> 3.3) timecop truncate_html - turbo-sprockets-rails3 uglifier (>= 1.0.3) unicorn unicorn-rails diff --git a/app/controllers/spree/paypal_controller_decorator.rb b/app/controllers/spree/paypal_controller_decorator.rb deleted file mode 100644 index 1512299198..0000000000 --- a/app/controllers/spree/paypal_controller_decorator.rb +++ /dev/null @@ -1,45 +0,0 @@ -Spree::PaypalController.class_eval do - before_filter :enable_embedded_shopfront - before_filter :destroy_orphaned_paypal_payments, only: :confirm - after_filter :reset_order_when_complete, only: :confirm - - def cancel - flash[:notice] = Spree.t('flash.cancel', scope: 'paypal') - redirect_to main_app.checkout_path - end - - # Clears the cached order. Required for #current_order to return a new order - # to serve as cart. See https://github.com/spree/spree/blob/1-3-stable/core/lib/spree/core/controller_helpers/order.rb#L14 - # for details. - def expire_current_order - session[:order_id] = nil - @current_order = nil - end - - private - - def reset_order_when_complete - if current_order.complete? - flash[:notice] = t(:order_processed_successfully) - - ResetOrderService.new(self, current_order).call - session[:access_token] = current_order.token - end - end - - # See #1074 and #1837 for more detail on why we need this - # An 'orphaned' Spree::Payment is created for every call to CheckoutController#update - # for orders that are processed using a Spree::Gateway::PayPalExpress payment method - # These payments are 'orphaned' because they are never used by the spree_paypal_express gem - # which creates a brand new Spree::Payment from scratch in PayPalController#confirm - # However, the 'orphaned' payments are useful when applying a transaction fee, because the fees - # need to be calculated before the order details are sent to PayPal for confirmation - # This is our best hook for removing the orphaned payments at an appropriate time. ie. after - # the payment details have been confirmed, but before any payments have been processed - def destroy_orphaned_paypal_payments - return unless payment_method.is_a?(Spree::Gateway::PayPalExpress) - - orphaned_payments = current_order.payments.where(payment_method_id: payment_method.id, source_id: nil) - orphaned_payments.each(&:destroy) - end -end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0142825667..0e66cde722 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,5 +1,5 @@ module ApplicationHelper - include FoundationRailsHelper::FlashHelper + #include FoundationRailsHelper::FlashHelper def feature?(feature) OpenFoodNetwork::FeatureToggle.enabled? feature diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 1deee05a40..a5de267e7e 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -17,7 +17,7 @@ class Enterprise < ActiveRecord::Base self.inheritance_column = nil - acts_as_gmappable process_geocoding: false + # acts_as_gmappable process_geocoding: false has_many :relationships_as_parent, class_name: 'EnterpriseRelationship', foreign_key: 'parent_id', diff --git a/config/initializers/rack_rewrite.rb b/config/initializers/rack_rewrite.rb index 98c93a79f3..251330f9d4 100644 --- a/config/initializers/rack_rewrite.rb +++ b/config/initializers/rack_rewrite.rb @@ -1,7 +1,7 @@ module Openfoodnetwork class Application < Rails::Application - config.middleware.insert_before(Rack::Lock, Rack::Rewrite) do - r301 '/admin/products/bulk_edit', '/admin/products' # TODO: Date added 15/06/2018 + config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do + r301 '/admin/products/bulk_edit', '/admin/products' end end end diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb deleted file mode 100644 index 59c7d2528b..0000000000 --- a/config/initializers/simple_form.rb +++ /dev/null @@ -1,138 +0,0 @@ -# Use this setup block to configure all options available in SimpleForm. -SimpleForm.setup do |config| - # Wrappers are used by the form builder to generate a - # complete input. You can remove any component from the - # wrapper, change the order or even add your own to the - # stack. The options given below are used to wrap the - # whole input. - config.wrappers :default, :class => :input, - :hint_class => :field_with_hint, :error_class => :field_with_errors do |b| - ## Extensions enabled by default - # Any of these extensions can be disabled for a - # given input by passing: `f.input EXTENSION_NAME => false`. - # You can make any of these extensions optional by - # renaming `b.use` to `b.optional`. - - # Determines whether to use HTML5 (:email, :url, ...) - # and required attributes - b.use :html5 - - # Calculates placeholders automatically from I18n - # You can also pass a string as f.input :placeholder => "Placeholder" - b.use :placeholder - - ## Optional extensions - # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup` - # to the input. If so, they will retrieve the values from the model - # if any exists. If you want to enable the lookup for any of those - # extensions by default, you can change `b.optional` to `b.use`. - - # Calculates maxlength from length validations for string inputs - b.optional :maxlength - - # Calculates pattern from format validations for string inputs - b.optional :pattern - - # Calculates min and max from length validations for numeric inputs - b.optional :min_max - - # Calculates readonly automatically from readonly attributes - b.optional :readonly - - ## Inputs - b.use :label_input - b.use :hint, :wrap_with => { :tag => :span, :class => :hint } - b.use :error, :wrap_with => { :tag => :span, :class => :error } - end - - # The default wrapper to be used by the FormBuilder. - config.default_wrapper = :default - - # Define the way to render check boxes / radio buttons with labels. - # Defaults to :nested for bootstrap config. - # :inline => input + label - # :nested => label > input - config.boolean_style = :nested - - # Default class for buttons - config.button_class = 'btn' - - # Method used to tidy up errors. Specify any Rails Array method. - # :first lists the first message for each field. - # Use :to_sentence to list all errors for each field. - # config.error_method = :first - - # Default tag used for error notification helper. - config.error_notification_tag = :div - - # CSS class to add for error notification helper. - config.error_notification_class = 'alert alert-error' - - # ID to add for error notification helper. - # config.error_notification_id = nil - - # Series of attempts to detect a default label method for collection. - # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] - - # Series of attempts to detect a default value method for collection. - # config.collection_value_methods = [ :id, :to_s ] - - # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. - # config.collection_wrapper_tag = nil - - # You can define the class to use on all collection wrappers. Defaulting to none. - # config.collection_wrapper_class = nil - - # You can wrap each item in a collection of radio/check boxes with a tag, - # defaulting to :span. Please note that when using :boolean_style = :nested, - # SimpleForm will force this option to be a label. - # config.item_wrapper_tag = :span - - # You can define a class to use in all item wrappers. Defaulting to none. - # config.item_wrapper_class = nil - - # How the label text should be generated altogether with the required text. - # config.label_text = lambda { |label, required| "#{required} #{label}" } - - # You can define the class to use on all labels. Default is nil. - config.label_class = 'control-label' - - # You can define the class to use on all forms. Default is simple_form. - # config.form_class = :simple_form - - # You can define which elements should obtain additional classes - # config.generate_additional_classes_for = [:wrapper, :label, :input] - - # Whether attributes are required by default (or not). Default is true. - # config.required_by_default = true - - # Tell browsers whether to use default HTML5 validations (novalidate option). - # Default is enabled. - config.browser_validations = false - - # Collection of methods to detect if a file type was given. - # config.file_methods = [ :mounted_as, :file?, :public_filename ] - - # Custom mappings for input types. This should be a hash containing a regexp - # to match as key, and the input type that will be used when the field name - # matches the regexp as value. - # config.input_mappings = { /count/ => :integer } - - # Default priority for time_zone inputs. - # config.time_zone_priority = nil - - # Default priority for country inputs. - # config.country_priority = nil - - # Default size for text inputs. - # config.default_input_size = 50 - - # When false, do not use translations for labels. - # config.translate_labels = true - - # Automatically discover new inputs in Rails' autoload path. - # config.inputs_discovery = true - - # Cache SimpleForm inputs discovery - # config.cache_discovery = !Rails.env.development? -end From 8e747e54a0a781b208d2abc5800dcd9773128485 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Thu, 21 Mar 2019 17:05:33 +0000 Subject: [PATCH 002/507] Setting eager loading on each env configuration --- config/environments/development.rb | 3 +-- config/environments/production.rb | 2 ++ config/environments/staging.rb | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index 20310726cb..3e74942275 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -9,8 +9,7 @@ Openfoodnetwork::Application.configure do # :file_store is used by default when no cache store is specifically configured. # config.cache_store = :file_store - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true + config.eager_load = false # Show full error reports and disable caching config.consider_all_requests_local = true diff --git a/config/environments/production.rb b/config/environments/production.rb index 91ff62a3be..4ab5a11dd4 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,6 +1,8 @@ Openfoodnetwork::Application.configure do # Settings specified here will take precedence over those in config/application.rb + config.eager_load = false + # Code is not reloaded between requests config.cache_classes = true diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 91ff62a3be..4ab5a11dd4 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -1,6 +1,8 @@ Openfoodnetwork::Application.configure do # Settings specified here will take precedence over those in config/application.rb + config.eager_load = false + # Code is not reloaded between requests config.cache_classes = true From 8fe3a8aea4acb123303dd7a4ef3094f605d9baa3 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Thu, 21 Mar 2019 18:19:28 +0000 Subject: [PATCH 003/507] Setting secret key in config/initializers/secret_token.rb --- config/initializers/secret_token.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb index 9aac0efd56..b203cf8485 100644 --- a/config/initializers/secret_token.rb +++ b/config/initializers/secret_token.rb @@ -9,3 +9,5 @@ Openfoodnetwork::Application.config.secret_token = if Rails.env.development? or else ENV["SECRET_TOKEN"] end + +Openfoodnetwork::Application.config.secret_key_base = 'ceb1eb86c50285e696f899b2e7ea306d1ec1e81fe5c7af0e5cbc238bebe3fd60f19df7b9076fab836182821ebe14e41b64bdcdb4370520dc5bb711c1bc0ae616' From c0dc999e0da7f646d6adca767b74a2338d38fabe Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Thu, 21 Mar 2019 18:30:09 +0000 Subject: [PATCH 004/507] Temporarily remove broken specs --- .../spree/paypal_controller_spec.rb | 42 -------------- spec/models/spree/gateway_tagging_spec.rb | 55 ------------------- 2 files changed, 97 deletions(-) delete mode 100644 spec/controllers/spree/paypal_controller_spec.rb delete mode 100644 spec/models/spree/gateway_tagging_spec.rb diff --git a/spec/controllers/spree/paypal_controller_spec.rb b/spec/controllers/spree/paypal_controller_spec.rb deleted file mode 100644 index 90f97fcb7d..0000000000 --- a/spec/controllers/spree/paypal_controller_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'spec_helper' - -module Spree - describe PaypalController, type: :controller do - context 'when cancelling' do - it 'redirects back to checkout' do - expect(spree_get(:cancel)).to redirect_to checkout_path - end - end - - context 'when confirming' do - let(:previous_order) { controller.current_order(true) } - let(:payment_method) { create(:payment_method) } - - before do - allow(previous_order).to receive(:complete?).and_return(true) - end - - it 'resets the order' do - spree_post :confirm, payment_method_id: payment_method.id - expect(controller.current_order).not_to eq(previous_order) - end - - it 'sets the access token of the session' do - spree_post :confirm, payment_method_id: payment_method.id - expect(session[:access_token]).to eq(controller.current_order.token) - end - end - - describe '#expire_current_order' do - it 'empties the order_id of the session' do - expect(session).to receive(:[]=).with(:order_id, nil) - controller.expire_current_order - end - - it 'resets the @current_order ivar' do - controller.expire_current_order - expect(controller.instance_variable_get(:@current_order)).to be_nil - end - end - end -end diff --git a/spec/models/spree/gateway_tagging_spec.rb b/spec/models/spree/gateway_tagging_spec.rb deleted file mode 100644 index 2a5eb5c23e..0000000000 --- a/spec/models/spree/gateway_tagging_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -require "spec_helper" - -# We extended Spree::PaymentMethod to be taggable. Unfortunately, an inheritance -# bug prevented the taggable code to be passed on to the descendants of -# PaymentMethod. We fixed that in config/initializers/spree.rb. -# -# This spec tests several descendants for their taggability. The tests are in -# a separate file, because they cover one aspect of several classes. -shared_examples "taggable" do |expected_taggable_type| - it "provides a tag list" do - expect(subject.tag_list).to eq [] - end - - it "stores tags for the root taggable type" do - subject.tag_list.add("one") - subject.save! - - expect(subject.taggings.last.taggable_type).to eq expected_taggable_type - end -end - -module Spree - describe "PaymentMethod and descendants" do - let(:shop) { create(:enterprise) } - let(:valid_subject) do - # Supply required parameters so that it can be saved to attach taggings. - described_class.new( - name: "Some payment method", - distributor_ids: [shop.id] - ) - end - subject { valid_subject } - - describe PaymentMethod do - it_behaves_like "taggable", "Spree::PaymentMethod" - end - - describe Gateway do - it_behaves_like "taggable", "Spree::PaymentMethod" - end - - describe Gateway::PayPalExpress do - it_behaves_like "taggable", "Spree::PaymentMethod" - end - - describe Gateway::StripeConnect do - subject do - # StripeConnect needs an owner to be valid. - valid_subject.tap { |m| m.preferred_enterprise_id = shop.id } - end - - it_behaves_like "taggable", "Spree::PaymentMethod" - end - end -end From 18ca9980c9f80da609db5116d7a7cc5bd87979ef Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Thu, 21 Mar 2019 19:00:13 +0000 Subject: [PATCH 005/507] Temporarily comment Enterprise.ensure_owner_is_manager otherwise all specs erroring out with 'Enterprise roles invalid' --- app/models/enterprise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index a5de267e7e..28acb0a6ff 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -410,7 +410,7 @@ class Enterprise < ActiveRecord::Base end def ensure_owner_is_manager - users << owner unless users.include?(owner) + #users << owner unless users.include?(owner) end def enforce_ownership_limit From b23ce204887cf7f36f86c8f243b26dc06208484d Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Thu, 21 Mar 2019 21:48:38 +0100 Subject: [PATCH 006/507] Add migration from spree v2.1 --- ...818_add_deleted_at_to_spree_stock_items.rb | 5 + db/schema.rb | 1021 +++++++++-------- 2 files changed, 518 insertions(+), 508 deletions(-) create mode 100644 db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb diff --git a/db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb b/db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb new file mode 100644 index 0000000000..3170545118 --- /dev/null +++ b/db/migrate/20190321203818_add_deleted_at_to_spree_stock_items.rb @@ -0,0 +1,5 @@ +class AddDeletedAtToSpreeStockItems < ActiveRecord::Migration + def up + add_column :spree_stock_items, :deleted_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 288c838266..3aa6f812b0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,11 +9,14 @@ # from scratch. The latter is a flawed and unsustainable approach (the more migrations # you'll amass, the slower it'll run and the greater likelihood for issues). # -# It's strongly recommended to check this file into your version control system. +# It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema.define(:version => 20191023172424) do - create_table "adjustment_metadata", :force => true do |t| + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "adjustment_metadata", force: true do |t| t.integer "adjustment_id" t.integer "enterprise_id" t.string "fee_name" @@ -21,95 +24,95 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "enterprise_role" end - add_index "adjustment_metadata", ["adjustment_id"], :name => "index_adjustment_metadata_on_adjustment_id" - add_index "adjustment_metadata", ["enterprise_id"], :name => "index_adjustment_metadata_on_enterprise_id" + add_index "adjustment_metadata", ["adjustment_id"], name: "index_adjustment_metadata_on_adjustment_id", using: :btree + add_index "adjustment_metadata", ["enterprise_id"], name: "index_adjustment_metadata_on_enterprise_id", using: :btree - create_table "column_preferences", :force => true do |t| - t.integer "user_id", :null => false - t.string "action_name", :null => false - t.string "column_name", :null => false - t.boolean "visible", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "column_preferences", force: true do |t| + t.integer "user_id", null: false + t.string "action_name", null: false + t.string "column_name", null: false + t.boolean "visible", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "column_preferences", ["user_id", "action_name", "column_name"], :name => "index_column_prefs_on_user_id_and_action_name_and_column_name", :unique => true + add_index "column_preferences", ["user_id", "action_name", "column_name"], name: "index_column_prefs_on_user_id_and_action_name_and_column_name", unique: true, using: :btree - create_table "coordinator_fees", :force => true do |t| + create_table "coordinator_fees", force: true do |t| t.integer "order_cycle_id" t.integer "enterprise_fee_id" end - add_index "coordinator_fees", ["enterprise_fee_id"], :name => "index_coordinator_fees_on_enterprise_fee_id" - add_index "coordinator_fees", ["order_cycle_id"], :name => "index_coordinator_fees_on_order_cycle_id" + add_index "coordinator_fees", ["enterprise_fee_id"], name: "index_coordinator_fees_on_enterprise_fee_id", using: :btree + add_index "coordinator_fees", ["order_cycle_id"], name: "index_coordinator_fees_on_order_cycle_id", using: :btree - create_table "customers", :force => true do |t| - t.string "email", :null => false - t.integer "enterprise_id", :null => false + create_table "customers", force: true do |t| + t.string "email", null: false + t.integer "enterprise_id", null: false t.string "code" t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "bill_address_id" t.integer "ship_address_id" t.string "name" - t.boolean "allow_charges", :default => false, :null => false + t.boolean "allow_charges", default: false, null: false end - add_index "customers", ["bill_address_id"], :name => "index_customers_on_bill_address_id" - add_index "customers", ["email"], :name => "index_customers_on_email" - add_index "customers", ["enterprise_id", "code"], :name => "index_customers_on_enterprise_id_and_code", :unique => true - add_index "customers", ["ship_address_id"], :name => "index_customers_on_ship_address_id" - add_index "customers", ["user_id"], :name => "index_customers_on_user_id" + add_index "customers", ["bill_address_id"], name: "index_customers_on_bill_address_id", using: :btree + add_index "customers", ["email"], name: "index_customers_on_email", using: :btree + add_index "customers", ["enterprise_id", "code"], name: "index_customers_on_enterprise_id_and_code", unique: true, using: :btree + add_index "customers", ["ship_address_id"], name: "index_customers_on_ship_address_id", using: :btree + add_index "customers", ["user_id"], name: "index_customers_on_user_id", using: :btree - create_table "delayed_jobs", :force => true do |t| - t.integer "priority", :default => 0, :null => false - t.integer "attempts", :default => 0, :null => false - t.text "handler", :null => false + create_table "delayed_jobs", force: true do |t| + t.integer "priority", default: 0, null: false + t.integer "attempts", default: 0, null: false + t.text "handler", null: false t.text "last_error" t.datetime "run_at" t.datetime "locked_at" t.datetime "failed_at" t.string "locked_by" t.string "queue" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" + add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree - create_table "distributors_payment_methods", :id => false, :force => true do |t| + create_table "distributors_payment_methods", id: false, force: true do |t| t.integer "distributor_id" t.integer "payment_method_id" end - add_index "distributors_payment_methods", ["distributor_id"], :name => "index_distributors_payment_methods_on_distributor_id" - add_index "distributors_payment_methods", ["payment_method_id"], :name => "index_distributors_payment_methods_on_payment_method_id" + add_index "distributors_payment_methods", ["distributor_id"], name: "index_distributors_payment_methods_on_distributor_id", using: :btree + add_index "distributors_payment_methods", ["payment_method_id"], name: "index_distributors_payment_methods_on_payment_method_id", using: :btree - create_table "distributors_shipping_methods", :force => true do |t| + create_table "distributors_shipping_methods", force: true do |t| t.integer "distributor_id" t.integer "shipping_method_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "distributors_shipping_methods", ["distributor_id"], :name => "index_distributors_shipping_methods_on_distributor_id" - add_index "distributors_shipping_methods", ["shipping_method_id"], :name => "index_distributors_shipping_methods_on_shipping_method_id" + add_index "distributors_shipping_methods", ["distributor_id"], name: "index_distributors_shipping_methods_on_distributor_id", using: :btree + add_index "distributors_shipping_methods", ["shipping_method_id"], name: "index_distributors_shipping_methods_on_shipping_method_id", using: :btree - create_table "enterprise_fees", :force => true do |t| + create_table "enterprise_fees", force: true do |t| t.integer "enterprise_id" t.string "fee_type" t.string "name" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "tax_category_id" - t.boolean "inherits_tax_category", :default => false, :null => false + t.boolean "inherits_tax_category", default: false, null: false end - add_index "enterprise_fees", ["enterprise_id"], :name => "index_enterprise_fees_on_enterprise_id" - add_index "enterprise_fees", ["tax_category_id"], :name => "index_enterprise_fees_on_tax_category_id" + add_index "enterprise_fees", ["enterprise_id"], name: "index_enterprise_fees_on_enterprise_id", using: :btree + add_index "enterprise_fees", ["tax_category_id"], name: "index_enterprise_fees_on_tax_category_id", using: :btree - create_table "enterprise_groups", :force => true do |t| + create_table "enterprise_groups", force: true do |t| t.string "name" t.boolean "on_front_page" t.integer "position" @@ -124,56 +127,56 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "logo_file_size" t.datetime "logo_updated_at" t.integer "address_id" - t.string "email", :default => "", :null => false - t.string "website", :default => "", :null => false - t.string "facebook", :default => "", :null => false - t.string "instagram", :default => "", :null => false - t.string "linkedin", :default => "", :null => false - t.string "twitter", :default => "", :null => false + t.string "email", default: "", null: false + t.string "website", default: "", null: false + t.string "facebook", default: "", null: false + t.string "instagram", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false t.integer "owner_id" - t.string "permalink", :null => false + t.string "permalink", null: false end - add_index "enterprise_groups", ["address_id"], :name => "index_enterprise_groups_on_address_id" - add_index "enterprise_groups", ["owner_id"], :name => "index_enterprise_groups_on_owner_id" - add_index "enterprise_groups", ["permalink"], :name => "index_enterprise_groups_on_permalink", :unique => true + add_index "enterprise_groups", ["address_id"], name: "index_enterprise_groups_on_address_id", using: :btree + add_index "enterprise_groups", ["owner_id"], name: "index_enterprise_groups_on_owner_id", using: :btree + add_index "enterprise_groups", ["permalink"], name: "index_enterprise_groups_on_permalink", unique: true, using: :btree - create_table "enterprise_groups_enterprises", :id => false, :force => true do |t| + create_table "enterprise_groups_enterprises", id: false, force: true do |t| t.integer "enterprise_group_id" t.integer "enterprise_id" end - add_index "enterprise_groups_enterprises", ["enterprise_group_id"], :name => "index_enterprise_groups_enterprises_on_enterprise_group_id" - add_index "enterprise_groups_enterprises", ["enterprise_id"], :name => "index_enterprise_groups_enterprises_on_enterprise_id" + add_index "enterprise_groups_enterprises", ["enterprise_group_id"], name: "index_enterprise_groups_enterprises_on_enterprise_group_id", using: :btree + add_index "enterprise_groups_enterprises", ["enterprise_id"], name: "index_enterprise_groups_enterprises_on_enterprise_id", using: :btree - create_table "enterprise_relationship_permissions", :force => true do |t| + create_table "enterprise_relationship_permissions", force: true do |t| t.integer "enterprise_relationship_id" - t.string "name", :null => false + t.string "name", null: false end - add_index "enterprise_relationship_permissions", ["enterprise_relationship_id"], :name => "index_erp_on_erid" + add_index "enterprise_relationship_permissions", ["enterprise_relationship_id"], name: "index_erp_on_erid", using: :btree - create_table "enterprise_relationships", :force => true do |t| + create_table "enterprise_relationships", force: true do |t| t.integer "parent_id" t.integer "child_id" end - add_index "enterprise_relationships", ["child_id"], :name => "index_enterprise_relationships_on_child_id" - add_index "enterprise_relationships", ["parent_id", "child_id"], :name => "index_enterprise_relationships_on_parent_id_and_child_id", :unique => true - add_index "enterprise_relationships", ["parent_id"], :name => "index_enterprise_relationships_on_parent_id" + add_index "enterprise_relationships", ["child_id"], name: "index_enterprise_relationships_on_child_id", using: :btree + add_index "enterprise_relationships", ["parent_id", "child_id"], name: "index_enterprise_relationships_on_parent_id_and_child_id", unique: true, using: :btree + add_index "enterprise_relationships", ["parent_id"], name: "index_enterprise_relationships_on_parent_id", using: :btree - create_table "enterprise_roles", :force => true do |t| + create_table "enterprise_roles", force: true do |t| t.integer "user_id" t.integer "enterprise_id" - t.boolean "receives_notifications", :default => false + t.boolean "receives_notifications", default: false end - add_index "enterprise_roles", ["enterprise_id", "user_id"], :name => "index_enterprise_roles_on_enterprise_id_and_user_id", :unique => true - add_index "enterprise_roles", ["enterprise_id"], :name => "index_enterprise_roles_on_enterprise_id" - add_index "enterprise_roles", ["user_id", "enterprise_id"], :name => "index_enterprise_roles_on_user_id_and_enterprise_id", :unique => true - add_index "enterprise_roles", ["user_id"], :name => "index_enterprise_roles_on_user_id" + add_index "enterprise_roles", ["enterprise_id", "user_id"], name: "index_enterprise_roles_on_enterprise_id_and_user_id", unique: true, using: :btree + add_index "enterprise_roles", ["enterprise_id"], name: "index_enterprise_roles_on_enterprise_id", using: :btree + add_index "enterprise_roles", ["user_id", "enterprise_id"], name: "index_enterprise_roles_on_user_id_and_enterprise_id", unique: true, using: :btree + add_index "enterprise_roles", ["user_id"], name: "index_enterprise_roles_on_user_id", using: :btree - create_table "enterprises", :force => true do |t| + create_table "enterprises", force: true do |t| t.string "name" t.text "description" t.text "long_description" @@ -187,8 +190,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "address_id" t.text "pickup_times" t.string "next_collection_at" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.text "distributor_info" t.string "logo_file_name" t.string "logo_content_type" @@ -198,139 +201,139 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "promo_image_content_type" t.integer "promo_image_file_size" t.datetime "promo_image_updated_at" - t.boolean "visible", :default => true + t.boolean "visible", default: true t.string "facebook" t.string "instagram" t.string "linkedin" - t.integer "owner_id", :null => false - t.string "sells", :default => "none", :null => false - t.boolean "producer_profile_only", :default => false - t.string "permalink", :null => false - t.boolean "charges_sales_tax", :default => false, :null => false + t.integer "owner_id", null: false + t.string "sells", default: "none", null: false + t.boolean "producer_profile_only", default: false + t.string "permalink", null: false + t.boolean "charges_sales_tax", default: false, null: false t.string "email_address" - t.boolean "require_login", :default => false, :null => false - t.boolean "allow_guest_orders", :default => true, :null => false + t.boolean "require_login", default: false, null: false + t.boolean "allow_guest_orders", default: true, null: false t.text "invoice_text" - t.boolean "display_invoice_logo", :default => false - t.boolean "allow_order_changes", :default => false, :null => false - t.boolean "enable_subscriptions", :default => false, :null => false + t.boolean "display_invoice_logo", default: false + t.boolean "allow_order_changes", default: false, null: false + t.boolean "enable_subscriptions", default: false, null: false end - add_index "enterprises", ["address_id"], :name => "index_enterprises_on_address_id" - add_index "enterprises", ["is_primary_producer", "sells"], :name => "index_enterprises_on_is_primary_producer_and_sells" - add_index "enterprises", ["name"], :name => "index_enterprises_on_name", :unique => true - add_index "enterprises", ["owner_id"], :name => "index_enterprises_on_owner_id" - add_index "enterprises", ["permalink"], :name => "index_enterprises_on_permalink", :unique => true - add_index "enterprises", ["sells"], :name => "index_enterprises_on_sells" + add_index "enterprises", ["address_id"], name: "index_enterprises_on_address_id", using: :btree + add_index "enterprises", ["is_primary_producer", "sells"], name: "index_enterprises_on_is_primary_producer_and_sells", using: :btree + add_index "enterprises", ["name"], name: "index_enterprises_on_name", unique: true, using: :btree + add_index "enterprises", ["owner_id"], name: "index_enterprises_on_owner_id", using: :btree + add_index "enterprises", ["permalink"], name: "index_enterprises_on_permalink", unique: true, using: :btree + add_index "enterprises", ["sells"], name: "index_enterprises_on_sells", using: :btree - create_table "exchange_fees", :force => true do |t| + create_table "exchange_fees", force: true do |t| t.integer "exchange_id" t.integer "enterprise_fee_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "exchange_fees", ["enterprise_fee_id"], :name => "index_exchange_fees_on_enterprise_fee_id" - add_index "exchange_fees", ["exchange_id"], :name => "index_exchange_fees_on_exchange_id" + add_index "exchange_fees", ["enterprise_fee_id"], name: "index_exchange_fees_on_enterprise_fee_id", using: :btree + add_index "exchange_fees", ["exchange_id"], name: "index_exchange_fees_on_exchange_id", using: :btree - create_table "exchange_variants", :force => true do |t| + create_table "exchange_variants", force: true do |t| t.integer "exchange_id" t.integer "variant_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "exchange_variants", ["exchange_id"], :name => "index_exchange_variants_on_exchange_id" - add_index "exchange_variants", ["variant_id"], :name => "index_exchange_variants_on_variant_id" + add_index "exchange_variants", ["exchange_id"], name: "index_exchange_variants_on_exchange_id", using: :btree + add_index "exchange_variants", ["variant_id"], name: "index_exchange_variants_on_variant_id", using: :btree - create_table "exchanges", :force => true do |t| + create_table "exchanges", force: true do |t| t.integer "order_cycle_id" t.integer "sender_id" t.integer "receiver_id" t.text "pickup_time" t.text "pickup_instructions" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "incoming", :default => false, :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "incoming", default: false, null: false t.text "receival_instructions" end - add_index "exchanges", ["order_cycle_id"], :name => "index_exchanges_on_order_cycle_id" - add_index "exchanges", ["receiver_id"], :name => "index_exchanges_on_receiver_id" - add_index "exchanges", ["sender_id"], :name => "index_exchanges_on_sender_id" + add_index "exchanges", ["order_cycle_id"], name: "index_exchanges_on_order_cycle_id", using: :btree + add_index "exchanges", ["receiver_id"], name: "index_exchanges_on_receiver_id", using: :btree + add_index "exchanges", ["sender_id"], name: "index_exchanges_on_sender_id", using: :btree - create_table "inventory_items", :force => true do |t| - t.integer "enterprise_id", :null => false - t.integer "variant_id", :null => false - t.boolean "visible", :default => true, :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "inventory_items", force: true do |t| + t.integer "enterprise_id", null: false + t.integer "variant_id", null: false + t.boolean "visible", default: true, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "inventory_items", ["enterprise_id", "variant_id"], :name => "index_inventory_items_on_enterprise_id_and_variant_id", :unique => true + add_index "inventory_items", ["enterprise_id", "variant_id"], name: "index_inventory_items_on_enterprise_id_and_variant_id", unique: true, using: :btree - create_table "order_cycle_schedules", :force => true do |t| - t.integer "order_cycle_id", :null => false - t.integer "schedule_id", :null => false + create_table "order_cycle_schedules", force: true do |t| + t.integer "order_cycle_id", null: false + t.integer "schedule_id", null: false end - add_index "order_cycle_schedules", ["order_cycle_id"], :name => "index_order_cycle_schedules_on_order_cycle_id" - add_index "order_cycle_schedules", ["schedule_id"], :name => "index_order_cycle_schedules_on_schedule_id" + add_index "order_cycle_schedules", ["order_cycle_id"], name: "index_order_cycle_schedules_on_order_cycle_id", using: :btree + add_index "order_cycle_schedules", ["schedule_id"], name: "index_order_cycle_schedules_on_schedule_id", using: :btree - create_table "order_cycles", :force => true do |t| + create_table "order_cycles", force: true do |t| t.string "name" t.datetime "orders_open_at" t.datetime "orders_close_at" t.integer "coordinator_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "producer_properties", :force => true do |t| + create_table "producer_properties", force: true do |t| t.string "value" t.integer "producer_id" t.integer "property_id" - t.integer "position", :default => 0, :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.integer "position", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "producer_properties", ["position"], :name => "index_producer_properties_on_position" - add_index "producer_properties", ["producer_id"], :name => "index_producer_properties_on_producer_id" - add_index "producer_properties", ["property_id"], :name => "index_producer_properties_on_property_id" + add_index "producer_properties", ["position"], name: "index_producer_properties_on_position", using: :btree + add_index "producer_properties", ["producer_id"], name: "index_producer_properties_on_producer_id", using: :btree + add_index "producer_properties", ["property_id"], name: "index_producer_properties_on_property_id", using: :btree - create_table "proxy_orders", :force => true do |t| - t.integer "subscription_id", :null => false + create_table "proxy_orders", force: true do |t| + t.integer "subscription_id", null: false t.integer "order_id" t.datetime "canceled_at" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "order_cycle_id", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "order_cycle_id", null: false t.datetime "placed_at" t.datetime "confirmed_at" end - add_index "proxy_orders", ["order_cycle_id", "subscription_id"], :name => "index_proxy_orders_on_order_cycle_id_and_subscription_id", :unique => true - add_index "proxy_orders", ["order_id"], :name => "index_proxy_orders_on_order_id", :unique => true - add_index "proxy_orders", ["subscription_id"], :name => "index_proxy_orders_on_subscription_id" + add_index "proxy_orders", ["order_cycle_id", "subscription_id"], name: "index_proxy_orders_on_order_cycle_id_and_subscription_id", unique: true, using: :btree + add_index "proxy_orders", ["order_id"], name: "index_proxy_orders_on_order_id", unique: true, using: :btree + add_index "proxy_orders", ["subscription_id"], name: "index_proxy_orders_on_subscription_id", using: :btree - create_table "schedules", :force => true do |t| - t.string "name", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "schedules", force: true do |t| + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "sessions", :force => true do |t| - t.string "session_id", :null => false + create_table "sessions", force: true do |t| + t.string "session_id", null: false t.text "data" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" - add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at" + add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree + add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree - create_table "spree_activators", :force => true do |t| + create_table "spree_activators", force: true do |t| t.string "description" t.datetime "expires_at" t.datetime "created_at" @@ -340,13 +343,13 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "event_name" t.string "type" t.integer "usage_limit" - t.string "match_policy", :default => "all" + t.string "match_policy", default: "all" t.string "code" - t.boolean "advertise", :default => false + t.boolean "advertise", default: false t.string "path" end - create_table "spree_addresses", :force => true do |t| + create_table "spree_addresses", force: true do |t| t.string "firstname" t.string "lastname" t.string "address1" @@ -358,79 +361,79 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "alternative_phone" t.integer "state_id" t.integer "country_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "company" t.float "latitude" t.float "longitude" end - add_index "spree_addresses", ["firstname"], :name => "index_addresses_on_firstname" - add_index "spree_addresses", ["lastname"], :name => "index_addresses_on_lastname" + add_index "spree_addresses", ["firstname"], name: "index_addresses_on_firstname", using: :btree + add_index "spree_addresses", ["lastname"], name: "index_addresses_on_lastname", using: :btree - create_table "spree_adjustments", :force => true do |t| + create_table "spree_adjustments", force: true do |t| t.integer "source_id" - t.decimal "amount", :precision => 10, :scale => 2 + t.decimal "amount", precision: 10, scale: 2 t.string "label" t.string "source_type" t.integer "adjustable_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "mandatory" t.integer "originator_id" t.string "originator_type" - t.boolean "eligible", :default => true + t.boolean "eligible", default: true t.string "adjustable_type" - t.decimal "included_tax", :precision => 10, :scale => 2, :default => 0.0, :null => false + t.decimal "included_tax", precision: 10, scale: 2, default: 0.0, null: false t.string "state" end - add_index "spree_adjustments", ["adjustable_id"], :name => "index_adjustments_on_order_id" + add_index "spree_adjustments", ["adjustable_id"], name: "index_adjustments_on_order_id", using: :btree - create_table "spree_assets", :force => true do |t| + create_table "spree_assets", force: true do |t| t.integer "viewable_id" t.integer "attachment_width" t.integer "attachment_height" t.integer "attachment_file_size" t.integer "position" - t.string "viewable_type", :limit => 50 + t.string "viewable_type", limit: 50 t.string "attachment_content_type" t.string "attachment_file_name" - t.string "type", :limit => 75 + t.string "type", limit: 75 t.datetime "attachment_updated_at" t.text "alt" end - add_index "spree_assets", ["viewable_id"], :name => "index_assets_on_viewable_id" - add_index "spree_assets", ["viewable_type", "type"], :name => "index_assets_on_viewable_type_and_type" + add_index "spree_assets", ["viewable_id"], name: "index_assets_on_viewable_id", using: :btree + add_index "spree_assets", ["viewable_type", "type"], name: "index_assets_on_viewable_type_and_type", using: :btree - create_table "spree_calculators", :force => true do |t| + create_table "spree_calculators", force: true do |t| t.string "type" - t.integer "calculable_id", :null => false - t.string "calculable_type", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.integer "calculable_id", null: false + t.string "calculable_type", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_configurations", :force => true do |t| + create_table "spree_configurations", force: true do |t| t.string "name" - t.string "type", :limit => 50 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.string "type", limit: 50 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "spree_configurations", ["name", "type"], :name => "index_configurations_on_name_and_type" + add_index "spree_configurations", ["name", "type"], name: "index_configurations_on_name_and_type", using: :btree - create_table "spree_countries", :force => true do |t| + create_table "spree_countries", force: true do |t| t.string "iso_name" t.string "iso" t.string "iso3" t.string "name" t.integer "numcode" - t.boolean "states_required", :default => true + t.boolean "states_required", default: true end - create_table "spree_credit_cards", :force => true do |t| + create_table "spree_credit_cards", force: true do |t| t.string "month" t.string "year" t.string "cc_type" @@ -441,123 +444,123 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "start_year" t.string "issue_number" t.integer "address_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "gateway_customer_profile_id" t.string "gateway_payment_profile_id" t.integer "user_id" t.integer "payment_method_id" - t.boolean "is_default", :default => false + t.boolean "is_default", default: false end - add_index "spree_credit_cards", ["payment_method_id"], :name => "index_spree_credit_cards_on_payment_method_id" - add_index "spree_credit_cards", ["user_id"], :name => "index_spree_credit_cards_on_user_id" + add_index "spree_credit_cards", ["payment_method_id"], name: "index_spree_credit_cards_on_payment_method_id", using: :btree + add_index "spree_credit_cards", ["user_id"], name: "index_spree_credit_cards_on_user_id", using: :btree - create_table "spree_gateways", :force => true do |t| + create_table "spree_gateways", force: true do |t| t.string "type" t.string "name" t.text "description" - t.boolean "active", :default => true - t.string "environment", :default => "development" - t.string "server", :default => "test" - t.boolean "test_mode", :default => true - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "active", default: true + t.string "environment", default: "development" + t.string "server", default: "test" + t.boolean "test_mode", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_inventory_units", :force => true do |t| + create_table "spree_inventory_units", force: true do |t| t.string "state" t.integer "variant_id" t.integer "order_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "shipment_id" t.integer "return_authorization_id" - t.boolean "pending", :default => true + t.boolean "pending", default: true end - add_index "spree_inventory_units", ["order_id"], :name => "index_inventory_units_on_order_id" - add_index "spree_inventory_units", ["shipment_id"], :name => "index_inventory_units_on_shipment_id" - add_index "spree_inventory_units", ["variant_id"], :name => "index_inventory_units_on_variant_id" + add_index "spree_inventory_units", ["order_id"], name: "index_inventory_units_on_order_id", using: :btree + add_index "spree_inventory_units", ["shipment_id"], name: "index_inventory_units_on_shipment_id", using: :btree + add_index "spree_inventory_units", ["variant_id"], name: "index_inventory_units_on_variant_id", using: :btree - create_table "spree_line_items", :force => true do |t| + create_table "spree_line_items", force: true do |t| t.integer "order_id" t.integer "variant_id" - t.integer "quantity", :null => false - t.decimal "price", :precision => 8, :scale => 2, :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.integer "quantity", null: false + t.decimal "price", precision: 8, scale: 2, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "max_quantity" t.string "currency" - t.decimal "distribution_fee", :precision => 10, :scale => 2 - t.decimal "final_weight_volume", :precision => 10, :scale => 2 - t.decimal "cost_price", :precision => 8, :scale => 2 + t.decimal "distribution_fee", precision: 10, scale: 2 + t.decimal "final_weight_volume", precision: 10, scale: 2 + t.decimal "cost_price", precision: 8, scale: 2 t.integer "tax_category_id" end - add_index "spree_line_items", ["order_id"], :name => "index_line_items_on_order_id" - add_index "spree_line_items", ["variant_id"], :name => "index_line_items_on_variant_id" + add_index "spree_line_items", ["order_id"], name: "index_line_items_on_order_id", using: :btree + add_index "spree_line_items", ["variant_id"], name: "index_line_items_on_variant_id", using: :btree - create_table "spree_log_entries", :force => true do |t| + create_table "spree_log_entries", force: true do |t| t.integer "source_id" t.string "source_type" t.text "details" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_mail_methods", :force => true do |t| + create_table "spree_mail_methods", force: true do |t| t.string "environment" - t.boolean "active", :default => true - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "active", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_option_types", :force => true do |t| - t.string "name", :limit => 100 - t.string "presentation", :limit => 100 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "position", :default => 0, :null => false + create_table "spree_option_types", force: true do |t| + t.string "name", limit: 100 + t.string "presentation", limit: 100 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "position", default: 0, null: false end - create_table "spree_option_values", :force => true do |t| + create_table "spree_option_values", force: true do |t| t.integer "position" t.string "name" t.string "presentation" t.integer "option_type_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_option_values_line_items", :id => false, :force => true do |t| + create_table "spree_option_values_line_items", id: false, force: true do |t| t.integer "line_item_id" t.integer "option_value_id" end - add_index "spree_option_values_line_items", ["line_item_id"], :name => "index_option_values_line_items_on_line_item_id" + add_index "spree_option_values_line_items", ["line_item_id"], name: "index_option_values_line_items_on_line_item_id", using: :btree - create_table "spree_option_values_variants", :id => false, :force => true do |t| + create_table "spree_option_values_variants", id: false, force: true do |t| t.integer "variant_id" t.integer "option_value_id" end - add_index "spree_option_values_variants", ["variant_id", "option_value_id"], :name => "index_option_values_variants_on_variant_id_and_option_value_id" - add_index "spree_option_values_variants", ["variant_id"], :name => "index_option_values_variants_on_variant_id" + add_index "spree_option_values_variants", ["variant_id", "option_value_id"], name: "index_option_values_variants_on_variant_id_and_option_value_id", using: :btree + add_index "spree_option_values_variants", ["variant_id"], name: "index_option_values_variants_on_variant_id", using: :btree - create_table "spree_orders", :force => true do |t| - t.string "number", :limit => 15 - t.decimal "item_total", :precision => 10, :scale => 2, :default => 0.0, :null => false - t.decimal "total", :precision => 10, :scale => 2, :default => 0.0, :null => false + create_table "spree_orders", force: true do |t| + t.string "number", limit: 15 + t.decimal "item_total", precision: 10, scale: 2, default: 0.0, null: false + t.decimal "total", precision: 10, scale: 2, default: 0.0, null: false t.string "state" - t.decimal "adjustment_total", :precision => 10, :scale => 2, :default => 0.0, :null => false + t.decimal "adjustment_total", precision: 10, scale: 2, default: 0.0, null: false t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.datetime "completed_at" t.integer "bill_address_id" t.integer "ship_address_id" - t.decimal "payment_total", :precision => 10, :scale => 2, :default => 0.0 + t.decimal "payment_total", precision: 10, scale: 2, default: 0.0 t.string "shipment_state" t.string "payment_state" t.string "email" @@ -570,29 +573,30 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "created_by_id" end - add_index "spree_orders", ["completed_at", "user_id", "created_by_id", "created_at"], :name => "spree_orders_completed_at_user_id_created_by_id_created_at_idx" - add_index "spree_orders", ["customer_id"], :name => "index_spree_orders_on_customer_id" - add_index "spree_orders", ["distributor_id"], :name => "index_spree_orders_on_distributor_id" - add_index "spree_orders", ["number"], :name => "index_orders_on_number" - add_index "spree_orders", ["order_cycle_id"], :name => "index_spree_orders_on_order_cycle_id" + add_index "spree_orders", ["completed_at", "user_id", "created_by_id", "created_at"], name: "spree_orders_completed_at_user_id_created_by_id_created_at_idx", using: :btree + add_index "spree_orders", ["customer_id"], name: "index_spree_orders_on_customer_id", using: :btree + add_index "spree_orders", ["number"], name: "index_orders_on_number", using: :btree + add_index "spree_orders", ["distributor_id"], name: "index_spree_orders_on_distributor_id", using: :btree + add_index "spree_orders", ["order_cycle_id"], name: "index_spree_orders_on_order_cycle_id", using: :btree - create_table "spree_payment_methods", :force => true do |t| + + create_table "spree_payment_methods", force: true do |t| t.string "type" t.string "name" t.text "description" - t.boolean "active", :default => true - t.string "environment", :default => "development" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "active", default: true + t.string "environment", default: "development" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.datetime "deleted_at" t.string "display_on" end - create_table "spree_payments", :force => true do |t| - t.decimal "amount", :precision => 10, :scale => 2, :default => 0.0, :null => false + create_table "spree_payments", force: true do |t| + t.decimal "amount", precision: 10, scale: 2, default: 0.0, null: false t.integer "order_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "source_id" t.string "source_type" t.integer "payment_method_id" @@ -604,99 +608,99 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "cvv_response_message" end - add_index "spree_payments", ["order_id"], :name => "index_spree_payments_on_order_id" + add_index "spree_payments", ["order_id"], name: "index_spree_payments_on_order_id", using: :btree - create_table "spree_paypal_accounts", :force => true do |t| + create_table "spree_paypal_accounts", force: true do |t| t.string "email" t.string "payer_id" t.string "payer_country" t.string "payer_status" end - create_table "spree_paypal_express_checkouts", :force => true do |t| + create_table "spree_paypal_express_checkouts", force: true do |t| t.string "token" t.string "payer_id" t.string "transaction_id" - t.string "state", :default => "complete" + t.string "state", default: "complete" t.string "refund_transaction_id" t.datetime "refunded_at" t.string "refund_type" t.datetime "created_at" end - add_index "spree_paypal_express_checkouts", ["transaction_id"], :name => "index_spree_paypal_express_checkouts_on_transaction_id" + add_index "spree_paypal_express_checkouts", ["transaction_id"], name: "index_spree_paypal_express_checkouts_on_transaction_id", using: :btree - create_table "spree_pending_promotions", :force => true do |t| + create_table "spree_pending_promotions", force: true do |t| t.integer "user_id" t.integer "promotion_id" end - add_index "spree_pending_promotions", ["promotion_id"], :name => "index_spree_pending_promotions_on_promotion_id" - add_index "spree_pending_promotions", ["user_id"], :name => "index_spree_pending_promotions_on_user_id" + add_index "spree_pending_promotions", ["promotion_id"], name: "index_spree_pending_promotions_on_promotion_id", using: :btree + add_index "spree_pending_promotions", ["user_id"], name: "index_spree_pending_promotions_on_user_id", using: :btree - create_table "spree_preferences", :force => true do |t| + create_table "spree_preferences", force: true do |t| t.text "value" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "key" t.string "value_type" end - add_index "spree_preferences", ["key"], :name => "index_spree_preferences_on_key", :unique => true + add_index "spree_preferences", ["key"], name: "index_spree_preferences_on_key", unique: true, using: :btree - create_table "spree_prices", :force => true do |t| - t.integer "variant_id", :null => false - t.decimal "amount", :precision => 8, :scale => 2 - t.string "currency" + create_table "spree_prices", force: true do |t| + t.integer "variant_id", null: false + t.decimal "amount", precision: 8, scale: 2 + t.string "currency" t.datetime "deleted_at" end - add_index "spree_prices", ["variant_id"], :name => "index_spree_prices_on_variant_id" + add_index "spree_prices", ["variant_id"], name: "index_spree_prices_on_variant_id", using: :btree - create_table "spree_product_groups", :force => true do |t| + create_table "spree_product_groups", force: true do |t| t.string "name" t.string "permalink" t.string "order" end - add_index "spree_product_groups", ["name"], :name => "index_product_groups_on_name" - add_index "spree_product_groups", ["permalink"], :name => "index_product_groups_on_permalink" + add_index "spree_product_groups", ["name"], name: "index_product_groups_on_name", using: :btree + add_index "spree_product_groups", ["permalink"], name: "index_product_groups_on_permalink", using: :btree - create_table "spree_product_groups_products", :id => false, :force => true do |t| + create_table "spree_product_groups_products", id: false, force: true do |t| t.integer "product_id" t.integer "product_group_id" end - create_table "spree_product_option_types", :force => true do |t| + create_table "spree_product_option_types", force: true do |t| t.integer "position" t.integer "product_id" t.integer "option_type_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_product_properties", :force => true do |t| + create_table "spree_product_properties", force: true do |t| t.string "value" t.integer "product_id" t.integer "property_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "position", :default => 0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "position", default: 0 end - add_index "spree_product_properties", ["product_id"], :name => "index_product_properties_on_product_id" + add_index "spree_product_properties", ["product_id"], name: "index_product_properties_on_product_id", using: :btree - create_table "spree_product_scopes", :force => true do |t| + create_table "spree_product_scopes", force: true do |t| t.string "name" t.text "arguments" t.integer "product_group_id" end - add_index "spree_product_scopes", ["name"], :name => "index_product_scopes_on_name" - add_index "spree_product_scopes", ["product_group_id"], :name => "index_product_scopes_on_product_group_id" + add_index "spree_product_scopes", ["name"], name: "index_product_scopes_on_name", using: :btree + add_index "spree_product_scopes", ["product_group_id"], name: "index_product_scopes_on_product_group_id", using: :btree - create_table "spree_products", :force => true do |t| - t.string "name", :default => "", :null => false + create_table "spree_products", force: true do |t| + t.string "name", default: "", null: false t.text "description" t.datetime "available_on" t.datetime "deleted_at" @@ -705,8 +709,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "meta_keywords" t.integer "tax_category_id" t.integer "shipping_category_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "supplier_id" t.boolean "group_buy" t.float "group_buy_unit_size" @@ -714,200 +718,201 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.float "variant_unit_scale" t.string "variant_unit_name" t.text "notes" - t.integer "primary_taxon_id", :null => false - t.boolean "inherits_properties", :default => true, :null => false + t.integer "primary_taxon_id", null: false + t.boolean "inherits_properties", default: true, null: false end - add_index "spree_products", ["available_on"], :name => "index_products_on_available_on" - add_index "spree_products", ["deleted_at"], :name => "index_products_on_deleted_at" - add_index "spree_products", ["name"], :name => "index_products_on_name" - add_index "spree_products", ["permalink"], :name => "index_products_on_permalink" - add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true - add_index "spree_products", ["primary_taxon_id"], :name => "index_spree_products_on_primary_taxon_id" + add_index "spree_products", ["available_on"], name: "index_products_on_available_on", using: :btree + add_index "spree_products", ["deleted_at"], name: "index_products_on_deleted_at", using: :btree + add_index "spree_products", ["name"], name: "index_products_on_name", using: :btree + add_index "spree_products", ["permalink"], name: "index_products_on_permalink", using: :btree + add_index "spree_products", ["permalink"], name: "permalink_idx_unique", unique: true, using: :btree + add_index "spree_products", ["primary_taxon_id"], name: "index_spree_products_on_primary_taxon_id", using: :btree - create_table "spree_products_promotion_rules", :id => false, :force => true do |t| + create_table "spree_products_promotion_rules", id: false, force: true do |t| t.integer "product_id" t.integer "promotion_rule_id" end - add_index "spree_products_promotion_rules", ["product_id"], :name => "index_products_promotion_rules_on_product_id" - add_index "spree_products_promotion_rules", ["promotion_rule_id"], :name => "index_products_promotion_rules_on_promotion_rule_id" + add_index "spree_products_promotion_rules", ["product_id"], name: "index_products_promotion_rules_on_product_id", using: :btree + add_index "spree_products_promotion_rules", ["promotion_rule_id"], name: "index_products_promotion_rules_on_promotion_rule_id", using: :btree - create_table "spree_products_taxons", :force => true do |t| + create_table "spree_products_taxons", force: true do |t| t.integer "product_id" t.integer "taxon_id" end - add_index "spree_products_taxons", ["product_id"], :name => "index_products_taxons_on_product_id" - add_index "spree_products_taxons", ["taxon_id"], :name => "index_products_taxons_on_taxon_id" + add_index "spree_products_taxons", ["product_id"], name: "index_products_taxons_on_product_id", using: :btree + add_index "spree_products_taxons", ["taxon_id"], name: "index_products_taxons_on_taxon_id", using: :btree - create_table "spree_promotion_action_line_items", :force => true do |t| + create_table "spree_promotion_action_line_items", force: true do |t| t.integer "promotion_action_id" t.integer "variant_id" - t.integer "quantity", :default => 1 + t.integer "quantity", default: 1 end - create_table "spree_promotion_actions", :force => true do |t| + create_table "spree_promotion_actions", force: true do |t| t.integer "activator_id" t.integer "position" t.string "type" end - create_table "spree_promotion_rules", :force => true do |t| + create_table "spree_promotion_rules", force: true do |t| t.integer "activator_id" t.integer "user_id" t.integer "product_group_id" t.string "type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "spree_promotion_rules", ["product_group_id"], :name => "index_promotion_rules_on_product_group_id" - add_index "spree_promotion_rules", ["user_id"], :name => "index_promotion_rules_on_user_id" + add_index "spree_promotion_rules", ["product_group_id"], name: "index_promotion_rules_on_product_group_id", using: :btree + add_index "spree_promotion_rules", ["user_id"], name: "index_promotion_rules_on_user_id", using: :btree - create_table "spree_promotion_rules_users", :id => false, :force => true do |t| + create_table "spree_promotion_rules_users", id: false, force: true do |t| t.integer "user_id" t.integer "promotion_rule_id" end - add_index "spree_promotion_rules_users", ["promotion_rule_id"], :name => "index_promotion_rules_users_on_promotion_rule_id" - add_index "spree_promotion_rules_users", ["user_id"], :name => "index_promotion_rules_users_on_user_id" + add_index "spree_promotion_rules_users", ["promotion_rule_id"], name: "index_promotion_rules_users_on_promotion_rule_id", using: :btree + add_index "spree_promotion_rules_users", ["user_id"], name: "index_promotion_rules_users_on_user_id", using: :btree - create_table "spree_properties", :force => true do |t| + create_table "spree_properties", force: true do |t| t.string "name" - t.string "presentation", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.string "presentation", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_return_authorizations", :force => true do |t| + create_table "spree_return_authorizations", force: true do |t| t.string "number" t.string "state" - t.decimal "amount", :precision => 10, :scale => 2, :default => 0.0, :null => false + t.decimal "amount", precision: 10, scale: 2, default: 0.0, null: false t.integer "order_id" t.text "reason" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "stock_location_id" end - create_table "spree_roles", :force => true do |t| + create_table "spree_roles", force: true do |t| t.string "name" end - create_table "spree_roles_users", :id => false, :force => true do |t| + create_table "spree_roles_users", id: false, force: true do |t| t.integer "role_id" t.integer "user_id" end - add_index "spree_roles_users", ["role_id"], :name => "index_roles_users_on_role_id" - add_index "spree_roles_users", ["user_id"], :name => "index_roles_users_on_user_id" + add_index "spree_roles_users", ["role_id"], name: "index_roles_users_on_role_id", using: :btree + add_index "spree_roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree - create_table "spree_shipments", :force => true do |t| + create_table "spree_shipments", force: true do |t| t.string "tracking" t.string "number" - t.decimal "cost", :precision => 8, :scale => 2 + t.decimal "cost", precision: 8, scale: 2 t.datetime "shipped_at" t.integer "order_id" t.integer "address_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "state" t.integer "stock_location_id" end - add_index "spree_shipments", ["number"], :name => "index_shipments_on_number" - add_index "spree_shipments", ["order_id"], :name => "index_spree_shipments_on_order_id", :unique => true + add_index "spree_shipments", ["number"], name: "index_shipments_on_number", using: :btree + add_index "spree_shipments", ["order_id"], name: "index_spree_shipments_on_order_id", unique: true, using: :btree - create_table "spree_shipping_categories", :force => true do |t| + create_table "spree_shipping_categories", force: true do |t| t.string "name" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "temperature_controlled", :default => false, :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "temperature_controlled", default: false, null: false end - create_table "spree_shipping_method_categories", :force => true do |t| - t.integer "shipping_method_id", :null => false - t.integer "shipping_category_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "spree_shipping_method_categories", force: true do |t| + t.integer "shipping_method_id", null: false + t.integer "shipping_category_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "spree_shipping_method_categories", ["shipping_category_id"], :name => "index_spree_shipping_method_categories_on_shipping_category_id" - add_index "spree_shipping_method_categories", ["shipping_method_id"], :name => "index_spree_shipping_method_categories_on_shipping_method_id" + add_index "spree_shipping_method_categories", ["shipping_category_id"], name: "index_spree_shipping_method_categories_on_shipping_category_id", using: :btree + add_index "spree_shipping_method_categories", ["shipping_method_id"], name: "index_spree_shipping_method_categories_on_shipping_method_id", using: :btree - create_table "spree_shipping_methods", :force => true do |t| + create_table "spree_shipping_methods", force: true do |t| t.string "name" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "display_on" t.datetime "deleted_at" - t.boolean "require_ship_address", :default => true + t.boolean "require_ship_address", default: true t.text "description" t.string "tracking_url" end - create_table "spree_shipping_methods_zones", :id => false, :force => true do |t| + create_table "spree_shipping_methods_zones", id: false, force: true do |t| t.integer "shipping_method_id" t.integer "zone_id" end - create_table "spree_shipping_rates", :force => true do |t| + create_table "spree_shipping_rates", force: true do |t| t.integer "shipment_id" t.integer "shipping_method_id" - t.boolean "selected", :default => false - t.decimal "cost", :precision => 8, :scale => 2, :default => 0.0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "selected", default: false + t.decimal "cost", precision: 8, scale: 2, default: 0.0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "spree_shipping_rates", ["shipment_id", "shipping_method_id"], :name => "spree_shipping_rates_join_index", :unique => true + add_index "spree_shipping_rates", ["shipment_id", "shipping_method_id"], name: "spree_shipping_rates_join_index", unique: true, using: :btree - create_table "spree_skrill_transactions", :force => true do |t| + create_table "spree_skrill_transactions", force: true do |t| t.string "email" t.float "amount" t.string "currency" t.integer "transaction_id" t.integer "customer_id" t.string "payment_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_state_changes", :force => true do |t| + create_table "spree_state_changes", force: true do |t| t.string "name" t.string "previous_state" t.integer "stateful_id" t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "stateful_type" t.string "next_state" end - create_table "spree_states", :force => true do |t| + create_table "spree_states", force: true do |t| t.string "name" t.string "abbr" t.integer "country_id" end - create_table "spree_stock_items", :force => true do |t| + create_table "spree_stock_items", force: true do |t| t.integer "stock_location_id" t.integer "variant_id" - t.integer "count_on_hand", :default => 0, :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "backorderable", :default => false + t.integer "count_on_hand", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "backorderable", default: false + t.datetime "deleted_at" end - add_index "spree_stock_items", ["stock_location_id", "variant_id"], :name => "stock_item_by_loc_and_var_id" - add_index "spree_stock_items", ["stock_location_id"], :name => "index_spree_stock_items_on_stock_location_id" - add_index "spree_stock_items", ["variant_id"], :name => "index_spree_stock_items_on_variant_id", :unique => true + add_index "spree_stock_items", ["stock_location_id", "variant_id"], name: "stock_item_by_loc_and_var_id", using: :btree + add_index "spree_stock_items", ["stock_location_id"], name: "index_spree_stock_items_on_stock_location_id", using: :btree + add_index "spree_stock_items", ["variant_id"], name: "index_spree_stock_items_on_variant_id", unique: true, using: :btree - create_table "spree_stock_locations", :force => true do |t| + create_table "spree_stock_locations", force: true do |t| t.string "name" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "address1" t.string "address2" t.string "city" @@ -916,73 +921,73 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "country_id" t.string "zipcode" t.string "phone" - t.boolean "active", :default => true - t.boolean "backorderable_default", :default => false - t.boolean "propagate_all_variants", :default => true + t.boolean "active", default: true + t.boolean "backorderable_default", default: false + t.boolean "propagate_all_variants", default: true end - create_table "spree_stock_movements", :force => true do |t| + create_table "spree_stock_movements", force: true do |t| t.integer "stock_item_id" - t.integer "quantity", :default => 0 + t.integer "quantity", default: 0 t.string "action" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "originator_id" t.string "originator_type" end - add_index "spree_stock_movements", ["stock_item_id"], :name => "index_spree_stock_movements_on_stock_item_id" + add_index "spree_stock_movements", ["stock_item_id"], name: "index_spree_stock_movements_on_stock_item_id", using: :btree - create_table "spree_stock_transfers", :force => true do |t| + create_table "spree_stock_transfers", force: true do |t| t.string "type" t.string "reference" t.integer "source_location_id" t.integer "destination_location_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "number" end - add_index "spree_stock_transfers", ["destination_location_id"], :name => "index_spree_stock_transfers_on_destination_location_id" - add_index "spree_stock_transfers", ["number"], :name => "index_spree_stock_transfers_on_number" - add_index "spree_stock_transfers", ["source_location_id"], :name => "index_spree_stock_transfers_on_source_location_id" + add_index "spree_stock_transfers", ["destination_location_id"], name: "index_spree_stock_transfers_on_destination_location_id", using: :btree + add_index "spree_stock_transfers", ["number"], name: "index_spree_stock_transfers_on_number", using: :btree + add_index "spree_stock_transfers", ["source_location_id"], name: "index_spree_stock_transfers_on_source_location_id", using: :btree - create_table "spree_tax_categories", :force => true do |t| + create_table "spree_tax_categories", force: true do |t| t.string "name" t.string "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "is_default", :default => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "is_default", default: false t.datetime "deleted_at" end - create_table "spree_tax_rates", :force => true do |t| - t.decimal "amount", :precision => 8, :scale => 5 + create_table "spree_tax_rates", force: true do |t| + t.decimal "amount", precision: 8, scale: 5 t.integer "zone_id" t.integer "tax_category_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "included_in_price", :default => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "included_in_price", default: false t.string "name" - t.boolean "show_rate_in_label", :default => true + t.boolean "show_rate_in_label", default: true t.datetime "deleted_at" end - create_table "spree_taxonomies", :force => true do |t| - t.string "name", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "position", :default => 0 + create_table "spree_taxonomies", force: true do |t| + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "position", default: 0 end - create_table "spree_taxons", :force => true do |t| + create_table "spree_taxons", force: true do |t| t.integer "parent_id" - t.integer "position", :default => 0 - t.string "name", :null => false + t.integer "position", default: 0 + t.string "name", null: false t.string "permalink" t.integer "taxonomy_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "lft" t.integer "rgt" t.string "icon_file_name" @@ -995,29 +1000,29 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "meta_keywords" end - add_index "spree_taxons", ["parent_id"], :name => "index_taxons_on_parent_id" - add_index "spree_taxons", ["permalink"], :name => "index_taxons_on_permalink" - add_index "spree_taxons", ["taxonomy_id"], :name => "index_taxons_on_taxonomy_id" + add_index "spree_taxons", ["parent_id"], name: "index_taxons_on_parent_id", using: :btree + add_index "spree_taxons", ["permalink"], name: "index_taxons_on_permalink", using: :btree + add_index "spree_taxons", ["taxonomy_id"], name: "index_taxons_on_taxonomy_id", using: :btree - create_table "spree_tokenized_permissions", :force => true do |t| + create_table "spree_tokenized_permissions", force: true do |t| t.integer "permissable_id" t.string "permissable_type" t.string "token" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "spree_tokenized_permissions", ["permissable_id", "permissable_type"], :name => "index_tokenized_name_and_type" + add_index "spree_tokenized_permissions", ["permissable_id", "permissable_type"], name: "index_tokenized_name_and_type", using: :btree - create_table "spree_trackers", :force => true do |t| + create_table "spree_trackers", force: true do |t| t.string "environment" t.string "analytics_id" - t.boolean "active", :default => true - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "active", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_users", :force => true do |t| + create_table "spree_users", force: true do |t| t.string "encrypted_password" t.string "password_salt" t.string "email" @@ -1025,8 +1030,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "persistence_token" t.string "reset_password_token" t.string "perishable_token" - t.integer "sign_in_count", :default => 0, :null => false - t.integer "failed_attempts", :default => 0, :null => false + t.integer "sign_in_count", default: 0, null: false + t.integer "failed_attempts", default: 0, null: false t.datetime "last_request_at" t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" @@ -1035,115 +1040,115 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "login" t.integer "ship_address_id" t.integer "bill_address_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "authentication_token" t.string "unlock_token" t.datetime "locked_at" t.datetime "remember_created_at" - t.string "spree_api_key", :limit => 48 + t.string "spree_api_key", limit: 48 t.datetime "reset_password_sent_at" - t.string "api_key", :limit => 40 - t.integer "enterprise_limit", :default => 5, :null => false - t.string "locale", :limit => 5 + t.string "api_key", limit: 40 + t.integer "enterprise_limit", default: 5, null: false + t.string "locale", limit: 5 t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" end - add_index "spree_users", ["confirmation_token"], :name => "index_spree_users_on_confirmation_token", :unique => true - add_index "spree_users", ["email"], :name => "email_idx_unique", :unique => true - add_index "spree_users", ["persistence_token"], :name => "index_users_on_persistence_token" + add_index "spree_users", ["confirmation_token"], name: "index_spree_users_on_confirmation_token", unique: true, using: :btree + add_index "spree_users", ["email"], name: "email_idx_unique", unique: true, using: :btree + add_index "spree_users", ["persistence_token"], name: "index_users_on_persistence_token", using: :btree - create_table "spree_variants", :force => true do |t| - t.string "sku", :default => "", :null => false - t.decimal "weight", :precision => 8, :scale => 2 - t.decimal "height", :precision => 8, :scale => 2 - t.decimal "width", :precision => 8, :scale => 2 - t.decimal "depth", :precision => 8, :scale => 2 + create_table "spree_variants", force: true do |t| + t.string "sku", default: "", null: false + t.decimal "weight", precision: 8, scale: 2 + t.decimal "height", precision: 8, scale: 2 + t.decimal "width", precision: 8, scale: 2 + t.decimal "depth", precision: 8, scale: 2 t.datetime "deleted_at" - t.boolean "is_master", :default => false + t.boolean "is_master", default: false t.integer "product_id" - t.decimal "cost_price", :precision => 8, :scale => 2 + t.decimal "cost_price", precision: 8, scale: 2 t.integer "position" t.string "cost_currency" t.float "unit_value" - t.string "unit_description", :default => "" + t.string "unit_description", default: "" t.string "display_name" t.string "display_as" t.datetime "import_date" end - add_index "spree_variants", ["product_id"], :name => "index_variants_on_product_id" - add_index "spree_variants", ["sku"], :name => "index_spree_variants_on_sku" + add_index "spree_variants", ["product_id"], name: "index_variants_on_product_id", using: :btree + add_index "spree_variants", ["sku"], name: "index_spree_variants_on_sku", using: :btree - create_table "spree_zone_members", :force => true do |t| + create_table "spree_zone_members", force: true do |t| t.integer "zoneable_id" t.string "zoneable_type" t.integer "zone_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "spree_zones", :force => true do |t| + create_table "spree_zones", force: true do |t| t.string "name" t.string "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "default_tax", :default => false - t.integer "zone_members_count", :default => 0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "default_tax", default: false + t.integer "zone_members_count", default: 0 end - create_table "stripe_accounts", :force => true do |t| + create_table "stripe_accounts", force: true do |t| t.string "stripe_user_id" t.string "stripe_publishable_key" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "enterprise_id" end - add_index "stripe_accounts", ["enterprise_id"], :name => "index_stripe_accounts_on_enterprise_id", :unique => true + add_index "stripe_accounts", ["enterprise_id"], name: "index_stripe_accounts_on_enterprise_id", unique: true, using: :btree - create_table "subscription_line_items", :force => true do |t| - t.integer "subscription_id", :null => false - t.integer "variant_id", :null => false - t.integer "quantity", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.decimal "price_estimate", :precision => 8, :scale => 2 + create_table "subscription_line_items", force: true do |t| + t.integer "subscription_id", null: false + t.integer "variant_id", null: false + t.integer "quantity", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.decimal "price_estimate", precision: 8, scale: 2 end - add_index "subscription_line_items", ["subscription_id"], :name => "index_subscription_line_items_on_subscription_id" - add_index "subscription_line_items", ["variant_id"], :name => "index_subscription_line_items_on_variant_id" + add_index "subscription_line_items", ["subscription_id"], name: "index_subscription_line_items_on_subscription_id", using: :btree + add_index "subscription_line_items", ["variant_id"], name: "index_subscription_line_items_on_variant_id", using: :btree - create_table "subscriptions", :force => true do |t| - t.integer "shop_id", :null => false - t.integer "customer_id", :null => false - t.integer "schedule_id", :null => false - t.integer "payment_method_id", :null => false - t.integer "shipping_method_id", :null => false + create_table "subscriptions", force: true do |t| + t.integer "shop_id", null: false + t.integer "customer_id", null: false + t.integer "schedule_id", null: false + t.integer "payment_method_id", null: false + t.integer "shipping_method_id", null: false t.datetime "begins_at" t.datetime "ends_at" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "bill_address_id", :null => false - t.integer "ship_address_id", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "bill_address_id", null: false + t.integer "ship_address_id", null: false t.datetime "canceled_at" t.datetime "paused_at" - t.decimal "shipping_fee_estimate", :precision => 8, :scale => 2 - t.decimal "payment_fee_estimate", :precision => 8, :scale => 2 + t.decimal "shipping_fee_estimate", precision: 8, scale: 2 + t.decimal "payment_fee_estimate", precision: 8, scale: 2 end - add_index "subscriptions", ["bill_address_id"], :name => "index_subscriptions_on_bill_address_id" - add_index "subscriptions", ["customer_id"], :name => "index_subscriptions_on_customer_id" - add_index "subscriptions", ["payment_method_id"], :name => "index_subscriptions_on_payment_method_id" - add_index "subscriptions", ["schedule_id"], :name => "index_subscriptions_on_schedule_id" - add_index "subscriptions", ["ship_address_id"], :name => "index_subscriptions_on_ship_address_id" - add_index "subscriptions", ["shipping_method_id"], :name => "index_subscriptions_on_shipping_method_id" - add_index "subscriptions", ["shop_id"], :name => "index_subscriptions_on_shop_id" + add_index "subscriptions", ["bill_address_id"], name: "index_subscriptions_on_bill_address_id", using: :btree + add_index "subscriptions", ["customer_id"], name: "index_subscriptions_on_customer_id", using: :btree + add_index "subscriptions", ["payment_method_id"], name: "index_subscriptions_on_payment_method_id", using: :btree + add_index "subscriptions", ["schedule_id"], name: "index_subscriptions_on_schedule_id", using: :btree + add_index "subscriptions", ["ship_address_id"], name: "index_subscriptions_on_ship_address_id", using: :btree + add_index "subscriptions", ["shipping_method_id"], name: "index_subscriptions_on_shipping_method_id", using: :btree + add_index "subscriptions", ["shop_id"], name: "index_subscriptions_on_shop_id", using: :btree - create_table "suburbs", :force => true do |t| + create_table "suburbs", force: true do |t| t.string "name" t.string "postcode" t.float "latitude" @@ -1151,39 +1156,39 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "state_id" end - create_table "tag_rules", :force => true do |t| - t.integer "enterprise_id", :null => false - t.string "type", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "is_default", :default => false, :null => false - t.integer "priority", :default => 99, :null => false + create_table "tag_rules", force: true do |t| + t.integer "enterprise_id", null: false + t.string "type", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "is_default", default: false, null: false + t.integer "priority", default: 99, null: false end - create_table "taggings", :force => true do |t| + create_table "taggings", force: true do |t| t.integer "tag_id" t.integer "taggable_id" t.string "taggable_type" t.integer "tagger_id" t.string "tagger_type" - t.string "context", :limit => 128 + t.string "context", limit: 128 t.datetime "created_at" end - add_index "taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], :name => "taggings_idx", :unique => true - add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + add_index "taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true, using: :btree + add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree - create_table "tags", :force => true do |t| + create_table "tags", force: true do |t| t.string "name" - t.integer "taggings_count", :default => 0 + t.integer "taggings_count", default: 0 end - add_index "tags", ["name"], :name => "index_tags_on_name", :unique => true + add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree - create_table "variant_overrides", :force => true do |t| - t.integer "variant_id", :null => false - t.integer "hub_id", :null => false - t.decimal "price", :precision => 8, :scale => 2 + create_table "variant_overrides", force: true do |t| + t.integer "variant_id", null: false + t.integer "hub_id", null: false + t.decimal "price", precision: 8, scale: 2 t.integer "count_on_hand" t.integer "default_stock" t.boolean "resettable" @@ -1193,18 +1198,18 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.datetime "import_date" end - add_index "variant_overrides", ["variant_id", "hub_id"], :name => "index_variant_overrides_on_variant_id_and_hub_id" + add_index "variant_overrides", ["variant_id", "hub_id"], name: "index_variant_overrides_on_variant_id_and_hub_id", using: :btree - create_table "versions", :force => true do |t| - t.string "item_type", :null => false - t.integer "item_id", :null => false - t.string "event", :null => false + create_table "versions", force: true do |t| + t.string "item_type", null: false + t.integer "item_id", null: false + t.string "event", null: false t.string "whodunnit" t.text "object" t.datetime "created_at" end - add_index "versions", ["item_type", "item_id"], :name => "index_versions_on_item_type_and_item_id" + add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree add_foreign_key "adjustment_metadata", "enterprises", name: "adjustment_metadata_enterprise_id_fk" add_foreign_key "adjustment_metadata", "spree_adjustments", name: "adjustment_metadata_adjustment_id_fk", column: "adjustment_id", dependent: :delete From 9c369caae264ab3270690b1c0cd4d5332e6a498b Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Thu, 21 Mar 2019 20:49:41 +0000 Subject: [PATCH 007/507] Temporarily comment part of Enterprise.relate_to_owners_enterprises so that most specs pass for now --- app/models/enterprise.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 28acb0a6ff..72564c6409 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -435,21 +435,21 @@ class Enterprise < ActiveRecord::Base # We grant permissions to all pre-existing hubs hub_permissions = [:add_to_order_cycle] hub_permissions << :create_variant_overrides if is_primary_producer - enterprises.is_hub.each do |enterprise| - EnterpriseRelationship.create!(parent: self, - child: enterprise, - permissions_list: hub_permissions) - end + #enterprises.is_hub.each do |enterprise| + # EnterpriseRelationship.create!(parent: self, + # child: enterprise, + # permissions_list: hub_permissions) + #end # All pre-existing producers grant permission to new hubs - if is_hub - enterprises.is_primary_producer.each do |enterprise| - EnterpriseRelationship.create!(parent: enterprise, - child: self, - permissions_list: [:add_to_order_cycle, - :create_variant_overrides]) - end - end + #if is_hub + # enterprises.is_primary_producer.each do |enterprise| + # EnterpriseRelationship.create!(parent: enterprise, + # child: self, + # permissions_list: [:add_to_order_cycle, + # :create_variant_overrides]) + # end + #end end def shopfront_taxons From 1ef9209183969127b6f8a1bece4008771a62d5e2 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Sat, 6 Apr 2019 19:42:55 +0200 Subject: [PATCH 008/507] Remove the assets group in the gemfile (removed in rails 4) --- Gemfile | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 322c12ea3c..8c28e15384 100644 --- a/Gemfile +++ b/Gemfile @@ -61,7 +61,7 @@ gem 'haml' gem 'rabl' gem 'redcarpet' #gem 'sass', "~> 3.3" -gem 'sass-rails', groups: [:default, :assets] +gem 'sass-rails', groups: [:default] gem 'truncate_html' gem 'unicorn' @@ -100,21 +100,17 @@ gem 'whenever', require: false gem 'test-unit', '~> 3.3' -# Gems used only for assets and not required -# in production environments by default. -group :assets do - gem 'coffee-rails', '~> 4.0.0' - gem 'compass-rails' +gem 'coffee-rails', '~> 4.0.0' +gem 'compass-rails' - gem 'mini_racer', '0.2.9' +gem 'mini_racer', '0.2.9' - gem 'uglifier', '>= 1.0.3' +gem 'uglifier', '>= 1.0.3' - gem 'angular-rails-templates', '~> 0.3.0' - gem 'foundation-icons-sass-rails' - gem 'momentjs-rails' - # gem 'turbo-sprockets-rails3' -end +gem 'angular-rails-templates', '~> 0.3.0' +gem 'foundation-icons-sass-rails' +gem 'momentjs-rails' +# gem 'turbo-sprockets-rails3' gem 'foundation-rails', '= 5.5.2.1' gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: 'rails3' From 4ca9a19d8a7ff47ac88e9006de931784137fbe37 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Sat, 6 Apr 2019 20:03:59 +0100 Subject: [PATCH 009/507] Temporarily remove broken fontawesome and spree_paypal_express assets --- app/assets/stylesheets/admin/components/todo.scss | 6 ------ app/assets/stylesheets/admin/icons.css.scss | 4 ---- 2 files changed, 10 deletions(-) diff --git a/app/assets/stylesheets/admin/components/todo.scss b/app/assets/stylesheets/admin/components/todo.scss index 8528e0cb8e..2edb71995d 100644 --- a/app/assets/stylesheets/admin/components/todo.scss +++ b/app/assets/stylesheets/admin/components/todo.scss @@ -1,5 +1,3 @@ -@import '../plugins/font-awesome'; - .todolist{ .todo { &.done { @@ -18,10 +16,6 @@ .steps { display: none; } - - i { - @extend .icon-check - } } } } diff --git a/app/assets/stylesheets/admin/icons.css.scss b/app/assets/stylesheets/admin/icons.css.scss index 9bd900d083..e69de29bb2 100644 --- a/app/assets/stylesheets/admin/icons.css.scss +++ b/app/assets/stylesheets/admin/icons.css.scss @@ -1,4 +0,0 @@ -@import 'plugins/font-awesome'; - -.icon-refund:before { @extend .icon-ok:before } -.icon-credit:before { @extend .icon-ok:before } From d1248c76fab91e31eb3cf35641b1cb2516d2f435 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Sat, 6 Apr 2019 20:28:57 +0100 Subject: [PATCH 010/507] Temporarily disable caching classes in test to fix karma rake task This fixes the error "can't modify immutable index" in lib/tasks/karma.rake:25:in `application_spec_files' --- config/environments/test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 299e2d9c19..030e29cb79 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -5,7 +5,7 @@ Openfoodnetwork::Application.configure do # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true + config.cache_classes = false # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true From 2dc78d2f501a5628cd16473c450e8cae62379a5e Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Sun, 8 Sep 2019 18:35:43 +0100 Subject: [PATCH 011/507] Remove spree_auth_devise and upgrade devise to 3.0.1 --- Gemfile | 1 - Gemfile.lock | 22 ---------------------- 2 files changed, 23 deletions(-) diff --git a/Gemfile b/Gemfile index 8c28e15384..ddcaf172c1 100644 --- a/Gemfile +++ b/Gemfile @@ -23,7 +23,6 @@ gem 'pg', '~> 0.21.0' gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-1-0-stable' gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable' -gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-1-stable', ref: '1c436c738d0f086b2ca0f75a977ac16bc6cb98b9' # Our branch contains two changes # - Pass customer email and phone number to PayPal (merged to upstream master) diff --git a/Gemfile.lock b/Gemfile.lock index 79f00de2e5..2b5aff6310 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -29,26 +29,6 @@ GIT state_machine (= 1.2.0) stringex (~> 1.5.1) truncate_html (= 0.9.2) - spree_frontend (2.1.0) - canonical-rails - jquery-rails (~> 3.0.0) - spree_api (= 2.1.0) - spree_core (= 2.1.0) - stringex (~> 1.5.1) - -GIT - remote: https://github.com/spree/spree_auth_devise.git - revision: 1c436c738d0f086b2ca0f75a977ac16bc6cb98b9 - ref: 1c436c738d0f086b2ca0f75a977ac16bc6cb98b9 - branch: 2-1-stable - specs: - spree_auth_devise (2.1.0) - cancan (~> 1.6.7) - devise (~> 3.0.1) - devise-encryptable (= 0.1.2) - spree_backend (~> 2.1.0.beta) - spree_core (~> 2.1.0.beta) - spree_frontend (~> 2.1.0.beta) GIT remote: https://github.com/spree/spree_i18n.git @@ -157,8 +137,6 @@ GEM builder (3.1.4) byebug (9.0.6) cancan (1.6.10) - canonical-rails (0.1.0) - rails (>= 3.1, < 5.1) capybara (2.18.0) addressable mini_mime (>= 0.1.3) From 2f69d2a7e7d10955f78aff9ed51234c100a65ee9 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Sun, 8 Sep 2019 18:40:28 +0100 Subject: [PATCH 012/507] Remove devise email validation regexp, it's not needed in this version --- config/initializers/devise.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 6f0a508ac4..e20b748148 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -65,9 +65,6 @@ Devise.setup do |config| # Range for password length # config.password_length = 6..20 - # Regex to use to validate the email address - config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i - # ==> Configuration for :timeoutable # The time you want to timeout the user session without activity. After this # time the user will be asked for credentials again. From 6f62c2cf27016a81848e3fe9e76020aa83c506df Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 00:36:51 +0100 Subject: [PATCH 013/507] Fix SCSS import file error --- app/assets/stylesheets/darkswarm/all.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index ee1c4fc690..c40eb7e303 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -13,7 +13,7 @@ @import 'layout/*'; @import '*'; @import 'pages/*'; -@import '../web/all'; +@import 'web/all'; ofn-modal { display: block; From 5b8552f5417d29bdc2212c772f8c71898829f22b Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 00:39:56 +0100 Subject: [PATCH 014/507] Fix ActiveRecord::Relation issue Rails 4 now returns an Activerecord::Relation when using `SomeModel.all`. To get all the objects (as in Rails 3) we need to use `SomeModel.all.to_a`. See: https://stackoverflow.com/a/22417170 --- app/helpers/injection_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb index 6ebf77a8fb..9b06121df4 100644 --- a/app/helpers/injection_helper.rb +++ b/app/helpers/injection_helper.rb @@ -78,11 +78,11 @@ module InjectionHelper end def inject_taxons - inject_json_ams "taxons", Spree::Taxon.all, Api::TaxonSerializer + inject_json_ams "taxons", Spree::Taxon.all.to_a, Api::TaxonSerializer end def inject_properties - inject_json_ams "properties", Spree::Property.all, Api::PropertySerializer + inject_json_ams "properties", Spree::Property.all.to_a, Api::PropertySerializer end def inject_currency_config From 1fa2d05c0c9b3b48b2019ad7e9411d25002a1519 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 00:44:58 +0100 Subject: [PATCH 015/507] Fix AuthenticationHelper#spree_current_user `current_spree_user`: method not found... --- lib/spree/authentication_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/spree/authentication_helpers.rb b/lib/spree/authentication_helpers.rb index 49bd97542a..29bb716d98 100644 --- a/lib/spree/authentication_helpers.rb +++ b/lib/spree/authentication_helpers.rb @@ -8,7 +8,7 @@ module Spree end def spree_current_user - current_spree_user + @current_spree_user ||= request.env['warden'].authenticate end delegate :login_path, to: :spree, prefix: true From 8ffdd806bfbeb2d4b21529f51afc08a52ed7bbd6 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 00:52:06 +0100 Subject: [PATCH 016/507] Enable rails-i18n 4.0 --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index ddcaf172c1..d305e53645 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" } gem 'i18n', '~> 0.6.11' gem 'i18n-js', '~> 3.6.0' gem 'rails', '~> 4.0.0' -# gem 'rails-i18n', '~> 4.0' +gem 'rails-i18n', '~> 4.0' gem 'rails_safe_tasks', '~> 1.0' gem "activerecord-import" diff --git a/Gemfile.lock b/Gemfile.lock index 2b5aff6310..b491a1547c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -584,7 +584,6 @@ GEM rubocop-rails (2.4.2) rack (>= 1.1) rubocop (>= 0.72.0) - ruby-ole (1.2.12.2) ruby-progressbar (1.10.1) ruby-rc4 (0.1.5) rubyzip (1.3.0) @@ -627,9 +626,9 @@ GEM state_machine (1.2.0) stringex (1.5.1) stripe (5.11.0) - test-unit (3.3.5) temple (0.8.2) power_assert + test-unit (3.3.5) thor (0.20.3) thread_safe (0.3.6) tilt (1.4.1) @@ -742,6 +741,7 @@ DEPENDENCIES rack-rewrite rack-ssl rails (~> 4.0.0) + rails-i18n (~> 4.0) rails_safe_tasks (~> 1.0) redcarpet roadie-rails (~> 1.3.0) @@ -750,7 +750,7 @@ DEPENDENCIES rspec-retry rubocop rubocop-rails - sass-rails (~> 3.2.3) + sass-rails select2-rails (~> 3.4.7) selenium-webdriver shoulda-matchers From b03ef140f7e3b657ecdb1f9a825b7459f56f96c8 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 00:54:19 +0100 Subject: [PATCH 017/507] Enable sass --- Gemfile | 2 +- Gemfile.lock | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index d305e53645..6d970fed74 100644 --- a/Gemfile +++ b/Gemfile @@ -59,7 +59,7 @@ gem 'db2fog' gem 'haml' gem 'rabl' gem 'redcarpet' -#gem 'sass', "~> 3.3" +gem 'sass' gem 'sass-rails', groups: [:default] gem 'truncate_html' gem 'unicorn' diff --git a/Gemfile.lock b/Gemfile.lock index b491a1547c..c999438bde 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -750,6 +750,7 @@ DEPENDENCIES rspec-retry rubocop rubocop-rails + sass sass-rails select2-rails (~> 3.4.7) selenium-webdriver From 5603b703793ec3eef7c8823d60966a0c69dd8ea3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 01:13:15 +0100 Subject: [PATCH 018/507] Fix html escaping of characters in AMS rendering causing fatal javascript errors --- app/views/json/_injection_ams.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/json/_injection_ams.html.haml b/app/views/json/_injection_ams.html.haml index 40635189c8..088e01eb63 100644 --- a/app/views/json/_injection_ams.html.haml +++ b/app/views/json/_injection_ams.html.haml @@ -1,2 +1,2 @@ :javascript - angular.module('Darkswarm').value("#{name.to_s}", #{json}) + angular.module('Darkswarm').value("#{name.to_s.html_safe}", #{json.html_safe}) From 6eef2555f11966cb4a925ea1adf9cae4bc07bcb6 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 12:50:47 +0100 Subject: [PATCH 019/507] Fix i18n available locales error For some reason the locales defined in config/environment/test.rb are `en,es`, but in the used application.yml they were `en,es,en-GB`. This seems to trigger errors in the test environment ("en-GB is not a valid locale") if the two lists don't match..? --- config/application.yml.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.yml.example b/config/application.yml.example index 28d271e111..8de7369f42 100644 --- a/config/application.yml.example +++ b/config/application.yml.example @@ -13,7 +13,7 @@ DEFAULT_COUNTRY_CODE: AU # Locale for translation. LOCALE: en # For multilingual - ENV doesn't have array so pass it as string with commas -AVAILABLE_LOCALES: en,es,en-GB +AVAILABLE_LOCALES: en,es # Spree zone. CHECKOUT_ZONE: Australia # Find currency codes at http://en.wikipedia.org/wiki/ISO_4217. From b8e608abc2fbe7cc3d11a64bcaba579853b4ceac Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 13:09:37 +0100 Subject: [PATCH 020/507] Remove deprecated #whiny_nils --- config/environments/test.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 030e29cb79..48410d5e13 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -14,10 +14,6 @@ Openfoodnetwork::Application.configure do # Separate cache stores when running in parallel config.cache_store = :file_store, Rails.root.join("tmp", "cache", "paralleltests#{ENV['TEST_ENV_NUMBER']}") - - # Log error messages when you accidentally call methods on nil - config.whiny_nils = true - # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false From 418e9d23fe64c61a8ef516572381b2498d569ff8 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 13:12:22 +0100 Subject: [PATCH 021/507] Add missing eager_load setting in test.rb --- config/environments/test.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/environments/test.rb b/config/environments/test.rb index 48410d5e13..bb1da68229 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -7,6 +7,8 @@ Openfoodnetwork::Application.configure do # and recreated between test runs. Don't rely on the data there! config.cache_classes = false + config.eager_load = false + # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" From 6dd982532cbc0132eebb502ca5caacee53acb62f Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 15:27:37 +0100 Subject: [PATCH 022/507] Update deprecated/changed Rubocop rule names --- .rubocop_todo.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 33970eb805..87b43474cb 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -73,6 +73,11 @@ Lint/DuplicateMethods: - 'lib/discourse/single_sign_on.rb' - 'lib/open_food_network/subscription_summary.rb' +# Offense count: 1 +Lint/DuplicateHashKey: + Exclude: + - 'spec/models/calculator/weight_spec.rb' + # Offense count: 10 Lint/IneffectiveAccessModifier: Exclude: @@ -192,12 +197,10 @@ Naming/PredicateName: - 'lib/open_food_network/packing_report.rb' - 'lib/tasks/data.rake' -# Offense count: 152 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, Include. -# SupportedStyles: action, filter -# Include: app/controllers/**/*.rb -Rails/ActionFilter: +# Offense count: 8 +# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. +# AllowedNames: io, id, to, by, on, in, at, ip, db +Naming/MethodParameterName: Exclude: - 'app/controllers/admin/column_preferences_controller.rb' - 'app/controllers/admin/customers_controller.rb' From 30558485deddf08982f7eb3cae1b8162402bcdc9 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 15:44:10 +0100 Subject: [PATCH 023/507] Update deprecated #find_or_create_by_* methods --- app/services/default_shipping_category.rb | 2 +- app/services/default_stock_location.rb | 2 +- db/default/users.rb | 2 +- lib/tasks/sample_data/addressing.rb | 2 +- lib/tasks/sample_data/enterprise_factory.rb | 2 +- lib/tasks/sample_data/inventory_factory.rb | 4 ++-- lib/tasks/sample_data/product_factory.rb | 2 +- lib/tasks/sample_data/shipping_method_factory.rb | 2 +- lib/tasks/sample_data/taxon_factory.rb | 2 +- lib/tasks/sample_data/user_factory.rb | 2 +- spec/controllers/admin/order_cycles_controller_spec.rb | 2 +- spec/controllers/spree/admin/users_controller_spec.rb | 10 +++++----- spec/factories/shipment_factory.rb | 2 +- spec/factories/user_factory.rb | 2 +- spec/features/admin/multilingual_spec.rb | 2 +- spec/lib/open_food_network/customers_report_spec.rb | 2 +- .../order_cycle_management_report_spec.rb | 2 +- .../products_and_inventory_report_spec.rb | 2 +- spec/support/controller_helper.rb | 2 +- spec/support/request/authentication_workflow.rb | 4 ++-- 20 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/services/default_shipping_category.rb b/app/services/default_shipping_category.rb index 10959de659..8e0a7b90ae 100644 --- a/app/services/default_shipping_category.rb +++ b/app/services/default_shipping_category.rb @@ -8,6 +8,6 @@ class DefaultShippingCategory end def self.find_or_create - Spree::ShippingCategory.find_or_create_by_name(NAME) + Spree::ShippingCategory.find_or_create_by(name: NAME) end end diff --git a/app/services/default_stock_location.rb b/app/services/default_stock_location.rb index dc4499198b..3a80bc98ab 100644 --- a/app/services/default_stock_location.rb +++ b/app/services/default_stock_location.rb @@ -14,6 +14,6 @@ class DefaultStockLocation end def self.find_or_create - Spree::StockLocation.find_or_create_by_name(NAME) + Spree::StockLocation.find_or_create_by(name: NAME) end end diff --git a/db/default/users.rb b/db/default/users.rb index 1bad9daf8a..f46b1eae74 100644 --- a/db/default/users.rb +++ b/db/default/users.rb @@ -59,7 +59,7 @@ def create_admin_user admin.skip_confirmation! admin.skip_confirmation_notification! if admin.save - role = Spree::Role.find_or_create_by_name 'admin' + role = Spree::Role.find_or_create_by(name: 'admin') admin.spree_roles << role admin.save say "Done!" diff --git a/lib/tasks/sample_data/addressing.rb b/lib/tasks/sample_data/addressing.rb index bc1471e276..dca3ebd973 100644 --- a/lib/tasks/sample_data/addressing.rb +++ b/lib/tasks/sample_data/addressing.rb @@ -14,7 +14,7 @@ module Addressing end def zone - zone = Spree::Zone.find_or_create_by_name!(ENV.fetch('CHECKOUT_ZONE')) + zone = Spree::Zone.find_or_create_by!(name: ENV.fetch('CHECKOUT_ZONE')) zone.members.create!(zoneable: country) unless zone.zoneables.include?(country) zone end diff --git a/lib/tasks/sample_data/enterprise_factory.rb b/lib/tasks/sample_data/enterprise_factory.rb index cf5d62db22..296d05cef8 100644 --- a/lib/tasks/sample_data/enterprise_factory.rb +++ b/lib/tasks/sample_data/enterprise_factory.rb @@ -11,7 +11,7 @@ class EnterpriseFactory name = data[:name] log "- #{name}" data[:long_description] = data[:long_description].strip_heredoc.tr("\n", " ") - Enterprise.create_with(data).find_or_create_by_name!(name) + Enterprise.create_with(data).find_or_create_by!(name: name) end end diff --git a/lib/tasks/sample_data/inventory_factory.rb b/lib/tasks/sample_data/inventory_factory.rb index b4147e024d..81201139cf 100644 --- a/lib/tasks/sample_data/inventory_factory.rb +++ b/lib/tasks/sample_data/inventory_factory.rb @@ -18,7 +18,7 @@ class InventoryFactory enterprise: shop, variant: product.variants.first, visible: true - ).find_or_create_by_variant_id!(product.variants.first.id) + ).find_or_create_by!(variant_id: product.variants.first.id) create_override(shop, product) end @@ -29,6 +29,6 @@ class InventoryFactory price: 12, on_demand: false, count_on_hand: 5 - ).find_or_create_by_variant_id!(product.variants.first.id) + ).find_or_create_by!(variant_id: product.variants.first.id) end end diff --git a/lib/tasks/sample_data/product_factory.rb b/lib/tasks/sample_data/product_factory.rb index 9d5411bef5..6c220a6527 100644 --- a/lib/tasks/sample_data/product_factory.rb +++ b/lib/tasks/sample_data/product_factory.rb @@ -75,7 +75,7 @@ class ProductFactory shipping_category: DefaultShippingCategory.find_or_create, tax_category_id: find_or_create_tax_category.id ) - product = Spree::Product.create_with(params).find_or_create_by_name!(params[:name]) + product = Spree::Product.create_with(params).find_or_create_by!(name: params[:name]) product.variants.first.update_attribute :on_demand, true product end diff --git a/lib/tasks/sample_data/shipping_method_factory.rb b/lib/tasks/sample_data/shipping_method_factory.rb index dfa3cd8556..02b5b2d59f 100644 --- a/lib/tasks/sample_data/shipping_method_factory.rb +++ b/lib/tasks/sample_data/shipping_method_factory.rb @@ -49,7 +49,7 @@ class ShippingMethodFactory params[:distributor_ids] = [enterprise.id] method = enterprise.shipping_methods.new(params) method.zones << zone - method.shipping_categories << Spree::ShippingCategory.find_or_create_by_name('Default') + method.shipping_categories << Spree::ShippingCategory.find_or_create_by(name: 'Default') method.save! method end diff --git a/lib/tasks/sample_data/taxon_factory.rb b/lib/tasks/sample_data/taxon_factory.rb index f6d4bf3945..4c9878af81 100644 --- a/lib/tasks/sample_data/taxon_factory.rb +++ b/lib/tasks/sample_data/taxon_factory.rb @@ -5,7 +5,7 @@ class TaxonFactory def create_samples log "Creating taxonomies:" - taxonomy = Spree::Taxonomy.find_or_create_by_name!('Products') + taxonomy = Spree::Taxonomy.find_or_create_by!(name: 'Products') taxons = ['Vegetables', 'Fruit', 'Oils', 'Preserves and Sauces', 'Dairy', 'Meat and Fish'] taxons.each do |taxon_name| create_taxon(taxonomy, taxon_name) diff --git a/lib/tasks/sample_data/user_factory.rb b/lib/tasks/sample_data/user_factory.rb index 36aae48b37..9b54e26a41 100644 --- a/lib/tasks/sample_data/user_factory.rb +++ b/lib/tasks/sample_data/user_factory.rb @@ -34,7 +34,7 @@ class UserFactory password_confirmation: password, confirmation_sent_at: Time.zone.now, confirmed_at: Time.zone.now - ).find_or_create_by_email!(email) + ).find_or_create_by!(email: email) [name, user] end end diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb index 67169a1047..43707cc8f2 100644 --- a/spec/controllers/admin/order_cycles_controller_spec.rb +++ b/spec/controllers/admin/order_cycles_controller_spec.rb @@ -291,7 +291,7 @@ module Admin let(:user) { create_enterprise_user } let(:admin_user) do user = create(:user) - user.spree_roles << Spree::Role.find_or_create_by_name!('admin') + user.spree_roles << Spree::Role.find_or_create_by!(name: 'admin') user end let(:order_cycle) { create(:simple_order_cycle) } diff --git a/spec/controllers/spree/admin/users_controller_spec.rb b/spec/controllers/spree/admin/users_controller_spec.rb index a42630964d..22c0bc71ab 100644 --- a/spec/controllers/spree/admin/users_controller_spec.rb +++ b/spec/controllers/spree/admin/users_controller_spec.rb @@ -13,13 +13,13 @@ describe Spree::Admin::UsersController do end it 'should grant access to users with an admin role' do - user.spree_roles << Spree::Role.find_or_create_by_name('admin') + user.spree_roles << Spree::Role.find_or_create_by(name: 'admin') spree_post :index expect(response).to render_template :index end it "allows admins to update a user's API key" do - user.spree_roles << Spree::Role.find_or_create_by_name('admin') + user.spree_roles << Spree::Role.find_or_create_by(name: 'admin') expect(test_user).to receive(:generate_spree_api_key!).and_return(true) puts user.id puts test_user.id @@ -28,21 +28,21 @@ describe Spree::Admin::UsersController do end it "allows admins to clear a user's API key" do - user.spree_roles << Spree::Role.find_or_create_by_name('admin') + user.spree_roles << Spree::Role.find_or_create_by(name: 'admin') expect(test_user).to receive(:clear_spree_api_key!).and_return(true) spree_put :clear_api_key, id: test_user.id expect(response).to redirect_to(spree.edit_admin_user_path(test_user)) end it 'should deny access to users with an bar role' do - user.spree_roles << Spree::Role.find_or_create_by_name('bar') + user.spree_roles << Spree::Role.find_or_create_by(name: 'bar') Spree::Ability.register_ability(BarAbility) spree_post :index expect(response).to redirect_to('/unauthorized') end it 'should deny access to users with an bar role' do - user.spree_roles << Spree::Role.find_or_create_by_name('bar') + user.spree_roles << Spree::Role.find_or_create_by(name: 'bar') Spree::Ability.register_ability(BarAbility) spree_post :update, id: '9' expect(response).to redirect_to('/unauthorized') diff --git a/spec/factories/shipment_factory.rb b/spec/factories/shipment_factory.rb index aa4002f9c6..75bc54654d 100644 --- a/spec/factories/shipment_factory.rb +++ b/spec/factories/shipment_factory.rb @@ -31,6 +31,6 @@ end FactoryBot.modify do factory :shipment, class: Spree::Shipment do # keeps test shipments unique per order - initialize_with { Spree::Shipment.find_or_create_by_order_id(order.id) } + initialize_with { Spree::Shipment.find_or_create_by(order_id: order.id) } end end diff --git a/spec/factories/user_factory.rb b/spec/factories/user_factory.rb index 9e902c202e..561aa064bf 100644 --- a/spec/factories/user_factory.rb +++ b/spec/factories/user_factory.rb @@ -23,7 +23,7 @@ FactoryBot.modify do confirmed_at '1970-01-01 00:00:01' after(:create) do |user| - user.spree_roles << Spree::Role.find_or_create_by_name!('admin') + user.spree_roles << Spree::Role.find_or_create_by!(name: 'admin') end end end diff --git a/spec/features/admin/multilingual_spec.rb b/spec/features/admin/multilingual_spec.rb index 7f86b30e74..ee9d44e195 100644 --- a/spec/features/admin/multilingual_spec.rb +++ b/spec/features/admin/multilingual_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature 'Multilingual', js: true do include AuthenticationWorkflow include WebHelper - let(:admin_role) { Spree::Role.find_or_create_by_name!('admin') } + let(:admin_role) { Spree::Role.find_or_create_by!(name: 'admin') } let(:admin_user) { create(:user) } background do diff --git a/spec/lib/open_food_network/customers_report_spec.rb b/spec/lib/open_food_network/customers_report_spec.rb index 14b3024d7e..173a093759 100644 --- a/spec/lib/open_food_network/customers_report_spec.rb +++ b/spec/lib/open_food_network/customers_report_spec.rb @@ -5,7 +5,7 @@ module OpenFoodNetwork context "as a site admin" do let(:user) do user = create(:user) - user.spree_roles << Spree::Role.find_or_create_by_name!("admin") + user.spree_roles << Spree::Role.find_or_create_by!(name: 'admin') user end subject { CustomersReport.new user, {}, true } diff --git a/spec/lib/open_food_network/order_cycle_management_report_spec.rb b/spec/lib/open_food_network/order_cycle_management_report_spec.rb index a9db775335..707cc8c77c 100644 --- a/spec/lib/open_food_network/order_cycle_management_report_spec.rb +++ b/spec/lib/open_food_network/order_cycle_management_report_spec.rb @@ -7,7 +7,7 @@ module OpenFoodNetwork context "as a site admin" do let(:user) do user = create(:user) - user.spree_roles << Spree::Role.find_or_create_by_name!("admin") + user.spree_roles << Spree::Role.find_or_create_by!(name: "admin") user end subject { OrderCycleManagementReport.new user, {}, true } diff --git a/spec/lib/open_food_network/products_and_inventory_report_spec.rb b/spec/lib/open_food_network/products_and_inventory_report_spec.rb index 4c34fa204a..193c5134e2 100644 --- a/spec/lib/open_food_network/products_and_inventory_report_spec.rb +++ b/spec/lib/open_food_network/products_and_inventory_report_spec.rb @@ -5,7 +5,7 @@ module OpenFoodNetwork context "As a site admin" do let(:user) do user = create(:user) - user.spree_roles << Spree::Role.find_or_create_by_name!("admin") + user.spree_roles << Spree::Role.find_or_create_by!(name: 'admin') user end subject do diff --git a/spec/support/controller_helper.rb b/spec/support/controller_helper.rb index f49907dbe0..b543555319 100644 --- a/spec/support/controller_helper.rb +++ b/spec/support/controller_helper.rb @@ -3,7 +3,7 @@ module OpenFoodNetwork def login_as_admin @admin_user ||= begin user = create(:user) - user.spree_roles << Spree::Role.find_or_create_by_name!('admin') + user.spree_roles << Spree::Role.find_or_create_by!(name: 'admin') user end diff --git a/spec/support/request/authentication_workflow.rb b/spec/support/request/authentication_workflow.rb index fb99f9e6ae..b1ff1587cd 100644 --- a/spec/support/request/authentication_workflow.rb +++ b/spec/support/request/authentication_workflow.rb @@ -6,7 +6,7 @@ module AuthenticationWorkflow end def quick_login_as_admin - admin_role = Spree::Role.find_or_create_by_name!('admin') + admin_role = Spree::Role.find_or_create_by!(name: 'admin') admin_user = create(:user, password: 'passw0rd', password_confirmation: 'passw0rd', @@ -42,7 +42,7 @@ module AuthenticationWorkflow end def login_to_consumer_section - user_role = Spree::Role.find_or_create_by_name!('user') + user_role = Spree::Role.find_or_create_by!(name: 'user') user = create_enterprise_user( email: 'someone@ofn.org', password: 'passw0rd', From 53645517af834f678b17e3094921267c353b2f8c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 16:15:34 +0100 Subject: [PATCH 024/507] Update deprecated #find_by_* methods --- .../darkswarm/services/geo.js.erb.coffee | 2 +- app/controllers/admin/customers_controller.rb | 2 +- .../admin/enterprise_fees_controller.rb | 4 +- .../admin/enterprise_groups_controller.rb | 4 +- .../admin/enterprises_controller.rb | 12 ++--- .../admin/manager_invitations_controller.rb | 2 +- .../admin/order_cycles_controller.rb | 2 +- .../admin/producer_properties_controller.rb | 2 +- .../admin/stripe_accounts_controller.rb | 2 +- .../subscription_line_items_controller.rb | 6 +-- app/controllers/api/base_controller.rb | 2 +- .../api/enterprise_attachment_controller.rb | 2 +- .../api/enterprise_fees_controller.rb | 2 +- app/controllers/api/enterprises_controller.rb | 6 +-- .../api/exchange_products_controller.rb | 6 +-- .../api/order_cycles_controller.rb | 4 +- app/controllers/api/products_controller.rb | 2 +- app/controllers/api/shipments_controller.rb | 6 +-- app/controllers/api/taxons_controller.rb | 2 +- app/controllers/api/variants_controller.rb | 2 +- app/controllers/cart_controller.rb | 2 +- app/controllers/enterprises_controller.rb | 6 +-- app/controllers/groups_controller.rb | 2 +- app/controllers/line_items_controller.rb | 2 +- app/controllers/shop_controller.rb | 2 +- .../spree/admin/images_controller.rb | 2 +- .../orders/customer_details_controller.rb | 4 +- .../spree/admin/payments_controller.rb | 2 +- .../spree/admin/search_controller.rb | 2 +- .../spree/credit_cards_controller.rb | 4 +- app/controllers/spree/orders_controller.rb | 10 ++-- app/controllers/spree/users_controller.rb | 2 +- app/controllers/user_passwords_controller.rb | 2 +- app/models/column_preference.rb | 2 +- app/models/concerns/order_shipment.rb | 2 +- app/models/customer.rb | 2 +- app/models/producer_property.rb | 2 +- app/models/spree/gateway/stripe_connect.rb | 2 +- app/models/spree/order_decorator.rb | 4 +- app/models/spree/product_decorator.rb | 2 +- app/models/spree/user.rb | 4 +- app/services/default_stock_location.rb | 2 +- app/services/line_item_syncer.rb | 2 +- app/services/order_factory.rb | 2 +- .../payment_methods/_stripe_connect.html.haml | 2 +- config/application.rb | 2 +- db/default/users.rb | 2 +- .../20120327000582_polymorphic_payments.rb | 2 +- ...00584_assign_creditcard_txns_to_payment.rb | 2 +- ...13335_add_shipping_method_to_line_items.rb | 2 +- ...20130805050109_update_line_item_caching.rb | 2 +- ...522044009_add_primary_taxon_to_products.rb | 2 +- ...1219034321_add_permalink_to_enterprises.rb | 2 +- ...instances_to_existing_enterprise_groups.rb | 2 +- .../20150508072938_add_customer_to_orders.rb | 4 +- .../20150527004427_add_permalink_to_groups.rb | 2 +- ...0612045544_make_enterprises_name_unique.rb | 2 +- ...728140134_remove_email_from_enterprises.rb | 4 +- db/seeds.rb | 6 +-- .../order_cycle_form_applicator.rb | 3 +- lib/open_food_network/sales_tax_report.rb | 2 +- lib/stripe/account_connector.rb | 2 +- lib/tasks/sample_data/addressing.rb | 2 +- lib/tasks/sample_data/customer_factory.rb | 2 +- lib/tasks/sample_data/inventory_factory.rb | 2 +- lib/tasks/sample_data/order_cycle_factory.rb | 2 +- lib/tasks/sample_data/product_factory.rb | 8 ++-- .../admin/enterprises_controller_spec.rb | 18 +++---- .../manager_invitations_controller_spec.rb | 6 +-- .../admin/order_cycles_controller_spec.rb | 2 +- .../variant_overrides_controller_spec.rb | 2 +- .../api/enterprises_controller_spec.rb | 2 +- spec/factories.rb | 6 +-- spec/factories/subscription_factory.rb | 5 +- spec/features/admin/enterprise_fees_spec.rb | 2 +- spec/features/admin/enterprise_roles_spec.rb | 2 +- spec/features/admin/order_cycles_spec.rb | 2 +- spec/features/admin/payment_method_spec.rb | 8 ++-- spec/features/admin/product_import_spec.rb | 26 +++++----- spec/features/admin/products_spec.rb | 6 +-- spec/features/admin/schedules_spec.rb | 2 +- spec/features/admin/shipping_methods_spec.rb | 2 +- spec/features/admin/users_spec.rb | 2 +- spec/features/consumer/registration_spec.rb | 2 +- .../features/consumer/shopping/orders_spec.rb | 2 +- spec/jobs/subscription_placement_job_spec.rb | 2 +- .../products_and_inventory_report_spec.rb | 4 +- spec/models/product_importer_spec.rb | 48 +++++++++---------- spec/models/spree/line_item_spec.rb | 2 +- spec/models/spree/product_spec.rb | 4 +- spec/models/spree/variant_spec.rb | 2 +- spec/services/default_stock_location_spec.rb | 4 +- spec/services/order_factory_spec.rb | 2 +- spec/services/order_syncer_spec.rb | 6 +-- spec/services/subscription_form_spec.rb | 12 ++--- spec/support/seeds.rb | 4 +- 96 files changed, 194 insertions(+), 194 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee b/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee index 2f96722b08..f0e60be529 100644 --- a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee +++ b/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee @@ -10,7 +10,7 @@ Darkswarm.service "Geo", -> # console.log "Error: #{status}" geocode: (address, callback) -> geocoder = new google.maps.Geocoder() - geocoder.geocode {'address': address, 'region': "<%= Spree::Country.find_by_id(Spree::Config[:default_country_id]).iso %>"}, callback + geocoder.geocode {'address': address, 'region': "<%= Spree::Country.find_by(id: Spree::Config[:default_country_id]).iso %>"}, callback distanceBetween: (src, dst) -> google.maps.geometry.spherical.computeDistanceBetween @toLatLng(src), @toLatLng(dst) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index a2109c3fca..9941829d2b 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -64,7 +64,7 @@ module Admin def collection return Customer.where("1=0") unless json_request? && params[:enterprise_id].present? - enterprise = Enterprise.managed_by(spree_current_user).find_by_id(params[:enterprise_id]) + enterprise = Enterprise.managed_by(spree_current_user).find_by(id: params[:enterprise_id]) Customer.of(enterprise) end diff --git a/app/controllers/admin/enterprise_fees_controller.rb b/app/controllers/admin/enterprise_fees_controller.rb index f462569c4b..47372fa5f4 100644 --- a/app/controllers/admin/enterprise_fees_controller.rb +++ b/app/controllers/admin/enterprise_fees_controller.rb @@ -51,8 +51,8 @@ module Admin def collection case action when :for_order_cycle - order_cycle = OrderCycle.find_by_id(params[:order_cycle_id]) if params[:order_cycle_id] - coordinator = Enterprise.find_by_id(params[:coordinator_id]) if params[:coordinator_id] + order_cycle = OrderCycle.find_by(id: params[:order_cycle_id]) if params[:order_cycle_id] + coordinator = Enterprise.find_by(id: params[:coordinator_id]) if params[:coordinator_id] order_cycle = OrderCycle.new(coordinator: coordinator) if order_cycle.nil? && coordinator.present? enterprises = OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, order_cycle).visible_enterprises EnterpriseFee.for_enterprises(enterprises).order('enterprise_id', 'fee_type', 'name') diff --git a/app/controllers/admin/enterprise_groups_controller.rb b/app/controllers/admin/enterprise_groups_controller.rb index 67a7dface3..4494a7927a 100644 --- a/app/controllers/admin/enterprise_groups_controller.rb +++ b/app/controllers/admin/enterprise_groups_controller.rb @@ -28,7 +28,7 @@ module Admin def build_resource_with_address enterprise_group = build_resource_without_address enterprise_group.address = Spree::Address.new - enterprise_group.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) + enterprise_group.address.country = Spree::Country.find_by(id: Spree::Config[:default_country_id]) enterprise_group end alias_method_chain :build_resource, :address @@ -38,7 +38,7 @@ module Admin # The ! version is important to raise a RecordNotFound error. def find_resource permalink = params[:id] || params[:enterprise_group_id] - EnterpriseGroup.find_by_permalink!(permalink) + EnterpriseGroup.find_by!(permalink: permalink) end private diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 970c09a7ee..105a3ee52d 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -117,7 +117,7 @@ module Admin def build_resource_with_address enterprise = build_resource_without_address enterprise.address ||= Spree::Address.new - enterprise.address.country ||= Spree::Country.find_by_id(Spree::Config[:default_country_id]) + enterprise.address.country ||= Spree::Country.find_by(id: Spree::Config[:default_country_id]) enterprise end alias_method_chain :build_resource, :address @@ -125,7 +125,7 @@ module Admin # Overriding method on Spree's resource controller, # so that resources are found using permalink def find_resource - Enterprise.find_by_permalink(params[:id]) + Enterprise.find_by(permalink: params[:id]) end private @@ -141,8 +141,8 @@ module Admin def collection case action when :for_order_cycle - @order_cycle = OrderCycle.find_by_id(params[:order_cycle_id]) if params[:order_cycle_id] - coordinator = Enterprise.find_by_id(params[:coordinator_id]) if params[:coordinator_id] + @order_cycle = OrderCycle.find_by(id: params[:order_cycle_id]) if params[:order_cycle_id] + coordinator = Enterprise.find_by(id: params[:coordinator_id]) if params[:coordinator_id] @order_cycle = OrderCycle.new(coordinator: coordinator) if @order_cycle.nil? && coordinator.present? enterprises = OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, @order_cycle) @@ -211,7 +211,7 @@ module Admin # record is persisted. This problem is compounded by the use of calculators. @object.transaction do tag_rules_attributes.select{ |_i, attrs| attrs[:type].present? }.each do |_i, attrs| - rule = @object.tag_rules.find_by_id(attrs.delete(:id)) || attrs[:type].constantize.new(enterprise: @object) + rule = @object.tag_rules.find_by(id: attrs.delete(:id)) || attrs[:type].constantize.new(enterprise: @object) create_calculator_for(rule, attrs) if rule.type == "TagRule::DiscountOrder" && rule.calculator.nil? rule.update_attributes(attrs) end @@ -234,7 +234,7 @@ module Admin def check_can_change_bulk_sells unless spree_current_user.admin? params[:enterprise_set][:collection_attributes].each do |_i, enterprise_params| - enterprise_params.delete :sells unless spree_current_user == Enterprise.find_by_id(enterprise_params[:id]).owner + enterprise_params.delete :sells unless spree_current_user == Enterprise.find_by(id: enterprise_params[:id]).owner end end end diff --git a/app/controllers/admin/manager_invitations_controller.rb b/app/controllers/admin/manager_invitations_controller.rb index 45898bd5eb..36b1554cf9 100644 --- a/app/controllers/admin/manager_invitations_controller.rb +++ b/app/controllers/admin/manager_invitations_controller.rb @@ -8,7 +8,7 @@ module Admin authorize! :edit, @enterprise - existing_user = Spree::User.find_by_email(@email) + existing_user = Spree::User.find_by(email: @email) if existing_user render json: { errors: t('admin.enterprises.invite_manager.user_already_exists') }, status: :unprocessable_entity diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 14d075514a..18521a6649 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -164,7 +164,7 @@ module Admin def require_coordinator @order_cycle.coordinator = - permitted_coordinating_enterprises_for(@order_cycle).find_by_id(params[:coordinator_id]) + permitted_coordinating_enterprises_for(@order_cycle).find_by(id: params[:coordinator_id]) return if params[:coordinator_id] && @order_cycle.coordinator available_coordinators = permitted_coordinating_enterprises_for(@order_cycle) diff --git a/app/controllers/admin/producer_properties_controller.rb b/app/controllers/admin/producer_properties_controller.rb index 7bc021c04e..f83911d6a4 100644 --- a/app/controllers/admin/producer_properties_controller.rb +++ b/app/controllers/admin/producer_properties_controller.rb @@ -11,7 +11,7 @@ module Admin end def load_enterprise - @enterprise = Enterprise.find_by_permalink! params[:enterprise_id] + @enterprise = Enterprise.find_by! permalink: params[:enterprise_id] end def load_properties diff --git a/app/controllers/admin/stripe_accounts_controller.rb b/app/controllers/admin/stripe_accounts_controller.rb index 54a48206f4..90b4e2c85c 100644 --- a/app/controllers/admin/stripe_accounts_controller.rb +++ b/app/controllers/admin/stripe_accounts_controller.rb @@ -28,7 +28,7 @@ module Admin def status return render json: { status: :stripe_disabled } unless Spree::Config.stripe_connect_enabled - stripe_account = StripeAccount.find_by_enterprise_id(params[:enterprise_id]) + stripe_account = StripeAccount.find_by(enterprise_id: params[:enterprise_id]) return render json: { status: :account_missing } unless stripe_account authorize! :status, stripe_account diff --git a/app/controllers/admin/subscription_line_items_controller.rb b/app/controllers/admin/subscription_line_items_controller.rb index b3649696ac..a87ddebe45 100644 --- a/app/controllers/admin/subscription_line_items_controller.rb +++ b/app/controllers/admin/subscription_line_items_controller.rb @@ -24,8 +24,8 @@ module Admin end def load_build_context - @shop = Enterprise.managed_by(spree_current_user).find_by_id(params[:shop_id]) - @schedule = permissions.editable_schedules.find_by_id(params[:schedule_id]) + @shop = Enterprise.managed_by(spree_current_user).find_by(id: params[:shop_id]) + @schedule = permissions.editable_schedules.find_by(id: params[:schedule_id]) @order_cycle = @schedule.andand.current_or_next_order_cycle @variant = variant_if_eligible(params[:subscription_line_item][:variant_id]) if @shop.present? end @@ -56,7 +56,7 @@ module Admin end def variant_if_eligible(variant_id) - SubscriptionVariantsService.eligible_variants(@shop).find_by_id(variant_id) + SubscriptionVariantsService.eligible_variants(@shop).find_by(id: variant_id) end end end diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 51b7acbe5c..ac67bb6aa3 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -55,7 +55,7 @@ module Api return end - return if @current_api_user = Spree.user_class.find_by_spree_api_key(api_key.to_s) + return if @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s) invalid_api_key end diff --git a/app/controllers/api/enterprise_attachment_controller.rb b/app/controllers/api/enterprise_attachment_controller.rb index 406b1988fe..00b7c87043 100644 --- a/app/controllers/api/enterprise_attachment_controller.rb +++ b/app/controllers/api/enterprise_attachment_controller.rb @@ -25,7 +25,7 @@ module Api end def load_enterprise - @enterprise = Enterprise.find_by_permalink(params[:enterprise_id].to_s) + @enterprise = Enterprise.find_by(permalink: params[:enterprise_id].to_s) raise UnknownEnterpriseAuthorizationActionError if enterprise_authorize_action.blank? authorize!(enterprise_authorize_action, @enterprise) diff --git a/app/controllers/api/enterprise_fees_controller.rb b/app/controllers/api/enterprise_fees_controller.rb index c6216a1270..9d0fda0d05 100644 --- a/app/controllers/api/enterprise_fees_controller.rb +++ b/app/controllers/api/enterprise_fees_controller.rb @@ -15,7 +15,7 @@ module Api private def enterprise_fee - @enterprise_fee ||= EnterpriseFee.find_by_id params[:id] + @enterprise_fee ||= EnterpriseFee.find_by id: params[:id] end end end diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index 82ae80d31e..dd77882e3f 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -19,7 +19,7 @@ module Api end def update - @enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id]) + @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id]) authorize! :update, @enterprise if @enterprise.update_attributes(params[:enterprise]) @@ -30,7 +30,7 @@ module Api end def update_image - @enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id]) + @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id]) authorize! :update, @enterprise if params[:logo] && @enterprise.update_attributes( logo: params[:logo] ) @@ -43,7 +43,7 @@ module Api end def shopfront - enterprise = Enterprise.find_by_id(params[:id]) + enterprise = Enterprise.find_by(id: params[:id]) render text: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok end diff --git a/app/controllers/api/exchange_products_controller.rb b/app/controllers/api/exchange_products_controller.rb index cb28bbbec6..ff9cc1ea46 100644 --- a/app/controllers/api/exchange_products_controller.rb +++ b/app/controllers/api/exchange_products_controller.rb @@ -58,7 +58,7 @@ module Api end def load_data_from_exchange - exchange = Exchange.find_by_id(params[:exchange_id]) + exchange = Exchange.find_by(id: params[:exchange_id]) @order_cycle = exchange.order_cycle @incoming = exchange.incoming @@ -66,10 +66,10 @@ module Api end def load_data_from_other_params - @enterprise = Enterprise.find_by_id(params[:enterprise_id]) + @enterprise = Enterprise.find_by(id: params[:enterprise_id]) if params[:order_cycle_id] - @order_cycle = OrderCycle.find_by_id(params[:order_cycle_id]) + @order_cycle = OrderCycle.find_by(id: params[:order_cycle_id]) elsif !params[:incoming] raise "order_cycle_id is required to list products for new outgoing exchange" end diff --git a/app/controllers/api/order_cycles_controller.rb b/app/controllers/api/order_cycles_controller.rb index e0088d43f4..9e598caa1c 100644 --- a/app/controllers/api/order_cycles_controller.rb +++ b/app/controllers/api/order_cycles_controller.rb @@ -70,11 +70,11 @@ module Api end def distributor - Enterprise.find_by_id(params[:distributor]) + Enterprise.find_by(id: params[:distributor]) end def order_cycle - OrderCycle.find_by_id(params[:id]) + OrderCycle.find_by(id: params[:id]) end def customer diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb index a45e9a8aea..cef1e975af 100644 --- a/app/controllers/api/products_controller.rb +++ b/app/controllers/api/products_controller.rb @@ -92,7 +92,7 @@ module Api private def find_product(id) - product_scope.find_by_permalink!(id.to_s) + product_scope.find_by!(permalink: id.to_s) rescue ActiveRecord::RecordNotFound product_scope.find(id) end diff --git a/app/controllers/api/shipments_controller.rb b/app/controllers/api/shipments_controller.rb index 4c9bb047eb..d7623da0c7 100644 --- a/app/controllers/api/shipments_controller.rb +++ b/app/controllers/api/shipments_controller.rb @@ -22,7 +22,7 @@ module Api def update authorize! :read, Spree::Shipment - @shipment = @order.shipments.find_by_number!(params[:id]) + @shipment = @order.shipments.find_by!(number: params[:id]) params[:shipment] ||= [] unlock = params[:shipment].delete(:unlock) @@ -82,12 +82,12 @@ module Api private def find_order - @order = Spree::Order.find_by_number!(params[:order_id]) + @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 = @order.shipments.find_by!(number: params[:id]) @shipment.update_attributes(params[:shipment]) @shipment.reload end diff --git a/app/controllers/api/taxons_controller.rb b/app/controllers/api/taxons_controller.rb index a69642c6e8..68d9a6fdd8 100644 --- a/app/controllers/api/taxons_controller.rb +++ b/app/controllers/api/taxons_controller.rb @@ -26,7 +26,7 @@ module Api 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]) + taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id]) if taxonomy.nil? @taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api') diff --git a/app/controllers/api/variants_controller.rb b/app/controllers/api/variants_controller.rb index d6f8f80d5c..b64d5f6082 100644 --- a/app/controllers/api/variants_controller.rb +++ b/app/controllers/api/variants_controller.rb @@ -47,7 +47,7 @@ module Api private def product - @product ||= Spree::Product.find_by_permalink(params[:product_id]) if params[:product_id] + @product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id] end def scope diff --git a/app/controllers/cart_controller.rb b/app/controllers/cart_controller.rb index d452228299..7fbe24b48b 100644 --- a/app/controllers/cart_controller.rb +++ b/app/controllers/cart_controller.rb @@ -38,7 +38,7 @@ class CartController < BaseController def check_authorization session[:access_token] ||= params[:token] - order = Spree::Order.find_by_number(params[:id]) || current_order + order = Spree::Order.find_by(number: params[:id]) || current_order if order authorize! :edit, order, session[:access_token] diff --git a/app/controllers/enterprises_controller.rb b/app/controllers/enterprises_controller.rb index e5c30438d0..d8dfc4b0c7 100644 --- a/app/controllers/enterprises_controller.rb +++ b/app/controllers/enterprises_controller.rb @@ -36,7 +36,7 @@ class EnterprisesController < BaseController end def check_permalink - if Enterprise.find_by_permalink params[:permalink] + if Enterprise.find_by permalink: params[:permalink] render(text: params[:permalink], status: :conflict) && return end @@ -51,7 +51,7 @@ class EnterprisesController < BaseController private def set_enterprise - @enterprise = Enterprise.find_by_id(params[:id]) + @enterprise = Enterprise.find_by(id: params[:id]) end def clean_permalink @@ -63,7 +63,7 @@ class EnterprisesController < BaseController end def reset_order - distributor = Enterprise.is_distributor.find_by_permalink(params[:id]) || + distributor = Enterprise.is_distributor.find_by(permalink: params[:id]) || Enterprise.is_distributor.find(params[:id]) order = current_order(true) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 6dcc582f86..d13876304e 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -4,6 +4,6 @@ class GroupsController < BaseController def show enable_embedded_shopfront @hide_menu = true if @shopfront_layout == 'embedded' - @group = EnterpriseGroup.find_by_permalink(params[:id]) || EnterpriseGroup.find(params[:id]) + @group = EnterpriseGroup.find_by(permalink: params[:id]) || EnterpriseGroup.find(params[:id]) end end diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index b2002b7c54..219b836ab4 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -16,7 +16,7 @@ class LineItemsController < BaseController private def load_line_item - @line_item = Spree::LineItem.find_by_id(params[:id]) + @line_item = Spree::LineItem.find_by(id: params[:id]) not_found unless @line_item end diff --git a/app/controllers/shop_controller.rb b/app/controllers/shop_controller.rb index ee304d1f96..7aa5e4e796 100644 --- a/app/controllers/shop_controller.rb +++ b/app/controllers/shop_controller.rb @@ -9,7 +9,7 @@ class ShopController < BaseController def order_cycle if request.post? - if oc = OrderCycle.with_distributor(@distributor).active.find_by_id(params[:order_cycle_id]) + if oc = OrderCycle.with_distributor(@distributor).active.find_by(id: params[:order_cycle_id]) current_order(true).set_order_cycle! oc @current_order_cycle = oc render json: @current_order_cycle, serializer: Api::OrderCycleSerializer diff --git a/app/controllers/spree/admin/images_controller.rb b/app/controllers/spree/admin/images_controller.rb index a506a9231d..2a46ebec92 100644 --- a/app/controllers/spree/admin/images_controller.rb +++ b/app/controllers/spree/admin/images_controller.rb @@ -19,7 +19,7 @@ module Spree end def load_data - @product = Product.find_by_permalink(params[:product_id]) + @product = Product.find_by(permalink: params[:product_id]) @variants = @product.variants.collect do |variant| [variant.options_text, variant.id] end diff --git a/app/controllers/spree/admin/orders/customer_details_controller.rb b/app/controllers/spree/admin/orders/customer_details_controller.rb index 2a22c1e086..e7bb5bf366 100644 --- a/app/controllers/spree/admin/orders/customer_details_controller.rb +++ b/app/controllers/spree/admin/orders/customer_details_controller.rb @@ -20,7 +20,7 @@ module Spree def update if @order.update_attributes(params[:order]) if params[:guest_checkout] == "false" - @order.associate_user!(Spree.user_class.find_by_email(@order.email)) + @order.associate_user!(Spree.user_class.find_by(email: @order.email)) end AdvanceOrderService.new(@order).call @@ -57,7 +57,7 @@ module Spree end def set_guest_checkout_status - registered_user = Spree::User.find_by_email(params[:order][:email]) + registered_user = Spree::User.find_by(email: params[:order][:email]) params[:order][:guest_checkout] = registered_user.nil? diff --git a/app/controllers/spree/admin/payments_controller.rb b/app/controllers/spree/admin/payments_controller.rb index 0c17f8154a..af100b7c80 100644 --- a/app/controllers/spree/admin/payments_controller.rb +++ b/app/controllers/spree/admin/payments_controller.rb @@ -72,7 +72,7 @@ module Spree @payment.payment_method.payment_profiles_supported? && params[:card].present? && (params[:card] != 'new') - @payment.source = CreditCard.find_by_id(params[:card]) + @payment.source = CreditCard.find_by(id: params[:card]) end end diff --git a/app/controllers/spree/admin/search_controller.rb b/app/controllers/spree/admin/search_controller.rb index cc63ae2328..1d0f05fc1f 100644 --- a/app/controllers/spree/admin/search_controller.rb +++ b/app/controllers/spree/admin/search_controller.rb @@ -6,7 +6,7 @@ module Spree respond_to :json def known_users - @users = if exact_match = Spree.user_class.find_by_email(params[:q]) + @users = if exact_match = Spree.user_class.find_by(email: params[:q]) [exact_match] else spree_current_user.known_users.ransack(ransack_hash).result.limit(10) diff --git a/app/controllers/spree/credit_cards_controller.rb b/app/controllers/spree/credit_cards_controller.rb index 79f60b4323..71a365e784 100644 --- a/app/controllers/spree/credit_cards_controller.rb +++ b/app/controllers/spree/credit_cards_controller.rb @@ -17,7 +17,7 @@ module Spree end def update - @credit_card = Spree::CreditCard.find_by_id(params[:id]) + @credit_card = Spree::CreditCard.find_by(id: params[:id]) return update_failed unless @credit_card authorize! :update, @credit_card @@ -32,7 +32,7 @@ module Spree end def destroy - @credit_card = Spree::CreditCard.find_by_id(params[:id]) + @credit_card = Spree::CreditCard.find_by(id: params[:id]) if @credit_card authorize! :destroy, @credit_card destroy_at_stripe diff --git a/app/controllers/spree/orders_controller.rb b/app/controllers/spree/orders_controller.rb index ff0a395fc6..09f9374247 100644 --- a/app/controllers/spree/orders_controller.rb +++ b/app/controllers/spree/orders_controller.rb @@ -26,7 +26,7 @@ module Spree before_filter :check_at_least_one_line_item, only: :update def show - @order = Spree::Order.find_by_number!(params[:id]) + @order = Spree::Order.find_by!(number: params[:id]) end def empty @@ -39,7 +39,7 @@ module Spree def check_authorization session[:access_token] ||= params[:token] - order = Spree::Order.find_by_number(params[:id]) || current_order + order = Spree::Order.find_by(number: params[:id]) || current_order if order authorize! :edit, order, session[:access_token] @@ -133,7 +133,7 @@ module Spree def remove_missing_line_items(attrs) attrs.select do |_i, line_item| - Spree::LineItem.find_by_id(line_item[:id]) + Spree::LineItem.find_by(id: line_item[:id]) end end @@ -149,7 +149,7 @@ module Spree end def cancel - @order = Spree::Order.find_by_number!(params[:id]) + @order = Spree::Order.find_by!(number: params[:id]) authorize! :cancel, @order if @order.cancel @@ -207,7 +207,7 @@ module Spree # If a specific order is requested, return it if it is COMPLETE and # changes are allowed and the user has access. Return nil if not. def changeable_order_from_number - order = Spree::Order.complete.find_by_number(params[:id]) + order = Spree::Order.complete.find_by(number: params[:id]) return nil unless order.andand.changes_allowed? && can?(:update, order) order diff --git a/app/controllers/spree/users_controller.rb b/app/controllers/spree/users_controller.rb index d6d13f0e48..c620136a94 100644 --- a/app/controllers/spree/users_controller.rb +++ b/app/controllers/spree/users_controller.rb @@ -20,7 +20,7 @@ module Spree # Endpoint for queries to check if a user is already registered def registered_email - user = Spree.user_class.find_by_email params[:email] + user = Spree.user_class.find_by email: params[:email] render json: { registered: user.present? } end diff --git a/app/controllers/user_passwords_controller.rb b/app/controllers/user_passwords_controller.rb index 37cceb6bfc..2db2dc81a4 100644 --- a/app/controllers/user_passwords_controller.rb +++ b/app/controllers/user_passwords_controller.rb @@ -34,7 +34,7 @@ class UserPasswordsController < Spree::UserPasswordsController end def user_unconfirmed? - user = Spree::User.find_by_email(params[:spree_user][:email]) + user = Spree::User.find_by(email: params[:spree_user][:email]) user && !user.confirmed? end end diff --git a/app/models/column_preference.rb b/app/models/column_preference.rb index 9007cfca8e..61672f7927 100644 --- a/app/models/column_preference.rb +++ b/app/models/column_preference.rb @@ -23,7 +23,7 @@ class ColumnPreference < ActiveRecord::Base default_preferences = __send__("#{action_name}_columns") filter(default_preferences, user, action_name) default_preferences.each_with_object([]) do |(column_name, default_attributes), preferences| - stored_preference = stored_preferences.find_by_column_name(column_name) + stored_preference = stored_preferences.find_by(column_name: column_name) if stored_preference stored_preference.assign_attributes(default_attributes.select{ |k, _v| stored_preference[k].nil? }) preferences << stored_preference diff --git a/app/models/concerns/order_shipment.rb b/app/models/concerns/order_shipment.rb index f03ecd2fcc..1f9c937bb5 100644 --- a/app/models/concerns/order_shipment.rb +++ b/app/models/concerns/order_shipment.rb @@ -35,7 +35,7 @@ module OrderShipment shipment = shipments.first - shipping_rate = shipment.shipping_rates.find_by_shipping_method_id(shipping_method_id) + shipping_rate = shipment.shipping_rates.find_by(shipping_method_id: shipping_method_id) return unless shipping_rate shipment.selected_shipping_rate_id = shipping_rate.id diff --git a/app/models/customer.rb b/app/models/customer.rb index 24564888ba..8328aba831 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -36,7 +36,7 @@ class Customer < ActiveRecord::Base end def associate_user - self.user = user || Spree::User.find_by_email(email) + self.user = user || Spree::User.find_by(email: email) end def check_for_orders diff --git a/app/models/producer_property.rb b/app/models/producer_property.rb index a2de688357..f29b682def 100644 --- a/app/models/producer_property.rb +++ b/app/models/producer_property.rb @@ -22,7 +22,7 @@ class ProducerProperty < ActiveRecord::Base def property_name=(name) if name.present? - self.property = Spree::Property.find_by_name(name) || + self.property = Spree::Property.find_by(name: name) || Spree::Property.create(name: name, presentation: name) end end diff --git a/app/models/spree/gateway/stripe_connect.rb b/app/models/spree/gateway/stripe_connect.rb index 052423e5e0..e9941a2f04 100644 --- a/app/models/spree/gateway/stripe_connect.rb +++ b/app/models/spree/gateway/stripe_connect.rb @@ -28,7 +28,7 @@ module Spree end def stripe_account_id - StripeAccount.find_by_enterprise_id(preferred_enterprise_id).andand.stripe_user_id + StripeAccount.find_by(enterprise_id: preferred_enterprise_id).andand.stripe_user_id end # NOTE: the name of this method is determined by Spree::Payment::Processing diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 28d487d6fd..4e1e2e67e5 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -185,7 +185,7 @@ Spree::Order.class_eval do Bugsnag.notify(e) do |report| report.add_tab(:order, attributes) report.add_tab(:shipment, shipment.attributes) - report.add_tab(:shipment_in_db, Spree::Shipment.find_by_id(shipment.id).attributes) + report.add_tab(:shipment_in_db, Spree::Shipment.find_by(id: shipment.id).attributes) end end @@ -379,7 +379,7 @@ Spree::Order.class_eval do def associate_customer return customer if customer.present? - self.customer = Customer.of(distributor).find_by_email(email_for_customer) + self.customer = Customer.of(distributor).find_by(email: email_for_customer) end def ensure_customer diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index d136c2b681..b601122a65 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -184,7 +184,7 @@ Spree::Product.class_eval do option_type_name = "unit_#{variant_unit}" option_type_presentation = variant_unit.capitalize - Spree::OptionType.find_by_name(option_type_name) || + Spree::OptionType.find_by(name: option_type_name) || Spree::OptionType.create!(name: option_type_name, presentation: option_type_presentation) end diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index 135e54d306..370b248023 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -92,7 +92,7 @@ module Spree def build_enterprise_roles Enterprise.all.find_each do |enterprise| - unless enterprise_roles.find_by_enterprise_id enterprise.id + unless enterprise_roles.find_by enterprise_id: enterprise.id enterprise_roles.build(enterprise: enterprise) end end @@ -101,7 +101,7 @@ module Spree def customer_of(enterprise) return nil unless enterprise - customers.find_by_enterprise_id(enterprise) + customers.find_by(enterprise_id: enterprise) end def welcome_after_confirm diff --git a/app/services/default_stock_location.rb b/app/services/default_stock_location.rb index 3a80bc98ab..7ec0476321 100644 --- a/app/services/default_stock_location.rb +++ b/app/services/default_stock_location.rb @@ -4,7 +4,7 @@ class DefaultStockLocation NAME = 'default'.freeze def self.create! - country = Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) + country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) state = country.states.first Spree::StockLocation.create!(name: NAME, country_id: country.id, state_id: state.id, backorderable_default: false) end diff --git a/app/services/line_item_syncer.rb b/app/services/line_item_syncer.rb index 7771ebf150..e190db0be5 100644 --- a/app/services/line_item_syncer.rb +++ b/app/services/line_item_syncer.rb @@ -21,7 +21,7 @@ class LineItemSyncer def update_item_quantities(order) changed_subscription_line_items.each do |sli| - line_item = order.line_items.find_by_variant_id(sli.variant_id) + line_item = order.line_items.find_by(variant_id: sli.variant_id) if line_item.blank? order_update_issues.add(order, sli.variant.product_and_full_name) diff --git a/app/services/order_factory.rb b/app/services/order_factory.rb index 1a2aeba1b3..a7845618b0 100644 --- a/app/services/order_factory.rb +++ b/app/services/order_factory.rb @@ -46,7 +46,7 @@ class OrderFactory def build_line_items attrs[:line_items].each do |li| - next unless variant = Spree::Variant.find_by_id(li[:variant_id]) + next unless variant = Spree::Variant.find_by(id: li[:variant_id]) scoper.scope(variant) li[:quantity] = stock_limited_quantity(variant.on_demand, variant.on_hand, li[:quantity]) diff --git a/app/views/spree/admin/payment_methods/_stripe_connect.html.haml b/app/views/spree/admin/payment_methods/_stripe_connect.html.haml index 0e9ff2f614..4e0c59e94f 100644 --- a/app/views/spree/admin/payment_methods/_stripe_connect.html.haml +++ b/app/views/spree/admin/payment_methods/_stripe_connect.html.haml @@ -11,7 +11,7 @@ placeholder: t(".enterprise_select_placeholder"), data: 'shops', ng: { model: 'paymentMethod.preferred_enterprise_id' } } - else - %strong= Enterprise.find_by_id(@payment_method).andand.name + %strong= Enterprise.find_by(id: @payment_method).andand.name #stripe-account-status{ ng: { show: "paymentMethod.preferred_enterprise_id" } } .alert-box.warning{ ng: { hide: "stripe_account.status" } } diff --git a/config/application.rb b/config/application.rb index 057d50ff2f..33db7342e5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -39,7 +39,7 @@ module Openfoodnetwork Spree::Config['checkout_zone'] = ENV['CHECKOUT_ZONE'] Spree::Config['currency'] = ENV['CURRENCY'] if Spree::Country.table_exists? - country = Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) + country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) Spree::Config['default_country_id'] = country.id if country.present? else Spree::Config['default_country_id'] = 12 # Australia diff --git a/db/default/users.rb b/db/default/users.rb index f46b1eae74..4681ec1531 100644 --- a/db/default/users.rb +++ b/db/default/users.rb @@ -52,7 +52,7 @@ def create_admin_user load 'spree/user.rb' - if Spree::User.find_by_email(email) + if Spree::User.find_by(email: email) say "\nWARNING: There is already a user with the email: #{email}, so no account changes were made. If you wish to create an additional admin user, please run rake spree_auth:admin:create again with a different email.\n\n" else admin = Spree::User.new(attributes) diff --git a/db/migrate/20120327000582_polymorphic_payments.rb b/db/migrate/20120327000582_polymorphic_payments.rb index 33787c3d26..d598e48757 100644 --- a/db/migrate/20120327000582_polymorphic_payments.rb +++ b/db/migrate/20120327000582_polymorphic_payments.rb @@ -16,7 +16,7 @@ class PolymorphicPayments < ActiveRecord::Migration Spree::Creditcard.table_name = 'creditcards' Spree::Creditcard.all.each do |creditcard| - if checkout = Checkout.find_by_id(creditcard.checkout_id) and checkout.order + if checkout = Checkout.find_by(id: creditcard.checkout_id) and checkout.order if payment = checkout.order.payments.first execute "UPDATE payments SET source_type = 'Creditcard', source_id = #{creditcard.id} WHERE id = #{payment.id}" end diff --git a/db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb b/db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb index 562f60c7b0..e3c6850856 100644 --- a/db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb +++ b/db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb @@ -6,7 +6,7 @@ class AssignCreditcardTxnsToPayment < ActiveRecord::Migration Spree::Creditcard.table_name = 'creditcards' ActiveRecord::Base.connection.select_all('SELECT * FROM creditcard_txns').each do |txn_attrs| - if creditcard = Spree::Creditcard.find_by_id(txn_attrs['creditcard_id']) and creditcard.payments.first + if creditcard = Spree::Creditcard.find_by(id: txn_attrs['creditcard_id']) and creditcard.payments.first execute "UPDATE creditcard_txns SET payment_id = #{creditcard.payments.first.id} WHERE id = #{txn_attrs['id']}" end end diff --git a/db/migrate/20120919013335_add_shipping_method_to_line_items.rb b/db/migrate/20120919013335_add_shipping_method_to_line_items.rb index fd5974992d..bab7b8533a 100644 --- a/db/migrate/20120919013335_add_shipping_method_to_line_items.rb +++ b/db/migrate/20120919013335_add_shipping_method_to_line_items.rb @@ -6,7 +6,7 @@ class AddShippingMethodToLineItems < ActiveRecord::Migration begin shipping_method = li.product.shipping_method_for_distributor(li.order.distributor) rescue ArgumentError - shipping_method = Spree::ShippingMethod.find_by_name 'Producer Delivery' + shipping_method = Spree::ShippingMethod.find_by name: 'Producer Delivery' say "Line item #{li.id} does not have a valid shipping method, setting to '#{shipping_method.name}'" end diff --git a/db/migrate/20130805050109_update_line_item_caching.rb b/db/migrate/20130805050109_update_line_item_caching.rb index 42760e7c02..70543775c0 100644 --- a/db/migrate/20130805050109_update_line_item_caching.rb +++ b/db/migrate/20130805050109_update_line_item_caching.rb @@ -32,7 +32,7 @@ class UpdateLineItemCaching < ActiveRecord::Migration add_column :spree_line_items, :shipping_method_id, :integer SpreeLineItem.all.each do |line_item| - shipping_method = Spree::ShippingMethod.find_by_name(line_item.shipping_method_name) + shipping_method = Spree::ShippingMethod.find_by(name: line_item.shipping_method_name) unless shipping_method say "Shipping method #{line_item.shipping_method_name} not found, using the first available shipping method for LineItem #{line_item.id}" shipping_method = Spree::ShippingMethod.where("name != 'Delivery'").first diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb index d985d7f1b8..34bfae4efa 100644 --- a/db/migrate/20140522044009_add_primary_taxon_to_products.rb +++ b/db/migrate/20140522044009_add_primary_taxon_to_products.rb @@ -7,7 +7,7 @@ class AddPrimaryTaxonToProducts < ActiveRecord::Migration Spree::Product.all.each do |p| primary_taxon = p.taxons.where('spree_taxons.name != ?', 'specials').first - first_taxon = Spree::Taxonomy.find_by_name('Products').andand.root || Spree::Taxon.first + first_taxon = Spree::Taxonomy.find_by(name: 'Products').andand.root || Spree::Taxon.first p.update_column :primary_taxon_id, (primary_taxon || first_taxon) end diff --git a/db/migrate/20141219034321_add_permalink_to_enterprises.rb b/db/migrate/20141219034321_add_permalink_to_enterprises.rb index b912180ba7..850e1cf171 100644 --- a/db/migrate/20141219034321_add_permalink_to_enterprises.rb +++ b/db/migrate/20141219034321_add_permalink_to_enterprises.rb @@ -8,7 +8,7 @@ class AddPermalinkToEnterprises < ActiveRecord::Migration counter = 1 permalink = enterprise.name.parameterize permalink = "my-enterprise-name" if permalink == "" - while Enterprise.find_by_permalink(permalink) do + while Enterprise.find_by(permalink: permalink) do permalink = enterprise.name.parameterize + counter.to_s counter += 1 end diff --git a/db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb b/db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb index 3b93ee6386..0ef08a39dc 100644 --- a/db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb +++ b/db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb @@ -1,6 +1,6 @@ class AddAddressInstancesToExistingEnterpriseGroups < ActiveRecord::Migration def change - country = Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) + country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) state = country.states.first EnterpriseGroup.all.each do |g| next if g.address.present? diff --git a/db/migrate/20150508072938_add_customer_to_orders.rb b/db/migrate/20150508072938_add_customer_to_orders.rb index 79d69baf49..e961840255 100644 --- a/db/migrate/20150508072938_add_customer_to_orders.rb +++ b/db/migrate/20150508072938_add_customer_to_orders.rb @@ -5,9 +5,9 @@ class AddCustomerToOrders < ActiveRecord::Migration add_foreign_key :spree_orders, :customers, column: :customer_id Spree::Order.where("spree_orders.email IS NOT NULL AND distributor_id IS NOT NULL AND customer_id IS NULL").each do |order| - customer = Customer.find_by_email_and_enterprise_id(order.email, order.distributor_id) + customer = Customer.find_by(email: order.email, enterprise_id: order.distributor_id) unless customer.present? - user = Spree::User.find_by_email(order.email) + user = Spree::User.find_by(email: order.email) customer = Customer.create!(email: order.email, enterprise_id: order.distributor_id, user_id: user.andand.id ) end order.update_attribute(:customer, customer) diff --git a/db/migrate/20150527004427_add_permalink_to_groups.rb b/db/migrate/20150527004427_add_permalink_to_groups.rb index ab6886cff4..df40798492 100644 --- a/db/migrate/20150527004427_add_permalink_to_groups.rb +++ b/db/migrate/20150527004427_add_permalink_to_groups.rb @@ -8,7 +8,7 @@ class AddPermalinkToGroups < ActiveRecord::Migration counter = 1 permalink = group.name.parameterize permalink = "my-group-name" if permalink == "" - while EnterpriseGroup.find_by_permalink(permalink) do + while EnterpriseGroup.find_by(permalink: permalink) do permalink = group.name.parameterize + counter.to_s counter += 1 end diff --git a/db/migrate/20150612045544_make_enterprises_name_unique.rb b/db/migrate/20150612045544_make_enterprises_name_unique.rb index 5722284d94..da92f6a8fe 100644 --- a/db/migrate/20150612045544_make_enterprises_name_unique.rb +++ b/db/migrate/20150612045544_make_enterprises_name_unique.rb @@ -4,7 +4,7 @@ class MakeEnterprisesNameUnique < ActiveRecord::Migration dup_names.each do |data| (data.num_enterprises.to_i - 1).times do |i| - e = Enterprise.find_by_name data.name + e = Enterprise.find_by name: data.name new_name = "#{data.name}-#{i+1}" e.update_column :name, new_name say "Renamed enterprise #{data.name} to #{new_name}" diff --git a/db/migrate/20170728140134_remove_email_from_enterprises.rb b/db/migrate/20170728140134_remove_email_from_enterprises.rb index 01e4fe7f87..0b670a6adc 100644 --- a/db/migrate/20170728140134_remove_email_from_enterprises.rb +++ b/db/migrate/20170728140134_remove_email_from_enterprises.rb @@ -29,7 +29,7 @@ class RemoveEmailFromEnterprises < ActiveRecord::Migration rename_column :enterprises, :contact_name, :contact Enterprise.select(:id).each do |e| - manager = EnterpriseRole.find_by_enterprise_id_and_receives_notifications(e.id, true) + manager = EnterpriseRole.find_by(enterprise_id: e.id, receives_notifications: true) user = Spree::User.find(manager.user_id) e.update_attribute :email, user.email end @@ -43,6 +43,6 @@ class RemoveEmailFromEnterprises < ActiveRecord::Migration end def contact_or_owner(enterprise) - Spree::User.find_by_email(enterprise.email) || Spree::User.find(enterprise.owner_id) + Spree::User.find_by(email: enterprise.email) || Spree::User.find(enterprise.owner_id) end end diff --git a/db/seeds.rb b/db/seeds.rb index e6cac36c2c..12b3cdd5ce 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -21,13 +21,13 @@ end set_mail_configuration # -- Spree -unless Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) +unless Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) puts "[db:seed] Seeding Spree" Spree::Core::Engine.load_seed if defined?(Spree::Core) Spree::Auth::Engine.load_seed if defined?(Spree::Auth) end -country = Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) +country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) puts "Country is #{country.to_s}" puts "[db:seed] loading states yaml" @@ -40,7 +40,7 @@ puts "[db:seed] Seeding states for " + country.name states.each do |state| puts "State: " + state.to_s - unless Spree::State.find_by_name(state['name']) + unless Spree::State.find_by(name: state['name']) Spree::State.create!( { name: state['name'], abbr: state['abbr'], country: country }, without_protection: true diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index 611f120f62..c729bca83d 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -141,7 +141,8 @@ module OpenFoodNetwork end def find_exchange(sender_id, receiver_id, incoming) - @order_cycle.exchanges.find_by_sender_id_and_receiver_id_and_incoming(sender_id, receiver_id, incoming) + @order_cycle.exchanges. + find_by(sender_id:sender_id, receiver_id: receiver_id, incoming: incoming) end def incoming_exchange_variant_ids(attrs) diff --git a/lib/open_food_network/sales_tax_report.rb b/lib/open_food_network/sales_tax_report.rb index 1ce3f860dd..a32d3fe311 100644 --- a/lib/open_food_network/sales_tax_report.rb +++ b/lib/open_food_network/sales_tax_report.rb @@ -95,7 +95,7 @@ module OpenFoodNetwork end def shipping_cost_for(order) - shipping_cost = order.adjustments.find_by_label("Shipping").andand.amount + shipping_cost = order.adjustments.find_by(label: "Shipping").andand.amount shipping_cost.nil? ? 0.0 : shipping_cost end diff --git a/lib/stripe/account_connector.rb b/lib/stripe/account_connector.rb index 0213479bcb..cb96c0e1d8 100644 --- a/lib/stripe/account_connector.rb +++ b/lib/stripe/account_connector.rb @@ -32,7 +32,7 @@ module Stripe end def enterprise - @enterprise ||= Enterprise.find_by_permalink(state["enterprise_id"]) + @enterprise ||= Enterprise.find_by(permalink: state["enterprise_id"]) end private diff --git a/lib/tasks/sample_data/addressing.rb b/lib/tasks/sample_data/addressing.rb index dca3ebd973..c7f651837f 100644 --- a/lib/tasks/sample_data/addressing.rb +++ b/lib/tasks/sample_data/addressing.rb @@ -20,6 +20,6 @@ module Addressing end def country - Spree::Country.find_by_iso(ENV.fetch('DEFAULT_COUNTRY_CODE')) + Spree::Country.find_by(iso: ENV.fetch('DEFAULT_COUNTRY_CODE')) end end diff --git a/lib/tasks/sample_data/customer_factory.rb b/lib/tasks/sample_data/customer_factory.rb index 9a49289e37..c574f3150b 100644 --- a/lib/tasks/sample_data/customer_factory.rb +++ b/lib/tasks/sample_data/customer_factory.rb @@ -6,7 +6,7 @@ class CustomerFactory def create_samples(users) log "Creating customers" jane = users["Jane Customer"] - maryse_shop = Enterprise.find_by_name("Maryse's Private Shop") + maryse_shop = Enterprise.find_by(name: "Maryse's Private Shop") return if Customer.where(user_id: jane, enterprise_id: maryse_shop).exists? log "- #{jane.email}" diff --git a/lib/tasks/sample_data/inventory_factory.rb b/lib/tasks/sample_data/inventory_factory.rb index 81201139cf..46a0ce5277 100644 --- a/lib/tasks/sample_data/inventory_factory.rb +++ b/lib/tasks/sample_data/inventory_factory.rb @@ -5,7 +5,7 @@ class InventoryFactory def create_samples(products) log "Creating inventories" - marys_shop = Enterprise.find_by_name("Mary's Online Shop") + marys_shop = Enterprise.find_by(name: "Mary's Online Shop") products.each do |product| create_item(marys_shop, product) end diff --git a/lib/tasks/sample_data/order_cycle_factory.rb b/lib/tasks/sample_data/order_cycle_factory.rb index 6ba5b8e5ef..7e441ad26f 100644 --- a/lib/tasks/sample_data/order_cycle_factory.rb +++ b/lib/tasks/sample_data/order_cycle_factory.rb @@ -48,7 +48,7 @@ class OrderCycleFactory private def create_order_cycle(name, coordinator_name, supplier_names, distributor_names, data) - coordinator = Enterprise.find_by_name(coordinator_name) + coordinator = Enterprise.find_by(name: coordinator_name) return if OrderCycle.active.where(name: name).exists? log "- #{name}" diff --git a/lib/tasks/sample_data/product_factory.rb b/lib/tasks/sample_data/product_factory.rb index 6c220a6527..962a7b1891 100644 --- a/lib/tasks/sample_data/product_factory.rb +++ b/lib/tasks/sample_data/product_factory.rb @@ -13,9 +13,9 @@ class ProductFactory private def product_data(enterprises) - vegetables = Spree::Taxon.find_by_name('Vegetables') - fruit = Spree::Taxon.find_by_name('Fruit') - meat = Spree::Taxon.find_by_name('Meat and Fish') + vegetables = Spree::Taxon.find_by(name: 'Vegetables') + fruit = Spree::Taxon.find_by(name: 'Fruit') + meat = Spree::Taxon.find_by(name: 'Meat and Fish') producers = enterprises.select(&:is_primary_producer) distributors = enterprises.select(&:is_distributor) [ @@ -82,7 +82,7 @@ class ProductFactory def find_or_create_tax_category tax_category_name = "Tax Category" - tax_category = Spree::TaxCategory.find_by_name(tax_category_name) + tax_category = Spree::TaxCategory.find_by(name: tax_category_name) tax_category ||= Spree::TaxCategory.create!(name: tax_category_name) tax_category end diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb index 52f111f17a..a8c2802e47 100644 --- a/spec/controllers/admin/enterprises_controller_spec.rb +++ b/spec/controllers/admin/enterprises_controller_spec.rb @@ -18,8 +18,8 @@ module Admin before { @request.env['HTTP_REFERER'] = 'http://test.com/' } describe "creating an enterprise" do - let(:country) { Spree::Country.find_by_name 'Australia' } - let(:state) { Spree::State.find_by_name 'Victoria' } + let(:country) { Spree::Country.find_by name: 'Australia' } + let(:state) { Spree::State.find_by name: 'Victoria' } let(:enterprise_params) { { enterprise: { name: 'zzz', permalink: 'zzz', is_primary_producer: '0', address_attributes: { address1: 'a', city: 'a', zipcode: 'a', country_id: country.id, state_id: state.id } } } } it "grants management permission if the current user is an enterprise user" do @@ -27,7 +27,7 @@ module Admin enterprise_params[:enterprise][:owner_id] = distributor_manager spree_put :create, enterprise_params - enterprise = Enterprise.find_by_name 'zzz' + enterprise = Enterprise.find_by name: 'zzz' expect(response).to redirect_to edit_admin_enterprise_path enterprise expect(distributor_manager.enterprise_roles.where(enterprise_id: enterprise).first).to be end @@ -37,7 +37,7 @@ module Admin enterprise_params[:enterprise][:owner_id] = user spree_put :create, enterprise_params - enterprise = Enterprise.find_by_name 'zzz' + enterprise = Enterprise.find_by name: 'zzz' expect(response).to redirect_to edit_admin_enterprise_path enterprise expect(distributor_manager.enterprise_roles.where(enterprise_id: enterprise).first).to be end @@ -50,7 +50,7 @@ module Admin enterprise_params[:enterprise][:owner_id] = distributor_owner spree_put :create, enterprise_params - enterprise = Enterprise.find_by_name 'zzz' + enterprise = Enterprise.find_by name: 'zzz' expect(response).to redirect_to edit_admin_enterprise_path enterprise expect(enterprise.sells).to eq('any') end @@ -61,7 +61,7 @@ module Admin enterprise_params[:enterprise][:is_primary_producer] = '1' spree_put :create, enterprise_params - enterprise = Enterprise.find_by_name 'zzz' + enterprise = Enterprise.find_by name: 'zzz' expect(response).to redirect_to edit_admin_enterprise_path enterprise expect(enterprise.sells).to eq('none') end @@ -74,7 +74,7 @@ module Admin enterprise_params[:enterprise][:sells] = 'none' spree_put :create, enterprise_params - enterprise = Enterprise.find_by_name 'zzz' + enterprise = Enterprise.find_by name: 'zzz' expect(response).to redirect_to edit_admin_enterprise_path enterprise expect(enterprise.sells).to eq('none') end @@ -86,7 +86,7 @@ module Admin enterprise_params[:enterprise][:owner_id] = supplier_manager spree_put :create, enterprise_params - enterprise = Enterprise.find_by_name 'zzz' + enterprise = Enterprise.find_by name: 'zzz' expect(enterprise.sells).to eq('none') end @@ -96,7 +96,7 @@ module Admin enterprise_params[:enterprise][:sells] = 'any' spree_put :create, enterprise_params - enterprise = Enterprise.find_by_name 'zzz' + enterprise = Enterprise.find_by name: 'zzz' expect(enterprise.sells).to eq('any') end end diff --git a/spec/controllers/admin/manager_invitations_controller_spec.rb b/spec/controllers/admin/manager_invitations_controller_spec.rb index 7d03361daa..d245f6cf4d 100644 --- a/spec/controllers/admin/manager_invitations_controller_spec.rb +++ b/spec/controllers/admin/manager_invitations_controller_spec.rb @@ -45,7 +45,7 @@ module Admin it "returns the user id" do spree_post :create, email: 'un.registered@email.com', enterprise_id: enterprise.id - new_user = Spree::User.find_by_email('un.registered@email.com') + new_user = Spree::User.find_by(email: 'un.registered@email.com') expect(json_response['user']).to eq new_user.id end end @@ -61,7 +61,7 @@ module Admin it "returns success code" do spree_post :create, email: 'an@email.com', enterprise_id: enterprise.id - new_user = Spree::User.find_by_email('an@email.com') + new_user = Spree::User.find_by(email: 'an@email.com') expect(new_user.reset_password_token).to_not be_nil expect(json_response['user']).to eq new_user.id @@ -77,7 +77,7 @@ module Admin it "returns unauthorized response" do spree_post :create, email: 'another@email.com', enterprise_id: enterprise.id - new_user = Spree::User.find_by_email('another@email.com') + new_user = Spree::User.find_by(email: 'another@email.com') expect(new_user).to be_nil expect(response.status).to eq 302 diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb index 43707cc8f2..28a453fa99 100644 --- a/spec/controllers/admin/order_cycles_controller_spec.rb +++ b/spec/controllers/admin/order_cycles_controller_spec.rb @@ -320,7 +320,7 @@ module Admin describe "when an order cycle is deleteable" do it "allows the order_cycle to be destroyed" do spree_get :destroy, id: oc.id - expect(OrderCycle.find_by_id(oc.id)).to be nil + expect(OrderCycle.find_by(id: oc.id)).to be nil end end diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb index 0d721e7d9a..c75a265cd1 100644 --- a/spec/controllers/admin/variant_overrides_controller_spec.rb +++ b/spec/controllers/admin/variant_overrides_controller_spec.rb @@ -65,7 +65,7 @@ describe Admin::VariantOverridesController, type: :controller do it "destroys the variant override" do spree_put :bulk_update, format: format, variant_overrides: variant_override_params - expect(VariantOverride.find_by_id(variant_override.id)).to be_nil + expect(VariantOverride.find_by(id: variant_override.id)).to be_nil end end diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index d2b27c1254..364a7fd146 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -16,7 +16,7 @@ module Api end describe "creating an enterprise" do - let(:australia) { Spree::Country.find_by_name('Australia') } + let(:australia) { Spree::Country.find_by(name: 'Australia') } let(:new_enterprise_params) do { enterprise: { diff --git a/spec/factories.rb b/spec/factories.rb index 4f9c6478f5..8474d44a6e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -120,7 +120,7 @@ FactoryBot.define do default_tax true after(:create) do |zone| - Spree::ZoneMember.create!(zone: zone, zoneable: Spree::Country.find_by_name('Australia')) + Spree::ZoneMember.create!(zone: zone, zoneable: Spree::Country.find_by(name: 'Australia')) end end @@ -160,8 +160,8 @@ end FactoryBot.modify do factory :address do - state { Spree::State.find_by_name 'Victoria' } - country { Spree::Country.find_by_name 'Australia' || Spree::Country.first } + state { Spree::State.find_by name: 'Victoria' } + country { Spree::Country.find_by name: 'Australia' || Spree::Country.first } end factory :payment do diff --git a/spec/factories/subscription_factory.rb b/spec/factories/subscription_factory.rb index 009f9ef802..c10110fe72 100644 --- a/spec/factories/subscription_factory.rb +++ b/spec/factories/subscription_factory.rb @@ -20,9 +20,8 @@ FactoryBot.define do 3, subscription: subscription) subscription.order_cycles.each do |oc| - ex = oc.exchanges.outgoing.find_by_sender_id_and_receiver_id( - subscription.shop_id, subscription.shop_id - ) + ex = oc.exchanges.outgoing.find_by(sender_id: subscription.shop_id, + receiver_id: subscription.shop_id) ex ||= create(:exchange, order_cycle: oc, sender: subscription.shop, receiver: subscription.shop, diff --git a/spec/features/admin/enterprise_fees_spec.rb b/spec/features/admin/enterprise_fees_spec.rb index 4fc10a1202..a231f272e5 100644 --- a/spec/features/admin/enterprise_fees_spec.rb +++ b/spec/features/admin/enterprise_fees_spec.rb @@ -137,7 +137,7 @@ feature ' # After saving, we should be redirected to the fees for our chosen enterprise expect(page).not_to have_select 'enterprise_fee_set_collection_attributes_1_enterprise_id', selected: 'Second Distributor' - enterprise_fee = EnterpriseFee.find_by_name 'foo' + enterprise_fee = EnterpriseFee.find_by name: 'foo' expect(enterprise_fee.enterprise).to eq(distributor1) end diff --git a/spec/features/admin/enterprise_roles_spec.rb b/spec/features/admin/enterprise_roles_spec.rb index c618064140..ff29207aeb 100644 --- a/spec/features/admin/enterprise_roles_spec.rb +++ b/spec/features/admin/enterprise_roles_spec.rb @@ -159,7 +159,7 @@ feature ' expect(page).not_to have_selector "#invite-manager-modal" expect(page).to have_selector "table.managers" - new_user = Spree::User.find_by_email_and_confirmed_at(new_email, nil) + new_user = Spree::User.find_by(email: new_email, confirmed_at: nil) expect(Enterprise.managed_by(new_user)).to include enterprise within 'table.managers' do diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 0da5f07c6d..85c58932b7 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -787,7 +787,7 @@ feature ' end click_button 'Save and Back to List' - order_cycle = OrderCycle.find_by_name('My order cycle') + order_cycle = OrderCycle.find_by(name: 'My order cycle') expect(page).to have_input "oc#{order_cycle.id}[name]", value: order_cycle.name expect(order_cycle.suppliers).to match_array [supplier_managed, supplier_permitted] diff --git a/spec/features/admin/payment_method_spec.rb b/spec/features/admin/payment_method_spec.rb index ea741fe004..34d96dc061 100644 --- a/spec/features/admin/payment_method_spec.rb +++ b/spec/features/admin/payment_method_spec.rb @@ -26,7 +26,7 @@ feature ' expect(flash_message).to eq('Payment Method has been successfully created!') - payment_method = Spree::PaymentMethod.find_by_name('Cheque payment method') + payment_method = Spree::PaymentMethod.find_by(name: 'Cheque payment method') expect(payment_method.distributors).to eq([@distributors[0]]) end @@ -108,7 +108,7 @@ feature ' expect(first('tags-input .tag-list ti-tag-item')).to have_content "member" - payment_method = Spree::PaymentMethod.find_by_name('New PM Name') + payment_method = Spree::PaymentMethod.find_by(name: 'New PM Name') expect(payment_method.distributors).to include @distributors[1], @distributors[2] expect(payment_method.distributors).not_to include @distributors[0] expect(payment_method.type).to eq "Spree::Gateway::PayPalExpress" @@ -123,7 +123,7 @@ feature ' expect(page).to have_field 'Password', with: '' expect(first('tags-input .tag-list ti-tag-item')).to have_content "member" - payment_method = Spree::PaymentMethod.find_by_name('New PM Name') + payment_method = Spree::PaymentMethod.find_by(name: 'New PM Name') expect(payment_method.tag_list).to eq ["member"] expect(payment_method.preferences[:login]).to eq 'otherlogin' expect(payment_method.preferences[:password]).to eq 'secret' @@ -166,7 +166,7 @@ feature ' expect(flash_message).to eq('Payment Method has been successfully created!') expect(first('tags-input .tag-list ti-tag-item')).to have_content "local" - payment_method = Spree::PaymentMethod.find_by_name('Cheque payment method') + payment_method = Spree::PaymentMethod.find_by(name: 'Cheque payment method') expect(payment_method.distributors).to eq([distributor1]) expect(payment_method.tag_list).to eq(["local"]) end diff --git a/spec/features/admin/product_import_spec.rb b/spec/features/admin/product_import_spec.rb index b14122ce5d..b3ddc0c88e 100644 --- a/spec/features/admin/product_import_spec.rb +++ b/spec/features/admin/product_import_spec.rb @@ -60,8 +60,8 @@ feature "Product Import", js: true do expect(page).to have_selector '.created-count', text: '2' expect(page).to have_no_selector '.updated-count' - carrots = Spree::Product.find_by_name('Carrots') - potatoes = Spree::Product.find_by_name('Potatoes') + carrots = Spree::Product.find_by(name: 'Carrots') + potatoes = Spree::Product.find_by(name: 'Potatoes') expect(potatoes.supplier).to eq enterprise expect(potatoes.on_hand).to eq 6 expect(potatoes.price).to eq 6.50 @@ -127,7 +127,7 @@ feature "Product Import", js: true do expect(page).to have_selector '.created-count', text: '1' expect(page).to have_no_selector '.updated-count' - carrots = Spree::Product.find_by_name('Carrots') + carrots = Spree::Product.find_by(name: 'Carrots') expect(carrots.tax_category).to eq tax_category expect(carrots.shipping_category).to eq shipping_category end @@ -150,9 +150,9 @@ feature "Product Import", js: true do save_data - carrots = Spree::Product.find_by_name('Carrots') + carrots = Spree::Product.find_by(name: 'Carrots') expect(carrots.variants.first.import_date).to be_within(1.minute).of Time.zone.now - potatoes = Spree::Product.find_by_name('Potatoes') + potatoes = Spree::Product.find_by(name: 'Potatoes') expect(potatoes.variants.first.import_date).to be_within(1.minute).of Time.zone.now click_link I18n.t('admin.product_import.save_results.view_products') @@ -200,9 +200,9 @@ feature "Product Import", js: true do expect(page).to have_selector '.created-count', text: '1' expect(page).to have_selector '.reset-count', text: '3' - expect(Spree::Product.find_by_name('Carrots').on_hand).to eq 500 - expect(Spree::Product.find_by_name('Cabbage').on_hand).to eq 0 - expect(Spree::Product.find_by_name('Beans').on_hand).to eq 0 + expect(Spree::Product.find_by(name: 'Carrots').on_hand).to eq 500 + expect(Spree::Product.find_by(name: 'Cabbage').on_hand).to eq 0 + expect(Spree::Product.find_by(name: 'Beans').on_hand).to eq 0 end it "can save a new product and variant of that product at the same time, add variant to existing product" do @@ -229,12 +229,12 @@ feature "Product Import", js: true do save_data - small_bag = Spree::Variant.find_by_display_name('Small Bag') + small_bag = Spree::Variant.find_by(display_name: 'Small Bag') expect(small_bag.product.name).to eq 'Potatoes' expect(small_bag.price).to eq 3.50 expect(small_bag.on_hand).to eq 5 - big_bag = Spree::Variant.find_by_display_name('Big Bag') + big_bag = Spree::Variant.find_by(display_name: 'Big Bag') expect(big_bag.product.name).to eq 'Potatoes' expect(big_bag.price).to eq 5.50 expect(big_bag.on_hand).to eq 6 @@ -453,9 +453,9 @@ feature "Product Import", js: true do expect_import_completed # Check that all rows are saved. - expect(producer.supplied_products.find_by_name("Imported Product 10")).to be_present - expect(producer.supplied_products.find_by_name("Imported Product 60")).to be_present - expect(producer.supplied_products.find_by_name("Imported Product 110")).to be_present + expect(producer.supplied_products.find_by(name: "Imported Product 10")).to be_present + expect(producer.supplied_products.find_by(name: "Imported Product 60")).to be_present + expect(producer.supplied_products.find_by(name: "Imported Product 110")).to be_present end end end diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb index 54c99ba8ea..b2ef204312 100644 --- a/spec/features/admin/products_spec.rb +++ b/spec/features/admin/products_spec.rb @@ -48,7 +48,7 @@ feature ' expect(current_path).to eq spree.admin_products_path expect(flash_message).to eq('Product "A new product !!!" has been successfully created!') - product = Spree::Product.find_by_name('A new product !!!') + product = Spree::Product.find_by(name: 'A new product !!!') expect(product.supplier).to eq(@supplier) expect(product.variant_unit).to eq('weight') expect(product.variant_unit_scale).to eq(1000) @@ -86,7 +86,7 @@ feature ' click_button 'Create' expect(current_path).to eq spree.admin_products_path - product = Spree::Product.find_by_name('Hot Cakes') + product = Spree::Product.find_by(name: 'Hot Cakes') expect(product.variants.count).to eq(1) variant = product.variants.first expect(variant.on_demand).to be true @@ -131,7 +131,7 @@ feature ' click_button 'Create' expect(flash_message).to eq('Product "A new product !!!" has been successfully created!') - product = Spree::Product.find_by_name('A new product !!!') + product = Spree::Product.find_by(name: 'A new product !!!') expect(product.supplier).to eq(@supplier2) expect(product.tax_category).to be_nil end diff --git a/spec/features/admin/schedules_spec.rb b/spec/features/admin/schedules_spec.rb index c2d5c9e521..0a457e1d2a 100644 --- a/spec/features/admin/schedules_spec.rb +++ b/spec/features/admin/schedules_spec.rb @@ -128,7 +128,7 @@ feature 'Schedules', js: true do expect(page).to have_no_selector "a", text: "Weekly" end - expect(Schedule.find_by_id(weekly_schedule.id)).to be_nil + expect(Schedule.find_by(id: weekly_schedule.id)).to be_nil expect(oc1.schedules).to eq [] expect(oc2.schedules).to eq [] expect(oc3.schedules).to eq [] diff --git a/spec/features/admin/shipping_methods_spec.rb b/spec/features/admin/shipping_methods_spec.rb index 1fe1658988..ba4ac46e19 100644 --- a/spec/features/admin/shipping_methods_spec.rb +++ b/spec/features/admin/shipping_methods_spec.rb @@ -130,7 +130,7 @@ feature 'shipping methods' do expect(first('tags-input .tag-list ti-tag-item')).to have_content "local" - shipping_method = Spree::ShippingMethod.find_by_name('Teleport') + shipping_method = Spree::ShippingMethod.find_by(name: 'Teleport') expect(shipping_method.distributors).to eq([distributor1]) expect(shipping_method.tag_list).to eq(["local"]) end diff --git a/spec/features/admin/users_spec.rb b/spec/features/admin/users_spec.rb index c89df5380f..b97089a0aa 100644 --- a/spec/features/admin/users_spec.rb +++ b/spec/features/admin/users_spec.rb @@ -73,7 +73,7 @@ feature "Managing users" do end it "should allow to generate, regenarate and clear the user api key", js: true do - user = Spree::User.find_by_email("a@example.com") + user = Spree::User.find_by(email: "a@example.com") expect(page).to have_content "NO KEY" click_button "Generate API key" diff --git a/spec/features/consumer/registration_spec.rb b/spec/features/consumer/registration_spec.rb index f92db8835a..1931614d07 100644 --- a/spec/features/consumer/registration_spec.rb +++ b/spec/features/consumer/registration_spec.rb @@ -72,7 +72,7 @@ feature "Registration", js: true do expect(page).to have_content 'Nice one!' # Enterprise should be created - e = Enterprise.find_by_name('My Awesome Enterprise') + e = Enterprise.find_by(name: 'My Awesome Enterprise') expect(e.address.address1).to eq "123 Abc Street" expect(e.sells).to eq "unspecified" expect(e.is_primary_producer).to eq true diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb index b9caaa7e75..90c3e6ad5f 100644 --- a/spec/features/consumer/shopping/orders_spec.rb +++ b/spec/features/consumer/shopping/orders_spec.rb @@ -170,7 +170,7 @@ feature "Order Management", js: true do end expect(find(".order-total.grand-total")).to have_content "105.00" - expect(Spree::LineItem.find_by_id(item2.id)).to be nil + expect(Spree::LineItem.find_by(id: item2.id)).to be nil # Cancelling the order accept_alert do diff --git a/spec/jobs/subscription_placement_job_spec.rb b/spec/jobs/subscription_placement_job_spec.rb index bd008682e3..c4f6349d0a 100644 --- a/spec/jobs/subscription_placement_job_spec.rb +++ b/spec/jobs/subscription_placement_job_spec.rb @@ -126,7 +126,7 @@ describe SubscriptionPlacementJob do let(:subscription) { create(:subscription, shop: shop, with_items: true) } let(:proxy_order) { create(:proxy_order, subscription: subscription) } let(:oc) { proxy_order.order_cycle } - let(:ex) { oc.exchanges.outgoing.find_by_sender_id_and_receiver_id(shop.id, shop.id) } + let(:ex) { oc.exchanges.outgoing.find_by(sender_id: shop.id, receiver_id: shop.id) } let(:fee) { create(:enterprise_fee, enterprise: shop, fee_type: 'sales', amount: 10) } let!(:exchange_fee) { ExchangeFee.create!(exchange: ex, enterprise_fee: fee) } let!(:order) { proxy_order.initialise_order! } diff --git a/spec/lib/open_food_network/products_and_inventory_report_spec.rb b/spec/lib/open_food_network/products_and_inventory_report_spec.rb index 193c5134e2..460de076d6 100644 --- a/spec/lib/open_food_network/products_and_inventory_report_spec.rb +++ b/spec/lib/open_food_network/products_and_inventory_report_spec.rb @@ -199,9 +199,9 @@ module OpenFoodNetwork # Remove the distribution of one product for one distributor but still # sell it through the other distributor. - order_cycle.exchanges.outgoing.find_by_receiver_id(distributor.id). + order_cycle.exchanges.outgoing.find_by(receiver_id: distributor.id). exchange_variants. - find_by_variant_id(variant_filtered_by_distributor). + find_by(variant_id: variant_filtered_by_distributor). destroy # Make product available to be filtered later. See OC comment above. diff --git a/spec/models/product_importer_spec.rb b/spec/models/product_importer_spec.rb index 032ee8c14f..35efd68488 100644 --- a/spec/models/product_importer_spec.rb +++ b/spec/models/product_importer_spec.rb @@ -80,7 +80,7 @@ describe ProductImport::ProductImporter do expect(importer.updated_ids).to be_a(Array) expect(importer.updated_ids.count).to eq 5 - carrots = Spree::Product.find_by_name('Carrots') + carrots = Spree::Product.find_by(name: 'Carrots') expect(carrots.supplier).to eq enterprise expect(carrots.on_hand).to eq 5 expect(carrots.price).to eq 3.20 @@ -90,7 +90,7 @@ describe ProductImport::ProductImporter do expect(carrots.on_demand).to_not eq true expect(carrots.variants.first.import_date).to be_within(1.minute).of Time.zone.now - potatoes = Spree::Product.find_by_name('Potatoes') + potatoes = Spree::Product.find_by(name: 'Potatoes') expect(potatoes.supplier).to eq enterprise expect(potatoes.on_hand).to eq 6 expect(potatoes.price).to eq 6.50 @@ -100,7 +100,7 @@ describe ProductImport::ProductImporter do expect(potatoes.on_demand).to_not eq true expect(potatoes.variants.first.import_date).to be_within(1.minute).of Time.zone.now - pea_soup = Spree::Product.find_by_name('Pea Soup') + pea_soup = Spree::Product.find_by(name: 'Pea Soup') expect(pea_soup.supplier).to eq enterprise expect(pea_soup.on_hand).to eq 8 expect(pea_soup.price).to eq 5.50 @@ -110,7 +110,7 @@ describe ProductImport::ProductImporter do expect(pea_soup.on_demand).to_not eq true expect(pea_soup.variants.first.import_date).to be_within(1.minute).of Time.zone.now - salad = Spree::Product.find_by_name('Salad') + salad = Spree::Product.find_by(name: 'Salad') expect(salad.supplier).to eq enterprise expect(salad.on_hand).to eq 7 expect(salad.price).to eq 4.50 @@ -120,7 +120,7 @@ describe ProductImport::ProductImporter do expect(salad.on_demand).to_not eq true expect(salad.variants.first.import_date).to be_within(1.minute).of Time.zone.now - buns = Spree::Product.find_by_name('Hot Cross Buns') + buns = Spree::Product.find_by(name: 'Hot Cross Buns') expect(buns.supplier).to eq enterprise expect(buns.on_hand).to eq 7 expect(buns.price).to eq 3.50 @@ -159,13 +159,13 @@ describe ProductImport::ProductImporter do expect(importer.updated_ids).to be_a(Array) expect(importer.updated_ids.count).to eq 1 - carrots = Spree::Product.find_by_name('Good Carrots') + carrots = Spree::Product.find_by(name: 'Good Carrots') expect(carrots.supplier).to eq enterprise expect(carrots.on_hand).to eq 5 expect(carrots.price).to eq 3.20 expect(carrots.variants.first.import_date).to be_within(1.minute).of Time.zone.now - expect(Spree::Product.find_by_name('Bad Potatoes')).to eq nil + expect(Spree::Product.find_by(name: 'Bad Potatoes')).to eq nil end end @@ -233,13 +233,13 @@ describe ProductImport::ProductImporter do expect(importer.updated_ids).to be_a(Array) expect(importer.updated_ids.count).to eq 2 - added_coffee = Spree::Variant.find_by_display_name('Emergent Coffee') + added_coffee = Spree::Variant.find_by(display_name: 'Emergent Coffee') expect(added_coffee.product.name).to eq 'Hypothetical Cake' expect(added_coffee.price).to eq 3.50 expect(added_coffee.on_hand).to eq 6 expect(added_coffee.import_date).to be_within(1.minute).of Time.zone.now - updated_banana = Spree::Variant.find_by_display_name('Preexisting Banana') + updated_banana = Spree::Variant.find_by(display_name: 'Preexisting Banana') expect(updated_banana.product.name).to eq 'Hypothetical Cake' expect(updated_banana.price).to eq 5.50 expect(updated_banana.on_hand).to eq 5 @@ -295,21 +295,21 @@ describe ProductImport::ProductImporter do expect(importer.updated_ids).to be_a(Array) expect(importer.updated_ids.count).to eq 3 - small_bag = Spree::Variant.find_by_display_name('Small Bag') + small_bag = Spree::Variant.find_by(display_name: 'Small Bag') expect(small_bag.product.name).to eq 'Potatoes' expect(small_bag.price).to eq 3.50 expect(small_bag.on_hand).to eq 5 - big_bag = Spree::Variant.find_by_display_name("Big Bag") + big_bag = Spree::Variant.find_by(display_name: "Big Bag") expect(big_bag).to be_blank - small_sack = Spree::Variant.find_by_display_name("Small Sack") + small_sack = Spree::Variant.find_by(display_name: "Small Sack") expect(small_sack.product.name).to eq "Potatoes" expect(small_sack.price).to eq 22.00 expect(small_sack.on_hand).to eq 6 expect(small_sack.product.id).to eq small_bag.product.id - big_sack = Spree::Variant.find_by_display_name("Big Sack") + big_sack = Spree::Variant.find_by(display_name: "Big Sack") expect(big_sack).to be_blank end end @@ -342,11 +342,11 @@ describe ProductImport::ProductImporter do expect(importer.updated_ids).to be_a(Array) expect(importer.updated_ids.count).to eq 2 - beetroot = Spree::Product.find_by_name('Beetroot').variants.first + beetroot = Spree::Product.find_by(name: 'Beetroot').variants.first expect(beetroot.price).to eq 3.50 expect(beetroot.on_demand).to_not eq true - tomato = Spree::Product.find_by_name('Tomato').variants.first + tomato = Spree::Product.find_by(name: 'Tomato').variants.first expect(tomato.price).to eq 5.50 expect(tomato.on_demand).to eq true end @@ -589,8 +589,8 @@ describe ProductImport::ProductImporter do expect(importer.updated_ids).to be_a(Array) expect(importer.updated_ids.count).to eq 1 - expect(Spree::Product.find_by_name('My Carrots')).to be_a Spree::Product - expect(Spree::Product.find_by_name('Your Potatoes')).to eq nil + expect(Spree::Product.find_by(name: 'My Carrots')).to be_a Spree::Product + expect(Spree::Product.find_by(name: 'Your Potatoes')).to eq nil end it "allows creating inventories for producers that a user's hub has permission for" do @@ -671,11 +671,11 @@ describe ProductImport::ProductImporter do expect(importer.products_reset_count).to eq 7 - expect(Spree::Product.find_by_name('Carrots').on_hand).to eq 5 # Present in file, added - expect(Spree::Product.find_by_name('Beans').on_hand).to eq 6 # Present in file, updated - expect(Spree::Product.find_by_name('Sprouts').on_hand).to eq 0 # In enterprise, not in file - expect(Spree::Product.find_by_name('Cabbage').on_hand).to eq 0 # In enterprise, not in file - expect(Spree::Product.find_by_name('Lettuce').on_hand).to eq 100 # In different enterprise; unchanged + expect(Spree::Product.find_by(name: 'Carrots').on_hand).to eq 5 # Present in file, added + expect(Spree::Product.find_by(name: 'Beans').on_hand).to eq 6 # Present in file, updated + expect(Spree::Product.find_by(name: 'Sprouts').on_hand).to eq 0 # In enterprise, not in file + expect(Spree::Product.find_by(name: 'Cabbage').on_hand).to eq 0 # In enterprise, not in file + expect(Spree::Product.find_by(name: 'Lettuce').on_hand).to eq 100 # In different enterprise; unchanged end it "can reset all inventory items for an enterprise that are not present in the uploaded file to zero stock" do @@ -762,13 +762,13 @@ describe ProductImport::ProductImporter do expect(importer.updated_ids).to be_a(Array) expect(importer.updated_ids.count).to eq 2 - carrots = Spree::Product.find_by_name('Carrots') + carrots = Spree::Product.find_by(name: 'Carrots') expect(carrots.on_hand).to eq 9000 expect(carrots.tax_category_id).to eq tax_category.id expect(carrots.shipping_category_id).to eq shipping_category.id expect(carrots.available_on).to be_within(1.day).of(Time.zone.local(2020, 1, 1)) - potatoes = Spree::Product.find_by_name('Potatoes') + potatoes = Spree::Product.find_by(name: 'Potatoes') expect(potatoes.on_hand).to eq 9000 expect(potatoes.tax_category_id).to eq tax_category2.id expect(potatoes.shipping_category_id).to eq shipping_category.id diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index 49edecb14b..f2f5cd7164 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -636,7 +636,7 @@ module Spree describe "deleting unit option values" do let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) } - let!(:ot) { Spree::OptionType.find_by_name 'unit_weight' } + let!(:ot) { Spree::OptionType.find_by name: 'unit_weight' } let!(:li) { create(:line_item, product: p) } it "removes option value associations for unit option types" do diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index a8c6368a70..7810978fc4 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -510,7 +510,7 @@ module Spree end it "removes the related option values from all its variants and replaces them" do - ot = Spree::OptionType.find_by_name 'unit_weight' + ot = Spree::OptionType.find_by name: 'unit_weight' v = create(:variant, unit_value: 1, product: p) p.reload @@ -525,7 +525,7 @@ module Spree end it "removes the related option values from its master variant and replaces them" do - ot = Spree::OptionType.find_by_name 'unit_weight' + ot = Spree::OptionType.find_by name: 'unit_weight' p.master.update_attributes!(unit_value: 1) p.reload diff --git a/spec/models/spree/variant_spec.rb b/spec/models/spree/variant_spec.rb index 39ac4bcead..d4889e6b4f 100644 --- a/spec/models/spree/variant_spec.rb +++ b/spec/models/spree/variant_spec.rb @@ -459,7 +459,7 @@ module Spree describe "deleting unit option values" do before do p = create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) - ot = Spree::OptionType.find_by_name 'unit_weight' + ot = Spree::OptionType.find_by name: 'unit_weight' @v = create(:variant, product: p) end diff --git a/spec/services/default_stock_location_spec.rb b/spec/services/default_stock_location_spec.rb index 8d91d7da83..3bd3a1eb26 100644 --- a/spec/services/default_stock_location_spec.rb +++ b/spec/services/default_stock_location_spec.rb @@ -8,13 +8,13 @@ describe DefaultStockLocation do end it 'sets the location in the default country' do - default_country = Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) + default_country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) stock_location = described_class.create! expect(stock_location.country).to eq(default_country) end it 'sets the first state in the country' do - default_country = Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) + default_country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE']) stock_location = described_class.create! expect(stock_location.state).to eq(default_country.states.first) end diff --git a/spec/services/order_factory_spec.rb b/spec/services/order_factory_spec.rb index 85e27881a5..c67cbaaf0e 100644 --- a/spec/services/order_factory_spec.rb +++ b/spec/services/order_factory_spec.rb @@ -149,7 +149,7 @@ describe OrderFactory do end def variant1_line_item - order.line_items.find_by_variant_id(variant1.id) + order.line_items.find_by(variant_id: variant1.id) end end end diff --git a/spec/services/order_syncer_spec.rb b/spec/services/order_syncer_spec.rb index 49622dfc68..c0e1b8d43a 100644 --- a/spec/services/order_syncer_spec.rb +++ b/spec/services/order_syncer_spec.rb @@ -415,7 +415,7 @@ describe OrderSyncer do line_items = Spree::LineItem.where(order_id: subscription.orders, variant_id: sli.variant_id) expect(line_items.map(&:quantity)).to eq [1] expect(order.reload.total.to_f).to eq 59.97 - line_item = order.line_items.find_by_variant_id(sli.variant_id) + line_item = order.line_items.find_by(variant_id: sli.variant_id) expect(syncer.order_update_issues[order.id]).to include "#{line_item.product.name} - #{line_item.variant.full_name} - Insufficient stock available" end @@ -426,7 +426,7 @@ describe OrderSyncer do expect(syncer.sync!).to be true - line_item = order.line_items.find_by_variant_id(sli.variant_id) + line_item = order.line_items.find_by(variant_id: sli.variant_id) expect(syncer.order_update_issues[order.id]).to include "#{line_item.product.name} - #{line_item.variant.full_name} - Out of Stock" end end @@ -435,7 +435,7 @@ describe OrderSyncer do context "where the quantity of the item on an initialised order has already been changed" do let(:params) { { subscription_line_items_attributes: [{ id: sli.id, quantity: 3 }] } } let(:syncer) { OrderSyncer.new(subscription) } - let(:changed_line_item) { order.line_items.find_by_variant_id(sli.variant_id) } + let(:changed_line_item) { order.line_items.find_by(variant_id: sli.variant_id) } before { variant.update_attribute(:on_hand, 3) } diff --git a/spec/services/subscription_form_spec.rb b/spec/services/subscription_form_spec.rb index 9a06ef7164..ae27363c8a 100644 --- a/spec/services/subscription_form_spec.rb +++ b/spec/services/subscription_form_spec.rb @@ -56,15 +56,15 @@ describe SubscriptionForm do expect(subscription.subscription_line_items[2].price_estimate).to eq 4.25 # This order cycle has already closed, so no order is initialized - proxy_order1 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle1.id) + proxy_order1 = subscription.proxy_orders.find_by(order_cycle_id: order_cycle1.id) expect(proxy_order1).to be nil # Currently open order cycle, closing after begins_at and before ends_at - proxy_order2 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle2.id) + proxy_order2 = subscription.proxy_orders.find_by(order_cycle_id: order_cycle2.id) expect(proxy_order2).to be_a ProxyOrder order2 = proxy_order2.initialise_order! expect(order2.line_items.count).to eq 3 - expect(order2.line_items.find_by_variant_id(variant3.id).quantity).to be 3 + expect(order2.line_items.find_by(variant_id: variant3.id).quantity).to be 3 expect(order2.shipments.count).to eq 1 expect(order2.shipments.first.shipping_method).to eq shipping_method expect(order2.payments.count).to eq 1 @@ -75,12 +75,12 @@ describe SubscriptionForm do # Future order cycle, closing after begins_at and before ends_at # Adds line items for variants that aren't yet available from the order cycle - proxy_order3 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle3.id) + proxy_order3 = subscription.proxy_orders.find_by(order_cycle_id: order_cycle3.id) expect(proxy_order3).to be_a ProxyOrder order3 = proxy_order3.initialise_order! expect(order3).to be_a Spree::Order expect(order3.line_items.count).to eq 3 - expect(order2.line_items.find_by_variant_id(variant3.id).quantity).to be 3 + expect(order2.line_items.find_by(variant_id: variant3.id).quantity).to be 3 expect(order3.shipments.count).to eq 1 expect(order3.shipments.first.shipping_method).to eq shipping_method expect(order3.payments.count).to eq 1 @@ -90,7 +90,7 @@ describe SubscriptionForm do expect(order3.completed?).to be false # Future order cycle closing after ends_at - proxy_order4 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle4.id) + proxy_order4 = subscription.proxy_orders.find_by(order_cycle_id: order_cycle4.id) expect(proxy_order4).to be nil end end diff --git a/spec/support/seeds.rb b/spec/support/seeds.rb index 0a603a03e0..023271aad0 100644 --- a/spec/support/seeds.rb +++ b/spec/support/seeds.rb @@ -7,7 +7,7 @@ if Spree::Country.scoped.empty? Spree::Country.create!({ "name" => "Australia", "iso3" => "AUS", "iso" => "AU", "iso_name" => "AUSTRALIA", "numcode" => "36" }, without_protection: true) - country = Spree::Country.find_by_name('Australia') + country = Spree::Country.find_by(name: 'Australia') Spree::State.create!({ "name" => "Victoria", "abbr" => "Vic", :country => country }, without_protection: true) Spree::State.create!({ "name" => "New South Wales", "abbr" => "NSW", :country => country }, without_protection: true) end @@ -15,4 +15,4 @@ end # Since the country seeding differs from other environments, the default # country id has to be updated here. This line can be removed as soon as the # default country id is replaced by something database independent. -Spree::Config.default_country_id = Spree::Country.find_by_name('Australia').id +Spree::Config.default_country_id = Spree::Country.find_by(name: 'Australia').id From b80929022b3add921c08b26c9cad0ed398531c81 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 16:18:04 +0100 Subject: [PATCH 025/507] Remove unused `newrelic_rpm` gem --- Gemfile | 2 +- Gemfile.lock | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 6d970fed74..6e925b1cfe 100644 --- a/Gemfile +++ b/Gemfile @@ -155,7 +155,7 @@ end group :development do gem 'byebug', '~> 9.0.0' # 9.1 requires ruby 2.2 gem 'debugger-linecache' - gem "newrelic_rpm", "~> 3.0" + #gem "newrelic_rpm", "~> 3.0" gem 'pry-byebug', '>= 3.4.3' gem 'rubocop' gem 'rubocop-rails' diff --git a/Gemfile.lock b/Gemfile.lock index c999438bde..5b6db44dad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -453,7 +453,6 @@ GEM multi_json (1.14.1) multi_xml (0.6.0) multipart-post (2.1.1) - newrelic_rpm (3.18.1.330) nokogiri (1.6.8.1) mini_portile2 (~> 2.1.0) oauth2 (1.4.4) @@ -726,7 +725,6 @@ DEPENDENCIES letter_opener (>= 1.4.1) mini_racer (= 0.2.9) momentjs-rails - newrelic_rpm (~> 3.0) nokogiri (~> 1.6.8.1) oauth2 (~> 1.4.4) oj From a8b8269a027917d7cab15dc082395a24969c822d Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 16:33:28 +0100 Subject: [PATCH 026/507] Update deprecated #find_or_initialize_by_* methods --- app/models/enterprise_relationship.rb | 2 +- ...60224034034_grant_explicit_variant_override_permissions.rb | 4 ++-- db/migrate/20170728140134_remove_email_from_enterprises.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/enterprise_relationship.rb b/app/models/enterprise_relationship.rb index 6acd672f2f..3088b05a49 100644 --- a/app/models/enterprise_relationship.rb +++ b/app/models/enterprise_relationship.rb @@ -74,7 +74,7 @@ class EnterpriseRelationship < ActiveRecord::Base permissions.destroy_all else permissions.where('name NOT IN (?)', perms).destroy_all - perms.map { |name| permissions.find_or_initialize_by_name name } + perms.map { |name| permissions.find_or_initialize_by name: name } end end diff --git a/db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb b/db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb index b56a4a8a93..e66c5ee7db 100644 --- a/db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb +++ b/db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb @@ -15,8 +15,8 @@ class GrantExplicitVariantOverridePermissions < ActiveRecord::Migration # create explicit VO permissions for producers currently granting implicit permission Enterprise.where(id: implicitly_granting_producer_ids).each do |producer| - relationship = producer.relationships_as_parent.find_or_initialize_by_child_id(hub.id) - permission = relationship.permissions.find_or_initialize_by_name(:create_variant_overrides) + relationship = producer.relationships_as_parent.find_or_initialize_by(child_id: hub.id) + permission = relationship.permissions.find_or_initialize_by(name: :create_variant_overrides) relationship.save! unless permission.persisted? end end diff --git a/db/migrate/20170728140134_remove_email_from_enterprises.rb b/db/migrate/20170728140134_remove_email_from_enterprises.rb index 0b670a6adc..b5cd8420c0 100644 --- a/db/migrate/20170728140134_remove_email_from_enterprises.rb +++ b/db/migrate/20170728140134_remove_email_from_enterprises.rb @@ -38,7 +38,7 @@ class RemoveEmailFromEnterprises < ActiveRecord::Migration def update_enterprise_contact(enterprise) contact_user = contact_or_owner(enterprise) - role = EnterpriseRole.find_or_initialize_by_user_id_and_enterprise_id(contact_user.id, enterprise.id) + role = EnterpriseRole.find_or_initialize_by(user_id: contact_user.id, enterprise_id: enterprise.id) role.update_attribute :receives_notifications, true end From 16d56a8cbdeacc5b383112776d87a80babb990f6 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 16:43:45 +0100 Subject: [PATCH 027/507] Routes using `match` must specify a request method in Rails 4 --- config/routes/spree.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes/spree.rb b/config/routes/spree.rb index 095350b699..d6c3ed4e46 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -45,7 +45,7 @@ Spree::Core::Engine.routes.draw do match '/admin', to: 'admin/overview#index', as: :admin_dashboard, via: :get - resources :credit_cards + #resources :credit_cards namespace :admin do get '/search/known_users' => "search#known_users", :as => :search_known_users From 046d8e0b87bed76950f50944977d9975e192c528 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 20 Dec 2019 17:33:00 +0100 Subject: [PATCH 028/507] Explicitly configure `shoulda-matchers` in spec_helper This is apparently needed in Rails 4 --- spec/spec_helper.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5eb8cad557..72f4627785 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,6 +24,14 @@ require 'paper_trail/frameworks/rspec' require 'webdrivers' +require 'shoulda/matchers' +Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end +end + # Allow connections to phantomjs/selenium whilst raising errors # when connecting to external sites require 'webmock/rspec' From a12ec8c5d98974507a9fd17591f45e8739fe1fcb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 01:42:04 +0100 Subject: [PATCH 029/507] Move filter parameters to initializer for Rails 4 --- config/application.rb | 3 --- config/initializers/filter_parameter_logging.rb | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 config/initializers/filter_parameter_logging.rb diff --git a/config/application.rb b/config/application.rb index 33db7342e5..a7ad92ff24 100644 --- a/config/application.rb +++ b/config/application.rb @@ -137,9 +137,6 @@ module Openfoodnetwork # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" - # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password] - # Enable the asset pipeline config.assets.enabled = true diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000000..e203fcee0a --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,2 @@ +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] From 5cc223e8f4066ef901ed2d0c16eb171c140fe30c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 01:47:18 +0100 Subject: [PATCH 030/507] Update routes loading for Rails 4 --- config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.rb b/config/application.rb index a7ad92ff24..973a1d942a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -105,7 +105,7 @@ module Openfoodnetwork #{config.root}/app/jobs ) - config.paths["config/routes"] = %w( + config.paths["config/routes.rb"] = %w( config/routes/api.rb config/routes.rb config/routes/admin.rb From 0a9d63dd2f27ca51e57b14a7ca305b5346ff8038 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 13:50:47 +0100 Subject: [PATCH 031/507] Fix deprecated syntax on associations --- app/models/spree/adjustment_decorator.rb | 5 +++-- app/models/spree/order_decorator.rb | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index 2e1dfcebf7..a12d68e7fa 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -9,8 +9,9 @@ module Spree # So we don't need the option `dependent: :destroy` as long as # AdjustmentMetadata has no destroy logic itself. has_one :metadata, class_name: 'AdjustmentMetadata' - belongs_to :tax_rate, foreign_key: 'originator_id', - conditions: "spree_adjustments.originator_type = 'Spree::TaxRate'" + belongs_to :tax_rate, -> { where spree_adjustments: { originator_type: 'Spree::TaxRate' } }, + foreign_key: 'originator_id' + scope :enterprise_fee, -> { where(originator_type: 'EnterpriseFee') } scope :admin, -> { where(source_type: nil, originator_type: nil) } diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 4e1e2e67e5..3c2dbafa0a 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -21,10 +21,9 @@ Spree::Order.class_eval do # This removes "inverse_of: source" which breaks shipment adjustment calculations # This change is done in Spree 2.1 (see https://github.com/spree/spree/commit/3fa44165c7825f79a2fa4eb79b99dc29944c5d55) # When OFN gets to Spree 2.1, this can be removed - has_many :adjustments, + has_many :adjustments, -> { order "#{Spree::Adjustment.table_name}.created_at ASC" }, as: :adjustable, - dependent: :destroy, - order: "#{Spree::Adjustment.table_name}.created_at ASC" + dependent: :destroy validates :customer, presence: true, if: :require_customer? validate :products_available_from_new_distribution, if: lambda { distributor_id_changed? || order_cycle_id_changed? } From 7aef5af71c6bf19c9346882452f0f07e94d50260 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 15:44:40 +0100 Subject: [PATCH 032/507] Fix report types spec --- spec/controllers/spree/admin/reports_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/spree/admin/reports_controller_spec.rb b/spec/controllers/spree/admin/reports_controller_spec.rb index e339e09fd1..3fccd41d43 100644 --- a/spec/controllers/spree/admin/reports_controller_spec.rb +++ b/spec/controllers/spree/admin/reports_controller_spec.rb @@ -151,8 +151,8 @@ describe Spree::Admin::ReportsController, type: :controller do spree_get :index report_types = assigns(:reports).keys - expect(report_types).to include "orders_and_fulfillment", "products_and_inventory", "packing" # and others - expect(report_types).to_not include "sales_tax" + expect(report_types).to include :orders_and_fulfillment, :products_and_inventory, :packing # and others + expect(report_types).to_not include :sales_tax end end From 39459b4a63005e13c47776efc86708cc24f301a0 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 16:08:30 +0100 Subject: [PATCH 033/507] Temporarily fix root_path missing error in many controllers --- config/routes/spree.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/routes/spree.rb b/config/routes/spree.rb index d6c3ed4e46..6c6c1a376d 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -1,5 +1,7 @@ # Overriding Devise routes to use our own controller Spree::Core::Engine.routes.draw do + root to: 'home#index' + devise_for :spree_user, :class_name => 'Spree::User', :controllers => { :sessions => 'spree/user_sessions', From aff8911309c432154a490e51f6a2ede519ed42e2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 18:57:11 +0100 Subject: [PATCH 034/507] Update database_cleaner to >1.0 to fix transaction issues in test suite --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 6e925b1cfe..935983ae8e 100644 --- a/Gemfile +++ b/Gemfile @@ -130,7 +130,7 @@ group :test, :development do gem 'atomic' gem 'awesome_print' gem 'capybara', '>= 2.18.0' # 3.0 requires nokogiri 1.8 - gem 'database_cleaner', '0.7.1', require: false + gem 'database_cleaner', require: false gem "factory_bot_rails", '4.8.2', require: false gem 'fuubar', '~> 2.4.1' gem 'json_spec', '~> 1.1.4' diff --git a/Gemfile.lock b/Gemfile.lock index 5b6db44dad..d3bd81a749 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -184,7 +184,7 @@ GEM addressable daemons (1.3.1) dalli (2.7.10) - database_cleaner (0.7.1) + database_cleaner (1.7.0) db2fog (0.9.0) activerecord (>= 3.2.0, < 5.0) fog (~> 1.0) @@ -691,7 +691,7 @@ DEPENDENCIES custom_error_message! daemons dalli - database_cleaner (= 0.7.1) + database_cleaner db2fog ddtrace debugger-linecache From 6541b558720ae10b1216a07ff77e168854558f5d Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 01:29:22 +0100 Subject: [PATCH 035/507] Fix default_association deprecated syntax in OrderCycle and Schedule --- app/models/order_cycle.rb | 8 ++++---- app/models/schedule.rb | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 9a30c493e5..ba94db1bda 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -10,11 +10,11 @@ class OrderCycle < ActiveRecord::Base # These scope names are prepended with "cached_" because there are existing accessor methods # :incoming_exchanges and :outgoing_exchanges. - has_many :cached_incoming_exchanges, conditions: { incoming: true }, class_name: "Exchange" - has_many :cached_outgoing_exchanges, conditions: { incoming: false }, class_name: "Exchange" + has_many :cached_incoming_exchanges, -> { where incoming: true }, class_name: "Exchange" + has_many :cached_outgoing_exchanges, -> { where incoming: false }, class_name: "Exchange" - has_many :suppliers, source: :sender, through: :cached_incoming_exchanges, uniq: true - has_many :distributors, source: :receiver, through: :cached_outgoing_exchanges, uniq: true + has_many :suppliers, -> { uniq }, source: :sender, through: :cached_incoming_exchanges + has_many :distributors, -> { uniq }, source: :receiver, through: :cached_outgoing_exchanges has_and_belongs_to_many :schedules, join_table: 'order_cycle_schedules' diff --git a/app/models/schedule.rb b/app/models/schedule.rb index 67443f7784..d882487d8f 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -1,6 +1,6 @@ class Schedule < ActiveRecord::Base has_and_belongs_to_many :order_cycles, join_table: 'order_cycle_schedules' - has_many :coordinators, uniq: true, through: :order_cycles + has_many :coordinators, -> { uniq }, through: :order_cycles attr_accessible :name, :order_cycle_ids From 9fd4863a135c624d80b6e03d753d9246438d7a33 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 02:00:35 +0100 Subject: [PATCH 036/507] Fix missing roles error in spec workflow #create_enterprise_user --- spec/support/request/authentication_workflow.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/support/request/authentication_workflow.rb b/spec/support/request/authentication_workflow.rb index b1ff1587cd..e4708a6e97 100644 --- a/spec/support/request/authentication_workflow.rb +++ b/spec/support/request/authentication_workflow.rb @@ -26,8 +26,8 @@ module AuthenticationWorkflow # TODO: Should probably just rename this to create_user def create_enterprise_user( attrs = {} ) - new_user = create(:user, attrs) - new_user.spree_roles = [] # for some reason unbeknown to me, this new user gets admin permissions by default. + new_user = build(:user, attrs) + new_user.spree_roles = [Spree::Role.find_or_create_by!(name: 'user')] new_user.save new_user end From 241e9221b4f150040c9a583be1e4a5f9b77fab19 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 14:46:43 +0100 Subject: [PATCH 037/507] Replace deprecated :restrict option in address_decorator.rb DEPRECATION WARNING: The :restrict option is deprecated. Please use :restrict_with_exception instead, which provides the same functionality. (called from block in at /home/user/Github/openfoodnetwork/app/models/spree/address_decorator.rb:4) --- app/models/spree/address_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/spree/address_decorator.rb b/app/models/spree/address_decorator.rb index 603423e8d6..a8b1799e54 100644 --- a/app/models/spree/address_decorator.rb +++ b/app/models/spree/address_decorator.rb @@ -1,7 +1,7 @@ Spree::Address.class_eval do include AddressDisplay - has_one :enterprise, dependent: :restrict + has_one :enterprise, dependent: :restrict_with_exception belongs_to :country, class_name: "Spree::Country" after_save :touch_enterprise From 98fdbb86218b2c7a2e0f7722832385042fcd2ec2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 15:07:06 +0100 Subject: [PATCH 038/507] Update deprecated #scoped calls Model#scoped is now deprecated. Model#where(nil) in Rails 4 returns the same result as Model#scoped in Rails 3 --- app/controllers/api/products_controller.rb | 2 +- app/controllers/api/variants_controller.rb | 2 +- app/controllers/spree/admin/payment_methods_controller.rb | 2 +- app/controllers/spree/admin/users_controller.rb | 2 +- app/models/enterprise.rb | 4 ++-- app/models/enterprise_fee.rb | 2 +- app/models/enterprise_group.rb | 2 +- app/models/exchange.rb | 2 +- app/models/order_cycle.rb | 4 ++-- app/models/spree/line_item_decorator.rb | 2 +- app/models/spree/order_decorator.rb | 4 ++-- app/models/spree/payment_method_decorator.rb | 2 +- app/models/spree/product_decorator.rb | 2 +- app/models/spree/shipping_method_decorator.rb | 2 +- app/models/spree/user.rb | 2 +- app/services/order_adjustments_fetcher.rb | 2 +- lib/open_food_network/permalink_generator.rb | 4 ++-- lib/open_food_network/permissions.rb | 4 ++-- lib/open_food_network/proxy_order_syncer.rb | 2 +- spec/lib/open_food_network/customers_report_spec.rb | 2 +- .../open_food_network/order_cycle_management_report_spec.rb | 2 +- .../open_food_network/products_and_inventory_report_spec.rb | 6 +++--- spec/support/seeds.rb | 2 +- 23 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb index cef1e975af..e346112326 100644 --- a/app/controllers/api/products_controller.rb +++ b/app/controllers/api/products_controller.rb @@ -119,7 +119,7 @@ module Api end def paged_products_for_producers(producers) - Spree::Product.scoped. + Spree::Product.where(nil). merge(product_scope). where(supplier_id: producers). by_producer.by_name. diff --git a/app/controllers/api/variants_controller.rb b/app/controllers/api/variants_controller.rb index b64d5f6082..f0e31e0035 100644 --- a/app/controllers/api/variants_controller.rb +++ b/app/controllers/api/variants_controller.rb @@ -58,7 +58,7 @@ module Api @product.variants_including_master end else - variants = Spree::Variant.scoped + variants = Spree::Variant.where(nil) if current_api_user.has_spree_role?("admin") unless params[:show_deleted] variants = Spree::Variant.active diff --git a/app/controllers/spree/admin/payment_methods_controller.rb b/app/controllers/spree/admin/payment_methods_controller.rb index 53bf22d06a..9d0cf5e817 100644 --- a/app/controllers/spree/admin/payment_methods_controller.rb +++ b/app/controllers/spree/admin/payment_methods_controller.rb @@ -69,7 +69,7 @@ module Spree model_class.accessible_by(current_ability, action) else - model_class.scoped + model_class.where(nil) end collection = collection.managed_by(spree_current_user).by_name # This line added diff --git a/app/controllers/spree/admin/users_controller.rb b/app/controllers/spree/admin/users_controller.rb index e66ec7f4af..8ebd40cbfc 100644 --- a/app/controllers/spree/admin/users_controller.rb +++ b/app/controllers/spree/admin/users_controller.rb @@ -131,7 +131,7 @@ module Spree end def load_roles - @roles = Spree::Role.scoped + @roles = Spree::Role.where(nil) end def new_email_unconfirmed? diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 72564c6409..42177ad7b5 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -123,7 +123,7 @@ class Enterprise < ActiveRecord::Base if ready_enterprises.present? where("enterprises.id NOT IN (?)", ready_enterprises) else - where("TRUE") + where(nil) end } scope :is_primary_producer, -> { where(is_primary_producer: true) } @@ -182,7 +182,7 @@ class Enterprise < ActiveRecord::Base scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else joins(:enterprise_roles).where('enterprise_roles.user_id = ?', user.id) end diff --git a/app/models/enterprise_fee.rb b/app/models/enterprise_fee.rb index 64c362b0fe..3c93f198ba 100644 --- a/app/models/enterprise_fee.rb +++ b/app/models/enterprise_fee.rb @@ -25,7 +25,7 @@ class EnterpriseFee < ActiveRecord::Base scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else where('enterprise_id IN (?)', user.enterprises) end diff --git a/app/models/enterprise_group.rb b/app/models/enterprise_group.rb index 4d8ff217f2..ab27b051f5 100644 --- a/app/models/enterprise_group.rb +++ b/app/models/enterprise_group.rb @@ -51,7 +51,7 @@ class EnterpriseGroup < ActiveRecord::Base scope :on_front_page, -> { where(on_front_page: true) } scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else where('owner_id = ?', user.id) end diff --git a/app/models/exchange.rb b/app/models/exchange.rb index ce28a7255d..175d641a8a 100644 --- a/app/models/exchange.rb +++ b/app/models/exchange.rb @@ -67,7 +67,7 @@ class Exchange < ActiveRecord::Base scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else joins("LEFT JOIN enterprises senders ON senders.id = exchanges.sender_id"). joins("LEFT JOIN enterprises receivers ON receivers.id = exchanges.receiver_id"). diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index ba94db1bda..48bbaf249d 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -61,7 +61,7 @@ class OrderCycle < ActiveRecord::Base scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else where(coordinator_id: user.enterprises) end @@ -70,7 +70,7 @@ class OrderCycle < ActiveRecord::Base # Return order cycles that user coordinates, sends to or receives from scope :accessible_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else with_exchanging_enterprises_outer. where('order_cycles.coordinator_id IN (?) OR enterprises.id IN (?)', diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 5581993dff..b2a5369ede 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -26,7 +26,7 @@ Spree::LineItem.class_eval do # -- Scopes scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else # Find line items that are from orders distributed by the user or supplied by the user joins(variant: :product). diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 3c2dbafa0a..9023438eae 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -50,7 +50,7 @@ Spree::Order.class_eval do # -- Scopes scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else # Find orders that are distributed by the user or have products supplied by the user # WARNING: This only filters orders, you'll need to filter line items separately using LineItem.managed_by @@ -62,7 +62,7 @@ Spree::Order.class_eval do scope :distributed_by_user, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else where('spree_orders.distributor_id IN (?)', user.enterprises) end diff --git a/app/models/spree/payment_method_decorator.rb b/app/models/spree/payment_method_decorator.rb index f32944fdcb..994888389c 100644 --- a/app/models/spree/payment_method_decorator.rb +++ b/app/models/spree/payment_method_decorator.rb @@ -17,7 +17,7 @@ Spree::PaymentMethod.class_eval do # -- Scopes scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else joins(:distributors). where('distributors_payment_methods.distributor_id IN (?)', user.enterprises). diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index b601122a65..5ec1f3c94b 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -115,7 +115,7 @@ Spree::Product.class_eval do scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else where('supplier_id IN (?)', user.enterprises.select("enterprises.id")) end diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index 813c947f38..d79e2b6853 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -12,7 +12,7 @@ Spree::ShippingMethod.class_eval do scope :managed_by, lambda { |user| if user.has_spree_role?('admin') - scoped + where(nil) else joins(:distributors). where('distributors_shipping_methods.distributor_id IN (?)', user.enterprises). diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index 370b248023..10075729bf 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -81,7 +81,7 @@ module Spree def known_users if admin? - Spree::User.scoped + Spree::User.where(nil) else Spree::User .includes(:enterprises) diff --git a/app/services/order_adjustments_fetcher.rb b/app/services/order_adjustments_fetcher.rb index dfde72f142..40d78cf6bc 100644 --- a/app/services/order_adjustments_fetcher.rb +++ b/app/services/order_adjustments_fetcher.rb @@ -61,7 +61,7 @@ class OrderAdjustmentsFetcher match_by_scope(adjustment, adjustment_scope) end else - adjustments.scoped.public_send scope + adjustments.where(nil).public_send scope end end diff --git a/lib/open_food_network/permalink_generator.rb b/lib/open_food_network/permalink_generator.rb index 3c5babc750..eeee1bf18f 100644 --- a/lib/open_food_network/permalink_generator.rb +++ b/lib/open_food_network/permalink_generator.rb @@ -40,7 +40,7 @@ module PermalinkGenerator if self.class.respond_to?(:with_deleted) self.class.with_deleted else - self.class.scoped - end + self.class.where(nil) +end end end diff --git a/lib/open_food_network/permissions.rb b/lib/open_food_network/permissions.rb index fe132a9be2..8f55de56fe 100644 --- a/lib/open_food_network/permissions.rb +++ b/lib/open_food_network/permissions.rb @@ -147,7 +147,7 @@ module OpenFoodNetwork def managed_and_related_enterprises_granting(permission) if admin? - Enterprise.scoped + Enterprise.where(nil) else Enterprise.where( id: managed_enterprises.select("enterprises.id") | @@ -158,7 +158,7 @@ module OpenFoodNetwork def managed_and_related_enterprises_with(permission) if admin? - Enterprise.scoped + Enterprise.where(nil) else managed_enterprise_ids = managed_enterprises.select("enterprises.id") granting_enterprise_ids = related_enterprises_granting(permission) diff --git a/lib/open_food_network/proxy_order_syncer.rb b/lib/open_food_network/proxy_order_syncer.rb index 416774d506..7cd53c74ba 100644 --- a/lib/open_food_network/proxy_order_syncer.rb +++ b/lib/open_food_network/proxy_order_syncer.rb @@ -55,7 +55,7 @@ module OpenFoodNetwork end def remove_orphaned_proxy_orders! - orphaned_proxy_orders.scoped.delete_all + orphaned_proxy_orders.where(nil).delete_all end def orphaned_proxy_orders diff --git a/spec/lib/open_food_network/customers_report_spec.rb b/spec/lib/open_food_network/customers_report_spec.rb index 173a093759..5ac29350c0 100644 --- a/spec/lib/open_food_network/customers_report_spec.rb +++ b/spec/lib/open_food_network/customers_report_spec.rb @@ -113,7 +113,7 @@ module OpenFoodNetwork end describe "filtering orders" do - let(:orders) { Spree::Order.scoped } + let(:orders) { Spree::Order.where(nil) } let(:supplier) { create(:supplier_enterprise) } it "returns all orders sans-params" do diff --git a/spec/lib/open_food_network/order_cycle_management_report_spec.rb b/spec/lib/open_food_network/order_cycle_management_report_spec.rb index 707cc8c77c..aa3b091204 100644 --- a/spec/lib/open_food_network/order_cycle_management_report_spec.rb +++ b/spec/lib/open_food_network/order_cycle_management_report_spec.rb @@ -70,7 +70,7 @@ module OpenFoodNetwork end describe "filtering orders" do - let!(:orders) { Spree::Order.scoped } + let!(:orders) { Spree::Order.where(nil) } let!(:supplier) { create(:supplier_enterprise) } let!(:oc1) { create(:simple_order_cycle) } diff --git a/spec/lib/open_food_network/products_and_inventory_report_spec.rb b/spec/lib/open_food_network/products_and_inventory_report_spec.rb index 460de076d6..abe9706454 100644 --- a/spec/lib/open_food_network/products_and_inventory_report_spec.rb +++ b/spec/lib/open_food_network/products_and_inventory_report_spec.rb @@ -95,18 +95,18 @@ module OpenFoodNetwork end describe "Filtering variants" do - let(:variants) { Spree::Variant.scoped.joins(:product).where(is_master: false) } + let(:variants) { Spree::Variant.where(nil).joins(:product).where(is_master: false) } it "should return unfiltered variants sans-params" do product1 = create(:simple_product, supplier: supplier) product2 = create(:simple_product, supplier: supplier) - expect(subject.filter(Spree::Variant.scoped)).to match_array [product1.master, product1.variants.first, product2.master, product2.variants.first] + expect(subject.filter(Spree::Variant.where(nil))).to match_array [product1.master, product1.variants.first, product2.master, product2.variants.first] end it "should filter deleted products" do product1 = create(:simple_product, supplier: supplier) product2 = create(:simple_product, supplier: supplier) product2.destroy - expect(subject.filter(Spree::Variant.scoped)).to match_array [product1.master, product1.variants.first] + expect(subject.filter(Spree::Variant.where(nil))).to match_array [product1.master, product1.variants.first] end describe "based on report type" do it "returns only variants on hand" do diff --git a/spec/support/seeds.rb b/spec/support/seeds.rb index 023271aad0..75aff1baf8 100644 --- a/spec/support/seeds.rb +++ b/spec/support/seeds.rb @@ -5,7 +5,7 @@ # leaves them there when deleting the rest (see spec/spec_helper.rb). # You can add more entries here if you need them for your tests. -if Spree::Country.scoped.empty? +if Spree::Country.where(nil).empty? Spree::Country.create!({ "name" => "Australia", "iso3" => "AUS", "iso" => "AU", "iso_name" => "AUSTRALIA", "numcode" => "36" }, without_protection: true) country = Spree::Country.find_by(name: 'Australia') Spree::State.create!({ "name" => "Victoria", "abbr" => "Vic", :country => country }, without_protection: true) From ae11cb9954be295c9f1a803aa380dff9535e9304 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 15:33:30 +0100 Subject: [PATCH 039/507] Update rubocop_styleguide for Rails 4 --- .rubocop_styleguide.yml | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/.rubocop_styleguide.yml b/.rubocop_styleguide.yml index 01067a59ce..1af15bd7f4 100644 --- a/.rubocop_styleguide.yml +++ b/.rubocop_styleguide.yml @@ -5,7 +5,7 @@ # rubocop locally, the default configuration file `.rubocop.yml` loads # our "todo lists" to ignore all current violations. AllCops: - TargetRailsVersion: 3.2 + TargetRailsVersion: 4.0 Exclude: - 'bin/**/*' - 'db/**/*' @@ -20,9 +20,6 @@ AllCops: # # Cop settings that have been agreed upon by the OFN community -Rails: - Enabled: true - Style/Documentation: Enabled: false @@ -61,24 +58,6 @@ Lint/UselessAssignment: Exclude: - spec/**/* -# AFAIK, there is no good alternative to dynamic matchers until we upgrade -# to Rails 4 and can use #find_by. If there is a better approach, let's do it. -Rails/DynamicFindBy: - Enabled: false - -# Same as above, #find_by is not available until Rails 4 -Rails/FindBy: - Enabled: false - -# Same as above, #update! is not available until Rails 4 -Rails/ActiveRecordAliases: - Enabled: false - -# This should be the programmer's discretion, perhaps we should review all of -# the uses of it an make specific exceptions though. -Rails/SkipsModelValidations: - Enabled: false - ## Relaxed.Ruby.Style SETTINGS # # These styles are a starting point for the conversation around conventions From e3ae65fad5097c3f88a0ae2002a0b8ac4b41e42b Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 15:36:35 +0100 Subject: [PATCH 040/507] Update rubocop_todo --- .rubocop_todo.yml | 252 +++++++++++++--------------------------------- 1 file changed, 71 insertions(+), 181 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 87b43474cb..7be6d93eb5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,11 +1,19 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 1400` -# on 2020-01-09 11:26:09 +1100 using RuboCop version 0.79.0. +# on 2019-12-22 15:36:14 +0100 using RuboCop version 0.78.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: TreatCommentsAsGroupSeparators, Include. +# Include: **/*.gemfile, **/Gemfile, **/gems.rb +Bundler/OrderedGems: + Exclude: + - 'Gemfile' + # Offense count: 6 # Cop supports --auto-correct. Layout/EmptyLineAfterGuardClause: @@ -14,10 +22,11 @@ Layout/EmptyLineAfterGuardClause: - 'lib/open_food_network/orders_and_fulfillments_report.rb' - 'lib/open_food_network/packing_report.rb' -# Offense count: 1 +# Offense count: 2 # Cop supports --auto-correct. Layout/EmptyLines: Exclude: + - 'app/models/spree/adjustment_decorator.rb' - 'spec/features/admin/order_cycles_spec.rb' # Offense count: 1 @@ -28,7 +37,15 @@ Layout/EmptyLinesAroundBlockBody: Exclude: - 'spec/controllers/api/orders_controller_spec.rb' -# Offense count: 2 +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyleAlignWith, AutoCorrect, Severity. +# SupportedStylesAlignWith: keyword, variable, start_of_line +Layout/EndAlignment: + Exclude: + - 'lib/open_food_network/permalink_generator.rb' + +# Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. # SupportedHashRocketStyles: key, separator, table @@ -36,8 +53,18 @@ Layout/EmptyLinesAroundBlockBody: # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit Layout/HashAlignment: Exclude: + - 'app/models/enterprise.rb' - 'spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb' +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: AllowDoxygenCommentStyle. +Layout/LeadingCommentSpace: + Exclude: + - 'Gemfile' + - 'app/helpers/application_helper.rb' + - 'app/models/enterprise.rb' + # Offense count: 27 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. @@ -45,6 +72,12 @@ Layout/HashAlignment: Layout/LineLength: Max: 129 +# Offense count: 1 +# Cop supports --auto-correct. +Layout/SpaceAfterColon: + Exclude: + - 'lib/open_food_network/order_cycle_form_applicator.rb' + # Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator. @@ -73,11 +106,6 @@ Lint/DuplicateMethods: - 'lib/discourse/single_sign_on.rb' - 'lib/open_food_network/subscription_summary.rb' -# Offense count: 1 -Lint/DuplicateHashKey: - Exclude: - - 'spec/models/calculator/weight_spec.rb' - # Offense count: 10 Lint/IneffectiveAccessModifier: Exclude: @@ -122,6 +150,12 @@ Lint/UselessAccessModifier: - 'lib/open_food_network/reports/bulk_coop_report.rb' - 'spec/lib/open_food_network/reports/report_spec.rb' +# Offense count: 1 +Lint/UselessAssignment: + Exclude: + - 'spec/**/*' + - 'app/models/enterprise.rb' + # Offense count: 1 # Configuration parameters: CheckForMethodsWithNoSideEffects. Lint/Void: @@ -149,13 +183,27 @@ Naming/HeredocDelimiterNaming: Exclude: - 'app/models/content_configuration.rb' -# Offense count: 4 +# Offense count: 5 # Configuration parameters: EnforcedStyleForLeadingUnderscores. # SupportedStylesForLeadingUnderscores: disallowed, required, optional Naming/MemoizedInstanceVariableName: Exclude: - 'app/controllers/spree/admin/payments_controller_decorator.rb' - 'lib/open_food_network/address_finder.rb' + - 'lib/spree/authentication_helpers.rb' + +# Offense count: 8 +# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. +# AllowedNames: io, id, to, by, on, in, at, ip, db, os +Naming/MethodParameterName: + Exclude: + - 'app/helpers/spree/admin/base_helper_decorator.rb' + - 'app/helpers/spree/base_helper_decorator.rb' + - 'app/services/subscription_validator.rb' + - 'lib/open_food_network/reports/bulk_coop_report.rb' + - 'lib/open_food_network/xero_invoices_report.rb' + - 'spec/lib/open_food_network/reports/report_spec.rb' + - 'spec/mailers/producer_mailer_spec.rb' # Offense count: 8 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. @@ -197,173 +245,19 @@ Naming/PredicateName: - 'lib/open_food_network/packing_report.rb' - 'lib/tasks/data.rake' -# Offense count: 8 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: io, id, to, by, on, in, at, ip, db -Naming/MethodParameterName: - Exclude: - - 'app/controllers/admin/column_preferences_controller.rb' - - 'app/controllers/admin/customers_controller.rb' - - 'app/controllers/admin/enterprise_fees_controller.rb' - - 'app/controllers/admin/enterprise_groups_controller.rb' - - 'app/controllers/admin/enterprises_controller.rb' - - 'app/controllers/admin/order_cycles_controller.rb' - - 'app/controllers/admin/producer_properties_controller.rb' - - 'app/controllers/admin/product_import_controller.rb' - - 'app/controllers/admin/schedules_controller.rb' - - 'app/controllers/admin/stripe_connect_settings_controller.rb' - - 'app/controllers/admin/subscription_line_items_controller.rb' - - 'app/controllers/admin/subscriptions_controller.rb' - - 'app/controllers/admin/variant_overrides_controller.rb' - - 'app/controllers/api/base_controller.rb' - - 'app/controllers/api/enterprise_attachment_controller.rb' - - 'app/controllers/api/enterprises_controller.rb' - - 'app/controllers/api/shipments_controller.rb' - - 'app/controllers/api/variants_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/base_controller.rb' - - 'app/controllers/cart_controller.rb' - - 'app/controllers/checkout_controller.rb' - - 'app/controllers/discourse_sso_controller.rb' - - 'app/controllers/enterprises_controller.rb' - - 'app/controllers/home_controller.rb' - - 'app/controllers/line_items_controller.rb' - - 'app/controllers/producers_controller.rb' - - 'app/controllers/registration_controller.rb' - - 'app/controllers/shop_controller.rb' - - 'app/controllers/shops_controller.rb' - - 'app/controllers/spree/admin/adjustments_controller.rb' - - 'app/controllers/spree/admin/base_controller.rb' - - 'app/controllers/spree/admin/images_controller.rb' - - 'app/controllers/spree/admin/mail_methods_controller.rb' - - 'app/controllers/spree/admin/orders/customer_details_controller_decorator.rb' - - 'app/controllers/spree/admin/orders_controller_decorator.rb' - - 'app/controllers/spree/admin/payment_methods_controller.rb' - - 'app/controllers/spree/admin/payments_controller_decorator.rb' - - 'app/controllers/spree/admin/product_properties_controller.rb' - - 'app/controllers/spree/admin/products_controller_decorator.rb' - - 'app/controllers/spree/admin/reports/enterprise_fee_summaries_controller.rb' - - 'app/controllers/spree/admin/reports_controller.rb' - - 'app/controllers/spree/admin/shipping_methods_controller.rb' - - 'app/controllers/spree/admin/states_controller.rb' - - 'app/controllers/spree/admin/tax_rates_controller.rb' - - 'app/controllers/spree/admin/users_controller.rb' - - 'app/controllers/spree/admin/zones_controller.rb' - - 'app/controllers/spree/checkout_controller.rb' - - 'app/controllers/spree/orders_controller.rb' - - 'app/controllers/spree/paypal_controller_decorator.rb' - - 'app/controllers/spree/store_controller.rb' - - 'app/controllers/spree/user_registrations_controller.rb' - - 'app/controllers/spree/user_sessions_controller.rb' - - 'app/controllers/spree/users_controller.rb' - - 'app/controllers/stripe/webhooks_controller.rb' - - 'app/controllers/user_passwords_controller.rb' - - 'app/controllers/user_registrations_controller.rb' - -# Offense count: 1 +# Offense count: 13 +# Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. -# SupportedStyles: strict, flexible -Rails/Date: +# SupportedStyles: braces, no_braces, context_dependent +Style/BracesAroundHashParameters: Exclude: - - 'app/models/order_cycle.rb' - -# Offense count: 16 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: slashes, arguments -Rails/FilePath: - Exclude: - - 'app/models/product_import/product_importer.rb' - - 'lib/tasks/karma.rake' - - 'spec/controllers/api/logos_controller_spec.rb' - - 'spec/controllers/api/product_images_controller_spec.rb' - - 'spec/controllers/api/promo_images_controller_spec.rb' - - 'spec/factories/product_factory.rb' - - 'spec/features/admin/content_spec.rb' - - 'spec/features/admin/enterprises/images_spec.rb' - - 'spec/models/content_configuration_spec.rb' - - 'spec/models/spree/variant_spec.rb' - - 'spec/serializers/api/admin/enterprise_serializer_spec.rb' - - 'spec/support/downloads_helper.rb' - -# Offense count: 7 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/HasAndBelongsToMany: - Exclude: - - 'app/models/enterprise.rb' - - 'app/models/enterprise_group.rb' - - 'app/models/order_cycle.rb' - - 'app/models/schedule.rb' - - 'app/models/spree/concerns/payment_method_distributors.rb' - - 'app/models/spree/line_item_decorator.rb' - -# Offense count: 26 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/HasManyOrHasOneDependent: - Exclude: - - 'app/models/customer.rb' - - 'app/models/enterprise.rb' - - 'app/models/order_cycle.rb' - - 'app/models/spree/adjustment_decorator.rb' - - 'app/models/spree/order_decorator.rb' - - 'app/models/spree/payment_method_decorator.rb' - - 'app/models/spree/property_decorator.rb' - - 'app/models/spree/shipping_method_decorator.rb' - - 'app/models/spree/user.rb' - - 'app/models/spree/variant_decorator.rb' - - 'app/models/subscription.rb' - -# Offense count: 78 -# Configuration parameters: Include. -# Include: app/helpers/**/*.rb -Rails/HelperInstanceVariable: - Exclude: - - 'app/helpers/admin/injection_helper.rb' - - 'app/helpers/angular_form_builder.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/enterprises_helper.rb' - - 'app/helpers/injection_helper.rb' - - 'app/helpers/order_cycles_helper.rb' - - 'app/helpers/shared_helper.rb' - - 'app/helpers/spree/admin/orders_helper_decorator.rb' - - 'app/helpers/spree/orders_helper.rb' - -# Offense count: 6 -Rails/OutputSafety: - Exclude: - - 'app/controllers/spree/admin/reports_controller.rb' - - 'app/helpers/angular_form_helper.rb' - - 'app/helpers/spree/admin/base_helper.rb' - - 'app/helpers/spree/admin/zones_helper.rb' - - 'app/helpers/spree/reports_helper.rb' - - 'app/helpers/spree/admin/navigation_helper.rb' - - 'app/helpers/spree/admin/orders_helper.rb' - - 'app/serializers/api/product_serializer.rb' - - 'lib/spree/money_decorator.rb' - - 'spec/features/admin/orders_spec.rb' - -# Offense count: 2 -# Configuration parameters: Include. -# Include: **/Rakefile, **/*.rake -Rails/RakeEnvironment: - Exclude: - - 'lib/tasks/specs.rake' - -# Offense count: 9 -Rails/ReflectionClassName: - Exclude: - - 'app/models/customer.rb' - - 'app/models/distributor_shipping_method.rb' - - 'app/models/enterprise_role.rb' - - 'app/models/subscription.rb' - -# Offense count: 1 -# Configuration parameters: Environments. -# Environments: development, test, production -Rails/UnknownEnv: - Exclude: - - 'app/models/spree/app_configuration_decorator.rb' + - 'app/models/spree/payment_decorator.rb' + - 'lib/open_food_network/variant_and_line_item_naming.rb' + - 'spec/features/consumer/registration_spec.rb' + - 'spec/models/enterprise_fee_spec.rb' + - 'spec/models/spree/product_spec.rb' + - 'spec/models/tag_rule/discount_order_spec.rb' + - 'spec/support/seeds.rb' # Offense count: 2 Style/CaseEquality: @@ -478,7 +372,7 @@ Style/FormatStringToken: - 'lib/open_food_network/sales_tax_report.rb' - 'spec/features/admin/bulk_order_management_spec.rb' -# Offense count: 928 +# Offense count: 925 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: always, never @@ -580,7 +474,6 @@ Style/FrozenStringLiteralComment: - 'app/controllers/spree/credit_cards_controller.rb' - 'app/controllers/spree/home_controller.rb' - 'app/controllers/spree/orders_controller.rb' - - 'app/controllers/spree/paypal_controller_decorator.rb' - 'app/controllers/spree/store_controller.rb' - 'app/controllers/spree/user_passwords_controller.rb' - 'app/controllers/spree/user_registrations_controller.rb' @@ -1074,7 +967,6 @@ Style/FrozenStringLiteralComment: - 'spec/controllers/spree/checkout_controller_spec.rb' - 'spec/controllers/spree/credit_cards_controller_spec.rb' - 'spec/controllers/spree/orders_controller_spec.rb' - - 'spec/controllers/spree/paypal_controller_spec.rb' - 'spec/controllers/spree/store_controller_spec.rb' - 'spec/controllers/spree/user_sessions_controller_spec.rb' - 'spec/controllers/spree/users_controller_spec.rb' @@ -1277,7 +1169,6 @@ Style/FrozenStringLiteralComment: - 'spec/models/spree/classification_spec.rb' - 'spec/models/spree/credit_card_spec.rb' - 'spec/models/spree/gateway/stripe_connect_spec.rb' - - 'spec/models/spree/gateway_tagging_spec.rb' - 'spec/models/spree/image_spec.rb' - 'spec/models/spree/line_item_spec.rb' - 'spec/models/spree/order/checkout_spec.rb' @@ -1413,7 +1304,7 @@ Style/FrozenStringLiteralComment: - 'spec/views/spree/admin/orders/edit.html.haml_spec.rb' - 'spec/views/spree/admin/orders/index.html.haml_spec.rb' -# Offense count: 58 +# Offense count: 59 # Configuration parameters: MinBodyLength. Style/GuardClause: Exclude: @@ -1428,7 +1319,6 @@ Style/GuardClause: - 'app/controllers/spree/admin/variants_controller_decorator.rb' - 'app/controllers/spree/checkout_controller.rb' - 'app/controllers/spree/orders_controller.rb' - - 'app/controllers/spree/paypal_controller_decorator.rb' - 'app/models/enterprise.rb' - 'app/models/enterprise_group.rb' - 'app/models/producer_property.rb' @@ -1491,7 +1381,7 @@ Style/NegatedUnless: Exclude: - 'app/services/cart_service.rb' -# Offense count: 41 +# Offense count: 42 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. # SupportedStyles: predicate, comparison From fd11d4fa5b7849b8f40db3af96d1d5b3b2653b3c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 19:42:45 +0100 Subject: [PATCH 041/507] Fix broken html encoding of injected json in admin views --- app/views/admin/json/_injection_ams.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/json/_injection_ams.html.haml b/app/views/admin/json/_injection_ams.html.haml index 50a22fa4ce..c95ecf5b03 100644 --- a/app/views/admin/json/_injection_ams.html.haml +++ b/app/views/admin/json/_injection_ams.html.haml @@ -1,2 +1,2 @@ :javascript - angular.module("#{ngModule}").value("#{name.to_s}", #{json}) \ No newline at end of file + angular.module("#{ngModule}").value("#{name.to_s.html_safe}", #{json.html_safe}) \ No newline at end of file From 49bc3308be1c643a8ad09da71058891f3dd32865 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 20:00:58 +0100 Subject: [PATCH 042/507] Fix broken references to url_helpers --- app/serializers/api/admin/order_serializer.rb | 2 +- app/serializers/api/order_serializer.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/serializers/api/admin/order_serializer.rb b/app/serializers/api/admin/order_serializer.rb index d6888994d3..b00aee730b 100644 --- a/app/serializers/api/admin/order_serializer.rb +++ b/app/serializers/api/admin/order_serializer.rb @@ -60,6 +60,6 @@ class Api::Admin::OrderSerializer < ActiveModel::Serializer private def spree_routes_helper - Spree::Core::Engine.routes_url_helpers + Spree::Core::Engine.routes.url_helpers end end diff --git a/app/serializers/api/order_serializer.rb b/app/serializers/api/order_serializer.rb index f90f6ef572..cbac0c00b4 100644 --- a/app/serializers/api/order_serializer.rb +++ b/app/serializers/api/order_serializer.rb @@ -42,13 +42,13 @@ module Api end def path - Spree::Core::Engine.routes_url_helpers.order_path(object) + Spree::Core::Engine.routes.url_helpers.order_path(object) end def cancel_path return nil unless object.changes_allowed? - Spree::Core::Engine.routes_url_helpers.cancel_order_path(object) + Spree::Core::Engine.routes.url_helpers.cancel_order_path(object) end def changes_allowed From 3615dcd35512015567eb52901a3dad26013ba5a3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 20:43:45 +0100 Subject: [PATCH 043/507] Fix namespacing in cookies test NameError: uninitialized constant ActionDispatch::Cookies::SignedCookieJar::MAX_COOKIE_SIZE # ./spec/requests/large_request_spec.rb:8 --- spec/requests/large_request_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/requests/large_request_spec.rb b/spec/requests/large_request_spec.rb index 6e389d5ecb..9a5e668aa7 100644 --- a/spec/requests/large_request_spec.rb +++ b/spec/requests/large_request_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'A very large request', type: :request do it 'should not overflow cookies' do - get '/admin', foo: 'x' * ActionDispatch::Cookies::SignedCookieJar::MAX_COOKIE_SIZE + get '/admin', foo: 'x' * ActionDispatch::Cookies::MAX_COOKIE_SIZE expect(response.status).to eq(302) # HTTP status 302 - Found ## Use the newer syntax if rspec gets upgraded # expect(response).to have_http_status(:redirect) From 6c22d655c8ba04d98c76bb0693a9dfb545949f36 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 22 Dec 2019 21:35:32 +0100 Subject: [PATCH 044/507] Temporarily remove additional email validation on Spree::Order A new custom email validator class was added to Spree::Order, and currently it fails every time (breaking lots of specs). This ugly hack disables it for now. --- app/models/spree/order_decorator.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 9023438eae..a11bab1707 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -30,6 +30,14 @@ Spree::Order.class_eval do validate :disallow_guest_order attr_accessible :order_cycle_id, :distributor_id, :customer_id + # Removes Spree 2.1 additional email validation (currently failing every time) + # See: spree/core/validators/email.rb + _validate_callbacks.each do |callback| + if callback.raw_filter.respond_to? :attributes + callback.raw_filter.attributes.delete :email + end + end + before_validation :associate_customer, unless: :customer_id? before_validation :ensure_customer, unless: :customer_is_valid? From c0ecdb9e3aafcf609781c1bfd80b0728f32050f3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 23 Dec 2019 13:57:33 +0100 Subject: [PATCH 045/507] Fix deprecated #includes in join without reference DEPRECATION WARNING: It looks like you are eager loading table(s) (one of: variant_overrides, enterprises, enterprise_roles) that are referenced in a string SQL snippet. For example: Post.includes(:comments).where("comments.title = 'foo'") Currently, Active Record recognizes the table in the string, and knows to JOIN the comments table to the query, rather than loading comments in a separate query. However, doing this without writing a full-blown SQL parser is inherently flawed. Since we don't want to write an SQL parser, we are removing this functionality. From now on, you must explicitly tell Active Record when you are referencing a table from a string: Post.includes(:comments).where("comments.title = 'foo'").references(:comments) If you don't rely on implicit join references you can disable the feature entirely by setting `config.active_record.disable_implicit_join_references = true`. (called from collection at /home/user/Github/openfoodnetwork/app/controllers/admin/variant_overrides_controller.rb:77) --- app/controllers/admin/variant_overrides_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index e12b43825b..331bfe6fce 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -73,7 +73,10 @@ module Admin end def collection - @variant_overrides = VariantOverride.includes(:variant).for_hubs(params[:hub_id] || @hubs) + @variant_overrides = VariantOverride. + includes(:variant). + for_hubs(params[:hub_id] || @hubs). + references(:variant) @variant_overrides.select { |vo| vo.variant.present? } end From df1299b2904282557b516f73954e2e8bbe27fbbb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 23 Dec 2019 15:47:52 +0100 Subject: [PATCH 046/507] Fix user not yet loaded in prepend_before_filter --- app/controllers/admin/variant_overrides_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 331bfe6fce..41c95a4451 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -5,7 +5,7 @@ module Admin include OpenFoodNetwork::SpreeApiKeyLoader include EnterprisesHelper - prepend_before_filter :load_data + before_filter :load_data before_filter :load_collection, only: [:bulk_update] before_filter :load_spree_api_key, only: :index From 04b760f22188826b70292bd1c1868f6aca583b56 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 23 Dec 2019 16:46:54 +0100 Subject: [PATCH 047/507] Fix changed order of arguments for TestCase#process DEPRECATION WARNING: TestCase#process now expects the HTTP method as second argument: process(action, http_method, params, session, flash). (called from api_process at /home/user/Github/openfoodnetwork/spec/support/controller_hacks.rb:22) --- spec/support/controller_hacks.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/support/controller_hacks.rb b/spec/support/controller_hacks.rb index 7645e87372..8d23cb7483 100644 --- a/spec/support/controller_hacks.rb +++ b/spec/support/controller_hacks.rb @@ -20,12 +20,12 @@ module ControllerHacks def api_process(action, params = {}, session = nil, flash = nil, method = "get") scoping = respond_to?(:resource_scoping) ? resource_scoping : {} process(action, + method, params. merge(scoping). reverse_merge!(use_route: :spree, format: :json), session, - flash, - method) + flash) end end From b3e7f9a07e09783f3dbbb89552a6d80401b53353 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 27 Dec 2019 23:05:19 +0100 Subject: [PATCH 048/507] Fix deprecated arguments used in #sanitize Failure/Error: d = sanitize(object.description, tags: "p, b, strong, em, i, a, u", attributes: "href, target") ArgumentError: You should pass :tags as an Enumerable # ./app/serializers/api/product_serializer.rb:26:in `description_html' # (eval):10:in `_fast_attributes' # ./app/services/products_renderer.rb:24:in `products_json' # ./app/controllers/api/order_cycles_controller.rb:14:in `products' # ./lib/open_food_network/rack_request_blocker.rb:36:in `call' --- app/serializers/api/product_serializer.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/serializers/api/product_serializer.rb b/app/serializers/api/product_serializer.rb index 592b67ecdb..733904c5b6 100644 --- a/app/serializers/api/product_serializer.rb +++ b/app/serializers/api/product_serializer.rb @@ -1,4 +1,4 @@ -require 'open_food_network/scope_variant_to_hub' +require "open_food_network/scope_variant_to_hub" class Api::ProductSerializer < ActiveModel::Serializer include ActionView::Helpers::SanitizeHelper @@ -23,7 +23,8 @@ class Api::ProductSerializer < ActiveModel::Serializer # return a sanitized html description def description_html - d = sanitize(object.description, tags: "p, b, strong, em, i, a, u", attributes: "href, target") + d = sanitize(object.description, tags: ["p", "b", "strong", "em", "i", "a", "u"], + attributes: ["href", "target"]) d.to_s.html_safe end From b9db6df952f74cfb218bd656c93c38da3402ff42 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 3 Jan 2020 02:13:09 +0100 Subject: [PATCH 049/507] Replace current_spree_user method This wasn't working before but now seems to be fixed --- lib/spree/authentication_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/spree/authentication_helpers.rb b/lib/spree/authentication_helpers.rb index 29bb716d98..49bd97542a 100644 --- a/lib/spree/authentication_helpers.rb +++ b/lib/spree/authentication_helpers.rb @@ -8,7 +8,7 @@ module Spree end def spree_current_user - @current_spree_user ||= request.env['warden'].authenticate + current_spree_user end delegate :login_path, to: :spree, prefix: true From e9e41681025b789c560eb66ab1b7ee6b6447da47 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 3 Jan 2020 21:50:55 +0100 Subject: [PATCH 050/507] Fix ActiveModel::MissingAttributeError in order_cycle_permissions.rb Failure/Error: variant_ids_by_supplier_id(permissions.all_incoming_editable_variants.all) ActiveModel::MissingAttributeError: missing attribute: product_id # ./app/serializers/api/admin/order_cycle_serializer.rb:36:in `editable_variants_for_incoming_exchanges' # (eval):9:in `_fast_attributes' # ./app/controllers/spree/admin/base_controller_decorator.rb:98:in `render_as_json' # ./app/controllers/admin/order_cycles_controller.rb:28:in `block (2 levels) in show' # ./app/controllers/admin/order_cycles_controller.rb:25:in `show' # ./lib/open_food_network/rack_request_blocker.rb:36:in `call' # ------------------ # --- Caused by: --- # ActiveModel::MissingAttributeError: # missing attribute: product_id # ./app/serializers/api/admin/order_cycle_serializer.rb:36:in `editable_variants_for_incoming_exchanges' --- lib/open_food_network/order_cycle_permissions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/open_food_network/order_cycle_permissions.rb b/lib/open_food_network/order_cycle_permissions.rb index e1d1301e36..0e30993117 100644 --- a/lib/open_food_network/order_cycle_permissions.rb +++ b/lib/open_food_network/order_cycle_permissions.rb @@ -160,7 +160,7 @@ module OpenFoodNetwork end.map(&:id) Spree::Variant.includes(product: :supplier). - select("spree_variants.id, spree_products.supplier_id"). + select("spree_variants.id, spree_variants.product_id, spree_products.supplier_id"). joins(:product).where(spree_products: { supplier_id: valid_suppliers }) end From 8b542812549b0ab684fda7768764a33b1d200894 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 15 Jan 2020 11:34:54 +0100 Subject: [PATCH 051/507] Add missing method removed from order model in Spree 2.1 It looks like #price_adjustments was refactored/removed in Spree 2.1, but we still call the method in order_decorator --- app/models/spree/order_decorator.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index a11bab1707..cdabd16515 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -312,6 +312,14 @@ Spree::Order.class_eval do end end + def price_adjustments + adjustments = [] + + line_items.each { |line_item| adjustments.concat line_item.adjustments } + + adjustments + end + def price_adjustment_totals Hash[tax_adjustment_totals.map do |tax_rate, tax_amount| [tax_rate.name, From 26ba37b117848ecc8a55752bb4870467d5210039 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 18 Feb 2020 14:27:01 +0000 Subject: [PATCH 052/507] Comment spree_paypal express in all.js temporarily --- app/assets/javascripts/admin/all.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 5525aa6828..19359a9a05 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -35,7 +35,8 @@ //= require equalize //= require css_browser_selector_dev //= require responsive-tables -//= require admin/spree_paypal_express +// needs to be readded: +// require admin/spree_paypal_express //= require admin/handlebar_extensions // OFN specific From 7640c7b606cebd01cdd4841369865b9be551266d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 18 Feb 2020 16:22:04 +0000 Subject: [PATCH 053/507] Make all timestamps nullable, non-nullable timestamps are not required to maketimestamps work properly --- db/schema.rb | 244 +++++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 3aa6f812b0..2e6e0ec609 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -32,8 +32,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "action_name", null: false t.string "column_name", null: false t.boolean "visible", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "column_preferences", ["user_id", "action_name", "column_name"], name: "index_column_prefs_on_user_id_and_action_name_and_column_name", unique: true, using: :btree @@ -51,8 +51,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "enterprise_id", null: false t.string "code" t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "bill_address_id" t.integer "ship_address_id" t.string "name" @@ -75,8 +75,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.datetime "failed_at" t.string "locked_by" t.string "queue" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree @@ -92,8 +92,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "distributors_shipping_methods", force: true do |t| t.integer "distributor_id" t.integer "shipping_method_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "distributors_shipping_methods", ["distributor_id"], name: "index_distributors_shipping_methods_on_distributor_id", using: :btree @@ -103,8 +103,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "enterprise_id" t.string "fee_type" t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "tax_category_id" t.boolean "inherits_tax_category", default: false, null: false end @@ -190,8 +190,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "address_id" t.text "pickup_times" t.string "next_collection_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.text "distributor_info" t.string "logo_file_name" t.string "logo_content_type" @@ -229,8 +229,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "exchange_fees", force: true do |t| t.integer "exchange_id" t.integer "enterprise_fee_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "exchange_fees", ["enterprise_fee_id"], name: "index_exchange_fees_on_enterprise_fee_id", using: :btree @@ -239,8 +239,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "exchange_variants", force: true do |t| t.integer "exchange_id" t.integer "variant_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "exchange_variants", ["exchange_id"], name: "index_exchange_variants_on_exchange_id", using: :btree @@ -252,8 +252,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "receiver_id" t.text "pickup_time" t.text "pickup_instructions" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "incoming", default: false, null: false t.text "receival_instructions" end @@ -266,8 +266,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "enterprise_id", null: false t.integer "variant_id", null: false t.boolean "visible", default: true, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "inventory_items", ["enterprise_id", "variant_id"], name: "index_inventory_items_on_enterprise_id_and_variant_id", unique: true, using: :btree @@ -285,8 +285,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.datetime "orders_open_at" t.datetime "orders_close_at" t.integer "coordinator_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "producer_properties", force: true do |t| @@ -294,8 +294,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "producer_id" t.integer "property_id" t.integer "position", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "producer_properties", ["position"], name: "index_producer_properties_on_position", using: :btree @@ -306,8 +306,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "subscription_id", null: false t.integer "order_id" t.datetime "canceled_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "order_cycle_id", null: false t.datetime "placed_at" t.datetime "confirmed_at" @@ -319,15 +319,15 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "schedules", force: true do |t| t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "sessions", force: true do |t| t.string "session_id", null: false t.text "data" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree @@ -361,8 +361,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "alternative_phone" t.integer "state_id" t.integer "country_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "company" t.float "latitude" t.float "longitude" @@ -377,8 +377,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "label" t.string "source_type" t.integer "adjustable_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "mandatory" t.integer "originator_id" t.string "originator_type" @@ -411,15 +411,15 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "type" t.integer "calculable_id", null: false t.string "calculable_type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_configurations", force: true do |t| t.string "name" t.string "type", limit: 50 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "spree_configurations", ["name", "type"], name: "index_configurations_on_name_and_type", using: :btree @@ -444,8 +444,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "start_year" t.string "issue_number" t.integer "address_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "gateway_customer_profile_id" t.string "gateway_payment_profile_id" t.integer "user_id" @@ -464,16 +464,16 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "environment", default: "development" t.string "server", default: "test" t.boolean "test_mode", default: true - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_inventory_units", force: true do |t| t.string "state" t.integer "variant_id" t.integer "order_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "shipment_id" t.integer "return_authorization_id" t.boolean "pending", default: true @@ -488,8 +488,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "variant_id" t.integer "quantity", null: false t.decimal "price", precision: 8, scale: 2, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "max_quantity" t.string "currency" t.decimal "distribution_fee", precision: 10, scale: 2 @@ -505,22 +505,22 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "source_id" t.string "source_type" t.text "details" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_mail_methods", force: true do |t| t.string "environment" t.boolean "active", default: true - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_option_types", force: true do |t| t.string "name", limit: 100 t.string "presentation", limit: 100 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "position", default: 0, null: false end @@ -529,8 +529,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "name" t.string "presentation" t.integer "option_type_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_option_values_line_items", id: false, force: true do |t| @@ -555,8 +555,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "state" t.decimal "adjustment_total", precision: 10, scale: 2, default: 0.0, null: false t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.datetime "completed_at" t.integer "bill_address_id" t.integer "ship_address_id" @@ -586,8 +586,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.text "description" t.boolean "active", default: true t.string "environment", default: "development" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.datetime "deleted_at" t.string "display_on" end @@ -595,8 +595,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_payments", force: true do |t| t.decimal "amount", precision: 10, scale: 2, default: 0.0, null: false t.integer "order_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "source_id" t.string "source_type" t.integer "payment_method_id" @@ -640,8 +640,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_preferences", force: true do |t| t.text "value" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "key" t.string "value_type" end @@ -675,16 +675,16 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "position" t.integer "product_id" t.integer "option_type_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_product_properties", force: true do |t| t.string "value" t.integer "product_id" t.integer "property_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "position", default: 0 end @@ -709,8 +709,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "meta_keywords" t.integer "tax_category_id" t.integer "shipping_category_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "supplier_id" t.boolean "group_buy" t.float "group_buy_unit_size" @@ -762,8 +762,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "user_id" t.integer "product_group_id" t.string "type" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "spree_promotion_rules", ["product_group_id"], name: "index_promotion_rules_on_product_group_id", using: :btree @@ -780,8 +780,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_properties", force: true do |t| t.string "name" t.string "presentation", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_return_authorizations", force: true do |t| @@ -790,8 +790,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.decimal "amount", precision: 10, scale: 2, default: 0.0, null: false t.integer "order_id" t.text "reason" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "stock_location_id" end @@ -814,8 +814,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.datetime "shipped_at" t.integer "order_id" t.integer "address_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "state" t.integer "stock_location_id" end @@ -825,16 +825,16 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_shipping_categories", force: true do |t| t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "temperature_controlled", default: false, null: false end create_table "spree_shipping_method_categories", force: true do |t| t.integer "shipping_method_id", null: false t.integer "shipping_category_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "spree_shipping_method_categories", ["shipping_category_id"], name: "index_spree_shipping_method_categories_on_shipping_category_id", using: :btree @@ -842,8 +842,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_shipping_methods", force: true do |t| t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "display_on" t.datetime "deleted_at" t.boolean "require_ship_address", default: true @@ -861,8 +861,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "shipping_method_id" t.boolean "selected", default: false t.decimal "cost", precision: 8, scale: 2, default: 0.0 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "spree_shipping_rates", ["shipment_id", "shipping_method_id"], name: "spree_shipping_rates_join_index", unique: true, using: :btree @@ -874,8 +874,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "transaction_id" t.integer "customer_id" t.string "payment_type" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_state_changes", force: true do |t| @@ -883,8 +883,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "previous_state" t.integer "stateful_id" t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "stateful_type" t.string "next_state" end @@ -899,8 +899,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "stock_location_id" t.integer "variant_id" t.integer "count_on_hand", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "backorderable", default: false t.datetime "deleted_at" end @@ -911,8 +911,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_stock_locations", force: true do |t| t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "address1" t.string "address2" t.string "city" @@ -930,8 +930,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "stock_item_id" t.integer "quantity", default: 0 t.string "action" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "originator_id" t.string "originator_type" end @@ -943,8 +943,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "reference" t.integer "source_location_id" t.integer "destination_location_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "number" end @@ -955,8 +955,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_tax_categories", force: true do |t| t.string "name" t.string "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "is_default", default: false t.datetime "deleted_at" end @@ -965,8 +965,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.decimal "amount", precision: 8, scale: 5 t.integer "zone_id" t.integer "tax_category_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "included_in_price", default: false t.string "name" t.boolean "show_rate_in_label", default: true @@ -975,8 +975,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "spree_taxonomies", force: true do |t| t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "position", default: 0 end @@ -986,8 +986,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "name", null: false t.string "permalink" t.integer "taxonomy_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "lft" t.integer "rgt" t.string "icon_file_name" @@ -1008,8 +1008,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "permissable_id" t.string "permissable_type" t.string "token" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "spree_tokenized_permissions", ["permissable_id", "permissable_type"], name: "index_tokenized_name_and_type", using: :btree @@ -1018,8 +1018,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "environment" t.string "analytics_id" t.boolean "active", default: true - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_users", force: true do |t| @@ -1040,8 +1040,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.string "login" t.integer "ship_address_id" t.integer "bill_address_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "authentication_token" t.string "unlock_token" t.datetime "locked_at" @@ -1087,15 +1087,15 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "zoneable_id" t.string "zoneable_type" t.integer "zone_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "spree_zones", force: true do |t| t.string "name" t.string "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "default_tax", default: false t.integer "zone_members_count", default: 0 end @@ -1103,8 +1103,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "stripe_accounts", force: true do |t| t.string "stripe_user_id" t.string "stripe_publishable_key" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "enterprise_id" end @@ -1114,8 +1114,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "subscription_id", null: false t.integer "variant_id", null: false t.integer "quantity", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.decimal "price_estimate", precision: 8, scale: 2 end @@ -1130,8 +1130,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do t.integer "shipping_method_id", null: false t.datetime "begins_at" t.datetime "ends_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "bill_address_id", null: false t.integer "ship_address_id", null: false t.datetime "canceled_at" @@ -1159,8 +1159,8 @@ ActiveRecord::Schema.define(:version => 20191023172424) do create_table "tag_rules", force: true do |t| t.integer "enterprise_id", null: false t.string "type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "is_default", default: false, null: false t.integer "priority", default: 99, null: false end From f06a4fb1d02eaba4c019306e8190f6a51c311891 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 18 Feb 2020 19:04:28 +0000 Subject: [PATCH 054/507] This configuration is no longer needed as this is the default behaviour in rails 4 --- config/initializers/wrap_parameters.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index 999df20181..c2f744d290 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -7,8 +7,3 @@ ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] end - -# Disable root element in JSON by default. -ActiveSupport.on_load(:active_record) do - self.include_root_in_json = false -end From 10c6e5ad9bea92dc5029013c80bc45a00c23f22c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 22 Feb 2020 11:24:30 +0000 Subject: [PATCH 055/507] Rebuild rubocop todo after latest rebase --- .rubocop_todo.yml | 482 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 405 insertions(+), 77 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 7be6d93eb5..d77216e023 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,19 +1,11 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 1400` -# on 2019-12-22 15:36:14 +0100 using RuboCop version 0.78.0. +# on 2020-02-22 11:23:29 +0000 using RuboCop version 0.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: TreatCommentsAsGroupSeparators, Include. -# Include: **/*.gemfile, **/Gemfile, **/gems.rb -Bundler/OrderedGems: - Exclude: - - 'Gemfile' - # Offense count: 6 # Cop supports --auto-correct. Layout/EmptyLineAfterGuardClause: @@ -45,7 +37,7 @@ Layout/EndAlignment: Exclude: - 'lib/open_food_network/permalink_generator.rb' -# Offense count: 3 +# Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. # SupportedHashRocketStyles: key, separator, table @@ -53,24 +45,23 @@ Layout/EndAlignment: # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit Layout/HashAlignment: Exclude: - - 'app/models/enterprise.rb' - 'spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb' -# Offense count: 9 +# Offense count: 8 # Cop supports --auto-correct. -# Configuration parameters: AllowDoxygenCommentStyle. +# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment. Layout/LeadingCommentSpace: Exclude: - 'Gemfile' - 'app/helpers/application_helper.rb' - 'app/models/enterprise.rb' -# Offense count: 27 +# Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Layout/LineLength: - Max: 129 + Max: 115 # Offense count: 1 # Cop supports --auto-correct. @@ -87,14 +78,26 @@ Layout/SpaceAroundOperators: - 'app/services/cart_service.rb' - 'spec/support/cancan_helper.rb' -# Offense count: 4 +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'spec/controllers/checkout_controller_spec.rb' + +# Offense count: 2 Lint/AmbiguousOperator: Exclude: - - 'app/controllers/spree/admin/orders/customer_details_controller_decorator.rb' - - 'app/controllers/spree/admin/orders_controller_decorator.rb' - 'spec/controllers/api/enterprise_fees_controller_spec.rb' - 'spec/controllers/spree/admin/payments_controller_spec.rb' +# Offense count: 2 +Lint/Debugger: + Exclude: + - 'app/services/order_factory.rb' + # Offense count: 1 Lint/DuplicateHashKey: Exclude: @@ -162,10 +165,20 @@ Lint/Void: Exclude: - 'app/serializers/api/enterprise_serializer.rb' +# Offense count: 1 +Metrics/AbcSize: + Max: 16 + +# Offense count: 1 +# Configuration parameters: CountComments, ExcludedMethods. +# ExcludedMethods: refine +Metrics/BlockLength: + Max: 27 + # Offense count: 1 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 114 + Max: 121 # Offense count: 8 Naming/AccessorMethodName: @@ -183,34 +196,18 @@ Naming/HeredocDelimiterNaming: Exclude: - 'app/models/content_configuration.rb' -# Offense count: 5 +# Offense count: 3 # Configuration parameters: EnforcedStyleForLeadingUnderscores. # SupportedStylesForLeadingUnderscores: disallowed, required, optional Naming/MemoizedInstanceVariableName: Exclude: - - 'app/controllers/spree/admin/payments_controller_decorator.rb' - 'lib/open_food_network/address_finder.rb' - - 'lib/spree/authentication_helpers.rb' -# Offense count: 8 +# Offense count: 7 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: io, id, to, by, on, in, at, ip, db, os +# AllowedNames: io, id, to, by, on, in, at, ip, db, os, pp Naming/MethodParameterName: Exclude: - - 'app/helpers/spree/admin/base_helper_decorator.rb' - - 'app/helpers/spree/base_helper_decorator.rb' - - 'app/services/subscription_validator.rb' - - 'lib/open_food_network/reports/bulk_coop_report.rb' - - 'lib/open_food_network/xero_invoices_report.rb' - - 'spec/lib/open_food_network/reports/report_spec.rb' - - 'spec/mailers/producer_mailer_spec.rb' - -# Offense count: 8 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: io, id, to, by, on, in, at, ip, db, os -Naming/MethodParameterName: - Exclude: - - 'app/helpers/spree/admin/base_helper_decorator.rb' - 'app/helpers/spree/base_helper_decorator.rb' - 'app/services/subscription_validator.rb' - 'lib/open_food_network/reports/bulk_coop_report.rb' @@ -245,19 +242,359 @@ Naming/PredicateName: - 'lib/open_food_network/packing_report.rb' - 'lib/tasks/data.rake' -# Offense count: 13 +# Offense count: 154 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: braces, no_braces, context_dependent -Style/BracesAroundHashParameters: +# Configuration parameters: EnforcedStyle, Include. +# SupportedStyles: action, filter +# Include: app/controllers/**/*.rb +Rails/ActionFilter: Exclude: - - 'app/models/spree/payment_decorator.rb' - - 'lib/open_food_network/variant_and_line_item_naming.rb' + - 'app/controllers/admin/column_preferences_controller.rb' + - 'app/controllers/admin/customers_controller.rb' + - 'app/controllers/admin/enterprise_fees_controller.rb' + - 'app/controllers/admin/enterprise_groups_controller.rb' + - 'app/controllers/admin/enterprises_controller.rb' + - 'app/controllers/admin/order_cycles_controller.rb' + - 'app/controllers/admin/producer_properties_controller.rb' + - 'app/controllers/admin/product_import_controller.rb' + - 'app/controllers/admin/schedules_controller.rb' + - 'app/controllers/admin/stripe_connect_settings_controller.rb' + - 'app/controllers/admin/subscription_line_items_controller.rb' + - 'app/controllers/admin/subscriptions_controller.rb' + - 'app/controllers/admin/variant_overrides_controller.rb' + - 'app/controllers/api/base_controller.rb' + - 'app/controllers/api/enterprise_attachment_controller.rb' + - 'app/controllers/api/enterprises_controller.rb' + - 'app/controllers/api/shipments_controller.rb' + - 'app/controllers/api/variants_controller.rb' + - 'app/controllers/application_controller.rb' + - 'app/controllers/base_controller.rb' + - 'app/controllers/cart_controller.rb' + - 'app/controllers/checkout_controller.rb' + - 'app/controllers/discourse_sso_controller.rb' + - 'app/controllers/enterprises_controller.rb' + - 'app/controllers/home_controller.rb' + - 'app/controllers/line_items_controller.rb' + - 'app/controllers/producers_controller.rb' + - 'app/controllers/registration_controller.rb' + - 'app/controllers/shop_controller.rb' + - 'app/controllers/shops_controller.rb' + - 'app/controllers/spree/admin/adjustments_controller.rb' + - 'app/controllers/spree/admin/base_controller.rb' + - 'app/controllers/spree/admin/images_controller.rb' + - 'app/controllers/spree/admin/mail_methods_controller.rb' + - 'app/controllers/spree/admin/orders/customer_details_controller.rb' + - 'app/controllers/spree/admin/orders_controller.rb' + - 'app/controllers/spree/admin/payment_methods_controller.rb' + - 'app/controllers/spree/admin/payments_controller.rb' + - 'app/controllers/spree/admin/product_properties_controller.rb' + - 'app/controllers/spree/admin/products_controller.rb' + - 'app/controllers/spree/admin/reports/enterprise_fee_summaries_controller.rb' + - 'app/controllers/spree/admin/reports_controller.rb' + - 'app/controllers/spree/admin/resource_controller.rb' + - 'app/controllers/spree/admin/search_controller.rb' + - 'app/controllers/spree/admin/shipping_methods_controller.rb' + - 'app/controllers/spree/admin/states_controller.rb' + - 'app/controllers/spree/admin/tax_rates_controller.rb' + - 'app/controllers/spree/admin/users_controller.rb' + - 'app/controllers/spree/admin/zones_controller.rb' + - 'app/controllers/spree/orders_controller.rb' + - 'app/controllers/spree/store_controller.rb' + - 'app/controllers/spree/user_registrations_controller.rb' + - 'app/controllers/spree/user_sessions_controller.rb' + - 'app/controllers/spree/users_controller.rb' + - 'app/controllers/stripe/webhooks_controller.rb' + - 'app/controllers/user_passwords_controller.rb' + - 'app/controllers/user_registrations_controller.rb' + +# Offense count: 192 +# Cop supports --auto-correct. +Rails/ActiveRecordAliases: + Exclude: + - 'app/controllers/admin/bulk_line_items_controller.rb' + - 'app/controllers/admin/enterprises_controller.rb' + - 'app/controllers/admin/subscriptions_controller.rb' + - 'app/controllers/api/customers_controller.rb' + - 'app/controllers/api/enterprise_attachment_controller.rb' + - 'app/controllers/api/enterprises_controller.rb' + - 'app/controllers/api/product_images_controller.rb' + - 'app/controllers/api/products_controller.rb' + - 'app/controllers/api/shipments_controller.rb' + - 'app/controllers/api/taxons_controller.rb' + - 'app/controllers/api/variants_controller.rb' + - 'app/controllers/checkout_controller.rb' + - 'app/controllers/spree/admin/orders/customer_details_controller.rb' + - 'app/controllers/spree/admin/orders_controller.rb' + - 'app/controllers/spree/admin/payment_methods_controller.rb' + - 'app/controllers/spree/admin/resource_controller.rb' + - 'app/controllers/spree/admin/taxons_controller.rb' + - 'app/controllers/spree/admin/users_controller.rb' + - 'app/controllers/spree/credit_cards_controller.rb' + - 'app/controllers/spree/orders_controller.rb' + - 'app/controllers/spree/users_controller.rb' + - 'app/helpers/i18n_helper.rb' + - 'app/jobs/subscription_placement_job.rb' + - 'app/models/spree/adjustment_decorator.rb' + - 'app/models/spree/line_item_decorator.rb' + - 'app/models/spree/product_set.rb' + - 'app/services/line_item_syncer.rb' + - 'app/services/order_factory.rb' + - 'app/services/order_syncer.rb' + - 'app/services/user_default_address_setter.rb' + - 'lib/open_food_network/order_cycle_form_applicator.rb' + - 'lib/open_food_network/subscription_payment_updater.rb' + - 'lib/stripe/profile_storer.rb' + - 'spec/controllers/admin/proxy_orders_controller_spec.rb' + - 'spec/controllers/admin/subscriptions_controller_spec.rb' + - 'spec/controllers/api/orders_controller_spec.rb' + - 'spec/controllers/line_items_controller_spec.rb' + - 'spec/controllers/spree/admin/payment_methods_controller_spec.rb' + - 'spec/controllers/spree/orders_controller_spec.rb' + - 'spec/features/admin/order_cycles_spec.rb' + - 'spec/features/admin/subscriptions_spec.rb' + - 'spec/features/admin/variant_overrides_spec.rb' + - 'spec/features/admin/variants_spec.rb' + - 'spec/features/consumer/account_spec.rb' - 'spec/features/consumer/registration_spec.rb' - - 'spec/models/enterprise_fee_spec.rb' + - 'spec/features/consumer/shopping/cart_spec.rb' + - 'spec/features/consumer/shopping/orders_spec.rb' + - 'spec/features/consumer/shopping/shopping_spec.rb' + - 'spec/jobs/subscription_confirm_job_spec.rb' + - 'spec/jobs/subscription_placement_job_spec.rb' + - 'spec/lib/open_food_network/proxy_order_syncer_spec.rb' + - 'spec/models/customer_spec.rb' + - 'spec/models/enterprise_caching_spec.rb' + - 'spec/models/exchange_spec.rb' + - 'spec/models/order_cycle_spec.rb' + - 'spec/models/producer_property_spec.rb' + - 'spec/models/proxy_order_spec.rb' + - 'spec/models/spree/adjustment_spec.rb' + - 'spec/models/spree/credit_card_spec.rb' + - 'spec/models/spree/line_item_spec.rb' + - 'spec/models/spree/order_spec.rb' - 'spec/models/spree/product_spec.rb' + - 'spec/models/spree/user_spec.rb' + - 'spec/models/spree/variant_spec.rb' + - 'spec/requests/checkout/stripe_connect_spec.rb' + - 'spec/services/order_syncer_spec.rb' + - 'spec/services/subscription_estimator_spec.rb' + +# Offense count: 1 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: strict, flexible +Rails/Date: + Exclude: + - 'app/models/order_cycle.rb' + +# Offense count: 5 +# Cop supports --auto-correct. +# Configuration parameters: Whitelist. +# Whitelist: find_by_sql +Rails/DynamicFindBy: + Exclude: + - 'app/controllers/spree/admin/orders/customer_details_controller.rb' + - 'app/controllers/spree/admin/orders_controller.rb' + - 'app/controllers/spree/admin/payments_controller.rb' + - 'app/controllers/spree/admin/products_controller.rb' + - 'spec/support/request/web_helper.rb' + +# Offense count: 16 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: slashes, arguments +Rails/FilePath: + Exclude: + - 'app/models/product_import/product_importer.rb' + - 'lib/tasks/karma.rake' + - 'spec/controllers/api/logos_controller_spec.rb' + - 'spec/controllers/api/product_images_controller_spec.rb' + - 'spec/controllers/api/promo_images_controller_spec.rb' + - 'spec/factories/product_factory.rb' + - 'spec/features/admin/content_spec.rb' + - 'spec/features/admin/enterprises/images_spec.rb' + - 'spec/models/content_configuration_spec.rb' + - 'spec/models/spree/variant_spec.rb' + - 'spec/serializers/api/admin/enterprise_serializer_spec.rb' + - 'spec/support/downloads_helper.rb' + +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/FindBy: + Exclude: + - 'app/models/enterprise.rb' + - 'app/models/product_import/entry_processor.rb' + - 'app/models/product_import/entry_validator.rb' + - 'app/models/product_import/spreadsheet_data.rb' + - 'app/models/spree/user.rb' + +# Offense count: 7 +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/HasAndBelongsToMany: + Exclude: + - 'app/models/enterprise.rb' + - 'app/models/enterprise_group.rb' + - 'app/models/order_cycle.rb' + - 'app/models/schedule.rb' + - 'app/models/spree/concerns/payment_method_distributors.rb' + - 'app/models/spree/line_item_decorator.rb' + +# Offense count: 24 +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/HasManyOrHasOneDependent: + Exclude: + - 'app/models/customer.rb' + - 'app/models/enterprise.rb' + - 'app/models/order_cycle.rb' + - 'app/models/spree/adjustment_decorator.rb' + - 'app/models/spree/order_decorator.rb' + - 'app/models/spree/payment_method_decorator.rb' + - 'app/models/spree/property_decorator.rb' + - 'app/models/spree/shipping_method_decorator.rb' + - 'app/models/spree/user.rb' + - 'app/models/spree/variant_decorator.rb' + - 'app/models/subscription.rb' + +# Offense count: 83 +# Configuration parameters: Include. +# Include: app/helpers/**/*.rb +Rails/HelperInstanceVariable: + Exclude: + - 'app/helpers/admin/injection_helper.rb' + - 'app/helpers/angular_form_builder.rb' + - 'app/helpers/application_helper.rb' + - 'app/helpers/enterprises_helper.rb' + - 'app/helpers/injection_helper.rb' + - 'app/helpers/order_cycles_helper.rb' + - 'app/helpers/shared_helper.rb' + - 'app/helpers/shop_helper.rb' + - 'app/helpers/spree/admin/orders_helper.rb' + - 'app/helpers/spree/orders_helper.rb' + +# Offense count: 1 +# Configuration parameters: Include. +# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb +Rails/Output: + Exclude: + - 'app/services/order_factory.rb' + +# Offense count: 12 +Rails/OutputSafety: + Exclude: + - 'app/controllers/spree/admin/reports_controller.rb' + - 'app/helpers/angular_form_helper.rb' + - 'app/helpers/spree/admin/base_helper.rb' + - 'app/helpers/spree/admin/navigation_helper.rb' + - 'app/helpers/spree/admin/orders_helper.rb' + - 'app/helpers/spree/admin/zones_helper.rb' + - 'app/helpers/spree/reports_helper.rb' + - 'app/serializers/api/product_serializer.rb' + - 'lib/spree/money_decorator.rb' + - 'spec/features/admin/orders_spec.rb' + +# Offense count: 2 +# Configuration parameters: Include. +# Include: **/Rakefile, **/*.rake +Rails/RakeEnvironment: + Exclude: + - 'lib/tasks/specs.rake' + +# Offense count: 9 +Rails/ReflectionClassName: + Exclude: + - 'app/models/customer.rb' + - 'app/models/distributor_shipping_method.rb' + - 'app/models/enterprise_role.rb' + - 'app/models/subscription.rb' + +# Offense count: 213 +# Configuration parameters: Blacklist, Whitelist. +# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters +Rails/SkipsModelValidations: + Exclude: + - 'app/controllers/spree/admin/payment_methods_controller.rb' + - 'app/controllers/spree/admin/resource_controller.rb' + - 'app/controllers/spree/admin/shipping_methods_controller.rb' + - 'app/controllers/spree/admin/taxons_controller.rb' + - 'app/controllers/spree/orders_controller.rb' + - 'app/jobs/subscription_confirm_job.rb' + - 'app/jobs/subscription_placement_job.rb' + - 'app/models/enterprise.rb' + - 'app/models/enterprise_relationship.rb' + - 'app/models/product_import/inventory_reset_strategy.rb' + - 'app/models/proxy_order.rb' + - 'app/models/spree/address_decorator.rb' + - 'app/models/spree/credit_card_decorator.rb' + - 'app/models/spree/order_decorator.rb' + - 'app/models/spree/payment_decorator.rb' + - 'app/models/subscription.rb' + - 'app/models/variant_override.rb' + - 'app/services/order_factory.rb' + - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb' + - 'lib/tasks/data/anonymize_data.rake' + - 'lib/tasks/sample_data/product_factory.rb' + - 'lib/tasks/users.rake' + - 'spec/controllers/admin/subscription_line_items_controller_spec.rb' + - 'spec/controllers/admin/variant_overrides_controller_spec.rb' + - 'spec/controllers/api/order_cycles_controller_spec.rb' + - 'spec/controllers/api/orders_controller_spec.rb' + - 'spec/controllers/api/products_controller_spec.rb' + - 'spec/controllers/api/shipments_controller_spec.rb' + - 'spec/controllers/api/variants_controller_spec.rb' + - 'spec/controllers/checkout_controller_spec.rb' + - 'spec/controllers/enterprises_controller_spec.rb' + - 'spec/controllers/spree/admin/orders_controller_spec.rb' + - 'spec/controllers/spree/admin/overview_controller_spec.rb' + - 'spec/controllers/spree/admin/payment_methods_controller_spec.rb' + - 'spec/controllers/spree/credit_cards_controller_spec.rb' + - 'spec/factories.rb' + - 'spec/factories/order_factory.rb' + - 'spec/features/admin/bulk_order_management_spec.rb' + - 'spec/features/admin/bulk_product_update_spec.rb' + - 'spec/features/admin/configuration/tax_rates_spec.rb' + - 'spec/features/admin/order_cycles_spec.rb' + - 'spec/features/admin/orders_spec.rb' + - 'spec/features/admin/reports_spec.rb' + - 'spec/features/consumer/shopping/checkout_spec.rb' + - 'spec/features/consumer/shopping/products_spec.rb' + - 'spec/features/consumer/shopping/shopping_spec.rb' + - 'spec/helpers/enterprises_helper_spec.rb' + - 'spec/helpers/order_cycles_helper_spec.rb' + - 'spec/jobs/subscription_placement_job_spec.rb' + - 'spec/lib/open_food_network/address_finder_spec.rb' + - 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb' + - 'spec/lib/open_food_network/permissions_spec.rb' + - 'spec/lib/open_food_network/products_and_inventory_report_spec.rb' + - 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb' + - 'spec/lib/open_food_network/subscription_payment_updater_spec.rb' + - 'spec/models/calculator/weight_spec.rb' + - 'spec/models/concerns/variant_stock_spec.rb' + - 'spec/models/enterprise_relationship_spec.rb' + - 'spec/models/exchange_spec.rb' + - 'spec/models/spree/adjustment_spec.rb' + - 'spec/models/spree/line_item_spec.rb' + - 'spec/models/spree/order_spec.rb' + - 'spec/models/spree/product_spec.rb' + - 'spec/models/spree/variant_spec.rb' - 'spec/models/tag_rule/discount_order_spec.rb' - - 'spec/support/seeds.rb' + - 'spec/performance/proxy_order_syncer_spec.rb' + - 'spec/serializers/api/admin/subscription_line_item_serializer_spec.rb' + - 'spec/services/order_cycle_distributed_products_spec.rb' + - 'spec/services/order_factory_spec.rb' + - 'spec/services/order_syncer_spec.rb' + - 'spec/services/product_tag_rules_filterer_spec.rb' + - 'spec/services/products_renderer_spec.rb' + - 'spec/services/restart_checkout_spec.rb' + - 'spec/support/request/shop_workflow.rb' + +# Offense count: 1 +# Configuration parameters: Environments. +# Environments: development, test, production +Rails/UnknownEnv: + Exclude: + - 'app/models/spree/app_configuration_decorator.rb' # Offense count: 2 Style/CaseEquality: @@ -372,10 +709,10 @@ Style/FormatStringToken: - 'lib/open_food_network/sales_tax_report.rb' - 'spec/features/admin/bulk_order_management_spec.rb' -# Offense count: 925 +# Offense count: 920 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. -# SupportedStyles: always, never +# SupportedStyles: always, always_true, never Style/FrozenStringLiteralComment: Exclude: - 'Gemfile' @@ -410,7 +747,6 @@ Style/FrozenStringLiteralComment: - 'app/controllers/api/enterprise_attachment_controller.rb' - 'app/controllers/api/enterprise_fees_controller.rb' - 'app/controllers/api/enterprises_controller.rb' - - 'app/controllers/api/exchange_products_controller.rb' - 'app/controllers/api/logos_controller.rb' - 'app/controllers/api/order_cycles_controller.rb' - 'app/controllers/api/orders_controller.rb' @@ -425,7 +761,6 @@ Style/FrozenStringLiteralComment: - 'app/controllers/application_controller.rb' - 'app/controllers/base_controller.rb' - 'app/controllers/cart_controller.rb' - - 'app/controllers/checkout_controller.rb' - 'app/controllers/discourse_sso_controller.rb' - 'app/controllers/enterprises_controller.rb' - 'app/controllers/groups_controller.rb' @@ -446,19 +781,18 @@ Style/FrozenStringLiteralComment: - 'app/controllers/spree/admin/images_controller.rb' - 'app/controllers/spree/admin/invoices_controller.rb' - 'app/controllers/spree/admin/mail_methods_controller.rb' - - 'app/controllers/spree/admin/orders/customer_details_controller_decorator.rb' - - 'app/controllers/spree/admin/orders_controller_decorator.rb' + - 'app/controllers/spree/admin/orders/customer_details_controller.rb' + - 'app/controllers/spree/admin/orders_controller.rb' - 'app/controllers/spree/admin/overview_controller.rb' - 'app/controllers/spree/admin/payment_methods_controller.rb' - - 'app/controllers/spree/admin/payments_controller_decorator.rb' - 'app/controllers/spree/admin/product_properties_controller.rb' - - 'app/controllers/spree/admin/products_controller_decorator.rb' + - 'app/controllers/spree/admin/products_controller.rb' - 'app/controllers/spree/admin/properties_controller.rb' - 'app/controllers/spree/admin/reports/enterprise_fee_summaries_controller.rb' - 'app/controllers/spree/admin/reports_controller.rb' - - 'app/controllers/spree/admin/resource_controller_decorator.rb' + - 'app/controllers/spree/admin/resource_controller.rb' - 'app/controllers/spree/admin/return_authorizations_controller.rb' - - 'app/controllers/spree/admin/search_controller_decorator.rb' + - 'app/controllers/spree/admin/search_controller.rb' - 'app/controllers/spree/admin/shipping_categories_controller.rb' - 'app/controllers/spree/admin/shipping_methods_controller.rb' - 'app/controllers/spree/admin/states_controller.rb' @@ -468,9 +802,8 @@ Style/FrozenStringLiteralComment: - 'app/controllers/spree/admin/taxonomies_controller.rb' - 'app/controllers/spree/admin/taxons_controller.rb' - 'app/controllers/spree/admin/users_controller.rb' - - 'app/controllers/spree/admin/variants_controller_decorator.rb' + - 'app/controllers/spree/admin/variants_controller.rb' - 'app/controllers/spree/admin/zones_controller.rb' - - 'app/controllers/spree/checkout_controller.rb' - 'app/controllers/spree/credit_cards_controller.rb' - 'app/controllers/spree/home_controller.rb' - 'app/controllers/spree/orders_controller.rb' @@ -484,6 +817,7 @@ Style/FrozenStringLiteralComment: - 'app/controllers/user_confirmations_controller.rb' - 'app/controllers/user_passwords_controller.rb' - 'app/controllers/user_registrations_controller.rb' + - 'app/helpers/admin/enterprises_helper.rb' - 'app/helpers/admin/image_settings_helper.rb' - 'app/helpers/admin/injection_helper.rb' - 'app/helpers/admin/orders_helper.rb' @@ -502,16 +836,16 @@ Style/FrozenStringLiteralComment: - 'app/helpers/injection_helper.rb' - 'app/helpers/map_helper.rb' - 'app/helpers/markdown_helper.rb' - - 'app/helpers/order_cycles_helper.rb' - 'app/helpers/serializer_helper.rb' - 'app/helpers/shared_helper.rb' - 'app/helpers/shop_helper.rb' - 'app/helpers/shop_mail_helper.rb' - - 'app/helpers/spree/admin/base_helper_decorator.rb' + - 'app/helpers/spree/admin/base_helper.rb' - 'app/helpers/spree/admin/general_settings_helper.rb' - - 'app/helpers/spree/admin/navigation_helper_decorator.rb' - - 'app/helpers/spree/admin/orders_helper_decorator.rb' + - 'app/helpers/spree/admin/orders_helper.rb' + - 'app/helpers/spree/admin/payments_helper.rb' - 'app/helpers/spree/admin/taxons_helper.rb' + - 'app/helpers/spree/admin/zones_helper.rb' - 'app/helpers/spree/api/api_helpers.rb' - 'app/helpers/spree/base_helper_decorator.rb' - 'app/helpers/spree/orders_helper.rb' @@ -639,7 +973,6 @@ Style/FrozenStringLiteralComment: - 'app/models/tag_rule/filter_shipping_methods.rb' - 'app/models/variant_override.rb' - 'app/models/variant_override_set.rb' - - 'app/presenters/variant_presenter.rb' - 'app/serializers/api/address_serializer.rb' - 'app/serializers/api/adjustment_serializer.rb' - 'app/serializers/api/admin/basic_enterprise_fee_serializer.rb' @@ -719,6 +1052,7 @@ Style/FrozenStringLiteralComment: - 'app/serializers/api/uncached_enterprise_serializer.rb' - 'app/serializers/api/user_serializer.rb' - 'app/serializers/api/variant_serializer.rb' + - 'app/services/action_callbacks.rb' - 'app/services/advance_order_service.rb' - 'app/services/bulk_invoice_service.rb' - 'app/services/cart_service.rb' @@ -727,7 +1061,6 @@ Style/FrozenStringLiteralComment: - 'app/services/default_shipping_category.rb' - 'app/services/default_stock_location.rb' - 'app/services/embedded_page_service.rb' - - 'app/services/exchange_products_renderer.rb' - 'app/services/exchange_variant_bulk_updater.rb' - 'app/services/exchange_variant_deleter.rb' - 'app/services/invoice_renderer.rb' @@ -826,7 +1159,6 @@ Style/FrozenStringLiteralComment: - 'lib/open_food_network/lettuce_share_report.rb' - 'lib/open_food_network/locking.rb' - 'lib/open_food_network/model_class_from_controller_name.rb' - - 'lib/open_food_network/option_value_namer.rb' - 'lib/open_food_network/order_and_distributor_report.rb' - 'lib/open_food_network/order_cycle_form_applicator.rb' - 'lib/open_food_network/order_cycle_management_report.rb' @@ -964,7 +1296,6 @@ Style/FrozenStringLiteralComment: - 'spec/controllers/spree/admin/shipping_methods_controller_spec.rb' - 'spec/controllers/spree/admin/users_controller_spec.rb' - 'spec/controllers/spree/admin/variants_controller_spec.rb' - - 'spec/controllers/spree/checkout_controller_spec.rb' - 'spec/controllers/spree/credit_cards_controller_spec.rb' - 'spec/controllers/spree/orders_controller_spec.rb' - 'spec/controllers/spree/store_controller_spec.rb' @@ -1243,6 +1574,7 @@ Style/FrozenStringLiteralComment: - 'spec/services/order_cycle_distributed_products_spec.rb' - 'spec/services/order_cycle_distributed_variants_spec.rb' - 'spec/services/order_cycle_form_spec.rb' + - 'spec/services/order_cycle_warning_spec.rb' - 'spec/services/order_factory_spec.rb' - 'spec/services/order_syncer_spec.rb' - 'spec/services/permissions/order_spec.rb' @@ -1304,7 +1636,7 @@ Style/FrozenStringLiteralComment: - 'spec/views/spree/admin/orders/edit.html.haml_spec.rb' - 'spec/views/spree/admin/orders/index.html.haml_spec.rb' -# Offense count: 59 +# Offense count: 50 # Configuration parameters: MinBodyLength. Style/GuardClause: Exclude: @@ -1315,9 +1647,6 @@ Style/GuardClause: - 'app/controllers/base_controller.rb' - 'app/controllers/checkout_controller.rb' - 'app/controllers/home_controller.rb' - - 'app/controllers/spree/admin/orders_controller_decorator.rb' - - 'app/controllers/spree/admin/variants_controller_decorator.rb' - - 'app/controllers/spree/checkout_controller.rb' - 'app/controllers/spree/orders_controller.rb' - 'app/models/enterprise.rb' - 'app/models/enterprise_group.rb' @@ -1338,14 +1667,13 @@ Style/GuardClause: - 'spec/support/request/distribution_helper.rb' - 'spec/support/request/shop_workflow.rb' -# Offense count: 4 +# Offense count: 3 # Configuration parameters: AllowIfModifier. Style/IfInsideElse: Exclude: - 'app/controllers/admin/column_preferences_controller.rb' - 'app/controllers/admin/variant_overrides_controller.rb' - 'app/controllers/api/taxons_controller.rb' - - 'app/controllers/spree/admin/products_controller_decorator.rb' # Offense count: 1 # Cop supports --auto-correct. @@ -1381,7 +1709,7 @@ Style/NegatedUnless: Exclude: - 'app/services/cart_service.rb' -# Offense count: 42 +# Offense count: 41 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. # SupportedStyles: predicate, comparison @@ -1413,16 +1741,17 @@ Style/NumericPredicate: - 'lib/spree/money_decorator.rb' - 'lib/tasks/sample_data.rake' -# Offense count: 15 +# Offense count: 16 # Cop supports --auto-correct. # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods. # AllowedMethods: present?, blank?, presence, try, try! Style/SafeNavigation: Exclude: - - 'app/controllers/checkout_controller.rb' + - 'app/controllers/spree/admin/payments_controller.rb' - 'app/controllers/spree/credit_cards_controller.rb' - 'app/controllers/spree/orders_controller.rb' - 'app/helpers/i18n_helper.rb' + - 'app/helpers/shop_helper.rb' - 'app/models/producer_property.rb' - 'app/models/product_import/entry_validator.rb' - 'app/models/product_import/product_importer.rb' @@ -1430,10 +1759,9 @@ Style/SafeNavigation: - 'lib/discourse/single_sign_on.rb' - 'spec/factories.rb' -# Offense count: 235 +# Offense count: 232 Style/Send: Exclude: - - 'app/controllers/spree/checkout_controller.rb' - 'app/models/spree/shipping_method_decorator.rb' - 'spec/controllers/admin/subscriptions_controller_spec.rb' - 'spec/controllers/checkout_controller_spec.rb' From 1dc7b5793c4a323b1e79c862698974469db53c06 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 21 Feb 2020 13:55:56 +0000 Subject: [PATCH 056/507] Fix Enterprise validation and factory so that users are added after the validation --- app/models/enterprise.rb | 4 ++-- spec/factories/enterprise_factory.rb | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 42177ad7b5..3c356134fc 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -93,9 +93,9 @@ class Enterprise < ActiveRecord::Base validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? } before_validation :initialize_permalink, if: lambda { permalink.nil? } - before_validation :ensure_owner_is_manager, if: lambda { owner_id_changed? && !owner_id.nil? } before_validation :set_unused_address_fields after_validation :geocode_address + after_validation :ensure_owner_is_manager, if: lambda { owner_id_changed? && !owner_id.nil? } after_touch :touch_distributors after_create :set_default_contact @@ -410,7 +410,7 @@ class Enterprise < ActiveRecord::Base end def ensure_owner_is_manager - #users << owner unless users.include?(owner) + users << owner unless users.include?(owner) end def enforce_ownership_limit diff --git a/spec/factories/enterprise_factory.rb b/spec/factories/enterprise_factory.rb index ea93a818aa..ea79a2dc05 100644 --- a/spec/factories/enterprise_factory.rb +++ b/spec/factories/enterprise_factory.rb @@ -1,11 +1,21 @@ FactoryBot.define do factory :enterprise, class: Enterprise do + transient do + users [] + end + owner { FactoryBot.create :user } sequence(:name) { |n| "Enterprise #{n}" } sells 'any' description 'enterprise' long_description '

Hello, world!

This is a paragraph.

' address { FactoryBot.create(:address) } + + after(:create) do |enterprise, proxy| + proxy.users.each do |user| + enterprise.users << user unless enterprise.users.include?(user) + end + end end factory :supplier_enterprise, parent: :enterprise do From e64d21d81dfd967fa9ad0ca6c2c93d17e6beec9f Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 21 Feb 2020 14:41:46 +0000 Subject: [PATCH 057/507] Move user enterprises definition in tests to after creation fixes a problem with enterprise_roles --- spec/factories/user_factory.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/factories/user_factory.rb b/spec/factories/user_factory.rb index 561aa064bf..5f9a367885 100644 --- a/spec/factories/user_factory.rb +++ b/spec/factories/user_factory.rb @@ -1,5 +1,9 @@ FactoryBot.modify do factory :user do + transient do + enterprises [] + end + confirmation_sent_at '1970-01-01 00:00:00' confirmed_at '1970-01-01 00:00:01' @@ -13,8 +17,10 @@ FactoryBot.modify do end end - after(:create) do |user| + after(:create) do |user, proxy| user.spree_roles.clear # Remove admin role + + user.enterprises << proxy.enterprises end end From 74965eb6354b8d0d4be0a32172ae314c9841198e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 22:10:42 +0100 Subject: [PATCH 058/507] Remove protected_attributes gem This starts the move towards using Strong Parameters in Rails 4 --- Gemfile | 1 - Gemfile.lock | 3 --- 2 files changed, 4 deletions(-) diff --git a/Gemfile b/Gemfile index 935983ae8e..79cbe5d241 100644 --- a/Gemfile +++ b/Gemfile @@ -81,7 +81,6 @@ gem 'gmaps4rails' gem 'oj' gem 'paper_trail', '~> 5.2.3' gem 'paperclip', '~> 3.4.1' -gem 'protected_attributes' gem 'rack-rewrite' gem 'rack-ssl', require: 'rack/ssl' gem 'roadie-rails', '~> 1.3.0' diff --git a/Gemfile.lock b/Gemfile.lock index d3bd81a749..5f264668a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -483,8 +483,6 @@ GEM activerecord (>= 3.0) polyglot (0.3.5) power_assert (1.1.5) - protected_attributes (1.1.4) - activemodel (>= 4.0.1, < 5.0) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -732,7 +730,6 @@ DEPENDENCIES paper_trail (~> 5.2.3) paperclip (~> 3.4.1) pg (~> 0.21.0) - protected_attributes pry-byebug (>= 3.4.3) rabl rack-mini-profiler (< 2.0.0) From 3896644a042708ad8ad9cab9ad7e82b349386d96 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 22:12:02 +0100 Subject: [PATCH 059/507] Remove attr_accessible declarations Needed for using Strong Parameters in Rails 4 --- app/models/calculator/flat_percent_per_item.rb | 2 -- app/models/calculator/weight.rb | 1 - app/models/column_preference.rb | 6 ------ app/models/concerns/variant_stock.rb | 1 - app/models/enterprise_fee.rb | 2 -- app/models/enterprise_group.rb | 7 ------- app/models/inventory_item.rb | 2 -- app/models/schedule.rb | 2 -- app/models/spree/adjustment_decorator.rb | 2 -- app/models/spree/concerns/payment_method_distributors.rb | 1 - app/models/spree/credit_card_decorator.rb | 6 ------ app/models/spree/gateway/migs.rb | 2 -- app/models/spree/gateway/pin.rb | 2 -- app/models/spree/gateway/stripe_connect.rb | 2 -- app/models/spree/line_item_decorator.rb | 4 ---- app/models/spree/order_decorator.rb | 1 - app/models/spree/payment_decorator.rb | 2 -- app/models/spree/payment_method_decorator.rb | 2 -- app/models/spree/product_decorator.rb | 5 ----- app/models/spree/property.rb | 2 -- app/models/spree/shipping_category_decorator.rb | 3 --- app/models/spree/shipping_method_decorator.rb | 2 -- app/models/spree/user.rb | 6 ------ app/models/spree/variant_decorator.rb | 1 - app/models/tag_rule.rb | 3 --- app/models/tag_rule/filter_order_cycles.rb | 2 -- app/models/tag_rule/filter_payment_methods.rb | 2 -- app/models/tag_rule/filter_products.rb | 2 -- app/models/tag_rule/filter_shipping_methods.rb | 2 -- config/initializers/spree.rb | 1 - .../spree/admin/payment_methods_controller_spec.rb | 1 - 31 files changed, 79 deletions(-) delete mode 100644 app/models/spree/shipping_category_decorator.rb diff --git a/app/models/calculator/flat_percent_per_item.rb b/app/models/calculator/flat_percent_per_item.rb index 035dfe09bd..ff6e222e89 100644 --- a/app/models/calculator/flat_percent_per_item.rb +++ b/app/models/calculator/flat_percent_per_item.rb @@ -11,8 +11,6 @@ class Calculator::FlatPercentPerItem < Spree::Calculator preference :flat_percent, :decimal, default: 0 - attr_accessible :preferred_flat_percent - localize_number :preferred_flat_percent def self.description diff --git a/app/models/calculator/weight.rb b/app/models/calculator/weight.rb index cff4dba4fa..60992e3e48 100644 --- a/app/models/calculator/weight.rb +++ b/app/models/calculator/weight.rb @@ -4,7 +4,6 @@ module Calculator class Weight < Spree::Calculator extend Spree::LocalizedNumber preference :per_kg, :decimal, default: 0.0 - attr_accessible :preferred_per_kg localize_number :preferred_per_kg def self.description diff --git a/app/models/column_preference.rb b/app/models/column_preference.rb index 61672f7927..ae5cdd9127 100644 --- a/app/models/column_preference.rb +++ b/app/models/column_preference.rb @@ -3,12 +3,6 @@ require 'open_food_network/column_preference_defaults' class ColumnPreference < ActiveRecord::Base extend OpenFoodNetwork::ColumnPreferenceDefaults - # These are the attributes used to identify a preference - attr_accessible :user_id, :action_name, :column_name - - # These are attributes that need to be mass assignable - attr_accessible :name, :visible - # Non-persisted attributes that only have one # setting (ie. the default) for a given column attr_accessor :name diff --git a/app/models/concerns/variant_stock.rb b/app/models/concerns/variant_stock.rb index 1cc0ec4e04..d0694f89d1 100644 --- a/app/models/concerns/variant_stock.rb +++ b/app/models/concerns/variant_stock.rb @@ -16,7 +16,6 @@ module VariantStock extend ActiveSupport::Concern included do - attr_accessible :on_hand, :on_demand after_update :save_stock end diff --git a/app/models/enterprise_fee.rb b/app/models/enterprise_fee.rb index 3c93f198ba..5520acff1c 100644 --- a/app/models/enterprise_fee.rb +++ b/app/models/enterprise_fee.rb @@ -10,8 +10,6 @@ class EnterpriseFee < ActiveRecord::Base has_many :exchange_fees, dependent: :destroy has_many :exchanges, through: :exchange_fees - attr_accessible :enterprise_id, :fee_type, :name, :tax_category_id, :calculator_type, :inherits_tax_category - FEE_TYPES = %w(packing transport admin sales fundraising).freeze PER_ORDER_CALCULATORS = ['Spree::Calculator::FlatRate', 'Spree::Calculator::FlexiRate', 'Spree::Calculator::PriceSack'].freeze diff --git a/app/models/enterprise_group.rb b/app/models/enterprise_group.rb index ab27b051f5..0bf0319bde 100644 --- a/app/models/enterprise_group.rb +++ b/app/models/enterprise_group.rb @@ -21,13 +21,6 @@ class EnterpriseGroup < ActiveRecord::Base before_validation :sanitize_permalink validates :permalink, uniqueness: true, presence: true - attr_accessible :name, :description, :long_description, :on_front_page, :enterprise_ids - attr_accessible :owner_id - attr_accessible :permalink - attr_accessible :logo, :promo_image - attr_accessible :address_attributes - attr_accessible :email, :website, :facebook, :instagram, :linkedin, :twitter - delegate :phone, :address1, :address2, :city, :zipcode, :state, :country, to: :address has_attached_file :logo, diff --git a/app/models/inventory_item.rb b/app/models/inventory_item.rb index 5e4bb4ef8b..68f491ff6d 100644 --- a/app/models/inventory_item.rb +++ b/app/models/inventory_item.rb @@ -1,6 +1,4 @@ class InventoryItem < ActiveRecord::Base - attr_accessible :enterprise, :enterprise_id, :variant, :variant_id, :visible - belongs_to :enterprise belongs_to :variant, class_name: "Spree::Variant" diff --git a/app/models/schedule.rb b/app/models/schedule.rb index d882487d8f..143db0642e 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -2,8 +2,6 @@ class Schedule < ActiveRecord::Base has_and_belongs_to_many :order_cycles, join_table: 'order_cycle_schedules' has_many :coordinators, -> { uniq }, through: :order_cycles - attr_accessible :name, :order_cycle_ids - validates :order_cycles, presence: true scope :with_coordinator, lambda { |enterprise| joins(:order_cycles).where('coordinator_id = ?', enterprise.id).select('DISTINCT schedules.*') } diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index a12d68e7fa..ecb91ffcea 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -25,8 +25,6 @@ module Spree scope :shipping, -> { where(AdjustmentScopes::SHIPPING_SCOPE) } scope :eligible, -> { where(AdjustmentScopes::ELIGIBLE_SCOPE) } - attr_accessible :included_tax - localize_number :amount def set_included_tax!(rate) diff --git a/app/models/spree/concerns/payment_method_distributors.rb b/app/models/spree/concerns/payment_method_distributors.rb index 0913889a8e..e5d93abd07 100644 --- a/app/models/spree/concerns/payment_method_distributors.rb +++ b/app/models/spree/concerns/payment_method_distributors.rb @@ -8,7 +8,6 @@ module Spree::PaymentMethodDistributors def self.included(base) base.class_eval do - attr_accessible :distributor_ids has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', class_name: 'Enterprise', foreign_key: 'payment_method_id', association_foreign_key: 'distributor_id' end end diff --git a/app/models/spree/credit_card_decorator.rb b/app/models/spree/credit_card_decorator.rb index f1f4a5d71c..b8c78f01b7 100644 --- a/app/models/spree/credit_card_decorator.rb +++ b/app/models/spree/credit_card_decorator.rb @@ -1,11 +1,5 @@ Spree::CreditCard.class_eval do - # Allows user to submit these attributes with checkout request - # Required to be able to correctly store details for token-based charges - # Obviously can be removed once we are using strong params - attr_accessible :cc_type, :last_digits - # For holding customer preference in memory - attr_accessible :save_requested_by_customer, :is_default attr_writer :save_requested_by_customer # Should be able to remove once we reach Spree v2.2.0 diff --git a/app/models/spree/gateway/migs.rb b/app/models/spree/gateway/migs.rb index 06f31c48e8..b829062f6e 100644 --- a/app/models/spree/gateway/migs.rb +++ b/app/models/spree/gateway/migs.rb @@ -3,8 +3,6 @@ module Spree preference :login, :string preference :password, :string - attr_accessible :preferred_login, :preferred_password - def provider_class ActiveMerchant::Billing::MigsGateway end diff --git a/app/models/spree/gateway/pin.rb b/app/models/spree/gateway/pin.rb index 127c2adeac..c50a3fa773 100644 --- a/app/models/spree/gateway/pin.rb +++ b/app/models/spree/gateway/pin.rb @@ -2,8 +2,6 @@ module Spree class Gateway::Pin < Gateway preference :api_key, :string - attr_accessible :preferred_api_key - def provider_class ActiveMerchant::Billing::PinGateway end diff --git a/app/models/spree/gateway/stripe_connect.rb b/app/models/spree/gateway/stripe_connect.rb index e9941a2f04..ba71049c92 100644 --- a/app/models/spree/gateway/stripe_connect.rb +++ b/app/models/spree/gateway/stripe_connect.rb @@ -7,8 +7,6 @@ module Spree validate :ensure_enterprise_selected - attr_accessible :preferred_enterprise_id - CARD_TYPE_MAPPING = { 'American Express' => 'american_express', 'Diners Club' => 'diners_club', diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index b2a5369ede..b3456d7ba9 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -12,10 +12,6 @@ Spree::LineItem.class_eval do # Allows manual skipping of Stock::AvailabilityValidator attr_accessor :skip_stock_check - attr_accessible :max_quantity, :final_weight_volume, :price - attr_accessible :final_weight_volume, :price, as: :api - attr_accessible :skip_stock_check - before_save :calculate_final_weight_volume, if: :quantity_changed?, unless: :final_weight_volume_changed? after_save :update_units diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index cdabd16515..88515cdd36 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -28,7 +28,6 @@ Spree::Order.class_eval do validates :customer, presence: true, if: :require_customer? validate :products_available_from_new_distribution, if: lambda { distributor_id_changed? || order_cycle_id_changed? } validate :disallow_guest_order - attr_accessible :order_cycle_id, :distributor_id, :customer_id # Removes Spree 2.1 additional email validation (currently failing every time) # See: spree/core/validators/email.rb diff --git a/app/models/spree/payment_decorator.rb b/app/models/spree/payment_decorator.rb index 5bd3e5b326..a3f19c9d3b 100644 --- a/app/models/spree/payment_decorator.rb +++ b/app/models/spree/payment_decorator.rb @@ -10,8 +10,6 @@ module Spree after_save :ensure_correct_adjustment, :update_order - attr_accessible :source - localize_number :amount def ensure_correct_adjustment diff --git a/app/models/spree/payment_method_decorator.rb b/app/models/spree/payment_method_decorator.rb index 994888389c..4cbb7e85d9 100644 --- a/app/models/spree/payment_method_decorator.rb +++ b/app/models/spree/payment_method_decorator.rb @@ -8,8 +8,6 @@ Spree::PaymentMethod.class_eval do has_many :credit_cards, class_name: "Spree::CreditCard" # from Spree v.2.3.0 d470b31798f37 - attr_accessible :tag_list - after_initialize :init validates_with DistributorsValidator diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 5ec1f3c94b..e4361a07dd 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -17,11 +17,6 @@ Spree::Product.class_eval do delegate_belongs_to :master, :unit_value, :unit_description delegate :images_attributes=, :display_as=, to: :master - attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids - attr_accessible :group_buy, :group_buy_unit_size, :unit_description, :notes, :images_attributes, :display_as - attr_accessible :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value - attr_accessible :inherits_properties, :sku - validates :supplier, presence: true validates :primary_taxon, presence: true validates :tax_category_id, presence: true, if: "Spree::Config.products_require_tax_category" diff --git a/app/models/spree/property.rb b/app/models/spree/property.rb index 514de54313..f9f3415bbc 100644 --- a/app/models/spree/property.rb +++ b/app/models/spree/property.rb @@ -3,8 +3,6 @@ module Spree has_many :product_properties, dependent: :destroy has_many :products, through: :product_properties - attr_accessible :name, :presentation - validates :name, :presentation, presence: true scope :sorted, -> { order(:name) } diff --git a/app/models/spree/shipping_category_decorator.rb b/app/models/spree/shipping_category_decorator.rb deleted file mode 100644 index b78ba3337c..0000000000 --- a/app/models/spree/shipping_category_decorator.rb +++ /dev/null @@ -1,3 +0,0 @@ -Spree::ShippingCategory.class_eval do - attr_accessible :temperature_controlled -end diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index d79e2b6853..cc77ea540d 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -5,8 +5,6 @@ Spree::ShippingMethod.class_eval do has_many :distributors, through: :distributor_shipping_methods, class_name: 'Enterprise', foreign_key: 'distributor_id' after_save :touch_distributors - attr_accessible :distributor_ids, :description - attr_accessible :require_ship_address, :tag_list validates_with DistributorsValidator diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index 10075729bf..c5bc3e9010 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -10,10 +10,6 @@ module Spree before_validation :set_login before_destroy :check_completed_orders - # Setup accessible (or protected) attributes for your model - attr_accessible :email, :password, :password_confirmation, - :remember_me, :persistence_token, :login - users_table_name = User.table_name roles_table_name = Role.table_name @@ -34,8 +30,6 @@ module Spree accepts_nested_attributes_for :bill_address accepts_nested_attributes_for :ship_address - attr_accessible :enterprise_ids, :enterprise_roles_attributes, :enterprise_limit, - :locale, :bill_address_attributes, :ship_address_attributes after_create :associate_customers validate :limit_owned_enterprises diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index 84750cbe94..bc7228646c 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -16,7 +16,6 @@ Spree::Variant.class_eval do has_many :variant_overrides has_many :inventory_items - attr_accessible :unit_value, :unit_description, :images_attributes, :display_as, :display_name, :import_date accepts_nested_attributes_for :images validates :unit_value, presence: true, if: ->(variant) { diff --git a/app/models/tag_rule.rb b/app/models/tag_rule.rb index fd1e744148..404c449e50 100644 --- a/app/models/tag_rule.rb +++ b/app/models/tag_rule.rb @@ -5,9 +5,6 @@ class TagRule < ActiveRecord::Base validates :enterprise, presence: true - attr_accessible :enterprise, :enterprise_id, :is_default, :priority - attr_accessible :preferred_customer_tags - scope :for, ->(enterprise) { where(enterprise_id: enterprise) } scope :prioritised, -> { order('priority ASC') } diff --git a/app/models/tag_rule/filter_order_cycles.rb b/app/models/tag_rule/filter_order_cycles.rb index de626ac70a..fd467a1658 100644 --- a/app/models/tag_rule/filter_order_cycles.rb +++ b/app/models/tag_rule/filter_order_cycles.rb @@ -2,8 +2,6 @@ class TagRule::FilterOrderCycles < TagRule preference :matched_order_cycles_visibility, :string, default: "visible" preference :exchange_tags, :string, default: "" - attr_accessible :preferred_matched_order_cycles_visibility, :preferred_exchange_tags - def tags_match?(order_cycle) exchange_tags = exchange_for(order_cycle).andand.tag_list || [] preferred_tags = preferred_exchange_tags.split(",") diff --git a/app/models/tag_rule/filter_payment_methods.rb b/app/models/tag_rule/filter_payment_methods.rb index 04a10889e0..11d5b5e737 100644 --- a/app/models/tag_rule/filter_payment_methods.rb +++ b/app/models/tag_rule/filter_payment_methods.rb @@ -2,8 +2,6 @@ class TagRule::FilterPaymentMethods < TagRule preference :matched_payment_methods_visibility, :string, default: "visible" preference :payment_method_tags, :string, default: "" - attr_accessible :preferred_matched_payment_methods_visibility, :preferred_payment_method_tags - def tags_match?(payment_method) payment_method_tags = payment_method.andand.tag_list || [] preferred_tags = preferred_payment_method_tags.split(",") diff --git a/app/models/tag_rule/filter_products.rb b/app/models/tag_rule/filter_products.rb index e1d3865036..40035a21d5 100644 --- a/app/models/tag_rule/filter_products.rb +++ b/app/models/tag_rule/filter_products.rb @@ -3,8 +3,6 @@ class TagRule preference :matched_variants_visibility, :string, default: "visible" preference :variant_tags, :string, default: "" - attr_accessible :preferred_matched_variants_visibility, :preferred_variant_tags - def self.tagged_children_for(product) product["variants"] end diff --git a/app/models/tag_rule/filter_shipping_methods.rb b/app/models/tag_rule/filter_shipping_methods.rb index 2091a14a63..a5de92da8b 100644 --- a/app/models/tag_rule/filter_shipping_methods.rb +++ b/app/models/tag_rule/filter_shipping_methods.rb @@ -2,8 +2,6 @@ class TagRule::FilterShippingMethods < TagRule preference :matched_shipping_methods_visibility, :string, default: "visible" preference :shipping_method_tags, :string, default: "" - attr_accessible :preferred_matched_shipping_methods_visibility, :preferred_shipping_method_tags - def reject_matched? preferred_matched_shipping_methods_visibility != "visible" end diff --git a/config/initializers/spree.rb b/config/initializers/spree.rb index c2f6a118a1..cc2ff359ba 100644 --- a/config/initializers/spree.rb +++ b/config/initializers/spree.rb @@ -15,7 +15,6 @@ require 'spree/product_filters' # https://github.com/openfoodfoundation/openfoodnetwork/issues/3121 Spree::Gateway.class_eval do acts_as_taggable - attr_accessible :tag_list end require "#{Rails.root}/app/models/spree/payment_method_decorator" diff --git a/spec/controllers/spree/admin/payment_methods_controller_spec.rb b/spec/controllers/spree/admin/payment_methods_controller_spec.rb index 2a2f03dbcc..9373986e6f 100644 --- a/spec/controllers/spree/admin/payment_methods_controller_spec.rb +++ b/spec/controllers/spree/admin/payment_methods_controller_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' module Spree class GatewayWithPassword < PaymentMethod - attr_accessible :preferred_password preference :password, :string, default: "password" end From f5bc120fb1bb31caf2138ea4b34afa3eb30eae8c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 21 Dec 2019 22:19:06 +0100 Subject: [PATCH 060/507] Remove `without_protection: true` argument from #create calls Needed for using Strong Parameters in Rails 4 --- app/models/spree/payment_decorator.rb | 2 +- ...857_remove_shipping_methods_using_itemwise_calculator.rb | 2 +- db/seeds.rb | 5 +---- lib/open_food_network/variant_and_line_item_naming.rb | 2 +- spec/features/consumer/registration_spec.rb | 6 +++--- spec/models/enterprise_fee_spec.rb | 2 +- spec/models/spree/product_spec.rb | 6 +++--- spec/models/tag_rule/discount_order_spec.rb | 2 +- spec/support/seeds.rb | 6 +++--- 9 files changed, 15 insertions(+), 18 deletions(-) diff --git a/app/models/spree/payment_decorator.rb b/app/models/spree/payment_decorator.rb index a3f19c9d3b..ed3c85233c 100644 --- a/app/models/spree/payment_decorator.rb +++ b/app/models/spree/payment_decorator.rb @@ -62,7 +62,7 @@ module Spree payment_method: payment_method, amount: refund_amount.abs * -1, response_code: response.authorization, - state: 'completed' }, without_protection: true) + state: 'completed' }) else gateway_error(response) end diff --git a/db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb b/db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb index 52351065dd..7ba21757fd 100644 --- a/db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb +++ b/db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb @@ -10,6 +10,6 @@ class RemoveShippingMethodsUsingItemwiseCalculator < ActiveRecord::Migration end def down - Spree::ShippingMethod.create!({name: 'Delivery', zone: Spree::Zone.last, calculator: OpenFoodNetwork::Calculator::Itemwise.new}, without_protection: true) + Spree::ShippingMethod.create!({name: 'Delivery', zone: Spree::Zone.last, calculator: OpenFoodNetwork::Calculator::Itemwise.new}) end end diff --git a/db/seeds.rb b/db/seeds.rb index 12b3cdd5ce..9afe88de4b 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -41,10 +41,7 @@ states.each do |state| puts "State: " + state.to_s unless Spree::State.find_by(name: state['name']) - Spree::State.create!( - { name: state['name'], abbr: state['abbr'], country: country }, - without_protection: true - ) + Spree::State.create!({ name: state['name'], abbr: state['abbr'], country: country }) end end diff --git a/lib/open_food_network/variant_and_line_item_naming.rb b/lib/open_food_network/variant_and_line_item_naming.rb index 596b93beee..fca7f25d0d 100644 --- a/lib/open_food_network/variant_and_line_item_naming.rb +++ b/lib/open_food_network/variant_and_line_item_naming.rb @@ -59,7 +59,7 @@ module OpenFoodNetwork option_type = product.variant_unit_option_type if option_type name = option_value_name - ov = Spree::OptionValue.where(option_type_id: option_type, name: name, presentation: name).first || Spree::OptionValue.create!({ option_type: option_type, name: name, presentation: name }, without_protection: true) + ov = Spree::OptionValue.where(option_type_id: option_type, name: name, presentation: name).first || Spree::OptionValue.create!({ option_type: option_type, name: name, presentation: name }) option_values << ov end end diff --git a/spec/features/consumer/registration_spec.rb b/spec/features/consumer/registration_spec.rb index 1931614d07..a62140f171 100644 --- a/spec/features/consumer/registration_spec.rb +++ b/spec/features/consumer/registration_spec.rb @@ -10,9 +10,9 @@ feature "Registration", js: true do before do Spree::Config.enterprises_require_tos = false - albania = Spree::Country.create!({ name: "Albania", iso3: "ALB", iso: "AL", iso_name: "ALBANIA", numcode: "8" }, without_protection: true) - Spree::State.create!({ name: "Berat", abbr: "BRA", country: albania }, without_protection: true) - Spree::Country.create!({ name: "Chad", iso3: "TCD", iso: "TD", iso_name: "CHAD", numcode: "148" }, without_protection: true) + albania = Spree::Country.create!({ name: "Albania", iso3: "ALB", iso: "AL", iso_name: "ALBANIA", numcode: "8" }) + Spree::State.create!({ name: "Berat", abbr: "BRA", country: albania }) + Spree::Country.create!({ name: "Chad", iso3: "TCD", iso: "TD", iso_name: "CHAD", numcode: "148" }) end after do diff --git a/spec/models/enterprise_fee_spec.rb b/spec/models/enterprise_fee_spec.rb index 4c09ccd62c..a422358bb8 100644 --- a/spec/models/enterprise_fee_spec.rb +++ b/spec/models/enterprise_fee_spec.rb @@ -130,7 +130,7 @@ describe EnterpriseFee do source: order, originator: tax_rate, state: 'closed', - label: 'hello' }, without_protection: true) + label: 'hello' }) expect do EnterpriseFee.clear_all_adjustments_on_order order diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 7810978fc4..cb6bf45f0f 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -450,9 +450,9 @@ module Spree pb = Spree::Property.create! name: 'B', presentation: 'B' pc = Spree::Property.create! name: 'C', presentation: 'C' - product.product_properties.create!({ property_id: pa.id, value: '1', position: 1 }, without_protection: true) - product.product_properties.create!({ property_id: pc.id, value: '3', position: 3 }, without_protection: true) - supplier.producer_properties.create!({ property_id: pb.id, value: '2', position: 2 }, without_protection: true) + product.product_properties.create!({ property_id: pa.id, value: '1', position: 1 }) + product.product_properties.create!({ property_id: pc.id, value: '3', position: 3 }) + supplier.producer_properties.create!({ property_id: pb.id, value: '2', position: 2 }) expect(product.properties_including_inherited).to eq( [{ id: pa.id, name: "A", value: '1' }, diff --git a/spec/models/tag_rule/discount_order_spec.rb b/spec/models/tag_rule/discount_order_spec.rb index d4e30a6d95..2a1260f7e3 100644 --- a/spec/models/tag_rule/discount_order_spec.rb +++ b/spec/models/tag_rule/discount_order_spec.rb @@ -31,7 +31,7 @@ describe TagRule::DiscountOrder, type: :model do pending "determining whether a the rule has already been applied to an order" do let!(:order) { create(:order) } - let!(:adjustment) { order.adjustments.create({ amount: 12.34, source: order, originator: tag_rule, label: 'discount' }, without_protection: true) } + let!(:adjustment) { order.adjustments.create({ amount: 12.34, source: order, originator: tag_rule, label: 'discount' }) } before do tag_rule.context = { subject: order } diff --git a/spec/support/seeds.rb b/spec/support/seeds.rb index 75aff1baf8..26cc7a46e0 100644 --- a/spec/support/seeds.rb +++ b/spec/support/seeds.rb @@ -6,10 +6,10 @@ # You can add more entries here if you need them for your tests. if Spree::Country.where(nil).empty? - Spree::Country.create!({ "name" => "Australia", "iso3" => "AUS", "iso" => "AU", "iso_name" => "AUSTRALIA", "numcode" => "36" }, without_protection: true) + Spree::Country.create!({ "name" => "Australia", "iso3" => "AUS", "iso" => "AU", "iso_name" => "AUSTRALIA", "numcode" => "36" }) country = Spree::Country.find_by(name: 'Australia') - Spree::State.create!({ "name" => "Victoria", "abbr" => "Vic", :country => country }, without_protection: true) - Spree::State.create!({ "name" => "New South Wales", "abbr" => "NSW", :country => country }, without_protection: true) + Spree::State.create!({ "name" => "Victoria", "abbr" => "Vic", :country => country }) + Spree::State.create!({ "name" => "New South Wales", "abbr" => "NSW", :country => country }) end # Since the country seeding differs from other environments, the default From eae7dc7f2e32bb1be39905cbe0184e21f55821d7 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 23 Dec 2019 12:23:46 +0100 Subject: [PATCH 061/507] Temporarily add extra debugging to help with strong parameters --- app/controllers/api/base_controller.rb | 6 ++++++ app/controllers/application_controller.rb | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index ac67bb6aa3..f591154d4c 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -32,6 +32,12 @@ module Api use_renderers :json check_authorization + # Temporary measure to help debugging strong_parameters + rescue_from ActiveModel::ForbiddenAttributesError, with: :print_params + def print_params + raise ActiveModel::ForbiddenAttributesError, params.to_s + end + def set_jsonp_format return unless params[:callback] && request.get? diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5b67897fab..fad20ce7aa 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,6 +10,12 @@ class ApplicationController < ActionController::Base include EnterprisesHelper include Spree::AuthenticationHelpers + # Temporary measure to help debugging strong_parameters + rescue_from ActiveModel::ForbiddenAttributesError, with: :print_params + def print_params + raise ActiveModel::ForbiddenAttributesError, params.to_s + end + def redirect_to(options = {}, response_status = {}) ::Rails.logger.error("Redirected by #{begin caller(1).first From bd6b409708776132c4b8c50088fd366213a6929f Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 23 Dec 2019 12:03:00 +0100 Subject: [PATCH 062/507] Add strong parameters to user_registrations_controller.rb --- app/controllers/user_registrations_controller.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/user_registrations_controller.rb b/app/controllers/user_registrations_controller.rb index fa6cb32028..258d990828 100644 --- a/app/controllers/user_registrations_controller.rb +++ b/app/controllers/user_registrations_controller.rb @@ -10,7 +10,7 @@ class UserRegistrationsController < Spree::UserRegistrationsController # POST /resource/sign_up def create - @user = build_resource(params[:spree_user]) + @user = build_resource(spree_user_params) @user.locale = I18n.locale.to_s unless resource.save return render_error(@user.errors) @@ -32,6 +32,11 @@ class UserRegistrationsController < Spree::UserRegistrationsController private + def spree_user_params + params.require(:spree_user). + permit(:email, :password, :password_confirmation, :remember_me) + end + def render_error(errors = {}) clean_up_passwords(resource) respond_to do |format| From f77194875c1446b86455627543b77b2c0574f7bc Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 23 Dec 2019 12:24:04 +0100 Subject: [PATCH 063/507] Add strong parameters to orders_controller.rb --- app/controllers/spree/admin/orders_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/orders_controller.rb b/app/controllers/spree/admin/orders_controller.rb index 2ddc9dccc7..4858b98d7e 100644 --- a/app/controllers/spree/admin/orders_controller.rb +++ b/app/controllers/spree/admin/orders_controller.rb @@ -44,7 +44,7 @@ module Spree end def update - unless @order.update_attributes(params[:order]) && @order.line_items.present? + unless @order.update_attributes(order_params) && @order.line_items.present? if @order.line_items.empty? @order.errors.add(:line_items, Spree.t('errors.messages.blank')) end @@ -108,6 +108,10 @@ module Spree private + def order_params + params.require(:order).permit(:distributor_id, :order_cycle_id) + end + def load_order @order = Order.find_by_number!(params[:id], include: :adjustments) if params[:id] authorize! action, @order From fccc8037f079f3fdccad01ccdf7f085bc3d23feb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 23 Feb 2020 14:26:14 +0100 Subject: [PATCH 064/507] Add strong_params to enterprise_relationships_controller.rb Fixes specs such as: 31) As an Administrator I want to manage relationships between enterprises as a site administrator creating a relationship Failure/Error: raise ActiveModel::ForbiddenAttributesError, params.to_s ActiveModel::ForbiddenAttributesError: {"enterprise_relationship"=>{"parent_id"=>284, "child_id"=>285, "permissions_list"=>["add_to_order_cycle", "edit_profile", "create_variant_overrides"]}, "action"=>"create", "controller"=>"admin/enterprise_relationships"} # ./app/controllers/application_controller.rb:16:in `print_params' # ./lib/open_food_network/rack_request_blocker.rb:36:in `call' # ------------------ # --- Caused by: --- # ActiveModel::ForbiddenAttributesError: # ActiveModel::ForbiddenAttributesError # ./app/controllers/admin/enterprise_relationships_controller.rb:10:in `create' --- .../admin/enterprise_relationships_controller.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index 0ffb648f44..1996b4f73d 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -7,7 +7,7 @@ module Admin end def create - @enterprise_relationship = EnterpriseRelationship.new params[:enterprise_relationship] + @enterprise_relationship = EnterpriseRelationship.new enterprise_relationship_params if @enterprise_relationship.save render text: Api::Admin::EnterpriseRelationshipSerializer.new(@enterprise_relationship).to_json @@ -21,5 +21,11 @@ module Admin @enterprise_relationship.destroy render nothing: true end + + private + + def enterprise_relationship_params + params.require(:enterprise_relationship).permit(:parent_id, :child_id, :permissions_list) + end end end From 90d1a5e605e10b8fb751052906d1e195741f1461 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 23 Feb 2020 14:52:06 +0100 Subject: [PATCH 065/507] Add strong params to admin/column_preferences_controller.rb Fixes failures such as: 119) Admin::ColumnPreferencesController bulk_update json where I don't own the preferences submitted prevents me from updating the column preferences Failure/Error: raise ActiveModel::ForbiddenAttributesError, params.to_s ActiveModel::ForbiddenAttributesError: {"action_name"=>"enterprises_index", "column_preferences"=>[{"id"=>1, "user_id"=>2716, "action_name"=>"enterprises_index", "column_name"=>"name", "visible"=>false}, {"id"=>nil, "user_id"=>2716, "action_name"=>"enterprises_index", "column_name"=>"producer", "visible"=>true}, {"id"=>nil, "user_id"=>2716, "action_name"=>"enterprises_index", "column_name"=>"status", "visible"=>true}], "format"=>"json", "controller"=>"admin/column_preferences", "action"=>"bulk_update"} # ./app/controllers/application_controller.rb:16:in `print_params' # ./spec/controllers/admin/column_preferences_controller_spec.rb:28:in `block (5 levels) in ' # ------------------ # --- Caused by: --- # ActiveModel::ForbiddenAttributesError: # ActiveModel::ForbiddenAttributesError # ./app/models/model_set.rb:24:in `block in collection_attributes=' --- app/controllers/admin/column_preferences_controller.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/column_preferences_controller.rb b/app/controllers/admin/column_preferences_controller.rb index 64c028b104..0d7198b5b3 100644 --- a/app/controllers/admin/column_preferences_controller.rb +++ b/app/controllers/admin/column_preferences_controller.rb @@ -21,14 +21,18 @@ module Admin private + def permitted_params + params.permit(:action_name, column_preferences: [:id, :user_id, :action_name, :column_name, :visible]) + end + def load_collection - collection_hash = Hash[params[:column_preferences].each_with_index.map { |cp, i| [i, cp] }] - collection_hash.select!{ |_i, cp| cp[:action_name] == params[:action_name] } + collection_hash = Hash[permitted_params[:column_preferences].each_with_index.map { |cp, i| [i, cp] }] + collection_hash.select!{ |_i, cp| cp[:action_name] == permitted_params[:action_name] } @cp_set = ColumnPreferenceSet.new @column_preferences, collection_attributes: collection_hash end def collection - ColumnPreference.where(user_id: spree_current_user, action_name: params[:action_name]) + ColumnPreference.where(user_id: spree_current_user, action_name: permitted_params[:action_name]) end def collection_actions From 167c8543aaf5fa80ac165e8b06677a7c9a431cc6 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:43:38 +0100 Subject: [PATCH 066/507] Fix #create_enterprise_user User was not being associated to enterprises passed in attributes --- spec/support/request/authentication_workflow.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/support/request/authentication_workflow.rb b/spec/support/request/authentication_workflow.rb index e4708a6e97..842a215508 100644 --- a/spec/support/request/authentication_workflow.rb +++ b/spec/support/request/authentication_workflow.rb @@ -29,6 +29,11 @@ module AuthenticationWorkflow new_user = build(:user, attrs) new_user.spree_roles = [Spree::Role.find_or_create_by!(name: 'user')] new_user.save + if attrs.has_key? :enterprises + attrs[:enterprises].each do |enterprise| + enterprise.users << new_user + end + end new_user end From 82052e459d2376725bbe10d35ac33b9916ea397e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 26 Feb 2020 11:33:45 +0100 Subject: [PATCH 067/507] Make private method #total_units public This method is being called by another class as if it were public. Fixes 2 instances of this error: 90) OpenFoodNetwork::OrdersAndFulfillmentsReport::SupplierTotalsReport generates the report Failure/Error: delegate :supplier_name, :product_name, :line_items_name, :total_units, to: :context NoMethodError: private method `total_units' called for # # ./lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report.rb:8:in `total_units' # ./lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report.rb:48:in `block in columns' # ./lib/open_food_network/order_grouper.rb:41:in `block in build_table' # ./lib/open_food_network/order_grouper.rb:41:in `map' # ./lib/open_food_network/order_grouper.rb:41:in `build_table' # ./lib/open_food_network/order_grouper.rb:47:in `block in build_table' # ./lib/open_food_network/order_grouper.rb:43:in `each' # ./lib/open_food_network/order_grouper.rb:43:in `build_table' # ./lib/open_food_network/order_grouper.rb:47:in `block in build_table' # ./lib/open_food_network/order_grouper.rb:43:in `each' # ./lib/open_food_network/order_grouper.rb:43:in `build_table' # ./lib/open_food_network/order_grouper.rb:47:in `block in build_table' # ./lib/open_food_network/order_grouper.rb:43:in `each' # ./lib/open_food_network/order_grouper.rb:43:in `build_table' # ./lib/open_food_network/order_grouper.rb:56:in `table' # ./spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report_spec.rb:19:in `block (2 levels) in ' # ./spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report_spec.rb:23:in `block (2 levels) in ' --- .../orders_and_fulfillments_report.rb | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index 01b2ae7617..fbac2f6551 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -45,6 +45,17 @@ module OpenFoodNetwork proc { |line_items| line_items.first.variant.product.name } end + def total_units(line_items) + return " " if not_all_have_unit?(line_items) + + total_units = line_items.sum do |li| + product = li.variant.product + li.quantity * li.unit_value / scale_factor(product) + end + + total_units.round(3) + end + private def report @@ -62,17 +73,6 @@ module OpenFoodNetwork end end - def total_units(line_items) - return " " if not_all_have_unit?(line_items) - - total_units = line_items.sum do |li| - product = li.variant.product - li.quantity * li.unit_value / scale_factor(product) - end - - total_units.round(3) - end - def not_all_have_unit?(line_items) line_items.map { |li| li.unit_value.nil? }.any? end From c758cb5508f75586b29ca391ede27de1843dc513 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 26 Feb 2020 11:50:51 +0100 Subject: [PATCH 068/507] Fix expectations in order_shipment_spec Some depreacted calls to #find_by_* had previously been updated elsewhere, but the spec was still checking if the object received the #find_by_shipping_method_id message. Fixes: 85) OrderShipment#select_shipping_method when order has a shipment when shipping_method_id is not valid for the order returns nil Failure/Error: expect(shipment.shipping_rates).to receive(:find_by_shipping_method_id).with(invalid_shipping_method_id) { nil } (#).find_by_shipping_method_id(1312) expected: 1 time with arguments: (1312) received: 0 times # ./spec/models/concerns/order_shipment_spec.rb:53:in `block (5 levels) in ' --- spec/models/concerns/order_shipment_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/concerns/order_shipment_spec.rb b/spec/models/concerns/order_shipment_spec.rb index 7821d61c81..08c23f76fb 100644 --- a/spec/models/concerns/order_shipment_spec.rb +++ b/spec/models/concerns/order_shipment_spec.rb @@ -41,7 +41,7 @@ describe OrderShipment do it "returns nil for empty shipping_method_id" do empty_shipping_method_id = ' ' - expect(shipment.shipping_rates).to_not receive(:find_by_shipping_method_id).with(empty_shipping_method_id) + expect(shipment.shipping_rates).to_not receive(:find_by).with(shipping_method_id: empty_shipping_method_id) expect(order.select_shipping_method(empty_shipping_method_id)).to be_nil end @@ -50,7 +50,7 @@ describe OrderShipment do context "when shipping_method_id is not valid for the order" do it "returns nil" do invalid_shipping_method_id = order.shipment.shipping_method.id + 1000 - expect(shipment.shipping_rates).to receive(:find_by_shipping_method_id).with(invalid_shipping_method_id) { nil } + expect(shipment.shipping_rates).to receive(:find_by).with(shipping_method_id: invalid_shipping_method_id) { nil } expect(order.select_shipping_method(invalid_shipping_method_id)).to be_nil end From 0fa73e3b02d8a757ce95fe29dd76fad49f628e96 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 27 Feb 2020 11:23:48 +0100 Subject: [PATCH 069/507] Fix headers in api/base_controller spec The headers in the request were not being populated correctly in the test, so the #api_key method was not functioning as intended. Fixes: 48) Api::BaseController cannot make a request to the API with an invalid API key Failure/Error: expect(json_response).to eq( "error" => "Invalid API key (fake_key) specified." ) expected: {"error"=>"Invalid API key (fake_key) specified."} got: {"products"=>[]} (compared using ==) Diff: @@ -1,2 +1,2 @@ -"error" => "Invalid API key (fake_key) specified.", +"products" => [], # ./spec/controllers/api/base_controller_spec.rb:40:in `block (3 levels) in ' --- spec/controllers/api/base_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/api/base_controller_spec.rb b/spec/controllers/api/base_controller_spec.rb index 9e31fc138e..3742fcab2c 100644 --- a/spec/controllers/api/base_controller_spec.rb +++ b/spec/controllers/api/base_controller_spec.rb @@ -35,7 +35,7 @@ describe Api::BaseController do context "cannot make a request to the API" do it "with an invalid API key" do - request.env["X-Spree-Token"] = "fake_key" + request.headers["X-Spree-Token"] = "fake_key" get :index, {} expect(json_response).to eq( "error" => "Invalid API key (fake_key) specified." ) expect(response.status).to eq(401) From ade52dd07d2cbdf97cc5f5ab1212bf4db019d8cc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 27 Feb 2020 17:40:32 +0000 Subject: [PATCH 070/507] Make ship methods services query work with rails 4, bool_or now results in a boolean and not in t or f as before --- app/models/spree/shipping_method_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index d79e2b6853..60f1976ed7 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -41,7 +41,7 @@ Spree::ShippingMethod.class_eval do select("distributor_id"). select("BOOL_OR(spree_shipping_methods.require_ship_address = 'f') AS pickup"). select("BOOL_OR(spree_shipping_methods.require_ship_address = 't') AS delivery"). - map { |sm| [sm.distributor_id.to_i, { pickup: sm.pickup == 't', delivery: sm.delivery == 't' }] } + map { |sm| [sm.distributor_id.to_i, { pickup: sm.pickup, delivery: sm.delivery }] } ] end From b1714d73ef8b4a85a3e5cd501585ad689c55337d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 27 Feb 2020 18:01:24 +0000 Subject: [PATCH 071/507] Capitalize 'Method' in the flash message to make specs pass --- spec/features/admin/shipping_methods_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/admin/shipping_methods_spec.rb b/spec/features/admin/shipping_methods_spec.rb index ba4ac46e19..2572194a0b 100644 --- a/spec/features/admin/shipping_methods_spec.rb +++ b/spec/features/admin/shipping_methods_spec.rb @@ -36,7 +36,7 @@ feature 'shipping methods' do expect(page).to have_no_button I18n.t("actions.create") # Then the shipping method should have its distributor set - message = "Shipping method \"Carrier Pidgeon\" has been successfully created!" + message = "Shipping Method \"Carrier Pidgeon\" has been successfully created!" expect(page).to have_flash_message message sm = Spree::ShippingMethod.last @@ -49,7 +49,7 @@ feature 'shipping methods' do scenario "deleting a shipping method" do visit_delete spree.admin_shipping_method_path(@shipping_method) - expect(page).to have_content "Shipping method \"#{@shipping_method.name}\" has been successfully removed!" + expect(page).to have_content "Shipping Method \"#{@shipping_method.name}\" has been successfully removed!" expect(Spree::ShippingMethod.where(id: @shipping_method.id)).to be_empty end @@ -126,7 +126,7 @@ feature 'shipping methods' do click_button I18n.t("actions.create") expect(page).to have_content I18n.t('spree.admin.shipping_methods.edit.editing_shipping_method') - expect(flash_message).to eq I18n.t('successfully_created', resource: 'Shipping method "Teleport"') + expect(flash_message).to eq I18n.t('successfully_created', resource: 'Shipping Method "Teleport"') expect(first('tags-input .tag-list ti-tag-item')).to have_content "local" From bd0245229b731a250ff148b5174505ab4a3b1e52 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 21 Feb 2020 15:17:54 +0000 Subject: [PATCH 072/507] Move enterprise logo and promo_image setting in factories to after creation fixes a problem with enterprise_roles in the enterprise validation --- app/controllers/api/enterprise_attachment_controller.rb | 2 ++ spec/factories/enterprise_factory.rb | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/controllers/api/enterprise_attachment_controller.rb b/app/controllers/api/enterprise_attachment_controller.rb index 00b7c87043..fe8f47469b 100644 --- a/app/controllers/api/enterprise_attachment_controller.rb +++ b/app/controllers/api/enterprise_attachment_controller.rb @@ -1,3 +1,5 @@ +require 'api/admin/enterprise_serializer' + module Api class EnterpriseAttachmentController < BaseController class MissingImplementationError < StandardError; end diff --git a/spec/factories/enterprise_factory.rb b/spec/factories/enterprise_factory.rb index ea79a2dc05..5382e0fd94 100644 --- a/spec/factories/enterprise_factory.rb +++ b/spec/factories/enterprise_factory.rb @@ -2,6 +2,8 @@ FactoryBot.define do factory :enterprise, class: Enterprise do transient do users [] + logo {} + promo_image {} end owner { FactoryBot.create :user } @@ -15,6 +17,7 @@ FactoryBot.define do proxy.users.each do |user| enterprise.users << user unless enterprise.users.include?(user) end + enterprise.update_attributes logo: proxy.logo, promo_image: proxy.promo_image end end From 7124c6bb73a93335f825315aa0d5f8667a612214 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 27 Feb 2020 20:52:26 +0100 Subject: [PATCH 073/507] Fix embedded response headers Rails 4 adds an extra layer of "default" headers that override any that are missing (or deleted). This was breaking embedded shopfront responses. Fixes: 74) setting response headers for embedded shopfronts with embedded shopfronts enabled with a valid whitelist allows iframes on certain pages when enabled in configuration Failure/Error: expect(response.headers['X-Frame-Options']).to be_nil expected: nil got: "SAMEORIGIN" # ./spec/requests/embedded_shopfronts_headers_spec.rb:54:in `block (4 levels) in ' 75) setting response headers for embedded shopfronts with embedded shopfronts enabled with www prefix matches the URL structure in the header Failure/Error: expect(response.headers['X-Frame-Options']).to be_nil expected: nil got: "SAMEORIGIN" # ./spec/requests/embedded_shopfronts_headers_spec.rb:75:in `block (4 levels) in ' --- app/services/embedded_page_service.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/embedded_page_service.rb b/app/services/embedded_page_service.rb index 9164ac4d94..f2d6021e20 100644 --- a/app/services/embedded_page_service.rb +++ b/app/services/embedded_page_service.rb @@ -49,7 +49,8 @@ class EmbeddedPageService end def set_response_headers - @response.headers.delete 'X-Frame-Options' + @response.headers.except! 'X-Frame-Options' + @response.default_headers.except! 'X-Frame-Options' @response.headers['Content-Security-Policy'] = "frame-ancestors 'self' #{@embedding_domain}" end From 8672124f3146d4cbb655a2ecd6562642d714fb00 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 26 Feb 2020 11:23:45 +0100 Subject: [PATCH 074/507] Add 'pt' to list of available locales in test suite Fixes several errors such as: 104) UserRegistrationsController via ajax sets user.locale from cookie on create Failure/Error: I18n.locale = spree_current_user.andand.locale || cookies[:locale] || I18n.default_locale I18n::InvalidLocale: "pt" is not a valid locale # ./app/helpers/i18n_helper.rb:14:in `set_locale' # ./spec/controllers/user_registrations_controller_spec.rb:56:in `block (3 levels) in ' --- config/environments/test.rb | 2 +- spec/features/admin/multilingual_spec.rb | 4 ++-- spec/features/consumer/multilingual_spec.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index bb1da68229..f33423acdd 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -35,7 +35,7 @@ Openfoodnetwork::Application.configure do # Tests assume English text on the site. config.i18n.default_locale = "en" - config.i18n.available_locales = ['en', 'es'] + config.i18n.available_locales = ['en', 'es', 'pt'] config.i18n.fallbacks = [:en] I18n.locale = config.i18n.locale = config.i18n.default_locale diff --git a/spec/features/admin/multilingual_spec.rb b/spec/features/admin/multilingual_spec.rb index ee9d44e195..90d21d1ecd 100644 --- a/spec/features/admin/multilingual_spec.rb +++ b/spec/features/admin/multilingual_spec.rb @@ -12,10 +12,10 @@ feature 'Multilingual', js: true do visit spree.admin_dashboard_path end - it 'has two locales available' do + it 'has three locales available' do expect(Rails.application.config.i18n[:default_locale]).to eq 'en' expect(Rails.application.config.i18n[:locale]).to eq 'en' - expect(Rails.application.config.i18n[:available_locales]).to eq ['en', 'es'] + expect(Rails.application.config.i18n[:available_locales]).to eq ['en', 'es', 'pt'] end it 'can switch language by params' do diff --git a/spec/features/consumer/multilingual_spec.rb b/spec/features/consumer/multilingual_spec.rb index 4bf209361c..3e8a19f4d0 100644 --- a/spec/features/consumer/multilingual_spec.rb +++ b/spec/features/consumer/multilingual_spec.rb @@ -7,10 +7,10 @@ feature 'Multilingual', js: true do include UIComponentHelper include CookieHelper - it 'has two locales available' do + it 'has three locales available' do expect(Rails.application.config.i18n[:default_locale]).to eq 'en' expect(Rails.application.config.i18n[:locale]).to eq 'en' - expect(Rails.application.config.i18n[:available_locales]).to eq ['en', 'es'] + expect(Rails.application.config.i18n[:available_locales]).to eq ['en', 'es', 'pt'] end it '18n-js fallsback to default language' do # in backend it doesn't until we change enforce_available_locales to `true` From 02d46b7c518c799ad4091521652e95b3298dea93 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 28 Feb 2020 11:51:09 +0100 Subject: [PATCH 075/507] Fix test in order_cycles_spec.rb --- spec/features/admin/order_cycles_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 85c58932b7..7d1567396a 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -117,10 +117,10 @@ feature ' end describe 'listing order cycles with other locales' do - let!(:oc_de) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } + let!(:oc_pt) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } around(:each) do |spec| - I18n.locale = :de + I18n.locale = :pt spec.run I18n.locale = :en end @@ -130,7 +130,7 @@ feature ' quick_login_as_admin visit admin_order_cycles_path - within("tr.order-cycle-#{oc_de.id}") do + within("tr.order-cycle-#{oc_pt.id}") do expect(find('input.datetimepicker', match: :first).value).to start_with '2012-01-01 00:00' find('img.ui-datepicker-trigger', match: :first).click end @@ -142,7 +142,7 @@ feature ' find('button.ui-datepicker-close', match: :first).click end - within("tr.order-cycle-#{oc_de.id}") do + within("tr.order-cycle-#{oc_pt.id}") do expect(find('input.datetimepicker', match: :first).value).to eq '2012-01-30 00:00' end end From 0e607003c183999ed2146c45bdae553f4d2ef15e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 28 Feb 2020 11:06:16 +0000 Subject: [PATCH 076/507] Fix problem in order cycles spec where miliseconds were not matching --- spec/models/order_cycle_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/order_cycle_spec.rb b/spec/models/order_cycle_spec.rb index 42fc875911..fb92fa8036 100644 --- a/spec/models/order_cycle_spec.rb +++ b/spec/models/order_cycle_spec.rb @@ -413,11 +413,11 @@ describe OrderCycle do let!(:oc3) { create(:simple_order_cycle, orders_close_at: time3, distributors: [e2]) } it "returns the closing time, indexed by enterprise id" do - expect(OrderCycle.earliest_closing_times[e1.id]).to eq(time1) + expect(OrderCycle.earliest_closing_times[e1.id].round).to eq(time1.round) end it "returns the earliest closing time" do - expect(OrderCycle.earliest_closing_times[e2.id]).to eq(time2) + expect(OrderCycle.earliest_closing_times[e2.id].round).to eq(time2.round) end end From 789ecbb8f2db04679e4a42670c9f247f998c45fb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 28 Feb 2020 12:06:44 +0100 Subject: [PATCH 077/507] Fix Gemfile.lock --- Gemfile.lock | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0c17daacb3..5319a16947 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -482,7 +482,6 @@ GEM polyamorous (0.6.4) activerecord (>= 3.0) polyglot (0.3.5) - power_assert (1.1.5) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -623,8 +622,7 @@ GEM state_machine (1.2.0) stringex (1.5.1) stripe (5.15.0) - test-unit (3.3.5) - power_assert + temple (0.8.2) test-unit (3.3.5) thor (0.20.3) thread_safe (0.3.6) From cc1ab1bdb94a4750ee8138f706ca4cdd0217be06 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 23 Feb 2020 16:32:54 +0100 Subject: [PATCH 078/507] Fix issue with broken SQL fragments in scopes and nested subqueries It looks like there are some issues with prepared statements here, where the resulting SQL contains something like: `WHERE "enterprise_roles"."user_id" = $1` in a subquery. The "$1" part is being lost somehow and isn't present if it's used in nested subqueries. Example fixed spec (there are lots like this one): 59) Spree::Admin::ReportsController Supplier Bulk Coop where I have granted P-OC to the distributor only shows product line items that I am supplying Failure/Error: produced_line_items.select("spree_line_items.id")) ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR: bind message supplies 0 parameters, but prepared statement "" requires 1 : SELECT id FROM "spree_line_items" WHERE "spree_line_items"."order_id" IN (SELECT id FROM "spree_orders" WHERE (("spree_orders"."distributor_id" IN (SELECT enterprises.id FROM "enterprises" INNER JOIN "enterprise_roles" ON "enterprise_roles"."enterprise_id" = "enterprises"."id" WHERE (enterprise_roles.user_id = 947)) OR "spree_orders"."order_cycle_id" IN (SELECT id FROM "order_cycles" WHERE "order_cycles"."coordinator_id" IN (SELECT "enterprises"."id" FROM "enterprises" INNER JOIN "enterprise_roles" ON "enterprises"."id" = "enterprise_roles"."enterprise_id" WHERE "enterprise_roles"."user_id" = $1))))) # ./app/services/permissions/order.rb:28:in `visible_line_items' # ./lib/open_food_network/reports/line_items.rb:16:in `list' # ./lib/open_food_network/bulk_coop_report.rb:54:in `table_items' # ./app/controllers/spree/admin/reports_controller.rb:264:in `order_grouper_table' # ./app/controllers/spree/admin/reports_controller.rb:101:in `bulk_coop' # ./spec/controllers/spree/admin/reports_controller_spec.rb:168:in `block (5 levels) in ' # ------------------ # --- Caused by: --- # PG::ProtocolViolation: # ERROR: bind message supplies 0 parameters, but prepared statement "" requires 1 # ./app/services/permissions/order.rb:28:in `visible_line_items' --- app/models/order_cycle.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 48bbaf249d..ba080e0cda 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -63,7 +63,7 @@ class OrderCycle < ActiveRecord::Base if user.has_spree_role?('admin') where(nil) else - where(coordinator_id: user.enterprises) + where(coordinator_id: user.enterprises.to_a) end } From 1f59bc8befeaaba60582014677393e61672940aa Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 26 Feb 2020 16:12:42 +0100 Subject: [PATCH 079/507] Use new branch of the paypal gem This uses the `2-1-0-stable` branch of the paypal gem. It's the 2-1-stable branch plus a couple of old OFN modifications (from 2-0-stable), plus a minor modification to the gemspec to allow it to be used with spree_core `2.1.0` --- Gemfile | 2 +- Gemfile.lock | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 938b2d88a3..d35748de34 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,7 @@ gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable' # Our branch contains two changes # - Pass customer email and phone number to PayPal (merged to upstream master) # - Change type of password from string to password to hide it in the form -# gem 'spree_paypal_express', github: "openfoodfoundation/better_spree_paypal_express", branch: "2-0-stable" +gem 'spree_paypal_express', github: 'openfoodfoundation/better_spree_paypal_express', branch: '2-1-0-stable' gem 'stripe' # We need at least this version to have Digicert's root certificate diff --git a/Gemfile.lock b/Gemfile.lock index 5319a16947..26bc8064bf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,6 +4,15 @@ GIT specs: custom_error_message (1.1.1) +GIT + remote: https://github.com/openfoodfoundation/better_spree_paypal_express.git + revision: e28e4a8c5cedba504eea9cdad4be440d277d7e68 + branch: 2-1-0-stable + specs: + spree_paypal_express (2.0.3) + paypal-sdk-merchant (= 1.106.1) + spree_core (~> 2.1.0) + GIT remote: https://github.com/openfoodfoundation/spree.git revision: 95d3ccb32f2e4016d0fc73f39446d1739da56c50 @@ -478,6 +487,11 @@ GEM activerecord (>= 4.0, < 6.1) parser (2.7.0.2) ast (~> 2.4.0) + paypal-sdk-core (0.2.10) + multi_json (~> 1.0) + xml-simple + paypal-sdk-merchant (1.106.1) + paypal-sdk-core (~> 0.2.3) pg (0.21.0) polyamorous (0.6.4) activerecord (>= 3.0) @@ -752,6 +766,7 @@ DEPENDENCIES spinjs-rails spree_core! spree_i18n! + spree_paypal_express! stripe test-unit (~> 3.3) timecop From 61439a375056e017e18abf7b1712b12e8e0d0213 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 26 Feb 2020 15:00:46 +0000 Subject: [PATCH 080/507] Re-add paypal controller code --- .../spree/paypal_controller_decorator.rb | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 app/controllers/spree/paypal_controller_decorator.rb diff --git a/app/controllers/spree/paypal_controller_decorator.rb b/app/controllers/spree/paypal_controller_decorator.rb new file mode 100644 index 0000000000..1512299198 --- /dev/null +++ b/app/controllers/spree/paypal_controller_decorator.rb @@ -0,0 +1,45 @@ +Spree::PaypalController.class_eval do + before_filter :enable_embedded_shopfront + before_filter :destroy_orphaned_paypal_payments, only: :confirm + after_filter :reset_order_when_complete, only: :confirm + + def cancel + flash[:notice] = Spree.t('flash.cancel', scope: 'paypal') + redirect_to main_app.checkout_path + end + + # Clears the cached order. Required for #current_order to return a new order + # to serve as cart. See https://github.com/spree/spree/blob/1-3-stable/core/lib/spree/core/controller_helpers/order.rb#L14 + # for details. + def expire_current_order + session[:order_id] = nil + @current_order = nil + end + + private + + def reset_order_when_complete + if current_order.complete? + flash[:notice] = t(:order_processed_successfully) + + ResetOrderService.new(self, current_order).call + session[:access_token] = current_order.token + end + end + + # See #1074 and #1837 for more detail on why we need this + # An 'orphaned' Spree::Payment is created for every call to CheckoutController#update + # for orders that are processed using a Spree::Gateway::PayPalExpress payment method + # These payments are 'orphaned' because they are never used by the spree_paypal_express gem + # which creates a brand new Spree::Payment from scratch in PayPalController#confirm + # However, the 'orphaned' payments are useful when applying a transaction fee, because the fees + # need to be calculated before the order details are sent to PayPal for confirmation + # This is our best hook for removing the orphaned payments at an appropriate time. ie. after + # the payment details have been confirmed, but before any payments have been processed + def destroy_orphaned_paypal_payments + return unless payment_method.is_a?(Spree::Gateway::PayPalExpress) + + orphaned_payments = current_order.payments.where(payment_method_id: payment_method.id, source_id: nil) + orphaned_payments.each(&:destroy) + end +end From 427d3b7641a1a15f9514f75a34db26316cb854ee Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 26 Feb 2020 15:01:11 +0000 Subject: [PATCH 081/507] Revert "Comment spree_paypal express in all.js temporarily" This reverts commit 26ba37b117848ecc8a55752bb4870467d5210039. --- app/assets/javascripts/admin/all.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 19359a9a05..5525aa6828 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -35,8 +35,7 @@ //= require equalize //= require css_browser_selector_dev //= require responsive-tables -// needs to be readded: -// require admin/spree_paypal_express +//= require admin/spree_paypal_express //= require admin/handlebar_extensions // OFN specific From 4f3247c196ac07b82a92a157a15b80c80926d9cf Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 26 Feb 2020 15:01:27 +0000 Subject: [PATCH 082/507] Revert "Temporarily remove broken specs" This reverts commit c0dc999e0da7f646d6adca767b74a2338d38fabe. --- .../spree/paypal_controller_spec.rb | 42 ++++++++++++++ spec/models/spree/gateway_tagging_spec.rb | 55 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 spec/controllers/spree/paypal_controller_spec.rb create mode 100644 spec/models/spree/gateway_tagging_spec.rb diff --git a/spec/controllers/spree/paypal_controller_spec.rb b/spec/controllers/spree/paypal_controller_spec.rb new file mode 100644 index 0000000000..90f97fcb7d --- /dev/null +++ b/spec/controllers/spree/paypal_controller_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +module Spree + describe PaypalController, type: :controller do + context 'when cancelling' do + it 'redirects back to checkout' do + expect(spree_get(:cancel)).to redirect_to checkout_path + end + end + + context 'when confirming' do + let(:previous_order) { controller.current_order(true) } + let(:payment_method) { create(:payment_method) } + + before do + allow(previous_order).to receive(:complete?).and_return(true) + end + + it 'resets the order' do + spree_post :confirm, payment_method_id: payment_method.id + expect(controller.current_order).not_to eq(previous_order) + end + + it 'sets the access token of the session' do + spree_post :confirm, payment_method_id: payment_method.id + expect(session[:access_token]).to eq(controller.current_order.token) + end + end + + describe '#expire_current_order' do + it 'empties the order_id of the session' do + expect(session).to receive(:[]=).with(:order_id, nil) + controller.expire_current_order + end + + it 'resets the @current_order ivar' do + controller.expire_current_order + expect(controller.instance_variable_get(:@current_order)).to be_nil + end + end + end +end diff --git a/spec/models/spree/gateway_tagging_spec.rb b/spec/models/spree/gateway_tagging_spec.rb new file mode 100644 index 0000000000..2a5eb5c23e --- /dev/null +++ b/spec/models/spree/gateway_tagging_spec.rb @@ -0,0 +1,55 @@ +require "spec_helper" + +# We extended Spree::PaymentMethod to be taggable. Unfortunately, an inheritance +# bug prevented the taggable code to be passed on to the descendants of +# PaymentMethod. We fixed that in config/initializers/spree.rb. +# +# This spec tests several descendants for their taggability. The tests are in +# a separate file, because they cover one aspect of several classes. +shared_examples "taggable" do |expected_taggable_type| + it "provides a tag list" do + expect(subject.tag_list).to eq [] + end + + it "stores tags for the root taggable type" do + subject.tag_list.add("one") + subject.save! + + expect(subject.taggings.last.taggable_type).to eq expected_taggable_type + end +end + +module Spree + describe "PaymentMethod and descendants" do + let(:shop) { create(:enterprise) } + let(:valid_subject) do + # Supply required parameters so that it can be saved to attach taggings. + described_class.new( + name: "Some payment method", + distributor_ids: [shop.id] + ) + end + subject { valid_subject } + + describe PaymentMethod do + it_behaves_like "taggable", "Spree::PaymentMethod" + end + + describe Gateway do + it_behaves_like "taggable", "Spree::PaymentMethod" + end + + describe Gateway::PayPalExpress do + it_behaves_like "taggable", "Spree::PaymentMethod" + end + + describe Gateway::StripeConnect do + subject do + # StripeConnect needs an owner to be valid. + valid_subject.tap { |m| m.preferred_enterprise_id = shop.id } + end + + it_behaves_like "taggable", "Spree::PaymentMethod" + end + end +end From 78e430613fc9f7c89e455e71d19b8109b4671b94 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 27 Feb 2020 13:05:46 +0100 Subject: [PATCH 083/507] Fix spree routes helper in payment_redirect.rb --- app/services/checkout/payment_redirect.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/checkout/payment_redirect.rb b/app/services/checkout/payment_redirect.rb index 1e74a9daa7..d6c632dce3 100644 --- a/app/services/checkout/payment_redirect.rb +++ b/app/services/checkout/payment_redirect.rb @@ -21,7 +21,7 @@ module Checkout private def spree_routes_helper - Spree::Core::Engine.routes_url_helpers + Spree::Core::Engine.routes.url_helpers end end end From 95996dc11e345cd89c7e8c9dde2645b2e9d75ec9 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 27 Feb 2020 12:20:34 +0100 Subject: [PATCH 084/507] Un-comment :credit_cards in routes --- config/routes/spree.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes/spree.rb b/config/routes/spree.rb index 6c6c1a376d..0dd14c8dea 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -47,7 +47,7 @@ Spree::Core::Engine.routes.draw do match '/admin', to: 'admin/overview#index', as: :admin_dashboard, via: :get - #resources :credit_cards + resources :credit_cards namespace :admin do get '/search/known_users' => "search#known_users", :as => :search_known_users From eef1574ebebb8b0481c456335505b5dccfb34023 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 26 Feb 2020 18:03:19 +0100 Subject: [PATCH 085/507] Call #permit on params object in before_filter --- app/controllers/spree/paypal_controller_decorator.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/spree/paypal_controller_decorator.rb b/app/controllers/spree/paypal_controller_decorator.rb index 1512299198..c6bbbd744d 100644 --- a/app/controllers/spree/paypal_controller_decorator.rb +++ b/app/controllers/spree/paypal_controller_decorator.rb @@ -2,6 +2,7 @@ Spree::PaypalController.class_eval do before_filter :enable_embedded_shopfront before_filter :destroy_orphaned_paypal_payments, only: :confirm after_filter :reset_order_when_complete, only: :confirm + before_filter :permit_parameters! def cancel flash[:notice] = Spree.t('flash.cancel', scope: 'paypal') @@ -18,6 +19,10 @@ Spree::PaypalController.class_eval do private + def permit_parameters! + params.permit(:token, :payment_method_id, :PayerID) + end + def reset_order_when_complete if current_order.complete? flash[:notice] = t(:order_processed_successfully) From a9e662263996711c1aad007b2d66764297620bff Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 27 Feb 2020 15:20:30 +0100 Subject: [PATCH 086/507] Update product import #assign_attributes calls For some reason some of the superfluous attributes being assigned here have started throwing fatal errors in Rails 4 instead of being silently ignored... --- app/models/product_import/entry_processor.rb | 2 +- app/models/product_import/entry_validator.rb | 11 ++++++++--- app/models/product_import/spreadsheet_entry.rb | 9 +++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/models/product_import/entry_processor.rb b/app/models/product_import/entry_processor.rb index eab1ed4cc3..64d444aaed 100644 --- a/app/models/product_import/entry_processor.rb +++ b/app/models/product_import/entry_processor.rb @@ -162,7 +162,7 @@ module ProductImport end product = Spree::Product.new - product.assign_attributes(entry.attributes.except('id', 'on_hand', 'on_demand')) + product.assign_attributes(entry.assignable_attributes.except('id', 'on_hand', 'on_demand', 'display_name')) product.supplier_id = entry.producer_id assign_defaults(product, entry) diff --git a/app/models/product_import/entry_validator.rb b/app/models/product_import/entry_validator.rb index 475dae953c..1f27ed7af7 100644 --- a/app/models/product_import/entry_validator.rb +++ b/app/models/product_import/entry_validator.rb @@ -62,7 +62,10 @@ module ProductImport end def mark_as_new_variant(entry, product_id) - new_variant = Spree::Variant.new(entry.attributes.except('id', 'product_id', 'on_hand', 'on_demand')) + new_variant = Spree::Variant.new( + entry.assignable_attributes.except('id', 'product_id', 'on_hand', 'on_demand', + 'variant_unit', 'variant_unit_scale', 'primary_taxon_id') + ) new_variant.save new_variant.on_demand = entry.attributes['on_demand'] if entry.attributes['on_demand'].present? new_variant.on_hand = entry.attributes['on_hand'] if entry.attributes['on_hand'].present? @@ -295,7 +298,7 @@ module ProductImport def mark_as_new_product(entry) new_product = Spree::Product.new - new_product.assign_attributes(entry.attributes.except('id')) + new_product.assign_attributes(entry.assignable_attributes.except('id', 'on_hand', 'on_demand', 'display_name')) new_product.supplier_id = entry.producer_id entry.on_hand = 0 if entry.on_hand.nil? @@ -307,7 +310,9 @@ module ProductImport end def mark_as_existing_variant(entry, existing_variant) - existing_variant.assign_attributes(entry.attributes.except('id', 'product_id')) + existing_variant.assign_attributes( + entry.assignable_attributes.except('id', 'product_id', 'variant_unit', 'variant_unit_scale', 'primary_taxon_id') + ) check_on_hand_nil(entry, existing_variant) if existing_variant.valid? diff --git a/app/models/product_import/spreadsheet_entry.rb b/app/models/product_import/spreadsheet_entry.rb index 990124e24b..9fd6ffd034 100644 --- a/app/models/product_import/spreadsheet_entry.rb +++ b/app/models/product_import/spreadsheet_entry.rb @@ -46,6 +46,10 @@ module ProductImport attrs.except(*non_product_attributes) end + def assignable_attributes + attributes.except(*non_assignable_attributes) + end + def displayable_attributes # Modified attributes list for displaying in user feedback attrs = {} @@ -92,5 +96,10 @@ module ProductImport 'product_validations', 'inventory_validations', 'validates_as', 'save_type', 'on_hand_nil', 'has_overrides'] end + + def non_assignable_attributes + ['producer', 'producer_id', 'category', 'shipping_category', 'tax_category', + 'units', 'unscaled_units', 'unit_type', 'enterprise', 'enterprise_id'] + end end end From 5c526bf5cca66ad844e2bf98251f0fef5fb698f2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 28 Feb 2020 11:33:04 +0100 Subject: [PATCH 087/507] Move definitions into constants and use #freeze --- .../product_import/spreadsheet_entry.rb | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/app/models/product_import/spreadsheet_entry.rb b/app/models/product_import/spreadsheet_entry.rb index 9fd6ffd034..f9ccac04a5 100644 --- a/app/models/product_import/spreadsheet_entry.rb +++ b/app/models/product_import/spreadsheet_entry.rb @@ -20,6 +20,20 @@ module ProductImport :tax_category_id, :shipping_category_id, :description, :import_date, :enterprise, :enterprise_id + NON_DISPLAY_ATTRIBUTES = ['id', 'product_id', 'unscaled_units', 'variant_id', 'enterprise', + 'enterprise_id', 'producer_id', 'distributor_id', 'primary_taxon', + 'primary_taxon_id', 'category_id', 'shipping_category_id', + 'tax_category_id', 'variant_unit_scale', 'variant_unit', + 'unit_value'].freeze + + NON_PRODUCT_ATTRIBUTES = ['line_number', 'valid', 'errors', 'product_object', + 'product_validations', 'inventory_validations', 'validates_as', + 'save_type', 'on_hand_nil', 'has_overrides'].freeze + + NON_ASSIGNABLE_ATTRIBUTES = ['producer', 'producer_id', 'category', 'shipping_category', + 'tax_category', 'units', 'unscaled_units', 'unit_type', + 'enterprise', 'enterprise_id'].freeze + def initialize(attrs) @validates_as = '' remove_empty_skus attrs @@ -43,11 +57,11 @@ module ProductImport instance_variables.each do |var| attrs[var.to_s.delete("@")] = instance_variable_get(var) end - attrs.except(*non_product_attributes) + attrs.except(*NON_PRODUCT_ATTRIBUTES) end def assignable_attributes - attributes.except(*non_assignable_attributes) + attributes.except(*NON_ASSIGNABLE_ATTRIBUTES) end def displayable_attributes @@ -56,7 +70,7 @@ module ProductImport instance_variables.each do |var| attrs[var.to_s.delete("@")] = instance_variable_get(var) end - attrs.except(*non_product_attributes, *non_display_attributes) + attrs.except(*NON_PRODUCT_ATTRIBUTES, *NON_DISPLAY_ATTRIBUTES) end def invalid_attributes @@ -65,7 +79,7 @@ module ProductImport errors.each do |attr, message| invalid_attrs[attr.to_s] = "#{attr.to_s.capitalize} #{message.first}" end - invalid_attrs.except(*non_product_attributes, *non_display_attributes) + invalid_attrs.except(* NON_PRODUCT_ATTRIBUTES, *NON_DISPLAY_ATTRIBUTES) end private @@ -79,27 +93,9 @@ module ProductImport units.converted_attributes.each do |attr, value| if respond_to?("#{attr}=") - public_send("#{attr}=", value) unless non_product_attributes.include?(attr) + public_send("#{attr}=", value) unless NON_PRODUCT_ATTRIBUTES.include?(attr) end end end - - def non_display_attributes - ['id', 'product_id', 'unscaled_units', 'variant_id', 'enterprise', - 'enterprise_id', 'producer_id', 'distributor_id', 'primary_taxon', - 'primary_taxon_id', 'category_id', 'shipping_category_id', - 'tax_category_id', 'variant_unit_scale', 'variant_unit', 'unit_value'] - end - - def non_product_attributes - ['line_number', 'valid', 'errors', 'product_object', - 'product_validations', 'inventory_validations', 'validates_as', - 'save_type', 'on_hand_nil', 'has_overrides'] - end - - def non_assignable_attributes - ['producer', 'producer_id', 'category', 'shipping_category', 'tax_category', - 'units', 'unscaled_units', 'unit_type', 'enterprise', 'enterprise_id'] - end end end From 7dbe0bd6b997b8916ee142032c6bc7a05b7d5f81 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 28 Feb 2020 15:10:30 +0100 Subject: [PATCH 088/507] Use new branch of `ofn-qz` gem --- Gemfile | 2 +- Gemfile.lock | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index d35748de34..434fd083f4 100644 --- a/Gemfile +++ b/Gemfile @@ -118,7 +118,7 @@ gem 'jquery-rails', '3.0.4' gem 'jquery-ui-rails', '~> 4.0.0' gem 'select2-rails', '~> 3.4.7' -# gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', ref: '60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c' +gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', branch: 'ofn-rails-4' group :production, :staging do gem 'ddtrace' diff --git a/Gemfile.lock b/Gemfile.lock index 26bc8064bf..58068e8222 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,6 +13,13 @@ GIT paypal-sdk-merchant (= 1.106.1) spree_core (~> 2.1.0) +GIT + remote: https://github.com/openfoodfoundation/ofn-qz.git + revision: 467f6ea1c44529c7c91cac4c8211bbd863588c0b + branch: ofn-rails-4 + specs: + ofn-qz (0.1.0) + GIT remote: https://github.com/openfoodfoundation/spree.git revision: 95d3ccb32f2e4016d0fc73f39446d1739da56c50 @@ -737,6 +744,7 @@ DEPENDENCIES momentjs-rails nokogiri (~> 1.6.8.1) oauth2 (~> 1.4.4) + ofn-qz! oj order_management! paper_trail (~> 5.2.3) From 847a349a6bd6a7257e8bf1ec98c580596516c2db Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 29 Feb 2020 12:40:40 +0100 Subject: [PATCH 089/507] Fix geocoding in Rails 4 :tada: Responsibility for geocoding has moved from the `gmaps4rails` gem using `acts_as_taggable`, to the `geocoding` gem using `geocoded_by`. We already use this in the Address model. --- app/models/enterprise.rb | 2 -- config/initializers/geocoder.rb | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 3c356134fc..52b5ccac4e 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -17,8 +17,6 @@ class Enterprise < ActiveRecord::Base self.inheritance_column = nil - # acts_as_gmappable process_geocoding: false - has_many :relationships_as_parent, class_name: 'EnterpriseRelationship', foreign_key: 'parent_id', dependent: :destroy diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb index 35b5510d5e..67ae27e7e4 100644 --- a/config/initializers/geocoder.rb +++ b/config/initializers/geocoder.rb @@ -1,6 +1,7 @@ # Google requires an API key with a billing account to use their API. # The key is stored in config/application.yml. Geocoder.configure( + lookup: :google, use_https: true, api_key: ENV.fetch('GOOGLE_MAPS_API_KEY', nil) ) From a0999f5d58370e1409f48bcd8849d4bb413c73d8 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 1 Mar 2020 18:40:15 +0100 Subject: [PATCH 090/507] Check #persisted? before calling #touch Rails 4 now throws a fatal error if calling #touch on an object that hasn't been saved yet: https://github.com/rails/rails/blob/c63cfc8722292ec39def505861fbc20bd9774f4c/activerecord/lib/active_record/persistence.rb#L957 Fixes: 41) Stock::Package#shipping_methods does not return shipping methods not used by the package's order distributor Failure/Error: distributors.each(&:touch) ActiveRecord::ActiveRecordError: can not touch on a new record object # ./app/models/spree/shipping_method_decorator.rb:81:in `touch_distributors' # ./spec/models/stock/package_spec.rb:39:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:17:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:32:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:7:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:44:in `block (3 levels) in ' 42) Stock::Package#shipping_categories returns shipping categories that are not shipping categories of the order's products Failure/Error: distributors.each(&:touch) ActiveRecord::ActiveRecordError: can not touch on a new record object # ./app/models/spree/shipping_method_decorator.rb:81:in `touch_distributors' # ./spec/models/stock/package_spec.rb:39:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:17:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:32:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:7:in `block (2 levels) in ' # ./spec/models/stock/package_spec.rb:50:in `block (3 levels) in ' --- app/models/spree/shipping_method_decorator.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index 837fd45ee6..c44bffe546 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -78,6 +78,8 @@ Spree::ShippingMethod.class_eval do private def touch_distributors - distributors.each(&:touch) + distributors.each do |distributor| + distributor.touch if distributor.persisted? + end end end From ed5351d23ed072f1a73f33c9574da51fdd3485af Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 2 Mar 2020 19:02:07 +0100 Subject: [PATCH 091/507] Fix duplicate validations in payment methods and shipping methods Updates the syntax to follow the recommended usage in the code comments of the ActiveModel #validates_with method. Fixes: 12) Spree::PaymentMethod raises errors when required fields are missing Failure/Error: expect(pm.errors.to_a).to eq(["Name can't be blank", "At least one hub must be selected"]) expected: ["Name can't be blank", "At least one hub must be selected"] got: ["Name can't be blank", "At least one hub must be selected", "At least one hub must be selected"] (compared using ==) # ./spec/models/spree/payment_method_spec.rb:16:in `block (2 levels) in ' --- app/models/spree/payment_method_decorator.rb | 8 +++++++- app/models/spree/shipping_method_decorator.rb | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/models/spree/payment_method_decorator.rb b/app/models/spree/payment_method_decorator.rb index 4cbb7e85d9..ebe5a68ad2 100644 --- a/app/models/spree/payment_method_decorator.rb +++ b/app/models/spree/payment_method_decorator.rb @@ -10,7 +10,7 @@ Spree::PaymentMethod.class_eval do after_initialize :init - validates_with DistributorsValidator + validate :distributor_validation # -- Scopes scope :managed_by, lambda { |user| @@ -73,4 +73,10 @@ Spree::PaymentMethod.class_eval do name[i..-1] end end + + private + + def distributor_validation + validates_with DistributorsValidator + end end diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index 837fd45ee6..55f79c946b 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -6,7 +6,7 @@ Spree::ShippingMethod.class_eval do after_save :touch_distributors - validates_with DistributorsValidator + validate :distributor_validation scope :managed_by, lambda { |user| if user.has_spree_role?('admin') @@ -80,4 +80,8 @@ Spree::ShippingMethod.class_eval do def touch_distributors distributors.each(&:touch) end + + def distributor_validation + validates_with DistributorsValidator + end end From 0784b8263ae1d3438a9170ba28c6afd53507f691 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 2 Mar 2020 19:22:43 +0100 Subject: [PATCH 092/507] Fix spec setup in api/orders_controller_spec ActionController doesn't accept nil values for :id as a valid route request in Rails 4. Fixes: 2) Api::OrdersController#show Resource not found when no order number is given Failure/Error: get :show, id: nil ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"api/orders", :id=>nil} # ./spec/controllers/api/orders_controller_spec.rb:168:in `block (4 levels) in ' --- spec/controllers/api/orders_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/api/orders_controller_spec.rb b/spec/controllers/api/orders_controller_spec.rb index 5e463fe7a2..69438ec2da 100644 --- a/spec/controllers/api/orders_controller_spec.rb +++ b/spec/controllers/api/orders_controller_spec.rb @@ -165,7 +165,7 @@ module Api before { allow(controller).to receive(:spree_current_user) { admin_user } } it "when no order number is given" do - get :show, id: nil + get :show, id: "" expect(response).to have_http_status(:not_found) end From 0d08ad7d2e98b9bdfa08010765dc0bc671bab122 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 2 Mar 2020 19:41:47 +0100 Subject: [PATCH 093/507] Fix expectation in helper spec The output of this link helper has changed slightly. All the attributes are the same as before, but they seem to be in alphabetical order now. Fixes: 69) Spree::BaseHelper#link_to_remove_fields returns an `a` tag followed by a hidden `input` tag Failure/Error: expect(subject).to eq("Hola<input type="hidden" name="_method" value="destroy">") expected: "<input type="hidden" name="_method" value="destroy">" got: "<input type="hidden" name="_method" value="destroy">" (compared using ==) # ./spec/helpers/spree/admin/base_helper_spec.rb:12:in `block (3 levels) in ' --- spec/helpers/spree/admin/base_helper_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/helpers/spree/admin/base_helper_spec.rb b/spec/helpers/spree/admin/base_helper_spec.rb index a47b04113f..db15d2a283 100644 --- a/spec/helpers/spree/admin/base_helper_spec.rb +++ b/spec/helpers/spree/admin/base_helper_spec.rb @@ -9,7 +9,7 @@ describe Spree::BaseHelper, type: :helper do subject { helper.link_to_remove_fields(name, form, options) } it 'returns an `a` tag followed by a hidden `input` tag' do - expect(subject).to eq("Hola<input type="hidden" name="_method" value="destroy">") + expect(subject).to eq("Hola<input type="hidden" name="_method" value="destroy">") end end end From 13b8cfcd9c8d5200a6103e5d2c5cfd4e214f2408 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 2 Mar 2020 20:37:58 +0100 Subject: [PATCH 094/507] Remove assignment of invalid attribute in test setup Fixes: 11) Order Management viewing a completed order when checking out as an anonymous guest allows the user to see the details Failure/Error: order.update_attributes!( bill_address: bill_address, ship_address: ship_address, shipping_method_id: shipping_method.id ) ActiveRecord::UnknownAttributeError: unknown attribute: shipping_method_id # ./spec/features/consumer/shopping/orders_spec.rb:30:in `block (3 levels) in ' # ------------------ # --- Caused by: --- # NoMethodError: # undefined method `shipping_method_id=' for # # ./spec/features/consumer/shopping/orders_spec.rb:30:in `block (3 levels) in ' 12) Order Management viewing a completed order when logged in as the customer allows the user to see order details Failure/Error: order.update_attributes!( bill_address: bill_address, ship_address: ship_address, shipping_method_id: shipping_method.id ) ActiveRecord::UnknownAttributeError: unknown attribute: shipping_method_id # ./spec/features/consumer/shopping/orders_spec.rb:30:in `block (3 levels) in ' # ------------------ # --- Caused by: --- # NoMethodError: # undefined method `shipping_method_id=' for # # ./spec/features/consumer/shopping/orders_spec.rb:30:in `block (3 levels) in ' 13) Order Management viewing a completed order when not logged in allows the user to see order details after login Failure/Error: order.update_attributes!( bill_address: bill_address, ship_address: ship_address, shipping_method_id: shipping_method.id ) ActiveRecord::UnknownAttributeError: unknown attribute: shipping_method_id # ./spec/features/consumer/shopping/orders_spec.rb:30:in `block (3 levels) in ' # ------------------ # --- Caused by: --- # NoMethodError: # undefined method `shipping_method_id=' for # # ./spec/features/consumer/shopping/orders_spec.rb:30:in `block (3 levels) in ' --- spec/features/consumer/shopping/orders_spec.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb index 90c3e6ad5f..e9b342c1c7 100644 --- a/spec/features/consumer/shopping/orders_spec.rb +++ b/spec/features/consumer/shopping/orders_spec.rb @@ -24,13 +24,9 @@ feature "Order Management", js: true do before do # For some reason, both bill_address and ship_address are not set # automatically. - # - # Also, assigning the shipping_method to a ShippingMethod instance results - # in a SystemStackError. order.update_attributes!( bill_address: bill_address, - ship_address: ship_address, - shipping_method_id: shipping_method.id + ship_address: ship_address ) end From 6cb8bb2fc3ef3b947550698db2f539c39db1c199 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 2 Mar 2020 22:07:20 +0100 Subject: [PATCH 095/507] Add missing :cc_type attribute to default :credit_card factory Fixes 5 specs, including: 11) Spree::CreditCardsController#update when the specified credit card is found and the card is owned by the user when the update completes successfully renders a serialized copy of the updated card Failure/Error: object.cc_type.capitalize NoMethodError: undefined method `capitalize' for nil:NilClass # ./app/serializers/api/credit_card_serializer.rb:6:in `brand' # (eval):4:in `_fast_attributes' # ./app/controllers/spree/credit_cards_controller.rb:26:in `update' # ./spec/controllers/spree/credit_cards_controller_spec.rb:100:in `block (7 levels) in ' # ./spec/controllers/spree/credit_cards_controller_spec.rb:100:in `block (6 levels) in ' # ------------------ # --- Caused by: --- # NoMethodError: # undefined method `capitalize' for nil:NilClass # ./app/serializers/api/credit_card_serializer.rb:6:in `brand' --- spec/factories.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/factories.rb b/spec/factories.rb index 8474d44a6e..40de71effa 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -164,6 +164,10 @@ FactoryBot.modify do country { Spree::Country.find_by name: 'Australia' || Spree::Country.first } end + factory :credit_card do + cc_type 'visa' + end + factory :payment do transient do distributor { From e584233c9e07d39504bfcc28e0de5feae93bdd7e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 3 Mar 2020 14:25:17 +0000 Subject: [PATCH 096/507] Uncomment code that was commented earlier on in the upgrade, we are now ready to handle this --- app/models/enterprise.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 52b5ccac4e..887b1deccd 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -433,21 +433,21 @@ class Enterprise < ActiveRecord::Base # We grant permissions to all pre-existing hubs hub_permissions = [:add_to_order_cycle] hub_permissions << :create_variant_overrides if is_primary_producer - #enterprises.is_hub.each do |enterprise| - # EnterpriseRelationship.create!(parent: self, - # child: enterprise, - # permissions_list: hub_permissions) - #end + enterprises.is_hub.each do |enterprise| + EnterpriseRelationship.create!(parent: self, + child: enterprise, + permissions_list: hub_permissions) + end # All pre-existing producers grant permission to new hubs - #if is_hub - # enterprises.is_primary_producer.each do |enterprise| - # EnterpriseRelationship.create!(parent: enterprise, - # child: self, - # permissions_list: [:add_to_order_cycle, - # :create_variant_overrides]) - # end - #end + if is_hub + enterprises.is_primary_producer.each do |enterprise| + EnterpriseRelationship.create!(parent: enterprise, + child: self, + permissions_list: [:add_to_order_cycle, + :create_variant_overrides]) + end + end end def shopfront_taxons From d8a92eec4b419669de7b498f2085777c9d76964d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 3 Mar 2020 16:37:00 +0000 Subject: [PATCH 097/507] Bring Shipment#manifest from spree as is --- app/models/spree/shipment_decorator.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/models/spree/shipment_decorator.rb b/app/models/spree/shipment_decorator.rb index b9cb0d07f1..a6f9e724ba 100644 --- a/app/models/spree/shipment_decorator.rb +++ b/app/models/spree/shipment_decorator.rb @@ -15,6 +15,14 @@ module Spree end end + def manifest + inventory_units.joins(:variant).includes(:variant).group_by(&:variant).map do |variant, units| + states = {} + units.group_by(&:state).each { |state, iu| states[state] = iu.count } + OpenStruct.new(variant: variant, quantity: units.length, states: states) + end + end + # The shipment manifest is built by loading inventory units and variants from the DB # These variants come unscoped # So, we need to scope the variants just after the manifest is built From 5688de4936124ae5266dcdcd606c0bcf95a0bd60 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 3 Mar 2020 16:38:03 +0000 Subject: [PATCH 098/507] Make Shipment#manifest work with deleted variants again This makes the default variant scope in inventory_unit being used which includes deleted variants --- app/models/spree/shipment_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/spree/shipment_decorator.rb b/app/models/spree/shipment_decorator.rb index a6f9e724ba..540a327268 100644 --- a/app/models/spree/shipment_decorator.rb +++ b/app/models/spree/shipment_decorator.rb @@ -16,7 +16,7 @@ module Spree end def manifest - inventory_units.joins(:variant).includes(:variant).group_by(&:variant).map do |variant, units| + inventory_units.group_by(&:variant).map do |variant, units| states = {} units.group_by(&:state).each { |state, iu| states[state] = iu.count } OpenStruct.new(variant: variant, quantity: units.length, states: states) From 3b37fa88722981a152d3e9ee0ee8e504f2761367 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 3 Mar 2020 16:40:31 +0000 Subject: [PATCH 099/507] Move variant scoping from alias method into manifest method --- app/models/spree/shipment_decorator.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/models/spree/shipment_decorator.rb b/app/models/spree/shipment_decorator.rb index 540a327268..b23bd7266f 100644 --- a/app/models/spree/shipment_decorator.rb +++ b/app/models/spree/shipment_decorator.rb @@ -19,18 +19,11 @@ module Spree inventory_units.group_by(&:variant).map do |variant, units| states = {} units.group_by(&:state).each { |state, iu| states[state] = iu.count } + scoper.scope(variant) OpenStruct.new(variant: variant, quantity: units.length, states: states) end end - # The shipment manifest is built by loading inventory units and variants from the DB - # These variants come unscoped - # So, we need to scope the variants just after the manifest is built - def manifest_with_scoping - manifest_without_scoping.each { |item| scoper.scope(item.variant) } - end - alias_method_chain :manifest, :scoping - def scoper @scoper ||= OpenFoodNetwork::ScopeVariantToHub.new(order.distributor) end From 0f726c207fef2a7d678b8d3b04aea82966e18728 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 4 Mar 2020 14:47:15 +0000 Subject: [PATCH 100/507] Fix shipments controller after PR #4675 adapted code to rails 4 finders --- spec/controllers/api/shipments_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/api/shipments_controller_spec.rb b/spec/controllers/api/shipments_controller_spec.rb index 9e838617e3..659e1dc761 100644 --- a/spec/controllers/api/shipments_controller_spec.rb +++ b/spec/controllers/api/shipments_controller_spec.rb @@ -214,7 +214,7 @@ describe Api::ShipmentsController, type: :controller do end def make_order_contents_fail - expect(Spree::Order).to receive(:find_by_number!) { order } + expect(Spree::Order).to receive(:find_by!).with({ number: order.number }) { order } expect(order).to receive(:contents) { raise error_message } end From cfbec2accc67012116e52301379468d5603918cc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 5 Mar 2020 11:55:13 +0000 Subject: [PATCH 101/507] Fix controller specs after PR #4675 adapted code to rails 4 finders --- spec/controllers/admin/enterprises_controller_spec.rb | 4 ++-- spec/controllers/api/enterprises_controller_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb index a8c2802e47..a95334d292 100644 --- a/spec/controllers/admin/enterprises_controller_spec.rb +++ b/spec/controllers/admin/enterprises_controller_spec.rb @@ -449,8 +449,8 @@ module Admin before do # As a user with permission allow(controller).to receive_messages spree_current_user: user - allow(OrderCycle).to receive_messages find_by_id: "existing OrderCycle" - allow(Enterprise).to receive_messages find_by_id: "existing Enterprise" + allow(OrderCycle).to receive_messages find_by: "existing OrderCycle" + allow(Enterprise).to receive_messages find_by: "existing Enterprise" allow(OrderCycle).to receive_messages new: "new OrderCycle" allow(OpenFoodNetwork::OrderCyclePermissions).to receive(:new) { permission_mock } diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index 364a7fd146..05a26ec143 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -52,7 +52,7 @@ module Api describe "submitting a valid image" do before do allow(Enterprise) - .to receive(:find_by_permalink).with(enterprise.id.to_s) { enterprise } + .to receive(:find_by).with({ permalink: enterprise.id.to_s }) { enterprise } allow(enterprise).to receive(:update_attributes).and_return(true) end @@ -68,7 +68,7 @@ module Api before do allow(Enterprise) - .to receive(:find_by_permalink).with(enterprise.id.to_s) { enterprise } + .to receive(:find_by).with({ permalink: enterprise.id.to_s }) { enterprise } allow(controller).to receive(:spree_current_user) { non_managing_user } end From 4b21aaafc44de7dd2ea28d61ad422d8566b55667 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 13:51:53 +0000 Subject: [PATCH 102/507] Convert ActiveRecord_Associations_CollectionProxy to array so that the modifications the tagRuleApplicator does on it will remain Reject on ActiveRecord_Associations_CollectionProxy wont work --- app/helpers/enterprises_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/enterprises_helper.rb b/app/helpers/enterprises_helper.rb index 64d78e7e93..0b6383f1b3 100644 --- a/app/helpers/enterprises_helper.rb +++ b/app/helpers/enterprises_helper.rb @@ -14,7 +14,7 @@ module EnterprisesHelper def available_shipping_methods return [] if current_distributor.blank? - shipping_methods = current_distributor.shipping_methods + shipping_methods = current_distributor.shipping_methods.to_a applicator = OpenFoodNetwork::TagRuleApplicator.new(current_distributor, "FilterShippingMethods", current_customer.andand.tag_list) applicator.filter!(shipping_methods) From 063f733dda1445cc743020f4dbc4f1b8a52594eb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 15:05:29 +0000 Subject: [PATCH 103/507] Use latest version of spree which includes PR openfoodfoundation/spree#39 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 58068e8222..88570026b9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,7 +22,7 @@ GIT GIT remote: https://github.com/openfoodfoundation/spree.git - revision: 95d3ccb32f2e4016d0fc73f39446d1739da56c50 + revision: b7ad5b473f9e38c5a1882550b2b4e348f4824f1f branch: 2-1-0-stable specs: spree_core (2.1.0) From 855d08957c177f545ecf7dbd6328f7cf6cfd55c8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 16:00:16 +0000 Subject: [PATCH 104/507] Adjust completed_order_with_totals to have a distributor so that logic around refreshing shipping rates doesnt fail badly --- spec/factories/order_factory.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/factories/order_factory.rb b/spec/factories/order_factory.rb index bab9767ca0..8948a8d247 100644 --- a/spec/factories/order_factory.rb +++ b/spec/factories/order_factory.rb @@ -118,4 +118,8 @@ FactoryBot.modify do end end end + + factory :completed_order_with_totals do + distributor { create(:distributor_enterprise) } + end end From e4d307fe5efe88357b9a1e83796cf2941a7a3fdb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 7 Mar 2020 12:52:32 +0000 Subject: [PATCH 105/507] Remove dead code related to user management --- .../spree/admin/users_controller.rb | 3 +-- app/models/spree/user.rb | 23 ------------------ spec/models/spree/user_spec.rb | 24 ------------------- 3 files changed, 1 insertion(+), 49 deletions(-) diff --git a/app/controllers/spree/admin/users_controller.rb b/app/controllers/spree/admin/users_controller.rb index 8ebd40cbfc..a1db20605c 100644 --- a/app/controllers/spree/admin/users_controller.rb +++ b/app/controllers/spree/admin/users_controller.rb @@ -76,7 +76,6 @@ module Spree return @collection if @collection.present? if request.xhr? && params[:q].present? - # Disabling proper nested include here due to rails 3.1 bug @collection = Spree::User. includes(:bill_address, :ship_address). where("spree_users.email #{LIKE} :search @@ -91,7 +90,7 @@ module Spree search: "#{params[:q].strip}%"). limit(params[:limit] || 100) else - @search = Spree::User.registered.ransack(params[:q]) + @search = Spree::User.ransack(params[:q]) @collection = @search. result. page(params[:page]). diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index c5bc3e9010..814ba38a6c 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -14,7 +14,6 @@ module Spree roles_table_name = Role.table_name scope :admin, lambda { includes(:spree_roles).where("#{roles_table_name}.name" => "admin") } - scope :registered, -> { where("#{users_table_name}.email NOT LIKE ?", "%@example.net") } has_many :enterprise_roles, dependent: :destroy has_many :enterprises, through: :enterprise_roles @@ -43,16 +42,6 @@ module Spree class DestroyWithOrdersError < StandardError; end - # Creates an anonymous user. An anonymous user is basically an auto-generated +User+ account - # that is created for the customer behind the scenes and it's transparent to the customer. - # All +Orders+ must have a +User+ so this is necessary when adding to the "cart" (an order) - # and before the customer has a chance to provide an email or to register. - def self.anonymous! - token = User.generate_token(:persistence_token) - User.create(email: "#{token}@example.net", - password: token, password_confirmation: token, persistence_token: token) - end - def self.admin_created? User.admin.count > 0 end @@ -61,10 +50,6 @@ module Spree has_spree_role?('admin') end - def anonymous? - email =~ /@example.net$/ ? true : false - end - def send_reset_password_instructions generate_reset_password_token! UserMailer.reset_password_instructions(id).deliver @@ -162,14 +147,6 @@ module Spree SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n") end - # Generate a token by looping and ensuring does not already exist. - def self.generate_token(column) - loop do - token = friendly_token - break token unless find(:first, conditions: { column => token }) - end - end - def limit_owned_enterprises return unless owned_enterprises.size > enterprise_limit diff --git a/spec/models/spree/user_spec.rb b/spec/models/spree/user_spec.rb index d73042c67a..f9fcd95056 100644 --- a/spec/models/spree/user_spec.rb +++ b/spec/models/spree/user_spec.rb @@ -188,14 +188,6 @@ describe Spree.user_class do expect(create(:user).admin?).to be_falsey end - context '#create' do - let(:user) { build(:user) } - - it 'should not be anonymous' do - expect(user).not_to be_anonymous - end - end - context '#destroy' do it 'can not delete if it has completed orders' do order = build(:order, completed_at: Time.zone.now) @@ -205,20 +197,4 @@ describe Spree.user_class do expect { user.destroy }.to raise_exception(Spree::User::DestroyWithOrdersError) end end - - context 'anonymous!' do - let(:user) { Spree::User.anonymous! } - - it 'should create a new user' do - expect(user.new_record?).to be_falsey - end - - it 'should create a user with an example.net email' do - expect(user.email).to match(/@example.net$/) - end - - it 'should be anonymous' do - expect(user).to be_anonymous - end - end end From ffe814ce6b525b0ec930cb58dd5bbeea59ce28e8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 7 Mar 2020 15:59:26 +0000 Subject: [PATCH 106/507] Adapt specs to not use anonymous user Api::BaseController#authenticate is already taking care of the unauthenticated use case when spree_current_user is nil --- spec/features/consumer/producers_spec.rb | 4 ---- spec/features/consumer/shops_spec.rb | 4 ---- spec/support/request/authentication_workflow.rb | 6 ------ 3 files changed, 14 deletions(-) diff --git a/spec/features/consumer/producers_spec.rb b/spec/features/consumer/producers_spec.rb index f8d7e3bb57..11d2e52cf6 100644 --- a/spec/features/consumer/producers_spec.rb +++ b/spec/features/consumer/producers_spec.rb @@ -22,10 +22,6 @@ feature ' let(:shop) { create(:distributor_enterprise) } let!(:er) { create(:enterprise_relationship, parent: shop, child: producer1) } - before :each do - use_api_as_unauthenticated_user - end - before do product1.set_property 'Organic', 'NASAA 12345' product2.set_property 'Biodynamic', 'ABC123' diff --git a/spec/features/consumer/shops_spec.rb b/spec/features/consumer/shops_spec.rb index 87db26883c..891ba07e8b 100644 --- a/spec/features/consumer/shops_spec.rb +++ b/spec/features/consumer/shops_spec.rb @@ -14,10 +14,6 @@ feature 'Shops', js: true do let!(:producer) { create(:supplier_enterprise) } let!(:er) { create(:enterprise_relationship, parent: distributor, child: producer) } - before :each do - use_api_as_unauthenticated_user - end - before do producer.set_producer_property 'Organic', 'NASAA 12345' end diff --git a/spec/support/request/authentication_workflow.rb b/spec/support/request/authentication_workflow.rb index 842a215508..0eb32e3e7a 100644 --- a/spec/support/request/authentication_workflow.rb +++ b/spec/support/request/authentication_workflow.rb @@ -68,12 +68,6 @@ module AuthenticationWorkflow fill_in "password", with: user.password click_button "Login" end - - def use_api_as_unauthenticated_user - allow_any_instance_of(Api::BaseController).to receive(:spree_current_user) { - Spree::User.anonymous! - } - end end RSpec.configure do |config| From 56c29ab472752140301523dd3f26be514bf54f11 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 7 Mar 2020 18:12:05 +0000 Subject: [PATCH 107/507] Make EnterprisesController inherit from Api::BaseController to fix authentication and fix problem with saving params[:user_ids] --- app/controllers/api/enterprises_controller.rb | 14 ++++++++- .../api/enterprises_controller_spec.rb | 29 +++++++++++++------ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index dd77882e3f..e25a69f0c7 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -1,5 +1,5 @@ module Api - class EnterprisesController < BaseController + class EnterprisesController < Api::BaseController before_filter :override_owner, only: [:create, :update] before_filter :check_type, only: :update before_filter :override_sells, only: [:create, :update] @@ -10,8 +10,12 @@ module Api def create authorize! :create, Enterprise + # params[:user_ids] breaks the enterprise creation + # We remove them from params and save them after creating the enterprise + user_ids = params[:enterprise].delete(:user_ids) @enterprise = Enterprise.new(params[:enterprise]) if @enterprise.save + save_enterprise_users(user_ids) render text: @enterprise.id, status: :created else invalid_resource!(@enterprise) @@ -72,5 +76,13 @@ module Api def override_visible params[:enterprise][:visible] = false end + + def save_enterprise_users(user_ids) + user_ids.each do |user_id| + next if @enterprise.user_ids.include? user_id.to_i + + @enterprise.users << Spree::User.find(user_id) + end + end end end diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index 05a26ec143..15c4606567 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -19,25 +19,36 @@ module Api let(:australia) { Spree::Country.find_by(name: 'Australia') } let(:new_enterprise_params) do { - enterprise: { - name: 'name', contact_name: 'Sheila', address_attributes: { - address1: '123 Abc Street', - city: 'Northcote', - zipcode: '3070', - state_id: australia.states.first, - country_id: australia.id - } + name: 'name', contact_name: 'Sheila', address_attributes: { + address1: '123 Abc Street', + city: 'Northcote', + zipcode: '3070', + state_id: australia.states.first, + country_id: australia.id } } end it "creates as sells=any when it is not a producer" do - spree_post :create, new_enterprise_params + spree_post :create, { enterprise: new_enterprise_params } expect(response).to be_success enterprise = Enterprise.last expect(enterprise.sells).to eq('any') end + + it "saves all user ids submitted" do + manager1 = create(:user) + manager2 = create(:user) + spree_post :create, { + enterprise: new_enterprise_params. + merge({ user_ids: [enterprise_owner.id, manager1.id, manager2.id] }) + } + expect(response).to be_success + + enterprise = Enterprise.last + expect(enterprise.user_ids).to eq([enterprise_owner.id, manager1.id, manager2.id]) + end end end From 7daa68a8bc05429aaf1bc801db29b8b83ff9f0a6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 7 Mar 2020 20:00:40 +0000 Subject: [PATCH 108/507] Adapt consumer/shopping/orders_spec to use an order with a nil user to test a guest checkout, which is what happens in the real checkout --- spec/features/consumer/shopping/orders_spec.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb index e9b342c1c7..2bb40d6dd5 100644 --- a/spec/features/consumer/shopping/orders_spec.rb +++ b/spec/features/consumer/shopping/orders_spec.rb @@ -31,7 +31,14 @@ feature "Order Management", js: true do end context "when checking out as an anonymous guest" do - let(:user) { Spree::User.anonymous! } + let!(:customer) { nil } + let!(:order) do + create(:order_with_credit_payment, + user: nil, + email: "guest@user.com", + distributor: distributor, + order_cycle: order_cycle) + end it "allows the user to see the details" do # Cannot load the page without token From e5f05b4db9b3dbdc7ffeaefc8b0ba55f032d17d8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 7 Mar 2020 20:10:32 +0000 Subject: [PATCH 109/507] Handle case where no user_ids are sent to the controller. Fixes original spec. --- app/controllers/api/enterprises_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index e25a69f0c7..603724c780 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -78,6 +78,8 @@ module Api end def save_enterprise_users(user_ids) + return unless user_ids + user_ids.each do |user_id| next if @enterprise.user_ids.include? user_id.to_i From 5ce4fec68b9e9de4683c50693212de85bdab3c5a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 9 Mar 2020 15:48:45 +0000 Subject: [PATCH 110/507] Add html to show the errors reported by devise 3 about password and password confirmation mismatch on user.errors[:password_confirmation] (instead of user.errors[:password]) --- app/assets/javascripts/templates/signup.html.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/assets/javascripts/templates/signup.html.haml b/app/assets/javascripts/templates/signup.html.haml index 51aa9d7fbc..dfb43394f3 100644 --- a/app/assets/javascripts/templates/signup.html.haml +++ b/app/assets/javascripts/templates/signup.html.haml @@ -37,6 +37,8 @@ autocomplete: "off", tabindex: 2, "ng-model" => "spree_user.password_confirmation"} + %span.error{"ng-show" => "errors.password_confirmation != null"} + {{ errors.password_confirmation.join(' ') }} .row .large-12.columns %input.button.primary{name: "commit", From 014e22a7ada75f86da3e240a7d060f3ccb51e805 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 9 Mar 2020 13:01:00 +0000 Subject: [PATCH 111/507] Fix problem with misssing params in schedules controller and adapt its spec --- app/controllers/admin/schedules_controller.rb | 9 +++++++++ .../controllers/admin/schedules_controller_spec.rb | 14 +++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 580a6a9c72..e71917044b 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -3,6 +3,7 @@ require 'open_food_network/proxy_order_syncer' module Admin class SchedulesController < ResourceController + before_filter :adapt_params, only: [:create, :update] before_filter :check_editable_order_cycle_ids, only: [:create, :update] before_filter :check_dependent_subscriptions, only: [:destroy] create.after :sync_subscriptions @@ -48,6 +49,14 @@ module Admin [:index] end + # In this controller, params like params[:name] are moved into params[:schedule] becoming params[:schedule][:name] + # For some reason in rails 4, this is not happening for params[:order_cycle_ids] + # We do it manually in this filter + def adapt_params + params[:schedule] = {} if params[:schedule].blank? + params[:schedule][:order_cycle_ids] = params[:order_cycle_ids] + end + def check_editable_order_cycle_ids return unless params[:schedule][:order_cycle_ids] diff --git a/spec/controllers/admin/schedules_controller_spec.rb b/spec/controllers/admin/schedules_controller_spec.rb index db974df917..3690835809 100644 --- a/spec/controllers/admin/schedules_controller_spec.rb +++ b/spec/controllers/admin/schedules_controller_spec.rb @@ -93,7 +93,7 @@ describe Admin::SchedulesController, type: :controller do it "allows me to add/remove only order cycles I coordinate to/from the schedule" do order_cycle_ids = [coordinated_order_cycle2.id, uncoordinated_order_cycle2.id, uncoordinated_order_cycle3.id] - spree_put :update, format: :json, id: coordinated_schedule.id, schedule: { order_cycle_ids: order_cycle_ids } + spree_put :update, format: :json, id: coordinated_schedule.id, order_cycle_ids: order_cycle_ids expect(assigns(:schedule)).to eq coordinated_schedule # coordinated_order_cycle2 is added, uncoordinated_order_cycle is NOT removed expect(coordinated_schedule.reload.order_cycles).to include coordinated_order_cycle2, uncoordinated_order_cycle, uncoordinated_order_cycle3 @@ -106,9 +106,9 @@ describe Admin::SchedulesController, type: :controller do allow(OpenFoodNetwork::ProxyOrderSyncer).to receive(:new) { syncer_mock } expect(syncer_mock).to receive(:sync!).exactly(2).times - spree_put :update, format: :json, id: coordinated_schedule.id, schedule: { order_cycle_ids: [coordinated_order_cycle.id, coordinated_order_cycle2.id] } - spree_put :update, format: :json, id: coordinated_schedule.id, schedule: { order_cycle_ids: [coordinated_order_cycle.id] } - spree_put :update, format: :json, id: coordinated_schedule.id, schedule: { order_cycle_ids: [coordinated_order_cycle.id] } + spree_put :update, format: :json, id: coordinated_schedule.id, order_cycle_ids: [coordinated_order_cycle.id, coordinated_order_cycle2.id] + spree_put :update, format: :json, id: coordinated_schedule.id, order_cycle_ids: [coordinated_order_cycle.id] + spree_put :update, format: :json, id: coordinated_schedule.id, order_cycle_ids: [coordinated_order_cycle.id] end end @@ -151,7 +151,7 @@ describe Admin::SchedulesController, type: :controller do context "where I manage at least one of the order cycles to be added to the schedules" do before do - params[:schedule].merge!( order_cycle_ids: [coordinated_order_cycle.id, uncoordinated_order_cycle.id] ) + params.merge!( order_cycle_ids: [coordinated_order_cycle.id, uncoordinated_order_cycle.id] ) end it "allows me to create the schedule, adding only order cycles that I manage" do @@ -172,7 +172,7 @@ describe Admin::SchedulesController, type: :controller do context "where I don't manage any of the order cycles to be added to the schedules" do before do - params[:schedule].merge!( order_cycle_ids: [uncoordinated_order_cycle.id] ) + params.merge!( order_cycle_ids: [uncoordinated_order_cycle.id] ) end it "prevents me from creating the schedule" do @@ -184,7 +184,7 @@ describe Admin::SchedulesController, type: :controller do context 'as an admin user' do before do allow(controller).to receive(:spree_current_user) { create(:admin_user) } - params[:schedule].merge!( order_cycle_ids: [coordinated_order_cycle.id, uncoordinated_order_cycle.id] ) + params.merge!( order_cycle_ids: [coordinated_order_cycle.id, uncoordinated_order_cycle.id] ) end it "allows me to create a schedule" do From de2c6a8717677bbeb7f0600c7022b5d26fa6bd28 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 10 Mar 2020 11:21:36 +0000 Subject: [PATCH 112/507] Revert previous commits and use collection_singular_ids=(ids) setter instead --- app/controllers/api/enterprises_controller.rb | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index 603724c780..7c545e5181 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -15,7 +15,7 @@ module Api user_ids = params[:enterprise].delete(:user_ids) @enterprise = Enterprise.new(params[:enterprise]) if @enterprise.save - save_enterprise_users(user_ids) + @enterprise.user_ids = user_ids render text: @enterprise.id, status: :created else invalid_resource!(@enterprise) @@ -76,15 +76,5 @@ module Api def override_visible params[:enterprise][:visible] = false end - - def save_enterprise_users(user_ids) - return unless user_ids - - user_ids.each do |user_id| - next if @enterprise.user_ids.include? user_id.to_i - - @enterprise.users << Spree::User.find(user_id) - end - end end end From 5506cc86d29dfea20744a0a2581d91b783fb4144 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 11 Mar 2020 13:07:38 +0000 Subject: [PATCH 113/507] Bypass after_rollback callback in payment This is causing several specs to fail on rollback and, according to some manual testing (and all the auto tests we have), we dont need this fix in OFN --- app/models/spree/payment_decorator.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/models/spree/payment_decorator.rb b/app/models/spree/payment_decorator.rb index ed3c85233c..69f4170f19 100644 --- a/app/models/spree/payment_decorator.rb +++ b/app/models/spree/payment_decorator.rb @@ -12,6 +12,13 @@ module Spree localize_number :amount + # We bypass this after_rollback callback that is setup in Spree::Payment + # The issues the callback fixes are not experienced in OFN: + # if a payment fails on checkout the state "failed" is persisted correctly + def persist_invalid + return + end + def ensure_correct_adjustment revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state) return if adjustment.try(:finalized?) From d62d89aa4fd20d28a10befe5c263be9a636f356e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 12 Mar 2020 12:44:50 +0100 Subject: [PATCH 114/507] Fix order index search form Fixes: 2) spree/admin/orders/index.html.haml print invoices button displays button when invoices are enabled Failure/Error: = form_tag nil, {name: "orders_form", "ng-submit" => "fetchResults()"} do ActionView::Template::Error: No route matches {:action=>"index", :controller=>"spree/admin/orders"} # ./app/views/spree/admin/orders/_filters.html.haml:2:in `_a1b716152f19bf3f4772a98e56adf411' # ./app/views/spree/admin/orders/index.html.haml:20:in `block in _d04c5552f7a480bf5f02e5fad0c10de6' # ./app/views/spree/admin/orders/index.html.haml:19:in `_d04c5552f7a480bf5f02e5fad0c10de6' # ./spec/views/spree/admin/orders/index.html.haml_spec.rb:26:in `block (3 levels) in ' # ./spec/views/spree/admin/orders/index.html.haml_spec.rb:8:in `block (2 levels) in ' # ------------------ # --- Caused by: --- # ActionController::UrlGenerationError: # No route matches {:action=>"index", :controller=>"spree/admin/orders"} # ./app/views/spree/admin/orders/_filters.html.haml:2:in `_a1b716152f19bf3f4772a98e56adf411' 3) spree/admin/orders/index.html.haml print invoices button does not display button when invoices are disabled Failure/Error: = form_tag nil, {name: "orders_form", "ng-submit" => "fetchResults()"} do ActionView::Template::Error: No route matches {:action=>"index", :controller=>"spree/admin/orders"} # ./app/views/spree/admin/orders/_filters.html.haml:2:in `_a1b716152f19bf3f4772a98e56adf411' # ./app/views/spree/admin/orders/index.html.haml:20:in `block in _d04c5552f7a480bf5f02e5fad0c10de6' # ./app/views/spree/admin/orders/index.html.haml:19:in `_d04c5552f7a480bf5f02e5fad0c10de6' # ./spec/views/spree/admin/orders/index.html.haml_spec.rb:34:in `block (3 levels) in ' # ./spec/views/spree/admin/orders/index.html.haml_spec.rb:8:in `block (2 levels) in ' # ------------------ # --- Caused by: --- # ActionController::UrlGenerationError: # No route matches {:action=>"index", :controller=>"spree/admin/orders"} # ./app/views/spree/admin/orders/_filters.html.haml:2:in `_a1b716152f19bf3f4772a98e56adf411' --- app/views/spree/admin/orders/_filters.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/admin/orders/_filters.html.haml b/app/views/spree/admin/orders/_filters.html.haml index b41c2d194a..5b1c9b4024 100644 --- a/app/views/spree/admin/orders/_filters.html.haml +++ b/app/views/spree/admin/orders/_filters.html.haml @@ -1,5 +1,5 @@ %div{"data-hook" => "admin_orders_index_search"} - = form_tag nil, {name: "orders_form", "ng-submit" => "fetchResults()"} do + = form_tag :orders, {name: "orders_form", "ng-submit" => "fetchResults()"} do .field-block.alpha.four.columns .date-range-filter.field = label_tag nil, t(:date_range) From a207c6c45f7f0dc9618349b80cd3c272b37379f0 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 12 Mar 2020 13:12:07 +0100 Subject: [PATCH 115/507] Fix cart page update Fixes: 2) full-page cart viewing the cart updating quantities with insufficient stock available shows the quantities saved, not those submitted Failure/Error: @app.call(env) AbstractController::ActionNotFound: The action 'update' could not be found for CartController # ./lib/open_food_network/rack_request_blocker.rb:36:in `call' # ------------------ # --- Caused by: --- # Capybara::ExpectationNotMet: # expected to find text "Insufficient stock available, only 2 remaining" in "Internal Server Error The action 'update' could not be found for CartController WEBrick/1.3.1 (Ruby/2.3.7/2018-03-28) at 127.0.0.1:38614" # ./spec/features/consumer/shopping/cart_spec.rb:182:in `block (5 levels) in ' --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 65a70165e1..09cce85165 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -24,7 +24,7 @@ Openfoodnetwork::Application.routes.draw do get "/learn", to: redirect("https://openfoodnetwork.org/#{ENV['DEFAULT_COUNTRY_CODE'].andand.downcase}/learn/") get "/cart", :to => "spree/orders#edit", :as => :cart - put "/cart", :to => "spree/orders#update", :as => :update_cart + patch "/cart", :to => "spree/orders#update", :as => :update_cart put "/cart/empty", :to => 'spree/orders#empty', :as => :empty_cart get '/orders/:id/token/:token' => 'spree/orders#show', :as => :token_order From 9a5452cd52bcc9ecca2d1fef37f0222d0f9b3cbe Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 12 Mar 2020 12:21:46 +0100 Subject: [PATCH 116/507] Delete test in line_items_controller_spec.rb Rails 4 does not recognise requests to destroy routes without ids as valid routes. Fixes: 14) LineItemsController destroying a line item on a completed order without a line item id fails and raises an error Failure/Error: delete :destroy ActionController::UrlGenerationError: No route matches {:action=>"destroy", :controller=>"line_items"} # ./spec/controllers/line_items_controller_spec.rb:46:in `block (5 levels) in ' --- spec/controllers/line_items_controller_spec.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 2a4dbd8835..7e4e76bac9 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -41,13 +41,6 @@ describe LineItemsController, type: :controller do before { allow(controller).to receive_messages spree_current_user: item.order.user } - context "without a line item id" do - it "fails and raises an error" do - delete :destroy - expect(response.status).to eq 404 - end - end - context "with a line item id" do let(:params) { { format: :json, id: item } } From 40b8eb470ce49afd48de438853a83121e32e3a71 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 12 Mar 2020 19:12:06 +0100 Subject: [PATCH 117/507] Fix deprecation warning for use of #all --- app/controllers/spree/admin/reports_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index ec08bca29c..78381a9d63 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -247,7 +247,7 @@ module Spree end def suppliers_of_products_distributed_by(distributors) - distributors.map { |d| Spree::Product.in_distributor(d).includes(:supplier).all }. + distributors.map { |d| Spree::Product.in_distributor(d).includes(:supplier).to_a }. flatten.map(&:supplier).uniq end From e24d8d71045b76e0aebd0696da2409ac59eb5250 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 12 Mar 2020 19:12:36 +0100 Subject: [PATCH 118/507] Fix deprecation warning for use of #includes without #references --- lib/open_food_network/reports/line_items.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/open_food_network/reports/line_items.rb b/lib/open_food_network/reports/line_items.rb index 4e272a7c13..59d9901552 100644 --- a/lib/open_food_network/reports/line_items.rb +++ b/lib/open_food_network/reports/line_items.rb @@ -21,7 +21,7 @@ module OpenFoodNetwork end if line_item_includes.present? - line_items = line_items.includes(*line_item_includes) + line_items = line_items.includes(*line_item_includes).references(:line_items) end editable_line_items = editable_line_items(line_items) From 1cba129432c6d430e6139744d0a5c750e718707d Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 12 Mar 2020 19:13:15 +0100 Subject: [PATCH 119/507] Ensure line_item.variant succeeds when variant is soft-deleted --- app/models/spree/line_item_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index b3456d7ba9..7012cec9ec 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -73,7 +73,7 @@ Spree::LineItem.class_eval do def variant # Overridden so that LineItems always have access to soft-deleted Variant attributes - Spree::Variant.unscoped { super } + Spree::Variant.unscoped { super } || Spree::Variant.unscoped.find(self.variant_id) end def cap_quantity_at_stock! From 03cdaf589ecab04ae64a121d0b4234a26e901d17 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 20 Mar 2020 15:08:29 +0000 Subject: [PATCH 120/507] Remove newly added attr_accessible from stripe_sca This is not needed, in rails 4 the params are permitted at controller level --- app/models/spree/gateway/stripe_sca.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/spree/gateway/stripe_sca.rb b/app/models/spree/gateway/stripe_sca.rb index d5ac331b89..0ec8b656e9 100644 --- a/app/models/spree/gateway/stripe_sca.rb +++ b/app/models/spree/gateway/stripe_sca.rb @@ -12,8 +12,6 @@ module Spree validate :ensure_enterprise_selected - attr_accessible :preferred_enterprise_id - def method_type 'stripe_sca' end From 9915717a225d0c24727dc0b969206ddc1b0dcfe5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 20 Mar 2020 15:09:18 +0000 Subject: [PATCH 121/507] Remove attr_accessible from paper_trail config In rails 4 this is not needed --- config/initializers/paper_trail.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/config/initializers/paper_trail.rb b/config/initializers/paper_trail.rb index e955bac9be..39a6679176 100644 --- a/config/initializers/paper_trail.rb +++ b/config/initializers/paper_trail.rb @@ -1,7 +1 @@ PaperTrail.config.track_associations = false - -module PaperTrail - class Version < ActiveRecord::Base - attr_accessible :custom_data - end -end From b33969e6a2259e35651451d86225d3bd5ac971d6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 12:50:34 +0000 Subject: [PATCH 122/507] Adapt to slightly different rails 4 sql data conversion --- .../data_representations/coordinator_fee.rb | 2 +- .../order_management/reports/enterprise_fee_summary/scope.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/data_representations/coordinator_fee.rb b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/data_representations/coordinator_fee.rb index 8eb14c44cf..0fda10c2f4 100644 --- a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/data_representations/coordinator_fee.rb +++ b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/data_representations/coordinator_fee.rb @@ -19,7 +19,7 @@ module OrderManagement end def inherits_tax_category? - data["enterprise_fee_inherits_tax_category"] == "t" + data["enterprise_fee_inherits_tax_category"] end end end diff --git a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb index 96fba8b7a4..d88b5dc2ea 100644 --- a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb +++ b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb @@ -364,7 +364,7 @@ module OrderManagement chain_to_scope do select( <<-JOIN_STRING.strip_heredoc - SUM(spree_adjustments.amount) AS total_amount, + SUM(spree_adjustments.amount)::TEXT AS total_amount, spree_payment_methods.name AS payment_method_name, spree_shipping_methods.name AS shipping_method_name, hubs.name AS hub_name, From 80e56084367972baf4fc7580f023792173693cbe Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 12 Mar 2020 10:50:10 +0100 Subject: [PATCH 123/507] Ensure customer selection dropdown is visible when adding customer details For some reason the order is in address state here instead of cart state when adding customer details. There's a conditional in the view which loads the customer selection dropdown that was not being triggered, so a customer could not be selected (and their existing address was not being filled out in the form). Fixes: 1) As an administrator I want to manage orders filling customer details Failure/Error: expect(order.ship_address.lastname).to eq @customer.ship_address.lastname NoMethodError: undefined method `lastname' for nil:NilClass # ./spec/features/admin/orders_spec.rb:179:in `block (2 levels) in ' --- app/views/spree/admin/orders/customer_details/edit.html.haml | 2 +- spec/features/admin/orders_spec.rb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/spree/admin/orders/customer_details/edit.html.haml b/app/views/spree/admin/orders/customer_details/edit.html.haml index e4fa93ffbb..f6a83316da 100644 --- a/app/views/spree/admin/orders/customer_details/edit.html.haml +++ b/app/views/spree/admin/orders/customer_details/edit.html.haml @@ -9,7 +9,7 @@ - content_for :page_actions do %li= button_link_to Spree.t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' -- if @order.cart? +- if @order.cart? || @order.address? #select-customer{"data-hook" => ""} %fieldset.no-border-bottom %legend{:align => "center"}= Spree.t(:customer_search) diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 09bec96ccf..caa0a1613b 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -169,6 +169,9 @@ feature ' expect(page).to have_selector 'h1.page-title', text: "Customer Details" + # The customer selection partial should be visible + expect(page).to have_selector '#select-customer' + # And I select that customer's email address and save the order targetted_select2_search @customer.email, from: '#customer_search_override', dropdown_css: '.select2-drop' click_button 'Update' From 86d09ff21e606b0db4eaa07ae8d5cd6e4528772d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 22 Feb 2020 17:41:45 +0000 Subject: [PATCH 124/507] Bring strong parameters code from spree to payment_methods_controller This code comes from spree commit https://github.com/openfoodfoundation/spree/commit/fbc2d150f640399d73baab5295416da7131b95e7 --- .../spree/admin/payment_methods_controller.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/controllers/spree/admin/payment_methods_controller.rb b/app/controllers/spree/admin/payment_methods_controller.rb index 4665417bcf..a1303eed0f 100644 --- a/app/controllers/spree/admin/payment_methods_controller.rb +++ b/app/controllers/spree/admin/payment_methods_controller.rb @@ -15,7 +15,7 @@ module Spree @payment_method = params[:payment_method]. delete(:type). constantize. - new(params[:payment_method]) + new(payment_method_params) @object = @payment_method invoke_callbacks(:create, :before) @@ -40,8 +40,8 @@ module Spree @payment_method = PaymentMethod.find(params[:id]) end - payment_method_params = params[ActiveModel::Naming.param_key(@payment_method)] || {} - attributes = params[:payment_method].merge(payment_method_params) + update_params = params[ActiveModel::Naming.param_key(@payment_method)] || {} + attributes = payment_method_params.merge(update_params) attributes.each do |k, _v| if k.include?("password") && attributes[k].blank? attributes.delete(k) @@ -100,6 +100,10 @@ module Spree private + def payment_method_params + params.require(:payment_method).permit! + end + def force_environment params[:payment_method][:environment] = Rails.env unless spree_current_user.admin? end From 38849f55894bc6b4c6faeced397b55b8c8b55030 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 14:48:03 +0000 Subject: [PATCH 125/507] Extract method in payments_method_controller to make it readable --- .../spree/admin/payment_methods_controller.rb | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/app/controllers/spree/admin/payment_methods_controller.rb b/app/controllers/spree/admin/payment_methods_controller.rb index a1303eed0f..c4c317abed 100644 --- a/app/controllers/spree/admin/payment_methods_controller.rb +++ b/app/controllers/spree/admin/payment_methods_controller.rb @@ -40,15 +40,7 @@ module Spree @payment_method = PaymentMethod.find(params[:id]) end - update_params = params[ActiveModel::Naming.param_key(@payment_method)] || {} - attributes = payment_method_params.merge(update_params) - attributes.each do |k, _v| - if k.include?("password") && attributes[k].blank? - attributes.delete(k) - end - end - - if @payment_method.update_attributes(attributes) + if @payment_method.update_attributes(params_for_update) invoke_callbacks(:update, :after) flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:payment_method)) redirect_to edit_admin_payment_method_path(@payment_method) @@ -160,6 +152,21 @@ module Spree def stripe_provider?(provider) provider.name.ends_with?("StripeConnect", "StripeSCA") end + + # Merge payment method params with gateway params like :gateway_stripe_connect + # Also, remove password if present and blank + def params_for_update + gateway_params = params[ActiveModel::Naming.param_key(@payment_method)] || {} + params_for_update = payment_method_params.merge(gateway_params) + + params_for_update.each do |key, _value| + if key.include?("password") && params_for_update[key].blank? + params_for_update.delete(key) + end + end + + params_for_update + end end end end From e5ebf457656391b8457699032a56c321e2bc4ecb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 15:05:04 +0000 Subject: [PATCH 126/507] Improve strong params implementation on payment methods controller by specifying specific list of permitted attributes --- app/controllers/spree/admin/payment_methods_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/payment_methods_controller.rb b/app/controllers/spree/admin/payment_methods_controller.rb index c4c317abed..31efc89b05 100644 --- a/app/controllers/spree/admin/payment_methods_controller.rb +++ b/app/controllers/spree/admin/payment_methods_controller.rb @@ -93,7 +93,10 @@ module Spree private def payment_method_params - params.require(:payment_method).permit! + params.require(:payment_method).permit( + :name, :type, :environment, :preferred_password, :preferred_enterprise_id, + :distributor_ids => [] + ) end def force_environment From eac0da9812de6d00bda71e2bdb7526ebf19f973a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 15:18:27 +0000 Subject: [PATCH 127/507] Fix payment method controllers by removing unnecessary param that only exists in stripe connect payment method preferred_enterprise_id --- .../spree/admin/payment_methods_controller_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/controllers/spree/admin/payment_methods_controller_spec.rb b/spec/controllers/spree/admin/payment_methods_controller_spec.rb index 9373986e6f..ff23298c44 100644 --- a/spec/controllers/spree/admin/payment_methods_controller_spec.rb +++ b/spec/controllers/spree/admin/payment_methods_controller_spec.rb @@ -8,7 +8,7 @@ module Spree describe Admin::PaymentMethodsController, type: :controller do describe "#create and #update" do let!(:enterprise) { create(:distributor_enterprise, owner: user) } - let(:payment_method) { GatewayWithPassword.create!(name: "Bogus", preferred_password: "haxme", distributor_ids: [enterprise.id], preferred_enterprise_id: enterprise.id) } + let(:payment_method) { GatewayWithPassword.create!(name: "Bogus", preferred_password: "haxme", distributor_ids: [enterprise.id]) } let!(:user) { create(:user) } before { allow(controller).to receive(:spree_current_user) { user } } @@ -32,7 +32,7 @@ module Spree it "can create a payment method of a valid type" do expect { - spree_post :create, payment_method: { name: "Test Method", type: "Spree::Gateway::Bogus", distributor_ids: [enterprise.id], preferred_enterprise_id: enterprise.id } + spree_post :create, payment_method: { name: "Test Method", type: "Spree::Gateway::Bogus", distributor_ids: [enterprise.id] } }.to change(Spree::PaymentMethod, :count).by(1) expect(response).to be_redirect @@ -41,7 +41,7 @@ module Spree it "can not create a payment method of an invalid type" do expect { - spree_post :create, payment_method: { name: "Invalid Payment Method", type: "Spree::InvalidType", distributor_ids: [enterprise.id], preferred_enterprise_id: enterprise.id } + spree_post :create, payment_method: { name: "Invalid Payment Method", type: "Spree::InvalidType", distributor_ids: [enterprise.id] } }.to change(Spree::PaymentMethod, :count).by(0) expect(response).to be_redirect From df799340dfa830bb6d3d899e9c67a9665c8d3013 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 7 Mar 2020 20:30:22 +0000 Subject: [PATCH 128/507] Add missing permitted attributes to payment_methods controller --- app/controllers/spree/admin/payment_methods_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/payment_methods_controller.rb b/app/controllers/spree/admin/payment_methods_controller.rb index 31efc89b05..a142eb6eb1 100644 --- a/app/controllers/spree/admin/payment_methods_controller.rb +++ b/app/controllers/spree/admin/payment_methods_controller.rb @@ -94,8 +94,12 @@ module Spree def payment_method_params params.require(:payment_method).permit( - :name, :type, :environment, :preferred_password, :preferred_enterprise_id, - :distributor_ids => [] + :name, :description, :type, :active, + :environment, :display_on, :tag_list, + :preferred_enterprise_id, :preferred_server, :preferred_login, :preferred_password, + :calculator_type, + :preferred_signature, :preferred_solution, :preferred_landing_page, :preferred_logourl, + :preferred_test_mode, distributor_ids: [] ) end From 905811ccb31639d820997d333ac2428785737135 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 17:32:00 +0000 Subject: [PATCH 129/507] Handle strong params in admin order_cycles controller --- app/controllers/admin/order_cycles_controller.rb | 11 +++++++++-- app/services/order_cycle_form.rb | 16 ++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 18521a6649..c2a38a5245 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -40,7 +40,7 @@ module Admin end def create - @order_cycle_form = OrderCycleForm.new(@order_cycle, params, spree_current_user) + @order_cycle_form = OrderCycleForm.new(@order_cycle, order_cycle_params, spree_current_user) if @order_cycle_form.save flash[:notice] = I18n.t(:order_cycles_create_notice) @@ -56,7 +56,7 @@ module Admin end def update - @order_cycle_form = OrderCycleForm.new(@order_cycle, params, spree_current_user) + @order_cycle_form = OrderCycleForm.new(@order_cycle, order_cycle_params, spree_current_user) if @order_cycle_form.save respond_to do |format| @@ -235,5 +235,12 @@ module Admin def ams_prefix_whitelist [:basic, :index] end + + def order_cycle_params + params.require(:order_cycle).permit( + :incoming_exchanges, :outgoing_exchanges, + :name, :orders_open_at, :orders_close_at, :coordinator_id, :schedule_ids, :coordinator_fee_ids + ) + end end end diff --git a/app/services/order_cycle_form.rb b/app/services/order_cycle_form.rb index 2ab5d109de..fa397aed44 100644 --- a/app/services/order_cycle_form.rb +++ b/app/services/order_cycle_form.rb @@ -3,16 +3,16 @@ require 'open_food_network/proxy_order_syncer' require 'open_food_network/order_cycle_form_applicator' class OrderCycleForm - def initialize(order_cycle, params, user) + def initialize(order_cycle, order_cycle_params, user) @order_cycle = order_cycle - @params = params + @order_cycle_params = order_cycle_params @user = user @permissions = OpenFoodNetwork::Permissions.new(user) end def save build_schedule_ids - order_cycle.assign_attributes(params[:order_cycle]) + order_cycle.assign_attributes(order_cycle_params) return false unless order_cycle.valid? order_cycle.transaction do @@ -27,7 +27,7 @@ class OrderCycleForm private - attr_accessor :order_cycle, :params, :user, :permissions + attr_accessor :order_cycle, :order_cycle_params, :user, :permissions def apply_exchange_changes return if exchanges_unchanged? @@ -37,12 +37,12 @@ class OrderCycleForm def exchanges_unchanged? [:incoming_exchanges, :outgoing_exchanges].all? do |direction| - params[:order_cycle][direction].nil? + order_cycle_params[direction].nil? end end def schedule_ids? - params[:order_cycle][:schedule_ids].present? + order_cycle_params[:schedule_ids].present? end def build_schedule_ids @@ -51,7 +51,7 @@ class OrderCycleForm result = existing_schedule_ids result |= (requested_schedule_ids & permitted_schedule_ids) # Add permitted and requested result -= ((result & permitted_schedule_ids) - requested_schedule_ids) # Remove permitted but not requested - params[:order_cycle][:schedule_ids] = result + order_cycle_params[:schedule_ids] = result end def sync_subscriptions @@ -70,7 +70,7 @@ class OrderCycleForm end def requested_schedule_ids - params[:order_cycle][:schedule_ids].map(&:to_i) + order_cycle_params[:schedule_ids].map(&:to_i) end def permitted_schedule_ids From 1a46e7b7eef9be5ff4de0b69bba4877c5dd1292e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 18:59:35 +0000 Subject: [PATCH 130/507] Improve strong params implementation on order_cycle controller and fix corresponding specs --- .../admin/order_cycles_controller.rb | 2 ++ .../admin/order_cycles_controller_spec.rb | 4 ++-- spec/services/order_cycle_form_spec.rb | 20 ++++++++++--------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index c2a38a5245..23cf8257e2 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -237,6 +237,8 @@ module Admin end def order_cycle_params + return params[:order_cycle] if params[:order_cycle].empty? + params.require(:order_cycle).permit( :incoming_exchanges, :outgoing_exchanges, :name, :orders_open_at, :orders_close_at, :coordinator_id, :schedule_ids, :coordinator_fee_ids diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb index 28a453fa99..74fb3303ea 100644 --- a/spec/controllers/admin/order_cycles_controller_spec.rb +++ b/spec/controllers/admin/order_cycles_controller_spec.rb @@ -203,7 +203,7 @@ module Admin context "as a manager of the coordinator" do let(:user) { coordinator.owner } - let(:expected) { [order_cycle, hash_including(order_cycle: allowed.merge(restricted)), user] } + let(:expected) { [order_cycle, hash_including(restricted), user] } it "allows me to update exchange information for exchanges, name and dates" do expect(OrderCycleForm).to receive(:new).with(*expected) { form_mock } @@ -213,7 +213,7 @@ module Admin context "as a producer supplying to an order cycle" do let(:user) { producer.owner } - let(:expected) { [order_cycle, hash_including(order_cycle: allowed), user] } + let(:expected) { [order_cycle, {}, user] } it "allows me to update exchange information for exchanges, but not name or dates" do expect(OrderCycleForm).to receive(:new).with(*expected) { form_mock } diff --git a/spec/services/order_cycle_form_spec.rb b/spec/services/order_cycle_form_spec.rb index 476adb3e39..f264592763 100644 --- a/spec/services/order_cycle_form_spec.rb +++ b/spec/services/order_cycle_form_spec.rb @@ -1,3 +1,5 @@ +require 'spec_helper' + describe OrderCycleForm do describe "save" do describe "creating a new order cycle from params" do @@ -6,7 +8,7 @@ describe OrderCycleForm do let(:form) { OrderCycleForm.new(order_cycle, params, shop.owner) } context "when creation is successful" do - let(:params) { { order_cycle: { name: "Test Order Cycle", coordinator_id: shop.id } } } + let(:params) { { name: "Test Order Cycle", coordinator_id: shop.id } } it "returns true" do expect do @@ -16,7 +18,7 @@ describe OrderCycleForm do end context "when creation fails" do - let(:params) { { order_cycle: { name: "Test Order Cycle" } } } + let(:params) { { name: "Test Order Cycle" } } it "returns false" do expect do @@ -32,7 +34,7 @@ describe OrderCycleForm do let(:form) { OrderCycleForm.new(order_cycle, params, shop.owner) } context "when update is successful" do - let(:params) { { order_cycle: { name: "Test Order Cycle", coordinator_id: shop.id } } } + let(:params) { { name: "Test Order Cycle", coordinator_id: shop.id } } it "returns true" do expect do @@ -42,7 +44,7 @@ describe OrderCycleForm do end context "when updating fails" do - let(:params) { { order_cycle: { name: nil } } } + let(:params) { { name: nil } } it "returns false" do expect do @@ -73,7 +75,7 @@ describe OrderCycleForm do end context "and I add an schedule that I own, and remove another that I own" do - let(:params) { { order_cycle: { schedule_ids: [coordinated_schedule2.id] } } } + let(:params) { { schedule_ids: [coordinated_schedule2.id] } } it "associates the order cycle to the schedule" do expect(form.save).to be true @@ -84,7 +86,7 @@ describe OrderCycleForm do end context "and I add a schedule that I don't own" do - let(:params) { { order_cycle: { schedule_ids: [coordinated_schedule.id, uncoordinated_schedule.id] } } } + let(:params) { { schedule_ids: [coordinated_schedule.id, uncoordinated_schedule.id] } } it "ignores the schedule that I don't own" do expect(form.save).to be true @@ -95,7 +97,7 @@ describe OrderCycleForm do end context "when I make no changes to the schedule ids" do - let(:params) { { order_cycle: { schedule_ids: [coordinated_schedule.id] } } } + let(:params) { { schedule_ids: [coordinated_schedule.id] } } it "ignores the schedule that I don't own" do expect(form.save).to be true @@ -111,7 +113,7 @@ describe OrderCycleForm do let(:order_cycle) { create(:simple_order_cycle) } let(:form_applicator_mock) { instance_double(OpenFoodNetwork::OrderCycleFormApplicator) } let(:form) { OrderCycleForm.new(order_cycle, params, user) } - let(:params) { { order_cycle: { name: 'Some new name' } } } + let(:params) { { name: 'Some new name' } } before do allow(OpenFoodNetwork::OrderCycleFormApplicator).to receive(:new) { form_applicator_mock } @@ -120,7 +122,7 @@ describe OrderCycleForm do context "when exchange params are provided" do let(:exchange_params) { { incoming_exchanges: [], outgoing_exchanges: [] } } - before { params[:order_cycle].merge!(exchange_params) } + before { params.merge!(exchange_params) } it "runs the OrderCycleFormApplicator, and saves other changes" do expect(form.save).to be true From 57f8fa26abedbce46409693e3ab75b5f21d32031 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 28 Feb 2020 13:00:50 +0000 Subject: [PATCH 131/507] Fix strong params in order_cycles --- .../admin/order_cycles_controller.rb | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 23cf8257e2..e4048e418d 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -240,9 +240,37 @@ module Admin return params[:order_cycle] if params[:order_cycle].empty? params.require(:order_cycle).permit( - :incoming_exchanges, :outgoing_exchanges, - :name, :orders_open_at, :orders_close_at, :coordinator_id, :schedule_ids, :coordinator_fee_ids + :name, :orders_open_at, :orders_close_at, :coordinator_id, + :incoming_exchanges => permitted_exchange_attributes, + :outgoing_exchanges => permitted_exchange_attributes, + :schedule_ids => [], :coordinator_fee_ids => [] ) end + + def permitted_exchange_attributes + [ + :id, :sender_id, :receiver_id, :enterprise_id, :incoming, :active, + :select_all_variants, :receival_instructions, + :pickup_time, :pickup_instructions, + :tag_list, :tags => [:text], + :enterprise_fee_ids => [], + :variants => permitted_variant_ids + ] + end + + # In rails 5 we will be able to permit random hash keys simply with :variants => {} + # See https://github.com/rails/rails/commit/e86524c0c5a26ceec92895c830d1355ae47a7034 + # + # Until then, we need to create an array of variant IDs in order to permit them + def permitted_variant_ids + variant_ids(params[:order_cycle][:incoming_exchanges]) + + variant_ids(params[:order_cycle][:outgoing_exchanges]) + end + + def variant_ids(exchange_params) + return [] unless exchange_params + + exchange_params.map { |exchange| exchange[:variants].map { |key, _value| key } }.flatten + end end end From 20c7a0d3ef03d2d8d16b8bb8d90e00b6185caf8d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 4 Mar 2020 10:03:04 +0000 Subject: [PATCH 132/507] Adapt to latest changes in order cycles controller strong params changes --- spec/controllers/admin/order_cycles_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb index 74fb3303ea..2ba98c9f8e 100644 --- a/spec/controllers/admin/order_cycles_controller_spec.rb +++ b/spec/controllers/admin/order_cycles_controller_spec.rb @@ -203,7 +203,7 @@ module Admin context "as a manager of the coordinator" do let(:user) { coordinator.owner } - let(:expected) { [order_cycle, hash_including(restricted), user] } + let(:expected) { [order_cycle, allowed.merge(restricted), user] } it "allows me to update exchange information for exchanges, name and dates" do expect(OrderCycleForm).to receive(:new).with(*expected) { form_mock } @@ -213,7 +213,7 @@ module Admin context "as a producer supplying to an order cycle" do let(:user) { producer.owner } - let(:expected) { [order_cycle, {}, user] } + let(:expected) { [order_cycle, allowed, user] } it "allows me to update exchange information for exchanges, but not name or dates" do expect(OrderCycleForm).to receive(:new).with(*expected) { form_mock } From fd2cf7295e74d6229bd3d349060539067baa77f3 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 16:15:48 +0000 Subject: [PATCH 133/507] Extract permitted_attributes from order_cycle_controller into a specific service --- .../admin/order_cycles_controller.rb | 35 +------------- .../permitted_attributes/order_cycle.rb | 46 +++++++++++++++++++ .../permitted_attributes/order_cycle_spec.rb | 42 +++++++++++++++++ 3 files changed, 89 insertions(+), 34 deletions(-) create mode 100644 app/services/permitted_attributes/order_cycle.rb create mode 100644 spec/services/permitted_attributes/order_cycle_spec.rb diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index e4048e418d..19c2240d25 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -237,40 +237,7 @@ module Admin end def order_cycle_params - return params[:order_cycle] if params[:order_cycle].empty? - - params.require(:order_cycle).permit( - :name, :orders_open_at, :orders_close_at, :coordinator_id, - :incoming_exchanges => permitted_exchange_attributes, - :outgoing_exchanges => permitted_exchange_attributes, - :schedule_ids => [], :coordinator_fee_ids => [] - ) - end - - def permitted_exchange_attributes - [ - :id, :sender_id, :receiver_id, :enterprise_id, :incoming, :active, - :select_all_variants, :receival_instructions, - :pickup_time, :pickup_instructions, - :tag_list, :tags => [:text], - :enterprise_fee_ids => [], - :variants => permitted_variant_ids - ] - end - - # In rails 5 we will be able to permit random hash keys simply with :variants => {} - # See https://github.com/rails/rails/commit/e86524c0c5a26ceec92895c830d1355ae47a7034 - # - # Until then, we need to create an array of variant IDs in order to permit them - def permitted_variant_ids - variant_ids(params[:order_cycle][:incoming_exchanges]) + - variant_ids(params[:order_cycle][:outgoing_exchanges]) - end - - def variant_ids(exchange_params) - return [] unless exchange_params - - exchange_params.map { |exchange| exchange[:variants].map { |key, _value| key } }.flatten + PermittedAttributes::OrderCycle.new(params).call end end end diff --git a/app/services/permitted_attributes/order_cycle.rb b/app/services/permitted_attributes/order_cycle.rb new file mode 100644 index 0000000000..e76cbe85be --- /dev/null +++ b/app/services/permitted_attributes/order_cycle.rb @@ -0,0 +1,46 @@ +module PermittedAttributes + class OrderCycle + def initialize(params) + @params = params + end + + def call + return @params[:order_cycle] if @params[:order_cycle].empty? + + @params.require(:order_cycle).permit( + :name, :orders_open_at, :orders_close_at, :coordinator_id, + :incoming_exchanges => permitted_exchange_attributes, + :outgoing_exchanges => permitted_exchange_attributes, + :schedule_ids => [], :coordinator_fee_ids => [] + ) + end + + private + + def permitted_exchange_attributes + [ + :id, :sender_id, :receiver_id, :enterprise_id, :incoming, :active, + :select_all_variants, :receival_instructions, + :pickup_time, :pickup_instructions, + :tag_list, :tags => [:text], + :enterprise_fee_ids => [], + :variants => permitted_variant_ids + ] + end + + # In rails 5 we will be able to permit random hash keys simply with :variants => {} + # See https://github.com/rails/rails/commit/e86524c0c5a26ceec92895c830d1355ae47a7034 + # + # Until then, we need to create an array of variant IDs in order to permit them + def permitted_variant_ids + variant_ids(@params[:order_cycle][:incoming_exchanges]) + + variant_ids(@params[:order_cycle][:outgoing_exchanges]) + end + + def variant_ids(exchange_params) + return [] unless exchange_params + + exchange_params.map { |exchange| exchange[:variants].map { |key, _value| key } }.flatten + end + end +end diff --git a/spec/services/permitted_attributes/order_cycle_spec.rb b/spec/services/permitted_attributes/order_cycle_spec.rb new file mode 100644 index 0000000000..f91f358aab --- /dev/null +++ b/spec/services/permitted_attributes/order_cycle_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +module PermittedAttributes + describe OrderCycle do + let(:oc_permitted_attributes) { PermittedAttributes::OrderCycle.new(params) } + + describe "with basic attributes" do + let(:params) { ActionController::Parameters.new(order_cycle: { id: "2", name: "First Order Cycle" } ) } + + it "keeps permitted and removes not permitted" do + permitted_attributes = oc_permitted_attributes.call + + expect(permitted_attributes[:id]).to be nil + expect(permitted_attributes[:name]).to eq "First Order Cycle" + end + end + + describe "nested incoming_exchanges attributes" do + let(:params) { ActionController::Parameters.new(order_cycle: { incoming_exchanges: [{ sender_id: "2", name: "Exchange Name", variants: [] }] } ) } + + it "keeps permitted and removes not permitted" do + permitted_attributes = oc_permitted_attributes.call + + exchange = permitted_attributes[:incoming_exchanges].first + expect(exchange[:name]).to be nil + expect(exchange[:sender_id]).to eq "2" + end + end + + describe "variants inside incoming_exchanges attributes" do + let(:params) { ActionController::Parameters.new(order_cycle: { incoming_exchanges: [{ variants: { "7" => true, "12" => true } }] } ) } + + it "keeps all variant_ids provided" do + permitted_attributes = oc_permitted_attributes.call + + exchange_variants = permitted_attributes[:incoming_exchanges].first[:variants] + expect(exchange_variants["7"]).to be true + expect(exchange_variants["12"]).to be true + end + end + end +end From 5af27bb14ef2823f2dbdcbfebd9441a898c72132 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 26 Feb 2020 15:02:10 +0000 Subject: [PATCH 134/507] Make checkout controller handle strong parameters --- app/controllers/checkout_controller.rb | 19 +++++++++++++++- app/services/checkout/form_data_adapter.rb | 6 +---- .../checkout/form_data_adapter_spec.rb | 22 ++++++------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 3e00127d8a..ce8728ee37 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -43,7 +43,7 @@ class CheckoutController < Spree::StoreController def update params_adapter = Checkout::FormDataAdapter.new(params, @order, spree_current_user) - return update_failed unless @order.update_attributes(params_adapter.order_params) + return update_failed unless @order.update_attributes(order_params(params_adapter.params)) fire_event('spree.checkout.update') @@ -237,4 +237,21 @@ class CheckoutController < Spree::StoreController end end end + + def order_params(params) + params.require(:order).permit( + :email, :special_instructions, + payments_attributes: + [ + :payment_method_id, :amount, + source_attributes: [ + :gateway_payment_profile_id, :cc_type, :last_digits, + :month, :year, :first_name, :last_name, + :number, :verification_value + ] + ], + bill_address_attributes: permitted_address_attributes, + ship_address_attributes: permitted_address_attributes + ) + end end diff --git a/app/services/checkout/form_data_adapter.rb b/app/services/checkout/form_data_adapter.rb index 8fc10fc4ca..a374444637 100644 --- a/app/services/checkout/form_data_adapter.rb +++ b/app/services/checkout/form_data_adapter.rb @@ -3,7 +3,7 @@ # Adapts checkout form data (params) so that the order can be directly saved to the database module Checkout class FormDataAdapter - attr_reader :shipping_method_id + attr_reader :params, :shipping_method_id def initialize(params, order, current_user) @params = params.dup @@ -19,10 +19,6 @@ module Checkout @shipping_method_id = @params[:order].delete(:shipping_method_id) end - def order_params - @params[:order] - end - private # For payment step, filter order parameters to produce the expected diff --git a/spec/services/checkout/form_data_adapter_spec.rb b/spec/services/checkout/form_data_adapter_spec.rb index b1b92b3053..be248a2af0 100644 --- a/spec/services/checkout/form_data_adapter_spec.rb +++ b/spec/services/checkout/form_data_adapter_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Checkout::FormDataAdapter do - describe '#order_params' do + describe '#params' do let(:params) { { order: { order_id: "123" } } } let(:order) { create(:order) } let(:user) { create(:user) } @@ -11,9 +11,7 @@ describe Checkout::FormDataAdapter do let(:adapter) { Checkout::FormDataAdapter.new(params, order, user) } it "returns the :order item in the params provided" do - order_params = adapter.order_params - - expect(order_params).to eq params[:order] + expect(adapter.params[:order]).to eq params[:order] end describe "when payment_attributes are provided" do @@ -25,9 +23,7 @@ describe Checkout::FormDataAdapter do before { params[:payment_source] = { "123" => source_attributes } } it "moves payment source attributes to the order payment attributes" do - order_params = adapter.order_params - - expect(order_params[:payments_attributes]. + expect(adapter.params[:order][:payments_attributes]. first[:source_attributes]).to eq source_attributes end end @@ -36,9 +32,7 @@ describe Checkout::FormDataAdapter do before { order.total = "50.0" } it "sets the payment attributes amount to the order total" do - order_params = adapter.order_params - - expect(order_params[:payments_attributes].first[:amount]).to eq order.total + expect(adapter.params[:order][:payments_attributes].first[:amount]).to eq order.total end end @@ -51,10 +45,8 @@ describe Checkout::FormDataAdapter do before { params[:order][:existing_card_id] = credit_card.id } it "adds card details to payment attributes" do - order_params = adapter.order_params - - expect(order_params[:payments_attributes].first[:source][:id]).to eq credit_card.id - expect(order_params[:payments_attributes]. + expect(adapter.params[:order][:payments_attributes].first[:source][:id]).to eq credit_card.id + expect(adapter.params[:order][:payments_attributes]. first[:source][:last_digits]).to eq credit_card.last_digits end end @@ -63,7 +55,7 @@ describe Checkout::FormDataAdapter do let(:credit_card) { create(:credit_card) } it "raises exception if credit card provided doesnt belong to the current user" do - expect { adapter.order_params }.to raise_error Spree::Core::GatewayError + expect { adapter.params[:order] }.to raise_error Spree::Core::GatewayError end end end From d7cccd41437cc435b973b1293978e2872150d446 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 2 Mar 2020 13:31:34 +0000 Subject: [PATCH 135/507] Add guard clause in checkout_controller for empty params[:order] --- app/controllers/checkout_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index ce8728ee37..e3c083e7eb 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -239,6 +239,8 @@ class CheckoutController < Spree::StoreController end def order_params(params) + return params[:order] if params[:order].empty? + params.require(:order).permit( :email, :special_instructions, payments_attributes: From 5ae2e6865c2ba38076726c4c34873e26fe7acf75 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 10:14:45 +0000 Subject: [PATCH 136/507] Add one more needed permitted attribute to checkout controller --- app/controllers/checkout_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index e3c083e7eb..83ecd4cc37 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -249,7 +249,8 @@ class CheckoutController < Spree::StoreController source_attributes: [ :gateway_payment_profile_id, :cc_type, :last_digits, :month, :year, :first_name, :last_name, - :number, :verification_value + :number, :verification_value, + :save_requested_by_customer ] ], bill_address_attributes: permitted_address_attributes, From 1d9a6edefbb2cdf36467489cc2e67163bfa0d141 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 9 Mar 2020 11:38:45 +0000 Subject: [PATCH 137/507] Permit params in checkout controller before we adapt them to bypass issues with permitting added attributes like source CreditCard --- app/controllers/checkout_controller.rb | 41 +++++++++++++++----------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 83ecd4cc37..0b9de7a174 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -42,8 +42,8 @@ class CheckoutController < Spree::StoreController end def update - params_adapter = Checkout::FormDataAdapter.new(params, @order, spree_current_user) - return update_failed unless @order.update_attributes(order_params(params_adapter.params)) + params_adapter = Checkout::FormDataAdapter.new(permitted_params, @order, spree_current_user) + return update_failed unless @order.update_attributes(params_adapter.params[:order]) fire_event('spree.checkout.update') @@ -238,23 +238,28 @@ class CheckoutController < Spree::StoreController end end - def order_params(params) - return params[:order] if params[:order].empty? - - params.require(:order).permit( - :email, :special_instructions, - payments_attributes: - [ - :payment_method_id, :amount, - source_attributes: [ - :gateway_payment_profile_id, :cc_type, :last_digits, - :month, :year, :first_name, :last_name, - :number, :verification_value, - :save_requested_by_customer - ] + def permitted_params + params.permit( + order: [ + :email, :special_instructions, + :existing_card_id, :shipping_method_id, + payments_attributes: [ + :payment_method_id, + source_attributes: payment_source_attributes ], - bill_address_attributes: permitted_address_attributes, - ship_address_attributes: permitted_address_attributes + ship_address_attributes: permitted_address_attributes, + bill_address_attributes: permitted_address_attributes + ], + payment_source: payment_source_attributes ) end + + def payment_source_attributes + [ + :gateway_payment_profile_id, :cc_type, :last_digits, + :month, :year, :first_name, :last_name, + :number, :verification_value, + :save_requested_by_customer + ] + end end From 2c453359c186e4bdfd0fe6fa321b7f38ec17a78f Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 16:38:11 +0000 Subject: [PATCH 138/507] Extract permitted params into a specific service --- app/controllers/checkout_controller.rb | 23 +------------ app/services/permitted_attributes/address.rb | 11 ++++++ app/services/permitted_attributes/checkout.rb | 34 +++++++++++++++++++ 3 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 app/services/permitted_attributes/address.rb create mode 100644 app/services/permitted_attributes/checkout.rb diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 0b9de7a174..d5f2e0ffee 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -239,27 +239,6 @@ class CheckoutController < Spree::StoreController end def permitted_params - params.permit( - order: [ - :email, :special_instructions, - :existing_card_id, :shipping_method_id, - payments_attributes: [ - :payment_method_id, - source_attributes: payment_source_attributes - ], - ship_address_attributes: permitted_address_attributes, - bill_address_attributes: permitted_address_attributes - ], - payment_source: payment_source_attributes - ) - end - - def payment_source_attributes - [ - :gateway_payment_profile_id, :cc_type, :last_digits, - :month, :year, :first_name, :last_name, - :number, :verification_value, - :save_requested_by_customer - ] + PermittedAttributes::Checkout.new(params).call end end diff --git a/app/services/permitted_attributes/address.rb b/app/services/permitted_attributes/address.rb new file mode 100644 index 0000000000..4fd7908297 --- /dev/null +++ b/app/services/permitted_attributes/address.rb @@ -0,0 +1,11 @@ +module PermittedAttributes + class Address + def self.attributes + [ + :firstname, :lastname, :address1, :address2, + :city, :country_id, :state_id, :zipcode, + :phone, :state_name, :alternative_phone, :company + ] + end + end +end diff --git a/app/services/permitted_attributes/checkout.rb b/app/services/permitted_attributes/checkout.rb new file mode 100644 index 0000000000..c5bda0739a --- /dev/null +++ b/app/services/permitted_attributes/checkout.rb @@ -0,0 +1,34 @@ +module PermittedAttributes + class Checkout + def initialize(params) + @params = params + end + + def call + @params.permit( + order: [ + :email, :special_instructions, + :existing_card_id, :shipping_method_id, + payments_attributes: [ + :payment_method_id, + source_attributes: payment_source_attributes + ], + ship_address_attributes: PermittedAttributes::Address.attributes, + bill_address_attributes: PermittedAttributes::Address.attributes + ], + payment_source: payment_source_attributes + ) + end + + private + + def payment_source_attributes + [ + :gateway_payment_profile_id, :cc_type, :last_digits, + :month, :year, :first_name, :last_name, + :number, :verification_value, + :save_requested_by_customer + ] + end + end +end From 980fdd65a132f6d977c80b930adfe57a50da3064 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 17:00:08 +0000 Subject: [PATCH 139/507] Replace hash rockets syntax --- app/services/permitted_attributes/order_cycle.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/permitted_attributes/order_cycle.rb b/app/services/permitted_attributes/order_cycle.rb index e76cbe85be..df15b47d58 100644 --- a/app/services/permitted_attributes/order_cycle.rb +++ b/app/services/permitted_attributes/order_cycle.rb @@ -9,9 +9,9 @@ module PermittedAttributes @params.require(:order_cycle).permit( :name, :orders_open_at, :orders_close_at, :coordinator_id, - :incoming_exchanges => permitted_exchange_attributes, - :outgoing_exchanges => permitted_exchange_attributes, - :schedule_ids => [], :coordinator_fee_ids => [] + incoming_exchanges: permitted_exchange_attributes, + outgoing_exchanges: permitted_exchange_attributes, + schedule_ids: [], coordinator_fee_ids: [] ) end From 431076fc6d8d8b6482490d3ab4a7a5815cd151cf Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 22 Feb 2020 19:03:48 +0000 Subject: [PATCH 140/507] Add strong parameters permits to admin users_controller --- app/controllers/spree/admin/users_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/users_controller.rb b/app/controllers/spree/admin/users_controller.rb index a1db20605c..6d8337a5ce 100644 --- a/app/controllers/spree/admin/users_controller.rb +++ b/app/controllers/spree/admin/users_controller.rb @@ -22,7 +22,7 @@ module Spree roles = params[:user].delete("spree_role_ids") end - @user = Spree::User.new(params[:user]) + @user = Spree::User.new(user_params) if @user.save if roles @@ -41,7 +41,7 @@ module Spree roles = params[:user].delete("spree_role_ids") end - if @user.update_attributes(params[:user]) + if @user.update_attributes(user_params) if roles @user.spree_roles = roles.reject(&:blank?).collect{ |r| Spree::Role.find(r) } end @@ -136,6 +136,10 @@ module Spree def new_email_unconfirmed? params[:user][:email] != @user.email end + + def user_params + params.require(:user).permit(:email, :enterprise_limit, :password, :password_confirmation) + end end end end From d0bd2818c22f2c203d4e97af78f170f194061606 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 17:34:39 +0000 Subject: [PATCH 141/507] Handle strong params on users_controller --- app/controllers/spree/users_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/users_controller.rb b/app/controllers/spree/users_controller.rb index c620136a94..99b7fa73de 100644 --- a/app/controllers/spree/users_controller.rb +++ b/app/controllers/spree/users_controller.rb @@ -25,7 +25,7 @@ module Spree end def create - @user = Spree::User.new(params[:user]) + @user = Spree::User.new(user_params) if @user.save if current_order @@ -39,7 +39,7 @@ module Spree end def update - if @user.update_attributes(params[:user]) + if @user.update_attributes(user_params) if params[:user][:password].present? # this logic needed b/c devise wants to log us out after password changes Spree::User.reset_password_by_token(params[:user]) @@ -70,5 +70,9 @@ module Spree def accurate_title Spree.t(:my_account) end + + def user_params + params.require(:user).permit(:email, :password, :password_confirmation) + end end end From 6ed93da3f130e3760bbb1583d4ba768ef7be56b7 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 5 Mar 2020 18:43:35 +0000 Subject: [PATCH 142/507] Fix case with empty spree_user in user_registrations controller --- app/controllers/user_registrations_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/user_registrations_controller.rb b/app/controllers/user_registrations_controller.rb index 258d990828..0482fc39c7 100644 --- a/app/controllers/user_registrations_controller.rb +++ b/app/controllers/user_registrations_controller.rb @@ -33,6 +33,8 @@ class UserRegistrationsController < Spree::UserRegistrationsController private def spree_user_params + return params[:spree_user] if params[:spree_user].empty? + params.require(:spree_user). permit(:email, :password, :password_confirmation, :remember_me) end From aec7f12f5aecc31aa222ec72a35495b443a3890e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 18:08:30 +0000 Subject: [PATCH 143/507] Extract common user permitted attributes to a separate class --- .../spree/admin/users_controller.rb | 2 +- app/controllers/spree/users_controller.rb | 2 +- .../user_registrations_controller.rb | 3 +-- app/services/permitted_attributes/user.rb | 21 +++++++++++++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 app/services/permitted_attributes/user.rb diff --git a/app/controllers/spree/admin/users_controller.rb b/app/controllers/spree/admin/users_controller.rb index 6d8337a5ce..d5525936a3 100644 --- a/app/controllers/spree/admin/users_controller.rb +++ b/app/controllers/spree/admin/users_controller.rb @@ -138,7 +138,7 @@ module Spree end def user_params - params.require(:user).permit(:email, :enterprise_limit, :password, :password_confirmation) + PermittedAttributes::User.new(params).call([:enterprise_limit]) end end end diff --git a/app/controllers/spree/users_controller.rb b/app/controllers/spree/users_controller.rb index 99b7fa73de..03aced66c8 100644 --- a/app/controllers/spree/users_controller.rb +++ b/app/controllers/spree/users_controller.rb @@ -72,7 +72,7 @@ module Spree end def user_params - params.require(:user).permit(:email, :password, :password_confirmation) + ::PermittedAttributes::User.new(params).call end end end diff --git a/app/controllers/user_registrations_controller.rb b/app/controllers/user_registrations_controller.rb index 0482fc39c7..2e9870b37e 100644 --- a/app/controllers/user_registrations_controller.rb +++ b/app/controllers/user_registrations_controller.rb @@ -35,8 +35,7 @@ class UserRegistrationsController < Spree::UserRegistrationsController def spree_user_params return params[:spree_user] if params[:spree_user].empty? - params.require(:spree_user). - permit(:email, :password, :password_confirmation, :remember_me) + PermittedAttributes::User.new(params, :spree_user).call([:remember_me]) end def render_error(errors = {}) diff --git a/app/services/permitted_attributes/user.rb b/app/services/permitted_attributes/user.rb new file mode 100644 index 0000000000..4efbf0e3b5 --- /dev/null +++ b/app/services/permitted_attributes/user.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module PermittedAttributes + class User + def initialize(params, resource_name = :user) + @params = params + @resource_name = resource_name + end + + def call(extra_permitted_attributes = []) + @params.require(@resource_name). + permit(permitted_attributes + extra_permitted_attributes) + end + + private + + def permitted_attributes + [:email, :password, :password_confirmation] + end + end +end From 0ee562c718a20155aa47a97937ad68330749a685 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 18:47:25 +0000 Subject: [PATCH 144/507] Add test coverage for PermittedAttributes::User --- .../permitted_attributes/user_spec.rb | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 spec/services/permitted_attributes/user_spec.rb diff --git a/spec/services/permitted_attributes/user_spec.rb b/spec/services/permitted_attributes/user_spec.rb new file mode 100644 index 0000000000..8b98311efa --- /dev/null +++ b/spec/services/permitted_attributes/user_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module PermittedAttributes + describe User do + describe "simple usage" do + let(:user_permitted_attributes) { PermittedAttributes::User.new(params) } + + describe "permits basic attributes" do + let(:params) { + ActionController::Parameters.new(user: { name: "John", + email: "email@example.com" } ) + } + + it "keeps permitted and removes not permitted" do + permitted_attributes = user_permitted_attributes.call + + expect(permitted_attributes[:name]).to be nil + expect(permitted_attributes[:email]).to eq "email@example.com" + end + + it "keeps extra permitted attributes" do + permitted_attributes = user_permitted_attributes.call([:name]) + + expect(permitted_attributes[:name]).to eq "John" + expect(permitted_attributes[:email]).to eq "email@example.com" + end + end + end + + describe "with custom resource_name" do + let(:user_permitted_attributes) { PermittedAttributes::User.new(params, :spree_user) } + let(:params) { + ActionController::Parameters.new(spree_user: { name: "John", + email: "email@example.com" } ) + } + + it "keeps permitted and removes not permitted" do + permitted_attributes = user_permitted_attributes.call + + expect(permitted_attributes[:name]).to be nil + expect(permitted_attributes[:email]).to eq "email@example.com" + end + end + end +end From d7cfda83853325fb6bc38279708d87004a94942b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 17:53:13 +0000 Subject: [PATCH 145/507] Handle strong params in subscription_line_items controller --- .../admin/subscription_line_items_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/subscription_line_items_controller.rb b/app/controllers/admin/subscription_line_items_controller.rb index a87ddebe45..27ec3611a1 100644 --- a/app/controllers/admin/subscription_line_items_controller.rb +++ b/app/controllers/admin/subscription_line_items_controller.rb @@ -11,7 +11,7 @@ module Admin respond_to :json def build - @subscription_line_item.assign_attributes(params[:subscription_line_item]) + @subscription_line_item.assign_attributes(subscription_line_item_params) @subscription_line_item.price_estimate = price_estimate render json: @subscription_line_item, serializer: Api::Admin::SubscriptionLineItemSerializer, shop: @shop, schedule: @schedule @@ -27,7 +27,7 @@ module Admin @shop = Enterprise.managed_by(spree_current_user).find_by(id: params[:shop_id]) @schedule = permissions.editable_schedules.find_by(id: params[:schedule_id]) @order_cycle = @schedule.andand.current_or_next_order_cycle - @variant = variant_if_eligible(params[:subscription_line_item][:variant_id]) if @shop.present? + @variant = variant_if_eligible(subscription_line_item_params[:variant_id]) if @shop.present? end def new_actions @@ -58,5 +58,9 @@ module Admin def variant_if_eligible(variant_id) SubscriptionVariantsService.eligible_variants(@shop).find_by(id: variant_id) end + + def subscription_line_item_params + params.require(:subscription_line_item).permit(:quantity, :variant_id) + end end end From c3897b2f1c0776ca4e16491900659fa55768cea0 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 22:03:04 +0000 Subject: [PATCH 146/507] Handle strong params in subscriptions controller --- .../admin/subscriptions_controller.rb | 18 ++++++++++++++++-- app/services/subscription_form.rb | 8 ++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/subscriptions_controller.rb b/app/controllers/admin/subscriptions_controller.rb index da99409469..4e6c65018a 100644 --- a/app/controllers/admin/subscriptions_controller.rb +++ b/app/controllers/admin/subscriptions_controller.rb @@ -65,7 +65,7 @@ module Admin private def save_form_and_render(render_issues = true) - form = SubscriptionForm.new(@subscription, params[:subscription]) + form = SubscriptionForm.new(@subscription, subscription_params) unless form.save render json: { errors: form.json_errors }, status: :unprocessable_entity return @@ -149,11 +149,25 @@ module Admin # Overriding Spree method to load data from params here so that # we can authorise #create using an object with required attributes def build_resource - Subscription.new(params[:subscription]) + Subscription.new(subscription_params) end def ams_prefix_whitelist [:index] end + + def subscription_params + return params[:subscription] if params[:subscription].empty? + + params.require(:subscription).permit( + :shop_id, :schedule_id, :customer_id, + :payment_method_id, :shipping_method_id, + :begins_at, :ends_at, + :canceled_at, :paused_at, + :subscription_line_items_attributes => [:id, :quantity, :variant_id], + :bill_address_attributes => permitted_address_attributes, + :ship_address_attributes => permitted_address_attributes + ) + end end end diff --git a/app/services/subscription_form.rb b/app/services/subscription_form.rb index da82063b5c..0458467fb5 100644 --- a/app/services/subscription_form.rb +++ b/app/services/subscription_form.rb @@ -1,21 +1,21 @@ require 'open_food_network/proxy_order_syncer' class SubscriptionForm - attr_accessor :subscription, :params, :order_update_issues, :validator, :order_syncer, :estimator + attr_accessor :subscription, :subscription_params, :order_update_issues, :validator, :order_syncer, :estimator delegate :json_errors, :valid?, to: :validator delegate :order_update_issues, to: :order_syncer - def initialize(subscription, params = {}) + def initialize(subscription, subscription_params = {}) @subscription = subscription - @params = params + @subscription_params = subscription_params @estimator = SubscriptionEstimator.new(subscription) @validator = SubscriptionValidator.new(subscription) @order_syncer = OrderSyncer.new(subscription) end def save - subscription.assign_attributes(params) + subscription.assign_attributes(subscription_params) return false unless valid? subscription.transaction do From 58c83d056db630477e757fc7cf257a0abbbc0ff7 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 10 Mar 2020 15:45:45 +0000 Subject: [PATCH 147/507] Add missing permitted attributes to subscriptions controller --- app/controllers/admin/subscriptions_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/subscriptions_controller.rb b/app/controllers/admin/subscriptions_controller.rb index 4e6c65018a..6b65ddda86 100644 --- a/app/controllers/admin/subscriptions_controller.rb +++ b/app/controllers/admin/subscriptions_controller.rb @@ -160,11 +160,12 @@ module Admin return params[:subscription] if params[:subscription].empty? params.require(:subscription).permit( - :shop_id, :schedule_id, :customer_id, + :id, :shop_id, :schedule_id, :customer_id, :payment_method_id, :shipping_method_id, :begins_at, :ends_at, :canceled_at, :paused_at, - :subscription_line_items_attributes => [:id, :quantity, :variant_id], + :shipping_fee_estimate, :payment_fee_estimate, + :subscription_line_items_attributes => [:id, :quantity, :variant_id, :price_estimate, :_destroy], :bill_address_attributes => permitted_address_attributes, :ship_address_attributes => permitted_address_attributes ) From 79b08675070ce8693050f5abe61545f3a0c57c1e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 19:05:01 +0000 Subject: [PATCH 148/507] Extract permitted attributes to separate service --- .../admin/subscriptions_controller.rb | 13 +------ .../permitted_attributes/subscription.rb | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 app/services/permitted_attributes/subscription.rb diff --git a/app/controllers/admin/subscriptions_controller.rb b/app/controllers/admin/subscriptions_controller.rb index 6b65ddda86..4561ef3a79 100644 --- a/app/controllers/admin/subscriptions_controller.rb +++ b/app/controllers/admin/subscriptions_controller.rb @@ -157,18 +157,7 @@ module Admin end def subscription_params - return params[:subscription] if params[:subscription].empty? - - params.require(:subscription).permit( - :id, :shop_id, :schedule_id, :customer_id, - :payment_method_id, :shipping_method_id, - :begins_at, :ends_at, - :canceled_at, :paused_at, - :shipping_fee_estimate, :payment_fee_estimate, - :subscription_line_items_attributes => [:id, :quantity, :variant_id, :price_estimate, :_destroy], - :bill_address_attributes => permitted_address_attributes, - :ship_address_attributes => permitted_address_attributes - ) + PermittedAttributes::Subscription.new(params).call end end end diff --git a/app/services/permitted_attributes/subscription.rb b/app/services/permitted_attributes/subscription.rb new file mode 100644 index 0000000000..2ab3956fca --- /dev/null +++ b/app/services/permitted_attributes/subscription.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module PermittedAttributes + class Subscription + def initialize(params) + @params = params + end + + def call + return @params[:subscription] if @params[:subscription].empty? + + @params.require(:subscription).permit(basic_permitted_attributes + other_permitted_attributes) + end + + private + + def basic_permitted_attributes + [ + :id, :shop_id, :schedule_id, :customer_id, + :payment_method_id, :shipping_method_id, + :begins_at, :ends_at, + :canceled_at, :paused_at, + :shipping_fee_estimate, :payment_fee_estimate, + ] + end + + def other_permitted_attributes + [ + subscription_line_items_attributes: [ + :id, :quantity, :variant_id, :price_estimate, :_destroy + ], + bill_address_attributes: PermittedAttributes::Address.attributes, + ship_address_attributes: PermittedAttributes::Address.attributes + ] + end + end +end From c110f4832d575248620388eb6d8af335da996beb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 12:49:39 +0000 Subject: [PATCH 149/507] Handle strong params in spree/admin/products_controller --- app/controllers/spree/admin/products_controller.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index 0b18072869..ae085d2b11 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -160,10 +160,16 @@ module Spree private def product_set_from_params(params) - collection_hash = Hash[params[:products].each_with_index.map { |p, i| [i, p] }] + collection_hash = Hash[products_params.each_with_index.map { |p, i| [i, p] }] Spree::ProductSet.new(collection_attributes: collection_hash) end + def products_params + params.require(:products).map do |product| + ActionController::Parameters.new(product.to_hash).permit(:id, :name) + end + end + def bulk_index_query(params) params[:filters].to_h.merge(page: params[:page], per_page: params[:per_page]) end From 5b37e8973817a4407ba3c64857667e5089ca8f23 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 16:11:42 +0000 Subject: [PATCH 150/507] Handle strong params in variant_overrides_controller We use a simpler way to permit on array within params here and change products_controller to the same style --- app/controllers/admin/variant_overrides_controller.rb | 8 +++++++- app/controllers/spree/admin/products_controller.rb | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 41c95a4451..adeb8747e5 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -68,7 +68,7 @@ module Admin end def load_collection - collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }] + collection_hash = Hash[variant_overrides_params.each_with_index.map { |vo, i| [i, vo] }] @vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash end @@ -92,5 +92,11 @@ module Admin full_messages.each { |fm| errors.add(:base, fm) } errors end + + def variant_overrides_params + params.require(:variant_overrides).map do |variant_override| + variant_override.permit(:id, :price, :count_on_hand, :sku, :on_demand) + end + end end end diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index ae085d2b11..5bd268ab27 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -166,7 +166,7 @@ module Spree def products_params params.require(:products).map do |product| - ActionController::Parameters.new(product.to_hash).permit(:id, :name) + product.permit(:id, :name) end end From 0151b5ee9a70d1bca6f5f81da22e2bc232fa08e0 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 19:49:34 +0000 Subject: [PATCH 151/507] Permit extra needed params in variant overrides controller --- app/controllers/admin/variant_overrides_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index adeb8747e5..0ad742ddbf 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -95,7 +95,7 @@ module Admin def variant_overrides_params params.require(:variant_overrides).map do |variant_override| - variant_override.permit(:id, :price, :count_on_hand, :sku, :on_demand) + variant_override.permit(:id, :price, :count_on_hand, :sku, :on_demand, :variant_id, :hub_id) end end end From 7320b38b93d5cb09dc0df323b36a8648d22fcc0c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 5 Mar 2020 16:05:33 +0000 Subject: [PATCH 152/507] Add missing attributes to variant override controller --- app/controllers/admin/variant_overrides_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 0ad742ddbf..bfb58a1ed7 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -95,7 +95,11 @@ module Admin def variant_overrides_params params.require(:variant_overrides).map do |variant_override| - variant_override.permit(:id, :price, :count_on_hand, :sku, :on_demand, :variant_id, :hub_id) + variant_override.permit( + :id, :variant_id, :hub_id, + :price, :count_on_hand, :sku, :on_demand, + :default_stock, :resettable + ) end end end From a261ae118dc9ea2b1f7bb310d52d4d8908f997db Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 15:17:50 +0000 Subject: [PATCH 153/507] Add missing permitted attributes to variant overrides controller --- app/controllers/admin/variant_overrides_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index bfb58a1ed7..3530b3648f 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -98,7 +98,7 @@ module Admin variant_override.permit( :id, :variant_id, :hub_id, :price, :count_on_hand, :sku, :on_demand, - :default_stock, :resettable + :default_stock, :resettable, :tag_list ) end end From b5cdcdf8cb446ea082363901bd7c7157594db7e6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 17:44:07 +0000 Subject: [PATCH 154/507] Permit specific params in products controller --- .../spree/admin/products_controller.rb | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index 5bd268ab27..a799336761 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -166,10 +166,26 @@ module Spree def products_params params.require(:products).map do |product| - product.permit(:id, :name) + product.permit(permitted_product_attributes) end end + def permitted_resource_params + params.require(:product).permit(permitted_product_attributes) + end + + def permitted_product_attributes + [ + :id, :name, :description, :supplier_id, :price, :permalink, + :variant_unit, :variant_unit_scale, :unit_value, :unit_description, + :display_as, :variant_unit_name, + :taxon_ids, :primary_taxon_id, :tax_category_id, :shipping_category_id, + :group_buy, :group_buy_unit_size, + :meta_keywords, :meta_description, :notes, + :inherits_properties, product_properties_attributes: [:id, :property_name, :value] + ] + end + def bulk_index_query(params) params[:filters].to_h.merge(page: params[:page], per_page: params[:per_page]) end From 36389b7bed1f134574c4c0142e4e06c9793fe83e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 2 Mar 2020 14:04:53 +0000 Subject: [PATCH 155/507] Add missing permitted attributes to bulk_product_update controller --- app/controllers/spree/admin/products_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index a799336761..56d0b22902 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -178,11 +178,13 @@ module Spree [ :id, :name, :description, :supplier_id, :price, :permalink, :variant_unit, :variant_unit_scale, :unit_value, :unit_description, - :display_as, :variant_unit_name, + :display_as, :variant_unit_name, :sku, :available_on, :taxon_ids, :primary_taxon_id, :tax_category_id, :shipping_category_id, :group_buy, :group_buy_unit_size, :meta_keywords, :meta_description, :notes, - :inherits_properties, product_properties_attributes: [:id, :property_name, :value] + :inherits_properties, + product_properties_attributes: [:id, :property_name, :value], + variants_attributes: [:id, :sku, :on_hand, :price, :unit_value, :unit_description, :display_name, :display_as] ] end From 527f6cb624bd59ff46c137e22edcecee9eca9599 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 3 Mar 2020 18:22:48 +0000 Subject: [PATCH 156/507] Add necessary attributes to admin/products_controller and handle empty params case --- app/controllers/spree/admin/products_controller.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index 56d0b22902..1856aeac2a 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -171,12 +171,14 @@ module Spree end def permitted_resource_params + return params[:product] if params[:product].empty? + params.require(:product).permit(permitted_product_attributes) end def permitted_product_attributes [ - :id, :name, :description, :supplier_id, :price, :permalink, + :id, :name, :description, :supplier_id, :price, :cost_price, :permalink, :variant_unit, :variant_unit_scale, :unit_value, :unit_description, :display_as, :variant_unit_name, :sku, :available_on, :taxon_ids, :primary_taxon_id, :tax_category_id, :shipping_category_id, @@ -184,7 +186,8 @@ module Spree :meta_keywords, :meta_description, :notes, :inherits_properties, product_properties_attributes: [:id, :property_name, :value], - variants_attributes: [:id, :sku, :on_hand, :price, :unit_value, :unit_description, :display_name, :display_as] + variants_attributes: [:id, :sku, :on_hand, :price, :unit_value, :unit_description, :display_name, :display_as], + images_attributes: [:attachment] ] end From 49a252230594525848a9e1777fc7a025f346f1df Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 18:46:23 +0000 Subject: [PATCH 157/507] Permit specific params in variants controller --- app/controllers/spree/admin/variants_controller.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/controllers/spree/admin/variants_controller.rb b/app/controllers/spree/admin/variants_controller.rb index 0045ef591c..11feb4b4c3 100644 --- a/app/controllers/spree/admin/variants_controller.rb +++ b/app/controllers/spree/admin/variants_controller.rb @@ -63,6 +63,19 @@ module Spree end @collection end + + def variant_params + params.require(:variant).permit( + :display_name, :display_as, :unit_value, :unit_description, + :sku, :price, :cost_price, + :weight, :height, :width, :depth, + :on_demand, :on_hand + ) + end + + def permitted_resource_params + variant_params + end end end end From 58a2805bc9216701bd8db8720eadfa1ffceff7b0 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 15:23:49 +0000 Subject: [PATCH 158/507] Make resource controller raise error if permitted_resource_params is not overriden --- app/controllers/spree/admin/resource_controller.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/resource_controller.rb b/app/controllers/spree/admin/resource_controller.rb index d1ce6e8b27..8b7c0cde12 100644 --- a/app/controllers/spree/admin/resource_controller.rb +++ b/app/controllers/spree/admin/resource_controller.rb @@ -28,7 +28,7 @@ module Spree def update invoke_callbacks(:update, :before) - if @object.update_attributes(params[object_name]) + if @object.update_attributes(permitted_resource_params) invoke_callbacks(:update, :after) flash[:success] = flash_message_for(@object, :successfully_updated) respond_with(@object) do |format| @@ -43,7 +43,7 @@ module Spree def create invoke_callbacks(:create, :before) - @object.attributes = params[object_name] + @object.attributes = permitted_resource_params if @object.save invoke_callbacks(:create, :after) flash[:success] = flash_message_for(@object, :successfully_created) @@ -251,6 +251,13 @@ module Spree end end + # Permit specific list of params + # + # Example: params.require(object_name).permit(:name) + def permitted_resource_params + raise "All extending controllers need to override the method permitted_resource_params" + end + def collection_url(options = {}) if parent_data.present? spree.polymorphic_url([:admin, parent, model_class], options) From 244499a27d6345c02b27912165fad8632e394734 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 19:30:03 +0000 Subject: [PATCH 159/507] Extract permitted atttributes to specific classes --- .../spree/admin/products_controller.rb | 19 ++----------------- .../spree/admin/variants_controller.rb | 7 +------ app/services/permitted_attributes/product.rb | 18 ++++++++++++++++++ app/services/permitted_attributes/variant.rb | 14 ++++++++++++++ 4 files changed, 35 insertions(+), 23 deletions(-) create mode 100644 app/services/permitted_attributes/product.rb create mode 100644 app/services/permitted_attributes/variant.rb diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index 1856aeac2a..fe727ac77e 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -166,29 +166,14 @@ module Spree def products_params params.require(:products).map do |product| - product.permit(permitted_product_attributes) + product.permit(::PermittedAttributes::Product.attributes) end end def permitted_resource_params return params[:product] if params[:product].empty? - params.require(:product).permit(permitted_product_attributes) - end - - def permitted_product_attributes - [ - :id, :name, :description, :supplier_id, :price, :cost_price, :permalink, - :variant_unit, :variant_unit_scale, :unit_value, :unit_description, - :display_as, :variant_unit_name, :sku, :available_on, - :taxon_ids, :primary_taxon_id, :tax_category_id, :shipping_category_id, - :group_buy, :group_buy_unit_size, - :meta_keywords, :meta_description, :notes, - :inherits_properties, - product_properties_attributes: [:id, :property_name, :value], - variants_attributes: [:id, :sku, :on_hand, :price, :unit_value, :unit_description, :display_name, :display_as], - images_attributes: [:attachment] - ] + params.require(:product).permit(::PermittedAttributes::Product.attributes) end def bulk_index_query(params) diff --git a/app/controllers/spree/admin/variants_controller.rb b/app/controllers/spree/admin/variants_controller.rb index 11feb4b4c3..fc66683906 100644 --- a/app/controllers/spree/admin/variants_controller.rb +++ b/app/controllers/spree/admin/variants_controller.rb @@ -65,12 +65,7 @@ module Spree end def variant_params - params.require(:variant).permit( - :display_name, :display_as, :unit_value, :unit_description, - :sku, :price, :cost_price, - :weight, :height, :width, :depth, - :on_demand, :on_hand - ) + params.require(:variant).permit(PermittedAttributes::Variant.attributes) end def permitted_resource_params diff --git a/app/services/permitted_attributes/product.rb b/app/services/permitted_attributes/product.rb new file mode 100644 index 0000000000..13ff8d56ef --- /dev/null +++ b/app/services/permitted_attributes/product.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module PermittedAttributes + class Product + def self.attributes + [ + :id, :name, :description, :supplier_id, :price, :cost_price, :permalink, + :variant_unit, :variant_unit_scale, :unit_value, :unit_description, :variant_unit_name, + :display_as, :sku, :available_on, :group_buy, :group_buy_unit_size, + :taxon_ids, :primary_taxon_id, :tax_category_id, :shipping_category_id, + :meta_keywords, :meta_description, :notes, :inherits_properties, + product_properties_attributes: [:id, :property_name, :value], + variants_attributes: [PermittedAttributes::Variant.attributes], + images_attributes: [:attachment] + ] + end + end +end diff --git a/app/services/permitted_attributes/variant.rb b/app/services/permitted_attributes/variant.rb new file mode 100644 index 0000000000..a04928af0d --- /dev/null +++ b/app/services/permitted_attributes/variant.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module PermittedAttributes + class Variant + def self.attributes + [ + :id, :sku, :on_hand, :on_demand, + :cost_price, :price, :unit_value, :unit_description, + :display_name, :display_as, + :weight, :height, :width, :depth + ] + end + end +end From c15433af3f207fcc1d40a5a9ba7ab42ecf284e2b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 22 Feb 2020 17:41:45 +0000 Subject: [PATCH 160/507] Bring some strong parameters code from spree to our Spree controllers This code comes from spree commit https://github.com/openfoodfoundation/spree/commit/fbc2d150f640399d73baab5295416da7131b95e7 --- app/controllers/spree/admin/payments_controller.rb | 2 +- app/controllers/spree/admin/taxons_controller.rb | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/payments_controller.rb b/app/controllers/spree/admin/payments_controller.rb index af100b7c80..7627e5c6a2 100644 --- a/app/controllers/spree/admin/payments_controller.rb +++ b/app/controllers/spree/admin/payments_controller.rb @@ -82,7 +82,7 @@ module Spree source_params = params.delete(:payment_source)[params[:payment][:payment_method_id]] params[:payment][:source_attributes] = source_params end - params[:payment] + params.require(:payment).permit(:amount, :payment_method_id, :source_attributes) end def load_data diff --git a/app/controllers/spree/admin/taxons_controller.rb b/app/controllers/spree/admin/taxons_controller.rb index ddc1b63c70..a79dfd28d8 100644 --- a/app/controllers/spree/admin/taxons_controller.rb +++ b/app/controllers/spree/admin/taxons_controller.rb @@ -89,7 +89,7 @@ module Spree @update_children = true end - if @taxon.update_attributes(params[:taxon]) + if @taxon.update_attributes(taxon_params) flash[:success] = flash_message_for(@taxon, :successfully_updated) end @@ -113,6 +113,17 @@ module Spree @taxon.destroy respond_with(@taxon) { |format| format.json { render json: '' } } end + + private + + def taxon_params + params.require(:taxon).permit(permitted_params) + end + + def permitted_params + [:name, :parent_id, :position, :icon, :description, :permalink, + :taxonomy_id, :meta_description, :meta_keywords, :meta_title] + end end end end From d496a4bdc8425230ae578989ee76576dc848fddc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 22 Feb 2020 19:03:48 +0000 Subject: [PATCH 161/507] Add strong parameters permits to some controllers --- app/controllers/admin/inventory_items_controller.rb | 6 ++++++ app/controllers/spree/orders_controller.rb | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/inventory_items_controller.rb b/app/controllers/admin/inventory_items_controller.rb index 4567c64632..fa65752def 100644 --- a/app/controllers/admin/inventory_items_controller.rb +++ b/app/controllers/admin/inventory_items_controller.rb @@ -2,6 +2,8 @@ module Admin class InventoryItemsController < ResourceController respond_to :json + prepend_before_filter :permit_params + respond_override update: { json: { success: lambda { render_as_json @inventory_item }, failure: lambda { render json: { errors: @inventory_item.errors.full_messages }, status: :unprocessable_entity } @@ -14,6 +16,10 @@ module Admin private + def permit_params + params.require(:inventory_item).permit! + end + # Overriding Spree method to load data from params here so that # we can authorise #create using an object with required attributes def build_resource diff --git a/app/controllers/spree/orders_controller.rb b/app/controllers/spree/orders_controller.rb index 09f9374247..36af289000 100644 --- a/app/controllers/spree/orders_controller.rb +++ b/app/controllers/spree/orders_controller.rb @@ -74,7 +74,7 @@ module Spree redirect_to(main_app.root_path) && return end - if @order.update_attributes(params[:order]) + if @order.update_attributes(order_params) discard_empty_line_items with_open_adjustments { update_totals_and_taxes } @@ -224,5 +224,9 @@ module Spree redirect_to order_path(order_to_update) end end + + def order_params + params.require(:order).permit(:distributor_id, :order_cycle_id) + end end end From 913ea5b8836dbdd2551775ac040fee8fb61b1445 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 15:29:08 +0000 Subject: [PATCH 162/507] Handle strong parameters in bulk_line_items controller --- app/controllers/admin/bulk_line_items_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/bulk_line_items_controller.rb b/app/controllers/admin/bulk_line_items_controller.rb index 86a2f539e2..dba7bd9bef 100644 --- a/app/controllers/admin/bulk_line_items_controller.rb +++ b/app/controllers/admin/bulk_line_items_controller.rb @@ -29,7 +29,7 @@ module Admin # See https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/locking/pessimistic.rb#L69 # and https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE order.with_lock do - if @line_item.update_attributes(params[:line_item]) + if @line_item.update_attributes(line_item_params) order.update_distribution_charge! render nothing: true, status: :no_content # No Content, does not trigger ng resource auto-update else @@ -73,5 +73,9 @@ module Admin def order @line_item.order end + + def line_item_params + params.require(:line_item).permit(:price, :quantity, :final_weight_volume) + end end end From 6bd72f44dec6e676f1a53f22d53535aa1c07bde9 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 17:43:54 +0000 Subject: [PATCH 163/507] Handle strong params in credit card controllers --- app/controllers/spree/credit_cards_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/credit_cards_controller.rb b/app/controllers/spree/credit_cards_controller.rb index 3381a240e8..91d5e2d223 100644 --- a/app/controllers/spree/credit_cards_controller.rb +++ b/app/controllers/spree/credit_cards_controller.rb @@ -26,7 +26,7 @@ module Spree authorize! :update, @credit_card - if @credit_card.update_attributes(params[:credit_card]) + if @credit_card.update_attributes(credit_card_params) render json: @credit_card, serializer: ::Api::CreditCardSerializer, status: :ok else update_failed @@ -96,5 +96,9 @@ module Spree def update_failed render json: { flash: { error: t(:card_could_not_be_updated) } }, status: :bad_request end + + def credit_card_params + params.require(:credit_card).permit(:is_default, :year, :month) + end end end From e23267156d1eafa89ebb1282a494b77544628fdb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 14:26:25 +0000 Subject: [PATCH 164/507] Improve inventory_items_controller strong params by not using permit! --- .../admin/inventory_items_controller.rb | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/app/controllers/admin/inventory_items_controller.rb b/app/controllers/admin/inventory_items_controller.rb index fa65752def..10ffbf1abd 100644 --- a/app/controllers/admin/inventory_items_controller.rb +++ b/app/controllers/admin/inventory_items_controller.rb @@ -2,8 +2,6 @@ module Admin class InventoryItemsController < ResourceController respond_to :json - prepend_before_filter :permit_params - respond_override update: { json: { success: lambda { render_as_json @inventory_item }, failure: lambda { render json: { errors: @inventory_item.errors.full_messages }, status: :unprocessable_entity } @@ -16,18 +14,14 @@ module Admin private - def permit_params - params.require(:inventory_item).permit! - end - - # Overriding Spree method to load data from params here so that + # Overriding resource_controller method to load data from params here so that # we can authorise #create using an object with required attributes def build_resource - if parent_data.present? - parent.public_send(controller_name).build - else - model_class.new(params[object_name]) # This line changed - end + model_class.new(permitted_resource_params) + end + + def permitted_resource_params + params.require(:inventory_item).permit(:enterprise_id, :variant_id, :visible) end end end From 46025915d55537b3999372d45d6449190d35d79c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 15:26:56 +0000 Subject: [PATCH 165/507] Make taxons_controller strong_params method consistent with all other controllers --- app/controllers/spree/admin/taxons_controller.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/controllers/spree/admin/taxons_controller.rb b/app/controllers/spree/admin/taxons_controller.rb index a79dfd28d8..739b2df31a 100644 --- a/app/controllers/spree/admin/taxons_controller.rb +++ b/app/controllers/spree/admin/taxons_controller.rb @@ -117,12 +117,10 @@ module Spree private def taxon_params - params.require(:taxon).permit(permitted_params) - end - - def permitted_params - [:name, :parent_id, :position, :icon, :description, :permalink, - :taxonomy_id, :meta_description, :meta_keywords, :meta_title] + params.require(:taxon).permit( + :name, :parent_id, :position, :icon, :description, :permalink, + :taxonomy_id, :meta_description, :meta_keywords, :meta_title + ) end end end From e5a214da782966a5c9e1899e178f863f92e0f629 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 17:10:50 +0000 Subject: [PATCH 166/507] Permit specific params in states controller --- app/controllers/spree/admin/states_controller.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/controllers/spree/admin/states_controller.rb b/app/controllers/spree/admin/states_controller.rb index eebbee8d44..91b7672df2 100644 --- a/app/controllers/spree/admin/states_controller.rb +++ b/app/controllers/spree/admin/states_controller.rb @@ -24,6 +24,10 @@ module Spree def load_data @countries = Country.order(:name) end + + def permitted_resource_params + params.require(:state).permit(:name, :abbr) + end end end end From 423d5a5a6145e66b6a418100a725d7882050f7f1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 17:12:51 +0000 Subject: [PATCH 167/507] Permit specific params in taxonomies controller --- app/controllers/spree/admin/taxonomies_controller.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/controllers/spree/admin/taxonomies_controller.rb b/app/controllers/spree/admin/taxonomies_controller.rb index cbbf85e212..fb735ec4fa 100644 --- a/app/controllers/spree/admin/taxonomies_controller.rb +++ b/app/controllers/spree/admin/taxonomies_controller.rb @@ -16,6 +16,10 @@ module Spree admin_taxonomies_url end end + + def permitted_resource_params + params.require(:taxonomy).permit(:name) + end end end end From b99d4ab627cc21ae67a293ef40d648eaab557ecb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 17:34:25 +0000 Subject: [PATCH 168/507] Permit specific params in schedules controller --- app/controllers/admin/schedules_controller.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index e71917044b..4c6354d8f0 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -93,5 +93,9 @@ module Admin syncer = OpenFoodNetwork::ProxyOrderSyncer.new(subscriptions) syncer.sync! end + + def permitted_resource_params + params.require(:schedule).permit(:name, order_cycle_ids: []) + end end end From 9681437fba2bef5b7f99ab09ce791a9ece38385d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 18:03:08 +0000 Subject: [PATCH 169/507] Permit specific params in tax_categories controller --- app/controllers/spree/admin/tax_categories_controller.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/spree/admin/tax_categories_controller.rb b/app/controllers/spree/admin/tax_categories_controller.rb index 26cff4479f..e4f7e4bff6 100644 --- a/app/controllers/spree/admin/tax_categories_controller.rb +++ b/app/controllers/spree/admin/tax_categories_controller.rb @@ -14,6 +14,12 @@ module Spree end end end + + private + + def permitted_resource_params + params.require(:tax_category).permit(:name, :description, :is_default) + end end end end From 495c3a381001a69096e212024643bb2f6d8b1ca5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 18:21:29 +0000 Subject: [PATCH 170/507] Permit specific params in images controller --- app/controllers/spree/admin/images_controller.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/spree/admin/images_controller.rb b/app/controllers/spree/admin/images_controller.rb index 2a46ebec92..168f01466d 100644 --- a/app/controllers/spree/admin/images_controller.rb +++ b/app/controllers/spree/admin/images_controller.rb @@ -34,6 +34,12 @@ module Spree def destroy_before @viewable = @image.viewable end + + def permitted_resource_params + params.require(:image).permit( + :attachment, :viewable_id, :alt + ) + end end end end From d73d851095a125135cc35cedea4720504e3a3669 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 18:24:00 +0000 Subject: [PATCH 171/507] Permit specific params in tax_rates controller --- app/controllers/spree/admin/tax_rates_controller.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/controllers/spree/admin/tax_rates_controller.rb b/app/controllers/spree/admin/tax_rates_controller.rb index 89d9098849..0f828abfee 100644 --- a/app/controllers/spree/admin/tax_rates_controller.rb +++ b/app/controllers/spree/admin/tax_rates_controller.rb @@ -21,6 +21,13 @@ module Spree def create_after Rails.cache.delete('vat_rates') end + + def permitted_resource_params + params.require(:tax_rate).permit( + :name, :amount, :included_in_price, :zone_id, + :tax_category_id, :show_rate_in_label, :calculator_type + ) + end end end end From 6fa1ed03dcb370bbcc5a764400c7040ffa09cb36 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 18:28:00 +0000 Subject: [PATCH 172/507] Permit specific params in adjustments controller --- app/controllers/spree/admin/adjustments_controller.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/spree/admin/adjustments_controller.rb b/app/controllers/spree/admin/adjustments_controller.rb index 07a9207c14..dc9596d242 100644 --- a/app/controllers/spree/admin/adjustments_controller.rb +++ b/app/controllers/spree/admin/adjustments_controller.rb @@ -66,6 +66,12 @@ module Spree def enable_updates @adjustment.close end + + def permitted_resource_params + params.require(:adjustment).permit( + :label, :amount, :included_tax + ) + end end end end From 47505b62257be1b8d77237df971a1fab9a526dfc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 18:37:25 +0000 Subject: [PATCH 173/507] Permit specific params in shipping methods controller --- .../spree/admin/shipping_methods_controller.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/controllers/spree/admin/shipping_methods_controller.rb b/app/controllers/spree/admin/shipping_methods_controller.rb index 902a028b5b..a8c5dbb1e1 100644 --- a/app/controllers/spree/admin/shipping_methods_controller.rb +++ b/app/controllers/spree/admin/shipping_methods_controller.rb @@ -81,6 +81,14 @@ module Spree @available_zones = Zone.order(:name) @calculators = ShippingMethod.calculators.sort_by(&:name) end + + def permitted_resource_params + params.require(:shipping_method).permit( + :name, :description, :display_on, + :require_ship_address, :tag_list, :calculator_type, + distributor_ids: [] + ) + end end end end From 2a426d29b63780139a0a898112c74492ceb7ab4a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 19:18:48 +0000 Subject: [PATCH 174/507] Permit specific params in zones controller --- app/controllers/spree/admin/zones_controller.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/spree/admin/zones_controller.rb b/app/controllers/spree/admin/zones_controller.rb index 5b5b9d876b..466729ed03 100644 --- a/app/controllers/spree/admin/zones_controller.rb +++ b/app/controllers/spree/admin/zones_controller.rb @@ -21,6 +21,12 @@ module Spree @states = State.order(:name) @zones = Zone.order(:name) end + + def permitted_resource_params + params.require(:zone).permit( + :name, :description, :default_tax + ) + end end end end From 8c5dfea92fe953eb529dbb88da142bd182eed8a0 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 28 Feb 2020 13:00:50 +0000 Subject: [PATCH 175/507] Fix strong params in order_cycles and schedules controllers --- app/controllers/admin/schedules_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 4c6354d8f0..f79b478810 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -95,7 +95,7 @@ module Admin end def permitted_resource_params - params.require(:schedule).permit(:name, order_cycle_ids: []) + params.permit(:name, order_cycle_ids: []) end end end From b7c0caf883934a821c9a8c87c63ff3fcc6fa18e7 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 4 Mar 2020 13:58:42 +0000 Subject: [PATCH 176/507] Add needed permitted attributes to orders_controller --- app/controllers/spree/orders_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/orders_controller.rb b/app/controllers/spree/orders_controller.rb index 36af289000..9c3889c8df 100644 --- a/app/controllers/spree/orders_controller.rb +++ b/app/controllers/spree/orders_controller.rb @@ -226,7 +226,10 @@ module Spree end def order_params - params.require(:order).permit(:distributor_id, :order_cycle_id) + params.require(:order).permit( + :distributor_id, :order_cycle_id, + line_items_attributes: [:id, :quantity] + ) end end end From 5a0319213fd4c9dc9df904097995e888b199b084 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 5 Mar 2020 15:10:20 +0000 Subject: [PATCH 177/507] Fix schedules controller permitted attributes --- app/controllers/admin/schedules_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index f79b478810..bd95a214e0 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -95,7 +95,10 @@ module Admin end def permitted_resource_params - params.permit(:name, order_cycle_ids: []) + params.require(:schedule).permit( + :name, + order_cycle_ids: [] + ) end end end From 3ccd58d50bac5b97e8be0cf070291a9b3b13ccc9 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 15:41:37 +0000 Subject: [PATCH 178/507] Fix a problem in the permit list to allow a list to be taken --- app/controllers/admin/enterprise_relationships_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index 1996b4f73d..c3e5dbe051 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -25,7 +25,7 @@ module Admin private def enterprise_relationship_params - params.require(:enterprise_relationship).permit(:parent_id, :child_id, :permissions_list) + params.require(:enterprise_relationship).permit(:parent_id, :child_id, permissions_list: []) end end end From 4e4353551224e88cb614e9bbec3299ea1062f7b3 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 9 Mar 2020 13:01:15 +0000 Subject: [PATCH 179/507] Add missing permitted attribute --- app/controllers/admin/schedules_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index bd95a214e0..8c8392372e 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -96,6 +96,7 @@ module Admin def permitted_resource_params params.require(:schedule).permit( + :id, :name, order_cycle_ids: [] ) From 5e6a210632ad54bd2556514c592d437a8b52f582 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 22:34:40 +0000 Subject: [PATCH 180/507] Fix problem in PermittedAttributes::User namespace --- app/controllers/spree/admin/users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/users_controller.rb b/app/controllers/spree/admin/users_controller.rb index d5525936a3..d70aaa8d9b 100644 --- a/app/controllers/spree/admin/users_controller.rb +++ b/app/controllers/spree/admin/users_controller.rb @@ -138,7 +138,7 @@ module Spree end def user_params - PermittedAttributes::User.new(params).call([:enterprise_limit]) + ::PermittedAttributes::User.new(params).call([:enterprise_limit]) end end end From 478f885b26b9072518f50476d66a8e7f5922ae18 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 22:35:12 +0000 Subject: [PATCH 181/507] Fix problem in PermittedAttributes::Variant namespace --- app/controllers/spree/admin/variants_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/variants_controller.rb b/app/controllers/spree/admin/variants_controller.rb index fc66683906..b4e4ff5f55 100644 --- a/app/controllers/spree/admin/variants_controller.rb +++ b/app/controllers/spree/admin/variants_controller.rb @@ -65,7 +65,7 @@ module Spree end def variant_params - params.require(:variant).permit(PermittedAttributes::Variant.attributes) + params.require(:variant).permit(::PermittedAttributes::Variant.attributes) end def permitted_resource_params From 658a024272ce3b71c5574b9b3368a4174c444571 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 22 Mar 2020 10:41:59 +0000 Subject: [PATCH 182/507] Re-add spring and newrelix_rpm --- Gemfile | 6 +++--- Gemfile.lock | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 39b27966b7..91eae74825 100644 --- a/Gemfile +++ b/Gemfile @@ -154,12 +154,12 @@ end group :development do gem 'byebug', '~> 9.0.0' # 9.1 requires ruby 2.2 gem 'debugger-linecache' - #gem "newrelic_rpm", "~> 3.0" + gem "newrelic_rpm", "~> 3.0" gem 'pry-byebug', '>= 3.4.3' gem 'rubocop' gem 'rubocop-rails' - #gem 'spring' - #gem 'spring-commands-rspec' + gem 'spring' + gem 'spring-commands-rspec' # 1.0.9 fixed openssl issues on macOS https://github.com/eventmachine/eventmachine/issues/602 # While we don't require this gem directly, no dependents forced the upgrade to a version diff --git a/Gemfile.lock b/Gemfile.lock index 47b51fa614..fbe845f1de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -469,6 +469,7 @@ GEM multi_json (1.14.1) multi_xml (0.6.0) multipart-post (2.1.1) + newrelic_rpm (3.18.1.330) nokogiri (1.6.8.1) mini_portile2 (~> 2.1.0) oauth2 (1.4.4) @@ -631,6 +632,9 @@ GEM tilt (>= 1.3, < 3) spinjs-rails (1.4) rails (>= 3.1) + spring (1.7.2) + spring-commands-rspec (1.0.4) + spring (>= 0.9.1) sprockets (2.12.5) hike (~> 1.2) multi_json (~> 1.0) @@ -742,6 +746,7 @@ DEPENDENCIES letter_opener (>= 1.4.1) mini_racer (= 0.2.9) momentjs-rails + newrelic_rpm (~> 3.0) nokogiri (~> 1.6.8.1) oauth2 (~> 1.4.4) ofn-qz! @@ -775,6 +780,8 @@ DEPENDENCIES spree_core! spree_i18n! spree_paypal_express! + spring + spring-commands-rspec stripe test-unit (~> 3.3) timecop From 2de550eac1958e20dac85a78e08919c13fadc3fe Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 22 Mar 2020 20:08:11 +0000 Subject: [PATCH 183/507] Make OrderUpdate update all adjustments again as in v2.0.4 otherwise adjustments that are not shipment adjustments will not be calculated correctly --- app/models/spree/order_updater_decorator.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/models/spree/order_updater_decorator.rb diff --git a/app/models/spree/order_updater_decorator.rb b/app/models/spree/order_updater_decorator.rb new file mode 100644 index 0000000000..029e39c74a --- /dev/null +++ b/app/models/spree/order_updater_decorator.rb @@ -0,0 +1,6 @@ +Spree::OrderUpdater.class_eval do + # Override spree method to make it update all adjustments as in Spree v2.0.4 + def update_shipping_adjustments + order.adjustments.reload.each { |adjustment| adjustment.update! } + end +end From b8ed28b38ccc64f8e8d8f865dc88b4c5f3a5767c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 24 Mar 2020 16:58:56 +0000 Subject: [PATCH 184/507] Remove deface, it's already included in spree_core, it's not a direct dependency of OFN anymore --- Gemfile | 1 - Gemfile.lock | 1 - 2 files changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index 4f004fd650..0c736ed4a7 100644 --- a/Gemfile +++ b/Gemfile @@ -74,7 +74,6 @@ gem 'angularjs-file-upload-rails', '~> 2.4.1' gem 'blockenspiel' gem 'custom_error_message', github: 'jeremydurham/custom-err-msg' gem 'dalli' -gem 'deface' gem 'diffy' gem 'figaro' gem 'geocoder' diff --git a/Gemfile.lock b/Gemfile.lock index 413ec6648e..6582ae99be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -718,7 +718,6 @@ DEPENDENCIES db2fog ddtrace debugger-linecache - deface delayed_job_active_record delayed_job_web devise (~> 3.0.1) From 5453fed7167b7c988c84b05aedd983b275a57aab Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 24 Mar 2020 17:30:10 +0000 Subject: [PATCH 185/507] Upgrade rails from 4.0.0 to 4.0.13 --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 0c736ed4a7..e7c6f9ce6d 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" } gem 'i18n', '~> 0.6.11' gem 'i18n-js', '~> 3.6.0' -gem 'rails', '~> 4.0.0' +gem 'rails', '~> 4.0.13' gem 'rails-i18n', '~> 4.0' gem 'rails_safe_tasks', '~> 1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 6582ae99be..88837b627a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -760,7 +760,7 @@ DEPENDENCIES rack-mini-profiler (< 3.0.0) rack-rewrite rack-ssl - rails (~> 4.0.0) + rails (~> 4.0.13) rails-i18n (~> 4.0) rails_safe_tasks (~> 1.0) redcarpet From 89cc7ee5ef27ac96641fb0b239b8a2dbd6aee987 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 24 Mar 2020 18:03:50 +0000 Subject: [PATCH 186/507] Upgrade devise-encryptable to 0.2.0 which is latest --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 88837b627a..112b0061b9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -233,7 +233,7 @@ GEM orm_adapter (~> 0.1) railties (>= 3.2.6, < 5) warden (~> 1.2.3) - devise-encryptable (0.1.2) + devise-encryptable (0.2.0) devise (>= 2.1.0) diff-lcs (1.3) diffy (3.3.0) From 570fb4bfb4975e89e2c2015be9905bce93a3976b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 24 Mar 2020 18:43:52 +0000 Subject: [PATCH 187/507] Upgrade factory_bot_rails --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index e7c6f9ce6d..8a8b9a5b3a 100644 --- a/Gemfile +++ b/Gemfile @@ -130,7 +130,7 @@ group :test, :development do gem 'awesome_print' gem 'capybara', '>= 2.18.0' # 3.0 requires nokogiri 1.8 gem 'database_cleaner', require: false - gem "factory_bot_rails", '4.8.2', require: false + gem "factory_bot_rails", '4.10.0', require: false gem 'fuubar', '~> 2.4.1' gem 'json_spec', '~> 1.1.4' gem 'knapsack' diff --git a/Gemfile.lock b/Gemfile.lock index 112b0061b9..54cb09004d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -243,10 +243,10 @@ GEM eventmachine (1.2.7) excon (0.71.1) execjs (2.7.0) - factory_bot (4.8.2) + factory_bot (4.10.0) activesupport (>= 3.0.0) - factory_bot_rails (4.8.2) - factory_bot (~> 4.8.2) + factory_bot_rails (4.10.0) + factory_bot (~> 4.10.0) railties (>= 3.0.0) faraday (1.0.0) multipart-post (>= 1.2, < 3) @@ -724,7 +724,7 @@ DEPENDENCIES devise-encryptable diffy eventmachine (>= 1.2.3) - factory_bot_rails (= 4.8.2) + factory_bot_rails (= 4.10.0) figaro foreigner foundation-icons-sass-rails From 6ba3a3c373662af5e6649b92da9ef50ca72264df Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 12:49:27 +0000 Subject: [PATCH 188/507] Handle strong params in admin/enterprises_controller --- .../admin/enterprises_controller.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index cf95180818..c51c586d73 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -41,7 +41,7 @@ module Admin tag_rules_attributes = params[object_name].delete :tag_rules_attributes update_tag_rules(tag_rules_attributes) if tag_rules_attributes.present? update_enterprise_notifications - if @object.update_attributes(params[object_name]) + if @object.update_attributes(enterprise_params) invoke_callbacks(:update, :after) flash[:success] = flash_message_for(@object, :successfully_updated) respond_with(@object) do |format| @@ -244,7 +244,7 @@ module Admin def override_sells unless spree_current_user.admin? has_hub = spree_current_user.owned_enterprises.is_hub.any? - new_enterprise_is_producer = Enterprise.new(params[:enterprise]).is_primary_producer + new_enterprise_is_producer = Enterprise.new(enterprise_params).is_primary_producer params[:enterprise][:sells] = has_hub && !new_enterprise_is_producer ? 'any' : 'none' end end @@ -303,5 +303,20 @@ module Admin def ams_prefix_whitelist [:index, :basic] end + + def enterprise_params + return params[:enterprise] if params[:enterprise].empty? + + params.require(:enterprise).permit( + :name, :is_primary_producer, :visible, :permalink, + :contact_name, :email_address, :phone, :sells, :owner_id, + :website, :facebook, :instagram, :linkedin, :twitter, + :abn, :acn, :charges_sales_tax, :display_invoice_logo, + :invoice_text, :description, :long_description, :promo_image, + :preferred_product_selection_from_inventory_only, :preferred_shopfront_message, + :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, + :preferred_shopfront_order_cycle_order, :require_login, + :allow_guest_orders, :allow_order_changes, :enable_subscriptions) + end end end From 34488e5f635eed4ebfe5a34be514b2367c5b0b1a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 23 Feb 2020 17:49:35 +0000 Subject: [PATCH 189/507] Handle strong params in enterprise_roles controller --- app/controllers/admin/enterprise_roles_controller.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/enterprise_roles_controller.rb b/app/controllers/admin/enterprise_roles_controller.rb index 98810e2a64..299292238e 100644 --- a/app/controllers/admin/enterprise_roles_controller.rb +++ b/app/controllers/admin/enterprise_roles_controller.rb @@ -7,7 +7,7 @@ module Admin end def create - @enterprise_role = EnterpriseRole.new params[:enterprise_role] + @enterprise_role = EnterpriseRole.new enterprise_role_params if @enterprise_role.save render text: Api::Admin::EnterpriseRoleSerializer.new(@enterprise_role).to_json @@ -22,5 +22,11 @@ module Admin @enterprise_role.destroy render nothing: true end + + private + + def enterprise_role_params + params.require(:enterprise_role).permit(:user_id, :enterprise_id) + end end end From 5c179a0932b81b62f49976444e88c57922732366 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 16:43:15 +0000 Subject: [PATCH 190/507] Ammend strong params on enterprise controller to cover create action --- app/controllers/admin/enterprises_controller.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index c51c586d73..ae3c5308d0 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -308,7 +308,7 @@ module Admin return params[:enterprise] if params[:enterprise].empty? params.require(:enterprise).permit( - :name, :is_primary_producer, :visible, :permalink, + :id, :name, :is_primary_producer, :visible, :permalink, :contact_name, :email_address, :phone, :sells, :owner_id, :website, :facebook, :instagram, :linkedin, :twitter, :abn, :acn, :charges_sales_tax, :display_invoice_logo, @@ -316,7 +316,14 @@ module Admin :preferred_product_selection_from_inventory_only, :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order, :require_login, - :allow_guest_orders, :allow_order_changes, :enable_subscriptions) + :allow_guest_orders, :allow_order_changes, :enable_subscriptions, + address_attributes: permitted_address_attributes + ) + end + + # Used in ResourceController#create + def permitted_resource_params + enterprise_params end end end From 29a457575b4f689b63304b24e87e36fee5fdaaff Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 18:13:40 +0000 Subject: [PATCH 191/507] Permit specific params in enterprise_groups controller --- app/controllers/admin/enterprise_groups_controller.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/controllers/admin/enterprise_groups_controller.rb b/app/controllers/admin/enterprise_groups_controller.rb index 4494a7927a..f926852f6f 100644 --- a/app/controllers/admin/enterprise_groups_controller.rb +++ b/app/controllers/admin/enterprise_groups_controller.rb @@ -55,5 +55,13 @@ module Admin def collection EnterpriseGroup.by_position end + + def permitted_resource_params + params.require(:enterprise_group).permit( + :name, :description, :long_description, :on_front_page, :owner_id, :permalink, + :email, :website, :facebook, :instagram, :linkedin, :twitter, + enterprise_ids: [], address_attributes: permitted_address_attributes + ) + end end end From ad9e5d979ab100a77ab5ec16eae51ca7f15a08bc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 19:14:10 +0000 Subject: [PATCH 192/507] Permit extra needed params in enterprises controller --- app/controllers/admin/enterprises_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index ae3c5308d0..157ac2937a 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -317,7 +317,10 @@ module Admin :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order, :require_login, :allow_guest_orders, :allow_order_changes, :enable_subscriptions, - address_attributes: permitted_address_attributes + group_ids: [], user_ids: [], + shipping_method_ids: [], payment_method_ids: [], + address_attributes: permitted_address_attributes, + producer_properties_attributes: [:id, :property_name, :value, :_destroy] ) end From fec5e1d84ea42cdfcc26032123bccad15eada7ac Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 12 Mar 2020 11:30:03 +0000 Subject: [PATCH 193/507] Add needed param to enterprises controller --- app/controllers/admin/enterprises_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 157ac2937a..4d2ea81eb2 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -312,7 +312,7 @@ module Admin :contact_name, :email_address, :phone, :sells, :owner_id, :website, :facebook, :instagram, :linkedin, :twitter, :abn, :acn, :charges_sales_tax, :display_invoice_logo, - :invoice_text, :description, :long_description, :promo_image, + :invoice_text, :description, :long_description, :logo, :promo_image, :preferred_product_selection_from_inventory_only, :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order, :require_login, From a9a92e11e2378e1cfd7436398132fa61ff897db0 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 22 Feb 2020 17:41:45 +0000 Subject: [PATCH 194/507] Bring some strong parameters code from spree to our Spree controllers This code comes from spree commit https://github.com/openfoodfoundation/spree/commit/fbc2d150f640399d73baab5295416da7131b95e7 --- .../spree/admin/orders/customer_details_controller.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/orders/customer_details_controller.rb b/app/controllers/spree/admin/orders/customer_details_controller.rb index e7bb5bf366..989e73fa46 100644 --- a/app/controllers/spree/admin/orders/customer_details_controller.rb +++ b/app/controllers/spree/admin/orders/customer_details_controller.rb @@ -18,7 +18,7 @@ module Spree end def update - if @order.update_attributes(params[:order]) + if @order.update_attributes(order_params) if params[:guest_checkout] == "false" @order.associate_user!(Spree.user_class.find_by(email: @order.email)) end @@ -41,6 +41,15 @@ module Spree private + def order_params + params.require(:order).permit( + :email, + :use_billing, + :bill_address_attributes => permitted_address_attributes, + :ship_address_attributes => permitted_address_attributes + ) + end + def load_order @order = Order.find_by_number!(params[:order_id], include: :adjustments) end From 4fd3026bd8e0ebb0c7aee5842d3124ed6816711f Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 22 Feb 2020 19:03:48 +0000 Subject: [PATCH 195/507] Add strong parameters permits to some controllers --- app/controllers/admin/customers_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index 9941829d2b..bc8137d1b6 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -28,7 +28,7 @@ module Admin end def create - @customer = Customer.new(params[:customer]) + @customer = Customer.new(customer_params) if user_can_create_customer? if @customer.save tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: @customer.enterprise)) @@ -80,5 +80,9 @@ module Admin def ams_prefix_whitelist [:subscription] end + + def customer_params + params.require(:customer).permit(:enterprise_id, :email) + end end end From 9b0d7b96047246a4bd114448d52e6ef7722a1946 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 17:01:49 +0000 Subject: [PATCH 196/507] Ammend customers_controller to include ship address attributes permit and also permit #update with specific attributes --- app/controllers/admin/customers_controller.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index bc8137d1b6..b3b8b87ffb 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -82,7 +82,15 @@ module Admin end def customer_params - params.require(:customer).permit(:enterprise_id, :email) + params.require(:customer).permit( + :enterprise_id, :email, + ship_address_attributes: permitted_address_attributes + ) + end + + # Used in ResourceController#update + def permitted_resource_params + customer_params end end end From 22a005df475bf257cfde8b96117be46f30b43c8c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 7 Mar 2020 20:37:04 +0000 Subject: [PATCH 197/507] Add needed permitted attributes to admin/customers_controller --- app/controllers/admin/customers_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index b3b8b87ffb..2a600db3bd 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -83,8 +83,9 @@ module Admin def customer_params params.require(:customer).permit( - :enterprise_id, :email, - ship_address_attributes: permitted_address_attributes + :enterprise_id, :name, :email, :code, :tag_list, + ship_address_attributes: permitted_address_attributes, + bill_address_attributes: permitted_address_attributes, ) end From e5f56c19c07a7ea6defab5202ab0277d8902ba98 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 20:00:26 +0000 Subject: [PATCH 198/507] Switch to using PermittedAttributes::Address instead of spree version of it that will be removed later --- app/controllers/admin/customers_controller.rb | 4 ++-- app/controllers/admin/enterprise_groups_controller.rb | 2 +- app/controllers/admin/enterprises_controller.rb | 2 +- .../spree/admin/orders/customer_details_controller.rb | 4 ++-- app/services/permitted_attributes/address.rb | 2 ++ 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index 2a600db3bd..d4cf9b15fe 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -84,8 +84,8 @@ module Admin def customer_params params.require(:customer).permit( :enterprise_id, :name, :email, :code, :tag_list, - ship_address_attributes: permitted_address_attributes, - bill_address_attributes: permitted_address_attributes, + ship_address_attributes: PermittedAttributes::Address.attributes, + bill_address_attributes: PermittedAttributes::Address.attributes, ) end diff --git a/app/controllers/admin/enterprise_groups_controller.rb b/app/controllers/admin/enterprise_groups_controller.rb index f926852f6f..5483cdd45e 100644 --- a/app/controllers/admin/enterprise_groups_controller.rb +++ b/app/controllers/admin/enterprise_groups_controller.rb @@ -60,7 +60,7 @@ module Admin params.require(:enterprise_group).permit( :name, :description, :long_description, :on_front_page, :owner_id, :permalink, :email, :website, :facebook, :instagram, :linkedin, :twitter, - enterprise_ids: [], address_attributes: permitted_address_attributes + enterprise_ids: [], address_attributes: PermittedAttributes::Address.attributes ) end end diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 4d2ea81eb2..518a8453a9 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -319,7 +319,7 @@ module Admin :allow_guest_orders, :allow_order_changes, :enable_subscriptions, group_ids: [], user_ids: [], shipping_method_ids: [], payment_method_ids: [], - address_attributes: permitted_address_attributes, + address_attributes: PermittedAttributes::Address.attributes, producer_properties_attributes: [:id, :property_name, :value, :_destroy] ) end diff --git a/app/controllers/spree/admin/orders/customer_details_controller.rb b/app/controllers/spree/admin/orders/customer_details_controller.rb index 989e73fa46..4537f828a6 100644 --- a/app/controllers/spree/admin/orders/customer_details_controller.rb +++ b/app/controllers/spree/admin/orders/customer_details_controller.rb @@ -45,8 +45,8 @@ module Spree params.require(:order).permit( :email, :use_billing, - :bill_address_attributes => permitted_address_attributes, - :ship_address_attributes => permitted_address_attributes + bill_address_attributes: PermittedAttributes::Address.attributes, + ship_address_attributes: PermittedAttributes::Address.attributes ) end diff --git a/app/services/permitted_attributes/address.rb b/app/services/permitted_attributes/address.rb index 4fd7908297..4c7a538caf 100644 --- a/app/services/permitted_attributes/address.rb +++ b/app/services/permitted_attributes/address.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module PermittedAttributes class Address def self.attributes From 6b62c8aafd614cc546b5169dcbb7040e40010be9 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 20:14:11 +0000 Subject: [PATCH 199/507] Extract permitted attributes to separate service --- .../admin/enterprises_controller.rb | 18 +-------- .../permitted_attributes/enterprise.rb | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 app/services/permitted_attributes/enterprise.rb diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 518a8453a9..6198497e98 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -305,23 +305,7 @@ module Admin end def enterprise_params - return params[:enterprise] if params[:enterprise].empty? - - params.require(:enterprise).permit( - :id, :name, :is_primary_producer, :visible, :permalink, - :contact_name, :email_address, :phone, :sells, :owner_id, - :website, :facebook, :instagram, :linkedin, :twitter, - :abn, :acn, :charges_sales_tax, :display_invoice_logo, - :invoice_text, :description, :long_description, :logo, :promo_image, - :preferred_product_selection_from_inventory_only, :preferred_shopfront_message, - :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, - :preferred_shopfront_order_cycle_order, :require_login, - :allow_guest_orders, :allow_order_changes, :enable_subscriptions, - group_ids: [], user_ids: [], - shipping_method_ids: [], payment_method_ids: [], - address_attributes: PermittedAttributes::Address.attributes, - producer_properties_attributes: [:id, :property_name, :value, :_destroy] - ) + PermittedAttributes::Enterprise.new(params).call end # Used in ResourceController#create diff --git a/app/services/permitted_attributes/enterprise.rb b/app/services/permitted_attributes/enterprise.rb new file mode 100644 index 0000000000..f02863b2a5 --- /dev/null +++ b/app/services/permitted_attributes/enterprise.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module PermittedAttributes + class Enterprise + def initialize(params) + @params = params + end + + def call + return @params[:enterprise] if @params[:enterprise].empty? + + @params.require(:enterprise).permit( + basic_permitted_attributes + [ + group_ids: [], user_ids: [], + shipping_method_ids: [], payment_method_ids: [], + address_attributes: PermittedAttributes::Address.attributes, + producer_properties_attributes: [:id, :property_name, :value, :_destroy] + ] + ) + end + + private + + def basic_permitted_attributes + [ + :id, :name, :visible, :permalink, :owner_id, :contact_name, :email_address, :phone, + :is_primary_producer, :sells, :website, :facebook, :instagram, :linkedin, :twitter, + :description, :long_description, :logo, :promo_image, + :allow_guest_orders, :allow_order_changes, :require_login, :enable_subscriptions, + :abn, :acn, :charges_sales_tax, :display_invoice_logo, :invoice_text, + :preferred_product_selection_from_inventory_only, :preferred_shopfront_message, + :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, + :preferred_shopfront_order_cycle_order + ] + end + end +end From b7cb95ae3ea53821c660f473871fc0f78449d1bb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 21 Mar 2020 22:34:25 +0000 Subject: [PATCH 200/507] Fix problem in PermittedAttributes::Address namespace --- .../spree/admin/orders/customer_details_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/orders/customer_details_controller.rb b/app/controllers/spree/admin/orders/customer_details_controller.rb index 4537f828a6..7503e42833 100644 --- a/app/controllers/spree/admin/orders/customer_details_controller.rb +++ b/app/controllers/spree/admin/orders/customer_details_controller.rb @@ -45,8 +45,8 @@ module Spree params.require(:order).permit( :email, :use_billing, - bill_address_attributes: PermittedAttributes::Address.attributes, - ship_address_attributes: PermittedAttributes::Address.attributes + bill_address_attributes: ::PermittedAttributes::Address.attributes, + ship_address_attributes: ::PermittedAttributes::Address.attributes ) end From 483d847b001201201a70136eec6df415a04925e0 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 13 Mar 2020 11:07:46 +0100 Subject: [PATCH 201/507] Use `eager_load = true` in production and staging environments --- config/environments/production.rb | 2 +- config/environments/staging.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index c92b4ee9bc..fa19d313f6 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,7 +1,7 @@ Openfoodnetwork::Application.configure do # Settings specified here will take precedence over those in config/application.rb - config.eager_load = false + config.eager_load = true # Code is not reloaded between requests config.cache_classes = true diff --git a/config/environments/staging.rb b/config/environments/staging.rb index c92b4ee9bc..fa19d313f6 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -1,7 +1,7 @@ Openfoodnetwork::Application.configure do # Settings specified here will take precedence over those in config/application.rb - config.eager_load = false + config.eager_load = true # Code is not reloaded between requests config.cache_classes = true From 7bc29769cddd617e02b05a6d36597753ca0840d5 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 13 Mar 2020 14:17:09 +0100 Subject: [PATCH 202/507] Fix logging configs for Rails 4 --- config/environments/production.rb | 9 ++------- config/environments/staging.rb | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index fa19d313f6..22950996c2 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -38,13 +38,8 @@ Openfoodnetwork::Application.configure do # Note: This config no longer works with our new logging strategy # config.log_level = :debug - # Configure logging for Rails 3.2: - config.logger = ActiveSupport::TaggedLogging.new(Logger.new(Rails.root.join("log", "#{Rails.env}.log"))) - config.logger.level = Logger::INFO - config.logger.formatter = Logger::Formatter.new - config.logger.datetime_format = "%Y-%m-%d %H:%M:%S" - # Once we get to Rails 4.0, we can replace the above with: - #config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" } + # Configure logging: + config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" } # Use a different cache store in production memcached_value_max_megabytes = ENV.fetch("MEMCACHED_VALUE_MAX_MEGABYTES", 1).to_i diff --git a/config/environments/staging.rb b/config/environments/staging.rb index fa19d313f6..22950996c2 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -38,13 +38,8 @@ Openfoodnetwork::Application.configure do # Note: This config no longer works with our new logging strategy # config.log_level = :debug - # Configure logging for Rails 3.2: - config.logger = ActiveSupport::TaggedLogging.new(Logger.new(Rails.root.join("log", "#{Rails.env}.log"))) - config.logger.level = Logger::INFO - config.logger.formatter = Logger::Formatter.new - config.logger.datetime_format = "%Y-%m-%d %H:%M:%S" - # Once we get to Rails 4.0, we can replace the above with: - #config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" } + # Configure logging: + config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" } # Use a different cache store in production memcached_value_max_megabytes = ENV.fetch("MEMCACHED_VALUE_MAX_MEGABYTES", 1).to_i From 433ae0081822683a599224e37435838e0fa24c2e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 18 Mar 2020 12:32:24 +0100 Subject: [PATCH 203/507] Ensure :info log level is set in Rails 4 --- config/environments/production.rb | 4 ++-- config/environments/staging.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index 22950996c2..9c61ebaab0 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -35,8 +35,8 @@ Openfoodnetwork::Application.configure do # Use https in email links config.action_mailer.default_url_options = { protocol: 'https' } - # Note: This config no longer works with our new logging strategy - # config.log_level = :debug + # Set log level (default is :debug in Rails 4) + config.log_level = :info # Configure logging: config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" } diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 22950996c2..9c61ebaab0 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -35,8 +35,8 @@ Openfoodnetwork::Application.configure do # Use https in email links config.action_mailer.default_url_options = { protocol: 'https' } - # Note: This config no longer works with our new logging strategy - # config.log_level = :debug + # Set log level (default is :debug in Rails 4) + config.log_level = :info # Configure logging: config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" } From f1b64e90e08f7b48d1f31420946ccf9542e66f03 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 25 Mar 2020 11:49:14 +0000 Subject: [PATCH 204/507] Add comment to explain unusual fix --- app/models/spree/line_item_decorator.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 7012cec9ec..37637f7564 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -71,8 +71,10 @@ Spree::LineItem.class_eval do where('spree_adjustments.id IS NULL') } + # Overridden so that LineItems always have access to soft-deleted Variant attributes + # In some situations, unscoped super will be nil, in these cases we fetch the variant using the variant_id + # See isssue #4946 for more details def variant - # Overridden so that LineItems always have access to soft-deleted Variant attributes Spree::Variant.unscoped { super } || Spree::Variant.unscoped.find(self.variant_id) end From 0c8635403a030c2cfa73915f344d452aa1598ead Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 12:08:17 +0000 Subject: [PATCH 205/507] Delete dead scope in line_items This is not used anywhere in the code --- app/models/spree/line_item_decorator.rb | 4 ---- spec/models/spree/line_item_spec.rb | 5 ----- 2 files changed, 9 deletions(-) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 37637f7564..9c99c9567f 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -46,10 +46,6 @@ Spree::LineItem.class_eval do where('order_cycles.id = ?', order_cycle) } - scope :supplied_by, lambda { |enterprise| - joins(:product). - where('spree_products.supplier_id = ?', enterprise) - } scope :supplied_by_any, lambda { |enterprises| joins(:product). where('spree_products.supplier_id IN (?)', enterprises) diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index f2f5cd7164..909c72947d 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -27,11 +27,6 @@ module Spree let(:oc_order) { create :order_with_totals_and_distribution } - it "finds line items for products supplied by a particular enterprise" do - expect(LineItem.supplied_by(s1)).to eq([li1]) - expect(LineItem.supplied_by(s2)).to eq([li2]) - end - it "finds line items for products supplied by one of a number of enterprises" do expect(LineItem.supplied_by_any([s1])).to eq([li1]) expect(LineItem.supplied_by_any([s2])).to eq([li2]) From 7c367da904b9bc728c039129ca9a3d232613cf58 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 12:10:21 +0000 Subject: [PATCH 206/507] Adapt LineItem#supplied_by_any scope to include deleted variants and deleted products (both not included in the respective default scopes) and use it in Permissions::Order so that variants of deleted products are seen in reports --- app/models/spree/line_item_decorator.rb | 7 +++++-- app/services/permissions/order.rb | 6 +----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 9c99c9567f..2526f6670a 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -47,8 +47,11 @@ Spree::LineItem.class_eval do } scope :supplied_by_any, lambda { |enterprises| - joins(:product). - where('spree_products.supplier_id IN (?)', enterprises) + joins("LEFT OUTER JOIN spree_variants + ON spree_line_items.variant_id = spree_variants.id + LEFT OUTER JOIN spree_products + ON spree_variants.product_id = spree_products.id"). + where("spree_products.supplier_id IN (?)", enterprises) } scope :with_tax, -> { diff --git a/app/services/permissions/order.rb b/app/services/permissions/order.rb index 5e95ba92c8..39e78ec96e 100644 --- a/app/services/permissions/order.rb +++ b/app/services/permissions/order.rb @@ -90,11 +90,7 @@ module Permissions # Any from visible orders, where the product is produced by one of my managed producers def produced_line_items Spree::LineItem.where(order_id: visible_orders.select("DISTINCT spree_orders.id")). - joins(:product). - where(spree_products: - { - supplier_id: @permissions.managed_enterprises.is_primary_producer.select("enterprises.id") - }) + supplied_by_any(@permissions.managed_enterprises.is_primary_producer.select("enterprises.id")) end end end From 890923868282f0c7f8c7ccafa3f06e77bf2ff7be Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 12:27:17 +0000 Subject: [PATCH 207/507] Fix one rubocop issue --- app/services/permissions/order.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/permissions/order.rb b/app/services/permissions/order.rb index 39e78ec96e..8b74dbe901 100644 --- a/app/services/permissions/order.rb +++ b/app/services/permissions/order.rb @@ -90,7 +90,9 @@ module Permissions # Any from visible orders, where the product is produced by one of my managed producers def produced_line_items Spree::LineItem.where(order_id: visible_orders.select("DISTINCT spree_orders.id")). - supplied_by_any(@permissions.managed_enterprises.is_primary_producer.select("enterprises.id")) + supplied_by_any( + @permissions.managed_enterprises.is_primary_producer.select("enterprises.id") + ) end end end From a4c7dbc3295a5c09bdf6a2dcf55e5d7a7d087b45 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 6 Mar 2020 12:30:13 +0000 Subject: [PATCH 208/507] Add comment to better explain why this scope is not simply using joins(:product) --- app/models/spree/line_item_decorator.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 2526f6670a..71e768c42d 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -46,6 +46,9 @@ Spree::LineItem.class_eval do where('order_cycles.id = ?', order_cycle) } + # Here we are simply joining the line item to its variant and product + # We do this with SQL to avoid the default scopes, + # and with that, include deleted variants and deleted products scope :supplied_by_any, lambda { |enterprises| joins("LEFT OUTER JOIN spree_variants ON spree_line_items.variant_id = spree_variants.id From 6e095bdb6826028863eca18bf71347234e0371b7 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 27 Mar 2020 11:57:53 +0000 Subject: [PATCH 209/507] Fix bug in line_item_decorator, should be inner join not left outer join --- app/models/spree/line_item_decorator.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 71e768c42d..51e36f7466 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -50,9 +50,9 @@ Spree::LineItem.class_eval do # We do this with SQL to avoid the default scopes, # and with that, include deleted variants and deleted products scope :supplied_by_any, lambda { |enterprises| - joins("LEFT OUTER JOIN spree_variants + joins("INNER JOIN spree_variants ON spree_line_items.variant_id = spree_variants.id - LEFT OUTER JOIN spree_products + INNER JOIN spree_products ON spree_variants.product_id = spree_products.id"). where("spree_products.supplier_id IN (?)", enterprises) } From 80b9800b3669d34a1682af9a41ad2e0556111f55 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 27 Mar 2020 12:00:56 +0000 Subject: [PATCH 210/507] Replace SQL with equivalent AR code --- app/models/spree/line_item_decorator.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 51e36f7466..2799c443b9 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -47,14 +47,12 @@ Spree::LineItem.class_eval do } # Here we are simply joining the line item to its variant and product - # We do this with SQL to avoid the default scopes, + # We dont use joins here to avoid the default scopes, # and with that, include deleted variants and deleted products scope :supplied_by_any, lambda { |enterprises| - joins("INNER JOIN spree_variants - ON spree_line_items.variant_id = spree_variants.id - INNER JOIN spree_products - ON spree_variants.product_id = spree_products.id"). - where("spree_products.supplier_id IN (?)", enterprises) + product_ids = Spree::Product.unscoped.where(supplier_id: enterprises).select(:id) + variant_ids = Spree::Variant.unscoped.where(product_id: product_ids).select(:id) + where("spree_line_items.variant_id IN (?)", variant_ids) } scope :with_tax, -> { From 154e223a12e79e241669aa5fbbfaa10fb4971568 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 1 Apr 2020 09:58:19 +0100 Subject: [PATCH 211/507] Make sure test data is available before the test --- spec/models/spree/line_item_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index 909c72947d..2eb9d2bb4d 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -28,6 +28,7 @@ module Spree let(:oc_order) { create :order_with_totals_and_distribution } it "finds line items for products supplied by one of a number of enterprises" do + li1; li2 expect(LineItem.supplied_by_any([s1])).to eq([li1]) expect(LineItem.supplied_by_any([s2])).to eq([li2]) expect(LineItem.supplied_by_any([s1, s2])).to match_array [li1, li2] From 07264446e6708efd9673a4bce49aa53db1494685 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 4 Apr 2020 11:17:22 +0100 Subject: [PATCH 212/507] Add strong params implementation to properties controller --- app/controllers/spree/admin/properties_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/spree/admin/properties_controller.rb b/app/controllers/spree/admin/properties_controller.rb index dcccad41f9..fd618f1272 100644 --- a/app/controllers/spree/admin/properties_controller.rb +++ b/app/controllers/spree/admin/properties_controller.rb @@ -1,6 +1,9 @@ module Spree module Admin class PropertiesController < ResourceController + def permitted_resource_params + params.require(:property).permit(:name, :presentation) + end end end end From 4f08ed18015cb63fb99d0796177e400f7b935810 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 4 Apr 2020 11:39:20 +0100 Subject: [PATCH 213/507] Remove commented turbo-sprockets-rails3 from Gemfile, thsi gem is not needed in rails 4 --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index af4a606437..5a13e1ff50 100644 --- a/Gemfile +++ b/Gemfile @@ -108,7 +108,6 @@ gem 'uglifier', '>= 1.0.3' gem 'angular-rails-templates', '~> 0.3.0' gem 'foundation-icons-sass-rails' gem 'momentjs-rails' -# gem 'turbo-sprockets-rails3' gem 'foundation-rails', '= 5.5.2.1' From 4ceaebf098d3682b018cbec50a63d7e3aa8c9244 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 4 Apr 2020 16:12:43 +0100 Subject: [PATCH 214/507] Add order.email regexp validation and add some tests for it --- app/models/spree/order_decorator.rb | 5 ++-- spec/models/spree/order_spec.rb | 37 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index ef8e140d18..8b8713e0f1 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -29,13 +29,14 @@ Spree::Order.class_eval do validate :products_available_from_new_distribution, if: lambda { distributor_id_changed? || order_cycle_id_changed? } validate :disallow_guest_order - # Removes Spree 2.1 additional email validation (currently failing every time) - # See: spree/core/validators/email.rb + # The EmailValidator introduced in Spree 2.1 is not working + # So here we remove it and re-introduce the regexp validation rule from Spree 2.0 _validate_callbacks.each do |callback| if callback.raw_filter.respond_to? :attributes callback.raw_filter.attributes.delete :email end end + validates :email, presence: true, format: /\A([\w\.%\+\-']+)@([\w\-]+\.)+([\w]{2,})\z/i, if: :require_email before_validation :associate_customer, unless: :customer_id? before_validation :ensure_customer, unless: :customer_is_valid? diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 893e450eff..4392acb998 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -3,6 +3,43 @@ require 'spec_helper' describe Spree::Order do include OpenFoodNetwork::EmailHelper + describe "email validation" do + let(:order) { build(:order) } + + it "has errors if email is blank" do + order.stub(require_email: true) + order.update_attributes email: "" + + order.valid? + expect(order.errors[:email]).to eq ["can't be blank", "is invalid"] + end + + it "has errors if email is invalid" do + order.stub(require_email: true) + order.update_attributes email: "invalid_email" + + order.valid? + expect(order.errors[:email]).to eq ["is invalid"] + end + + it "has errors if email has invalid domain" do + order.stub(require_email: true) + order.update_attributes email: "single_letter_tld@domain.z" + + order.valid? + expect(order.errors[:email]).to eq ["is invalid"] + end + + it "is valid if email is valid" do + order.stub(require_email: true) + order.update_attributes email: "a@b.ca" + + order.valid? + expect(order.errors[:email]).to eq [] + end + + end + describe "setting variant attributes" do it "sets attributes on line items for variants" do d = create(:distributor_enterprise) From fa4b8832e90c39ad5d42e41c8ac6d1cbe51c3dd8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 4 Apr 2020 16:39:23 +0100 Subject: [PATCH 215/507] Fix timezone mix up in specs Converting times with timezones to string was ignoring the timezone and this making the start date be before the end date in this spec --- .../reports/enterprise_fee_summary/parameters_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/parameters_spec.rb b/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/parameters_spec.rb index 6fd3c8b9a7..130401cb34 100644 --- a/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/parameters_spec.rb +++ b/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/parameters_spec.rb @@ -39,7 +39,7 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::Parameters do end describe "requiring start_at to be before end_at" do - let(:now) { Time.zone.now } + let(:now) { Time.zone.now.utc } it "adds error when start_at is after end_at" do allow(subject).to receive(:start_at) { now.to_s } From ff799b6e82a77ceb352d5b43972d64f03e34ba9d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 7 Apr 2020 11:13:29 +0100 Subject: [PATCH 216/507] Avoid using update_attributes that save the order to the DB --- spec/models/spree/order_spec.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 4392acb998..5135d70b6d 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -8,7 +8,7 @@ describe Spree::Order do it "has errors if email is blank" do order.stub(require_email: true) - order.update_attributes email: "" + order.email = "" order.valid? expect(order.errors[:email]).to eq ["can't be blank", "is invalid"] @@ -16,7 +16,7 @@ describe Spree::Order do it "has errors if email is invalid" do order.stub(require_email: true) - order.update_attributes email: "invalid_email" + order.email = "invalid_email" order.valid? expect(order.errors[:email]).to eq ["is invalid"] @@ -24,7 +24,7 @@ describe Spree::Order do it "has errors if email has invalid domain" do order.stub(require_email: true) - order.update_attributes email: "single_letter_tld@domain.z" + order.email = "single_letter_tld@domain.z" order.valid? expect(order.errors[:email]).to eq ["is invalid"] @@ -32,12 +32,11 @@ describe Spree::Order do it "is valid if email is valid" do order.stub(require_email: true) - order.update_attributes email: "a@b.ca" + order.email = "a@b.ca" order.valid? expect(order.errors[:email]).to eq [] end - end describe "setting variant attributes" do From 7d82c6a014ff578c72b3eeae6f6083e09293dd52 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 9 Apr 2020 13:51:54 +0100 Subject: [PATCH 217/507] Update spre revision to a version that doesnt depend on deface, this allows us to upgrade nokogiri (done in another PR in the master branch) --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a2f479853c..4ea04c16c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,7 +22,7 @@ GIT GIT remote: https://github.com/openfoodfoundation/spree.git - revision: b7ad5b473f9e38c5a1882550b2b4e348f4824f1f + revision: f9264ebca0d8dd932a7dbee471514a3b85774c8f branch: 2-1-0-stable specs: spree_core (2.1.0) From 8c29797b23bcd2ab47406f4012afb3da81ac0eef Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 28 Apr 2020 14:57:21 +0100 Subject: [PATCH 218/507] Remove empty space on ffi line that was breaking bundle install fuubar gets automatically moved to 2-5-0 as it is in master --- Gemfile.lock | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f984accedf..e833837c26 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -395,12 +395,12 @@ GEM foundation-rails (5.5.2.1) railties (>= 3.1.0) sass (>= 3.3.0, < 3.5) - fuubar (2.4.1) + fuubar (2.5.0) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) geocoder (1.5.2) get_process_mem (0.2.5) - ffi (~> 1.0) + ffi (~> 1.0) gmaps4rails (2.1.2) haml (5.1.2) temple (>= 0.8.0) @@ -493,7 +493,6 @@ GEM pg (0.21.0) polyamorous (0.6.4) activerecord (>= 3.0) - polyglot (0.3.5) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -501,8 +500,6 @@ GEM byebug (>= 9.0, < 9.1) pry (~> 0.10) public_suffix (4.0.3) - rabl (0.8.4) - activesupport (>= 2.3.14) rack (1.5.5) rack-mini-profiler (2.0.1) rack (>= 1.2.0) @@ -722,7 +719,7 @@ DEPENDENCIES foreigner foundation-icons-sass-rails foundation-rails (= 5.5.2.1) - fuubar (~> 2.4.1) + fuubar (~> 2.5.0) geocoder gmaps4rails haml From 7e12142f91551bfb3e85fa1fd8ee5b29c776b7ef Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 2 Mar 2020 17:06:08 +0000 Subject: [PATCH 219/507] Collection must be after load_data so that hubs are already available for VOs calculation --- app/controllers/admin/variant_overrides_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 07894a9498..31aff8ce8c 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -5,7 +5,7 @@ module Admin include OpenFoodNetwork::SpreeApiKeyLoader include EnterprisesHelper - before_filter :load_data + prepend_before_filter :load_data before_filter :load_collection, only: [:bulk_update] before_filter :load_spree_api_key, only: :index From f3e651b1f7491f30c05dcce4f4b87e749b856335 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 28 Apr 2020 16:26:10 +0100 Subject: [PATCH 220/507] present? calls length which is breaking it with error ActiveModel::MissingAttributeError Exception: missing attribute: address_id any? works well as it just verifies the size of the collection --- app/models/enterprise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 4c90dae789..0e60be9a14 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -118,7 +118,7 @@ class Enterprise < ActiveRecord::Base except(:select). select('DISTINCT enterprises.id') - if ready_enterprises.present? + if ready_enterprises.any? where("enterprises.id NOT IN (?)", ready_enterprises) else where(nil) From 3b8acdc577148eb2b256311eb0d60946466ba65a Mon Sep 17 00:00:00 2001 From: Steve Roberts Date: Tue, 5 May 2020 14:38:06 +1000 Subject: [PATCH 221/507] Split order_cycle_spec into smaller specs grouped by theme --- .../admin/order_cycles_complex_spec.rb | 438 ++++++++++++++ spec/features/admin/order_cycles_list_spec.rb | 162 +++++ ...es_spec.rb => order_cycles_simple_spec.rb} | 562 +----------------- 3 files changed, 602 insertions(+), 560 deletions(-) create mode 100644 spec/features/admin/order_cycles_complex_spec.rb create mode 100644 spec/features/admin/order_cycles_list_spec.rb rename spec/features/admin/{order_cycles_spec.rb => order_cycles_simple_spec.rb} (51%) diff --git a/spec/features/admin/order_cycles_complex_spec.rb b/spec/features/admin/order_cycles_complex_spec.rb new file mode 100644 index 0000000000..cca8c0ea10 --- /dev/null +++ b/spec/features/admin/order_cycles_complex_spec.rb @@ -0,0 +1,438 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to manage complex order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + context "with specific time" do + let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } + let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } + + scenario "creating an order cycle with full interface", js: true do + # Given coordinating, supplying and distributing enterprises with some products with variants + coordinator = create(:distributor_enterprise, name: 'My coordinator') + supplier = create(:supplier_enterprise, name: 'My supplier') + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) + + # And some enterprise fees + supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') + coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') + distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') + + # When I go to the new order cycle page + quick_login_as_admin + visit admin_order_cycles_path + click_link 'New Order Cycle' + + # Select a coordinator since there are two available + select2_select 'My coordinator', from: 'coordinator_id' + click_button "Continue >" + + # I cannot save before filling in the required fields + expect(page).to have_button("Create", disabled: true) + + # The Create button is enabled once Name is entered + fill_in 'order_cycle_name', with: 'Plums & Avos' + expect(page).to have_button("Create", disabled: false) + + # If I fill in the basic fields + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time + + # And I add a coordinator fee + click_button 'Add coordinator fee' + select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' + + click_button 'Create' + expect(page).to have_content 'Your order cycle has been created.' + + # I should not be able to add a blank supplier + expect(page).to have_select 'new_supplier_id', selected: '' + expect(page).to have_button 'Add supplier', disabled: true + + # And I add a supplier and some products + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' + page.find('table.exchanges tr.supplier td.products').click + check "order_cycle_incoming_exchange_0_variants_#{v1.id}" + check "order_cycle_incoming_exchange_0_variants_#{v2.id}" + + # I should not be able to re-add the supplier + expect(page).not_to have_select 'new_supplier_id', with_options: ['My supplier'] + expect(page).to have_button 'Add supplier', disabled: true + expect(page.all("td.supplier_name").map(&:text)).to eq(['My supplier']) + + # And I add a supplier fee + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' + select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Next' + + # And I add a distributor with the same products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' + + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' + + page.find('table.exchanges tr.distributor td.products').click + check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" + + page.find('table.exchanges tr.distributor td.tags').click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + # And I add a distributor fee + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' + select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Back to List' + + oc = OrderCycle.last + toggle_columns "Producers", "Shops" + + expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" + expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time + expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time + expect(page).to have_content "My coordinator" + + expect(page).to have_selector 'td.producers', text: 'My supplier' + expect(page).to have_selector 'td.shops', text: 'My distributor' + + # And it should have some fees + expect(oc.exchanges.incoming.first.enterprise_fees).to eq([supplier_fee]) + expect(oc.coordinator_fees).to eq([coordinator_fee]) + expect(oc.exchanges.outgoing.first.enterprise_fees).to eq([distributor_fee]) + + # And it should have some variants selected + expect(oc.exchanges.first.variants.count).to eq(2) + expect(oc.exchanges.last.variants.count).to eq(2) + + # And my receival and pickup time and instructions should have been saved + exchange = oc.exchanges.incoming.first + expect(exchange.receival_instructions).to eq('receival instructions') + + exchange = oc.exchanges.outgoing.first + expect(exchange.pickup_time).to eq('pickup time') + expect(exchange.pickup_instructions).to eq('pickup instructions') + expect(exchange.tag_list).to eq(['wholesale']) + end + + scenario "updating an order cycle", js: true do + # Given an order cycle with all the settings + oc = create(:order_cycle) + initial_variants = oc.variants.sort_by(&:id) + + # And a coordinating, supplying and distributing enterprise with some products with variants + coordinator = oc.coordinator + supplier = create(:supplier_enterprise, name: 'My supplier') + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) + + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) + + # And some enterprise fees + supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') + supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') + coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') + coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') + distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') + distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') + + # When I go to its edit page + quick_login_as_admin + visit admin_order_cycles_path + within "tr.order-cycle-#{oc.id}" do + find("a.edit-order-cycle").click + end + + wait_for_edit_form_to_load_order_cycle(oc) + + # And I update it + fill_in 'order_cycle_name', with: 'Plums & Avos' + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time + + # And I configure some coordinator fees + click_button 'Add coordinator fee' + select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' + click_button 'Add coordinator fee' + click_button 'Add coordinator fee' + click_link 'order_cycle_coordinator_fee_2_remove' + select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' + + click_button 'Save and Next' + expect(page).to have_content 'Your order cycle has been updated.' + + # And I add a supplier and some products + expect(page).to have_selector("table.exchanges tr.supplier") + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + expect(page).to have_selector("table.exchanges tr.supplier", text: "My supplier") + page.all("table.exchanges tr.supplier td.products").each(&:click) + + + expect(page).to have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true + page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) + check "order_cycle_incoming_exchange_2_variants_#{v1.id}" + check "order_cycle_incoming_exchange_2_variants_#{v2.id}" + + # And I configure some supplier fees + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Next' + + # And I add a distributor and some products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' + expect(page).to have_field("order_cycle_outgoing_exchange_2_pickup_time") + + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' + fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' + fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' + fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' + fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' + + page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + exchange_rows = page.all("table.exchanges tbody") + exchange_rows.each do |exchange_row| + exchange_row.find("td.products").click + # Wait for the products panel to be visible. + expect(exchange_row).to have_selector "tr", count: 2 + end + + uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" + + # And I configure some distributor fees + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + + expect(page).to have_selector "#save-bar" + click_button 'Save and Back to List' + + oc = OrderCycle.last + toggle_columns "Producers", "Shops" + + expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" + expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time + expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time + expect(page).to have_content coordinator.name + + expect(page).to have_selector 'td.producers', text: 'My supplier' + expect(page).to have_selector 'td.shops', text: 'My distributor' + + # And my coordinator fees should have been configured + expect(oc.coordinator_fee_ids).to match_array [coordinator_fee1.id, coordinator_fee2.id] + + # And my supplier fees should have been configured + expect(oc.exchanges.incoming.last.enterprise_fee_ids).to eq([supplier_fee2.id]) + + # And my distributor fees should have been configured + expect(oc.exchanges.outgoing.last.enterprise_fee_ids).to eq([distributor_fee2.id]) + + # And my tags should have been save + expect(oc.exchanges.outgoing.last.tag_list).to eq(['wholesale']) + + # And it should have some variants selected + selected_initial_variants = initial_variants.take initial_variants.size - 1 + expect(oc.variants.map(&:id)).to match_array((selected_initial_variants.map(&:id) + [v1.id, v2.id])) + + # And the collection details should have been updated + expect(oc.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0')).to be_present + expect(oc.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1')).to be_present + end + end + + scenario "editing an order cycle" do + # Given an order cycle with all the settings + oc = create(:order_cycle) + oc.suppliers.first.update_attribute :name, 'AAA' + oc.suppliers.last.update_attribute :name, 'ZZZ' + oc.distributors.first.update_attribute :name, 'AAAA' + oc.distributors.last.update_attribute :name, 'ZZZZ' + + # When I edit it + quick_login_as_admin + visit edit_admin_order_cycle_path(oc) + + wait_for_edit_form_to_load_order_cycle(oc) + + # Then I should see the basic settings + expect(page.find('#order_cycle_name').value).to eq(oc.name) + expect(page.find('#order_cycle_orders_open_at').value).to eq(oc.orders_open_at.to_s) + expect(page.find('#order_cycle_orders_close_at').value).to eq(oc.orders_close_at.to_s) + expect(page).to have_content "COORDINATOR #{oc.coordinator.name}" + + click_button 'Next' + + # And I should see the suppliers + expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.first.name + expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.last.name + + expect(page).to have_field 'order_cycle_incoming_exchange_0_receival_instructions', with: 'instructions 0' + expect(page).to have_field 'order_cycle_incoming_exchange_1_receival_instructions', with: 'instructions 1' + + # And the suppliers should have products + page.all('table.exchanges tbody tr.supplier').each_with_index do |row, i| + row.find('td.products').click + + products_panel = page.all('table.exchanges tr.panel-row .exchange-supplied-products').select(&:visible?).first + expect(products_panel).to have_selector "input[name='order_cycle_incoming_exchange_#{i}_select_all_variants']" + + row.find('td.products').click + end + + # And the suppliers should have fees + supplier = oc.suppliers.min_by(&:name) + expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id', selected: supplier.name + expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name + + supplier = oc.suppliers.max_by(&:name) + expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id', selected: supplier.name + expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name + + click_button 'Next' + + # And I should see the distributors + expect(page).to have_selector 'td.distributor_name', text: oc.distributors.first.name + expect(page).to have_selector 'td.distributor_name', text: oc.distributors.last.name + + expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'time 0' + expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'instructions 0' + expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_time', with: 'time 1' + expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'instructions 1' + + # And the distributors should have products + page.all('table.exchanges tbody tr.distributor').each_with_index do |row, i| + row.find('td.products').click + + products_panel = page.all('table.exchanges tr.panel-row .exchange-distributed-products').select(&:visible?).first + expect(products_panel).to have_selector "input[name='order_cycle_outgoing_exchange_#{i}_select_all_variants']" + + row.find('td.products').click + end + + # And the distributors should have fees + distributor = oc.distributors.min_by(&:id) + expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id', selected: distributor.name + expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name + + distributor = oc.distributors.max_by(&:id) + expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id', selected: distributor.name + expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name + end + + scenario "editing an order cycle with an exchange between the same enterprise" do + c = create(:distributor_enterprise, is_primary_producer: true) + + # Given two order cycles, one with a mono-enterprise incoming exchange... + oc_incoming = create(:simple_order_cycle, suppliers: [c], coordinator: c) + + # And the other with a mono-enterprise outgoing exchange + oc_outgoing = create(:simple_order_cycle, coordinator: c, distributors: [c]) + + # When I edit the first order cycle, the exchange should appear as incoming + quick_login_as_admin + visit admin_order_cycle_incoming_path(oc_incoming) + expect(page).to have_selector 'table.exchanges tr.supplier' + visit admin_order_cycle_outgoing_path(oc_incoming) + expect(page).not_to have_selector 'table.exchanges tr.distributor' + + # And when I edit the second order cycle, the exchange should appear as outgoing + visit admin_order_cycle_outgoing_path(oc_outgoing) + expect(page).to have_selector 'table.exchanges tr.distributor' + visit admin_order_cycle_incoming_path(oc_outgoing) + expect(page).not_to have_selector 'table.exchanges tr.supplier' + end + + describe "editing an order cycle with multiple pages of products", js: true do + let(:order_cycle) { create(:order_cycle) } + let(:supplier_enterprise) { order_cycle.exchanges.incoming.first.sender } + let!(:new_product) { create(:product, supplier: supplier_enterprise) } + + before do + stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) + + quick_login_as_admin + visit admin_order_cycle_incoming_path(order_cycle) + expect(page).to have_content "1 / 2 selected" + + page.find("tr.supplier-#{supplier_enterprise.id} td.products").click + expect(page).to have_selector ".exchange-product-details" + + expect(page).to have_content "1 of 2 Variants Loaded" + expect(page).to_not have_content new_product.name + end + + scenario "load all products" do + page.find(".exchange-load-all-variants a").click + + expect_all_products_loaded + end + + scenario "select all products" do + check "order_cycle_incoming_exchange_0_select_all_variants" + + expect_all_products_loaded + + expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{new_product.variants.first.id}", disabled: false + end + + def expect_all_products_loaded + expect(page).to have_content new_product.name.upcase + expect(page).to have_content "2 of 2 Variants Loaded" + end + end + + private + + def wait_for_edit_form_to_load_order_cycle(order_cycle) + expect(page).to have_field "order_cycle_name", with: order_cycle.name + end + + def select_incoming_variant(supplier, exchange_no, variant) + page.find("table.exchanges tr.supplier-#{supplier.id} td.products").click + check "order_cycle_incoming_exchange_#{exchange_no}_variants_#{variant.id}" + end +end \ No newline at end of file diff --git a/spec/features/admin/order_cycles_list_spec.rb b/spec/features/admin/order_cycles_list_spec.rb new file mode 100644 index 0000000000..6021a83f12 --- /dev/null +++ b/spec/features/admin/order_cycles_list_spec.rb @@ -0,0 +1,162 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to list and filter order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + scenario "listing and filtering order cycles" do + # Given some order cycles (created in an arbitrary order) + oc4 = create(:simple_order_cycle, name: 'oc4', + orders_open_at: 2.days.from_now, orders_close_at: 1.month.from_now) + oc2 = create(:simple_order_cycle, name: 'oc2', orders_close_at: 1.month.from_now) + oc6 = create(:simple_order_cycle, name: 'oc6', + orders_open_at: 1.month.ago, orders_close_at: 3.weeks.ago) + oc3 = create(:simple_order_cycle, name: 'oc3', + orders_open_at: 1.day.from_now, orders_close_at: 1.month.from_now) + oc5 = create(:simple_order_cycle, name: 'oc5', + orders_open_at: 1.month.ago, orders_close_at: 2.weeks.ago) + oc1 = create(:order_cycle, name: 'oc1') + oc0 = create(:simple_order_cycle, name: 'oc0', + orders_open_at: nil, orders_close_at: nil) + oc7 = create(:simple_order_cycle, name: 'oc7', + orders_open_at: 2.months.ago, orders_close_at: 5.weeks.ago) + schedule1 = create(:schedule, name: 'Schedule1', order_cycles: [oc1, oc3]) + create(:proxy_order, subscription: create(:subscription, schedule: schedule1), order_cycle: oc1) + + # When I go to the admin order cycles page + login_to_admin_section + click_link 'Order Cycles' + + # Then the order cycles should be ordered correctly + expect(page).to have_selector "#listing_order_cycles tr td:first-child", count: 7 + + order_cycle_names = ["oc0", "oc1", "oc2", "oc3", "oc4", "oc5", "oc6"] + expect(all("#listing_order_cycles tr td:first-child input").map(&:value)).to eq order_cycle_names + + # And the rows should have the correct classes + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}.undated" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}.open" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}.open" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}.upcoming" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc4.id}.upcoming" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc5.id}.closed" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc6.id}.closed" + + toggle_columns "Producers", "Shops" + + # And I should see all the details for an order cycle + within('table#listing_order_cycles tbody tr:nth-child(2)') do + # Then I should see the basic fields + expect(page).to have_input "oc#{oc1.id}[name]", value: oc1.name + expect(page).to have_input "oc#{oc1.id}[orders_open_at]", value: oc1.orders_open_at + expect(page).to have_input "oc#{oc1.id}[orders_close_at]", value: oc1.orders_close_at + expect(page).to have_content oc1.coordinator.name + + # And I should see the suppliers and distributors + oc1.suppliers.each { |s| expect(page).to have_content s.name } + oc1.distributors.each { |d| expect(page).to have_content d.name } + + # And I should see the number of variants + expect(page).to have_selector 'td.products', text: '2 variants' + end + + # I can load more order_cycles + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" + click_button "Show 30 more days" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" + + # I can filter order cycle by involved enterprises + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + select2_select oc1.suppliers.first.name, from: "involving_filter" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + select2_select "Any Enterprise", from: "involving_filter" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + + # I can filter order cycles by name + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + fill_in "query", with: oc0.name + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + fill_in "query", with: '' + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + + # I can filter order cycle by schedule + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" + select2_select schedule1.name, from: "schedule_filter" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" + select2_select 'Any Schedule', from: "schedule_filter" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" + + # Attempting to edit dates of an open order cycle with active subscriptions + find("#oc#{oc1.id}_orders_open_at").click + expect(page).to have_selector "#confirm-dialog .message", text: I18n.t('admin.order_cycles.date_warning.msg', n: 1) + end + + describe 'listing order cycles with other locales' do + let!(:oc_de) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } + + around(:each) do |spec| + I18n.locale = :de + spec.run + I18n.locale = :en + end + + context 'using datepickers' do + it "correctly opens the datepicker and changes the date field" do + quick_login_as_admin + visit admin_order_cycles_path + + within("tr.order-cycle-#{oc_de.id}") do + expect(find('input.datetimepicker', match: :first).value).to start_with '2012-01-01 00:00' + find('img.ui-datepicker-trigger', match: :first).click + end + + within("#ui-datepicker-div") do + expect(page).to have_selector 'a.ui-state-active', text: '1' + + click_link '30' + find('button.ui-datepicker-close', match: :first).click + end + + within("tr.order-cycle-#{oc_de.id}") do + expect(find('input.datetimepicker', match: :first).value).to eq '2012-01-30 00:00' + end + end + end + end + + private + + def wait_for_edit_form_to_load_order_cycle(order_cycle) + expect(page).to have_field "order_cycle_name", with: order_cycle.name + end + + def select_incoming_variant(supplier, exchange_no, variant) + page.find("table.exchanges tr.supplier-#{supplier.id} td.products").click + check "order_cycle_incoming_exchange_#{exchange_no}_variants_#{variant.id}" + end +end diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_simple_spec.rb similarity index 51% rename from spec/features/admin/order_cycles_spec.rb rename to spec/features/admin/order_cycles_simple_spec.rb index 0da5f07c6d..c4296c0919 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_simple_spec.rb @@ -2,570 +2,12 @@ require 'spec_helper' feature ' As an administrator - I want to manage order cycles + I want to manage simple order cycles ', js: true do include AdminHelper include AuthenticationWorkflow include WebHelper - scenario "listing and filtering order cycles" do - # Given some order cycles (created in an arbitrary order) - oc4 = create(:simple_order_cycle, name: 'oc4', - orders_open_at: 2.days.from_now, orders_close_at: 1.month.from_now) - oc2 = create(:simple_order_cycle, name: 'oc2', orders_close_at: 1.month.from_now) - oc6 = create(:simple_order_cycle, name: 'oc6', - orders_open_at: 1.month.ago, orders_close_at: 3.weeks.ago) - oc3 = create(:simple_order_cycle, name: 'oc3', - orders_open_at: 1.day.from_now, orders_close_at: 1.month.from_now) - oc5 = create(:simple_order_cycle, name: 'oc5', - orders_open_at: 1.month.ago, orders_close_at: 2.weeks.ago) - oc1 = create(:order_cycle, name: 'oc1') - oc0 = create(:simple_order_cycle, name: 'oc0', - orders_open_at: nil, orders_close_at: nil) - oc7 = create(:simple_order_cycle, name: 'oc7', - orders_open_at: 2.months.ago, orders_close_at: 5.weeks.ago) - schedule1 = create(:schedule, name: 'Schedule1', order_cycles: [oc1, oc3]) - create(:proxy_order, subscription: create(:subscription, schedule: schedule1), order_cycle: oc1) - - # When I go to the admin order cycles page - login_to_admin_section - click_link 'Order Cycles' - - # Then the order cycles should be ordered correctly - expect(page).to have_selector "#listing_order_cycles tr td:first-child", count: 7 - - order_cycle_names = ["oc0", "oc1", "oc2", "oc3", "oc4", "oc5", "oc6"] - expect(all("#listing_order_cycles tr td:first-child input").map(&:value)).to eq order_cycle_names - - # And the rows should have the correct classes - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}.undated" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}.open" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}.open" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}.upcoming" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc4.id}.upcoming" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc5.id}.closed" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc6.id}.closed" - - toggle_columns "Producers", "Shops" - - # And I should see all the details for an order cycle - within('table#listing_order_cycles tbody tr:nth-child(2)') do - # Then I should see the basic fields - expect(page).to have_input "oc#{oc1.id}[name]", value: oc1.name - expect(page).to have_input "oc#{oc1.id}[orders_open_at]", value: oc1.orders_open_at - expect(page).to have_input "oc#{oc1.id}[orders_close_at]", value: oc1.orders_close_at - expect(page).to have_content oc1.coordinator.name - - # And I should see the suppliers and distributors - oc1.suppliers.each { |s| expect(page).to have_content s.name } - oc1.distributors.each { |d| expect(page).to have_content d.name } - - # And I should see the number of variants - expect(page).to have_selector 'td.products', text: '2 variants' - end - - # I can load more order_cycles - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" - click_button "Show 30 more days" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" - - # I can filter order cycle by involved enterprises - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - select2_select oc1.suppliers.first.name, from: "involving_filter" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - select2_select "Any Enterprise", from: "involving_filter" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - - # I can filter order cycles by name - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - fill_in "query", with: oc0.name - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - fill_in "query", with: '' - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - - # I can filter order cycle by schedule - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" - select2_select schedule1.name, from: "schedule_filter" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" - select2_select 'Any Schedule', from: "schedule_filter" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" - - # Attempting to edit dates of an open order cycle with active subscriptions - find("#oc#{oc1.id}_orders_open_at").click - expect(page).to have_selector "#confirm-dialog .message", text: I18n.t('admin.order_cycles.date_warning.msg', n: 1) - end - - describe 'listing order cycles with other locales' do - let!(:oc_de) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } - - around(:each) do |spec| - I18n.locale = :de - spec.run - I18n.locale = :en - end - - context 'using datepickers' do - it "correctly opens the datepicker and changes the date field" do - quick_login_as_admin - visit admin_order_cycles_path - - within("tr.order-cycle-#{oc_de.id}") do - expect(find('input.datetimepicker', match: :first).value).to start_with '2012-01-01 00:00' - find('img.ui-datepicker-trigger', match: :first).click - end - - within("#ui-datepicker-div") do - expect(page).to have_selector 'a.ui-state-active', text: '1' - - click_link '30' - find('button.ui-datepicker-close', match: :first).click - end - - within("tr.order-cycle-#{oc_de.id}") do - expect(find('input.datetimepicker', match: :first).value).to eq '2012-01-30 00:00' - end - end - end - end - - context "with specific time" do - let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } - let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } - - scenario "creating an order cycle with full interface", js: true do - # Given coordinating, supplying and distributing enterprises with some products with variants - coordinator = create(:distributor_enterprise, name: 'My coordinator') - supplier = create(:supplier_enterprise, name: 'My supplier') - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - - # And some enterprise fees - supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') - coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') - distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') - - # When I go to the new order cycle page - quick_login_as_admin - visit admin_order_cycles_path - click_link 'New Order Cycle' - - # Select a coordinator since there are two available - select2_select 'My coordinator', from: 'coordinator_id' - click_button "Continue >" - - # I cannot save before filling in the required fields - expect(page).to have_button("Create", disabled: true) - - # The Create button is enabled once Name is entered - fill_in 'order_cycle_name', with: 'Plums & Avos' - expect(page).to have_button("Create", disabled: false) - - # If I fill in the basic fields - fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time - fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - - # And I add a coordinator fee - click_button 'Add coordinator fee' - select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' - - click_button 'Create' - expect(page).to have_content 'Your order cycle has been created.' - - # I should not be able to add a blank supplier - expect(page).to have_select 'new_supplier_id', selected: '' - expect(page).to have_button 'Add supplier', disabled: true - - # And I add a supplier and some products - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' - page.find('table.exchanges tr.supplier td.products').click - check "order_cycle_incoming_exchange_0_variants_#{v1.id}" - check "order_cycle_incoming_exchange_0_variants_#{v2.id}" - - # I should not be able to re-add the supplier - expect(page).not_to have_select 'new_supplier_id', with_options: ['My supplier'] - expect(page).to have_button 'Add supplier', disabled: true - expect(page.all("td.supplier_name").map(&:text)).to eq(['My supplier']) - - # And I add a supplier fee - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' - select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Next' - - # And I add a distributor with the same products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' - - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' - - page.find('table.exchanges tr.distributor td.products').click - check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" - - page.find('table.exchanges tr.distributor td.tags').click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" - end - - # And I add a distributor fee - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' - select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Back to List' - - oc = OrderCycle.last - toggle_columns "Producers", "Shops" - - expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" - expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time - expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time - expect(page).to have_content "My coordinator" - - expect(page).to have_selector 'td.producers', text: 'My supplier' - expect(page).to have_selector 'td.shops', text: 'My distributor' - - # And it should have some fees - expect(oc.exchanges.incoming.first.enterprise_fees).to eq([supplier_fee]) - expect(oc.coordinator_fees).to eq([coordinator_fee]) - expect(oc.exchanges.outgoing.first.enterprise_fees).to eq([distributor_fee]) - - # And it should have some variants selected - expect(oc.exchanges.first.variants.count).to eq(2) - expect(oc.exchanges.last.variants.count).to eq(2) - - # And my receival and pickup time and instructions should have been saved - exchange = oc.exchanges.incoming.first - expect(exchange.receival_instructions).to eq('receival instructions') - - exchange = oc.exchanges.outgoing.first - expect(exchange.pickup_time).to eq('pickup time') - expect(exchange.pickup_instructions).to eq('pickup instructions') - expect(exchange.tag_list).to eq(['wholesale']) - end - - scenario "updating an order cycle", js: true do - # Given an order cycle with all the settings - oc = create(:order_cycle) - initial_variants = oc.variants.sort_by(&:id) - - # And a coordinating, supplying and distributing enterprise with some products with variants - coordinator = oc.coordinator - supplier = create(:supplier_enterprise, name: 'My supplier') - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - - # And some enterprise fees - supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') - supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') - coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') - coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') - distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') - distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') - - # When I go to its edit page - quick_login_as_admin - visit admin_order_cycles_path - within "tr.order-cycle-#{oc.id}" do - find("a.edit-order-cycle").click - end - - wait_for_edit_form_to_load_order_cycle(oc) - - # And I update it - fill_in 'order_cycle_name', with: 'Plums & Avos' - fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time - fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - - # And I configure some coordinator fees - click_button 'Add coordinator fee' - select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' - click_button 'Add coordinator fee' - click_button 'Add coordinator fee' - click_link 'order_cycle_coordinator_fee_2_remove' - select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' - - click_button 'Save and Next' - expect(page).to have_content 'Your order cycle has been updated.' - - # And I add a supplier and some products - expect(page).to have_selector("table.exchanges tr.supplier") - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - expect(page).to have_selector("table.exchanges tr.supplier", text: "My supplier") - page.all("table.exchanges tr.supplier td.products").each(&:click) - - - expect(page).to have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true - page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) - check "order_cycle_incoming_exchange_2_variants_#{v1.id}" - check "order_cycle_incoming_exchange_2_variants_#{v2.id}" - - # And I configure some supplier fees - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Next' - - # And I add a distributor and some products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' - expect(page).to have_field("order_cycle_outgoing_exchange_2_pickup_time") - - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' - fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' - fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' - fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' - fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' - - page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" - end - - exchange_rows = page.all("table.exchanges tbody") - exchange_rows.each do |exchange_row| - exchange_row.find("td.products").click - # Wait for the products panel to be visible. - expect(exchange_row).to have_selector "tr", count: 2 - end - - uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" - - # And I configure some distributor fees - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - - expect(page).to have_selector "#save-bar" - click_button 'Save and Back to List' - - oc = OrderCycle.last - toggle_columns "Producers", "Shops" - - expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" - expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time - expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time - expect(page).to have_content coordinator.name - - expect(page).to have_selector 'td.producers', text: 'My supplier' - expect(page).to have_selector 'td.shops', text: 'My distributor' - - # And my coordinator fees should have been configured - expect(oc.coordinator_fee_ids).to match_array [coordinator_fee1.id, coordinator_fee2.id] - - # And my supplier fees should have been configured - expect(oc.exchanges.incoming.last.enterprise_fee_ids).to eq([supplier_fee2.id]) - - # And my distributor fees should have been configured - expect(oc.exchanges.outgoing.last.enterprise_fee_ids).to eq([distributor_fee2.id]) - - # And my tags should have been save - expect(oc.exchanges.outgoing.last.tag_list).to eq(['wholesale']) - - # And it should have some variants selected - selected_initial_variants = initial_variants.take initial_variants.size - 1 - expect(oc.variants.map(&:id)).to match_array((selected_initial_variants.map(&:id) + [v1.id, v2.id])) - - # And the collection details should have been updated - expect(oc.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0')).to be_present - expect(oc.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1')).to be_present - end - end - - scenario "editing an order cycle" do - # Given an order cycle with all the settings - oc = create(:order_cycle) - oc.suppliers.first.update_attribute :name, 'AAA' - oc.suppliers.last.update_attribute :name, 'ZZZ' - oc.distributors.first.update_attribute :name, 'AAAA' - oc.distributors.last.update_attribute :name, 'ZZZZ' - - # When I edit it - quick_login_as_admin - visit edit_admin_order_cycle_path(oc) - - wait_for_edit_form_to_load_order_cycle(oc) - - # Then I should see the basic settings - expect(page.find('#order_cycle_name').value).to eq(oc.name) - expect(page.find('#order_cycle_orders_open_at').value).to eq(oc.orders_open_at.to_s) - expect(page.find('#order_cycle_orders_close_at').value).to eq(oc.orders_close_at.to_s) - expect(page).to have_content "COORDINATOR #{oc.coordinator.name}" - - click_button 'Next' - - # And I should see the suppliers - expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.first.name - expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.last.name - - expect(page).to have_field 'order_cycle_incoming_exchange_0_receival_instructions', with: 'instructions 0' - expect(page).to have_field 'order_cycle_incoming_exchange_1_receival_instructions', with: 'instructions 1' - - # And the suppliers should have products - page.all('table.exchanges tbody tr.supplier').each_with_index do |row, i| - row.find('td.products').click - - products_panel = page.all('table.exchanges tr.panel-row .exchange-supplied-products').select(&:visible?).first - expect(products_panel).to have_selector "input[name='order_cycle_incoming_exchange_#{i}_select_all_variants']" - - row.find('td.products').click - end - - # And the suppliers should have fees - supplier = oc.suppliers.min_by(&:name) - expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id', selected: supplier.name - expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name - - supplier = oc.suppliers.max_by(&:name) - expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id', selected: supplier.name - expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name - - click_button 'Next' - - # And I should see the distributors - expect(page).to have_selector 'td.distributor_name', text: oc.distributors.first.name - expect(page).to have_selector 'td.distributor_name', text: oc.distributors.last.name - - expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'time 0' - expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'instructions 0' - expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_time', with: 'time 1' - expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'instructions 1' - - # And the distributors should have products - page.all('table.exchanges tbody tr.distributor').each_with_index do |row, i| - row.find('td.products').click - - products_panel = page.all('table.exchanges tr.panel-row .exchange-distributed-products').select(&:visible?).first - expect(products_panel).to have_selector "input[name='order_cycle_outgoing_exchange_#{i}_select_all_variants']" - - row.find('td.products').click - end - - # And the distributors should have fees - distributor = oc.distributors.min_by(&:id) - expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id', selected: distributor.name - expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name - - distributor = oc.distributors.max_by(&:id) - expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id', selected: distributor.name - expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name - end - - scenario "editing an order cycle with an exchange between the same enterprise" do - c = create(:distributor_enterprise, is_primary_producer: true) - - # Given two order cycles, one with a mono-enterprise incoming exchange... - oc_incoming = create(:simple_order_cycle, suppliers: [c], coordinator: c) - - # And the other with a mono-enterprise outgoing exchange - oc_outgoing = create(:simple_order_cycle, coordinator: c, distributors: [c]) - - # When I edit the first order cycle, the exchange should appear as incoming - quick_login_as_admin - visit admin_order_cycle_incoming_path(oc_incoming) - expect(page).to have_selector 'table.exchanges tr.supplier' - visit admin_order_cycle_outgoing_path(oc_incoming) - expect(page).not_to have_selector 'table.exchanges tr.distributor' - - # And when I edit the second order cycle, the exchange should appear as outgoing - visit admin_order_cycle_outgoing_path(oc_outgoing) - expect(page).to have_selector 'table.exchanges tr.distributor' - visit admin_order_cycle_incoming_path(oc_outgoing) - expect(page).not_to have_selector 'table.exchanges tr.supplier' - end - - describe "editing an order cycle with multiple pages of products", js: true do - let(:order_cycle) { create(:order_cycle) } - let(:supplier_enterprise) { order_cycle.exchanges.incoming.first.sender } - let!(:new_product) { create(:product, supplier: supplier_enterprise) } - - before do - stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) - - quick_login_as_admin - visit admin_order_cycle_incoming_path(order_cycle) - expect(page).to have_content "1 / 2 selected" - - page.find("tr.supplier-#{supplier_enterprise.id} td.products").click - expect(page).to have_selector ".exchange-product-details" - - expect(page).to have_content "1 of 2 Variants Loaded" - expect(page).to_not have_content new_product.name - end - - scenario "load all products" do - page.find(".exchange-load-all-variants a").click - - expect_all_products_loaded - end - - scenario "select all products" do - check "order_cycle_incoming_exchange_0_select_all_variants" - - expect_all_products_loaded - - expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{new_product.variants.first.id}", disabled: false - end - - def expect_all_products_loaded - expect(page).to have_content new_product.name.upcase - expect(page).to have_content "2 of 2 Variants Loaded" - end - end - scenario "updating many order cycle opening/closing times at once", js: true do # Given three order cycles oc1 = create(:simple_order_cycle) @@ -1171,4 +613,4 @@ feature ' page.find("table.exchanges tr.supplier-#{supplier.id} td.products").click check "order_cycle_incoming_exchange_#{exchange_no}_variants_#{variant.id}" end -end +end \ No newline at end of file From 4083da5b1676b5ff6aad27ff459be915815f7c7b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 5 May 2020 22:27:27 +0100 Subject: [PATCH 222/507] Add sample order to sample data --- lib/tasks/sample_data.rake | 3 ++ lib/tasks/sample_data/order_factory.rb | 62 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 lib/tasks/sample_data/order_factory.rb diff --git a/lib/tasks/sample_data.rake b/lib/tasks/sample_data.rake index bf929281b6..1dcac757c9 100644 --- a/lib/tasks/sample_data.rake +++ b/lib/tasks/sample_data.rake @@ -10,6 +10,7 @@ require "tasks/sample_data/product_factory" require "tasks/sample_data/shipping_method_factory" require "tasks/sample_data/taxon_factory" require "tasks/sample_data/user_factory" +require "tasks/sample_data/order_factory" # The sample data generated by this task is supposed to save some time during # manual testing. It is not meant to be complete, but we try to improve it @@ -49,6 +50,8 @@ namespace :ofn do CustomerFactory.new.create_samples(users) GroupFactory.new.create_samples + + OrderFactory.new.create_samples end def seeded? diff --git a/lib/tasks/sample_data/order_factory.rb b/lib/tasks/sample_data/order_factory.rb new file mode 100644 index 0000000000..cbd7059dab --- /dev/null +++ b/lib/tasks/sample_data/order_factory.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require "tasks/sample_data/logging" +require "tasks/sample_data/addressing" + +class OrderFactory + include Logging + include Addressing + + def create_samples + log "Creating a sample order" + order_cycle = OrderCycle.find_by(name: "Fredo's Farm Hub OC") + distributor = Enterprise.find_by(name: "Fredo's Farm Hub") + + create_order( + "new.customer@example.org", + order_cycle, + distributor + ) + end + + private + + def create_order(email, order_cycle, distributor) + order = Spree::Order.create!( + email: email, + order_cycle: order_cycle, + distributor: distributor, + bill_address: order_address, + ship_address: order_address + ) + order.line_items.create( variant_id: variant(order_cycle).id, quantity: 5 ) + order.payments.create(payment_method_id: payment_method_id(distributor)) + + place_order(order) + end + + def variant(order_cycle) + # First variant on the first outgoing exchange of the OC + order_cycle.exchanges.outgoing.first.variants.first + end + + def payment_method_id(distributor) + # First payment method of the distributor + distributor.payment_methods.first.id + end + + def place_order(order) + order.save + + AdvanceOrderService.new(order).call + order + end + + def order_address + address = address("25 Myrtle Street, Bayswater, 3153") + address.firstname = "John" + address.lastname = "Mistery" + address.phone = "0987654321" + address + end +end From 825f747dffc5f2c4926c03db799abb0c526f4075 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 5 May 2020 23:14:46 +0100 Subject: [PATCH 223/507] Add more types of sample orders --- lib/tasks/sample_data/order_factory.rb | 88 ++++++++++++++++---------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/lib/tasks/sample_data/order_factory.rb b/lib/tasks/sample_data/order_factory.rb index cbd7059dab..0be836ac0e 100644 --- a/lib/tasks/sample_data/order_factory.rb +++ b/lib/tasks/sample_data/order_factory.rb @@ -8,50 +8,74 @@ class OrderFactory include Addressing def create_samples - log "Creating a sample order" - order_cycle = OrderCycle.find_by(name: "Fredo's Farm Hub OC") - distributor = Enterprise.find_by(name: "Fredo's Farm Hub") + log "Creating orders" + @order_cycle = OrderCycle.find_by(name: "Fredo's Farm Hub OC") + @distributor = Enterprise.find_by(name: "Fredo's Farm Hub") + @email = "new.customer@example.org" - create_order( - "new.customer@example.org", - order_cycle, - distributor - ) + log "- cart order" + create_cart_order + + log "- complete order - not paid" + create_complete_order + + log "- complete order - paid" + order = create_complete_order + order.payments.first.capture! + + log "- complete order - delivery" + order = create_complete_order + order.select_shipping_method(delivery_shipping_method_id) + order.save + + log "- complete order - shipped" + order = create_complete_order + order.payments.first.capture! + order.save + order.shipment.ship! end private - def create_order(email, order_cycle, distributor) + def create_cart_order + order = create_order + order.save + order + end + + def create_complete_order + order = create_cart_order + AdvanceOrderService.new(order).call + order + end + + def create_order order = Spree::Order.create!( - email: email, - order_cycle: order_cycle, - distributor: distributor, + email: @email, + order_cycle: @order_cycle, + distributor: @distributor, bill_address: order_address, ship_address: order_address ) - order.line_items.create( variant_id: variant(order_cycle).id, quantity: 5 ) - order.payments.create(payment_method_id: payment_method_id(distributor)) - - place_order(order) - end - - def variant(order_cycle) - # First variant on the first outgoing exchange of the OC - order_cycle.exchanges.outgoing.first.variants.first - end - - def payment_method_id(distributor) - # First payment method of the distributor - distributor.payment_methods.first.id - end - - def place_order(order) - order.save - - AdvanceOrderService.new(order).call + order.line_items.create( variant_id: first_variant.id, quantity: 5 ) + order.payments.create(payment_method_id: first_payment_method_id) order end + def first_variant + # First variant on the first outgoing exchange of the OC + @order_cycle.exchanges.outgoing.first.variants.first + end + + def first_payment_method_id + # First payment method of the distributor + @distributor.payment_methods.first.id + end + + def delivery_shipping_method_id + @distributor.shipping_methods.find_by(name: "Home delivery").id + end + def order_address address = address("25 Myrtle Street, Bayswater, 3153") address.firstname = "John" From 7804c740a6d14f541e23cfd5756d1ee361f5808e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 12 May 2020 15:30:59 +0100 Subject: [PATCH 224/507] Add name to permitted params and fix some rubocop issues --- .../templates/admin/columns_dropdown.html.haml | 2 +- .../admin/column_preferences_controller.rb | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/templates/admin/columns_dropdown.html.haml b/app/assets/javascripts/templates/admin/columns_dropdown.html.haml index cae123bbcf..f06944182a 100644 --- a/app/assets/javascripts/templates/admin/columns_dropdown.html.haml +++ b/app/assets/javascripts/templates/admin/columns_dropdown.html.haml @@ -4,7 +4,7 @@ %div.menu{ 'ng-show' => "expanded" } %div.menu_item{ ng: { repeat: "column in columns", click: "toggle(column)", class: "{selected: column.visible}" } } %span.check - %span.name {{column.name }} + %span.name {{ column.name }} %hr %div.menu_item.text-center %input.fullwidth.orange{ type: "button", ng: { value: "saved() ? 'Saved': 'Saving'", show: "saved() || saving", disabled: "saved()" } } diff --git a/app/controllers/admin/column_preferences_controller.rb b/app/controllers/admin/column_preferences_controller.rb index 0d7198b5b3..ee21a14131 100644 --- a/app/controllers/admin/column_preferences_controller.rb +++ b/app/controllers/admin/column_preferences_controller.rb @@ -8,7 +8,6 @@ module Admin @cp_set.collection.each { |cp| authorize! :bulk_update, cp } if @cp_set.save - # Return saved VOs with IDs render json: @cp_set.collection, each_serializer: Api::Admin::ColumnPreferenceSerializer else if @cp_set.errors.present? @@ -22,17 +21,22 @@ module Admin private def permitted_params - params.permit(:action_name, column_preferences: [:id, :user_id, :action_name, :column_name, :visible]) + params.permit( + :action_name, + column_preferences: [:id, :user_id, :action_name, :column_name, :name, :visible] + ) end def load_collection - collection_hash = Hash[permitted_params[:column_preferences].each_with_index.map { |cp, i| [i, cp] }] + collection_hash = Hash[permitted_params[:column_preferences]. + each_with_index.map { |cp, i| [i, cp] }] collection_hash.select!{ |_i, cp| cp[:action_name] == permitted_params[:action_name] } @cp_set = ColumnPreferenceSet.new @column_preferences, collection_attributes: collection_hash end def collection - ColumnPreference.where(user_id: spree_current_user, action_name: permitted_params[:action_name]) + ColumnPreference.where(user_id: spree_current_user, + action_name: permitted_params[:action_name]) end def collection_actions From 83381ad439135af1e908ab0ebbc369f189dc8716 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 12 May 2020 15:46:23 +0100 Subject: [PATCH 225/507] Relax array order verification --- spec/controllers/api/enterprises_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index ef21340e3f..54c5efc3b3 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -47,7 +47,7 @@ module Api expect(response).to be_success enterprise = Enterprise.last - expect(enterprise.user_ids).to eq([enterprise_owner.id, manager1.id, manager2.id]) + expect(enterprise.user_ids).to match_array([enterprise_owner.id, manager1.id, manager2.id]) end end end From be998a9eb6fd585ce3726621c880fd3041af142c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 13 May 2020 12:00:37 +0100 Subject: [PATCH 226/507] Reload shipment before shipping otherwise shipment stays as ready but with shipped_at defined --- lib/tasks/sample_data/order_factory.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/sample_data/order_factory.rb b/lib/tasks/sample_data/order_factory.rb index 0be836ac0e..bc5c9f3675 100644 --- a/lib/tasks/sample_data/order_factory.rb +++ b/lib/tasks/sample_data/order_factory.rb @@ -32,7 +32,7 @@ class OrderFactory order = create_complete_order order.payments.first.capture! order.save - order.shipment.ship! + order.shipment.reload.ship! end private From 3bc09cfcfbbf3956dae60d231150498ff4266d81 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 14 May 2020 21:03:21 +0000 Subject: [PATCH 227/507] Bump stripe from 5.15.0 to 5.22.0 Bumps [stripe](https://github.com/stripe/stripe-ruby) from 5.15.0 to 5.22.0. - [Release notes](https://github.com/stripe/stripe-ruby/releases) - [Changelog](https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md) - [Commits](https://github.com/stripe/stripe-ruby/compare/v5.15.0...v5.22.0) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2414376473..b9c2a390c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -636,7 +636,7 @@ GEM tilt (~> 1.1, != 1.3.0) state_machine (1.2.0) stringex (1.5.1) - stripe (5.15.0) + stripe (5.22.0) test-unit (3.3.5) power_assert thor (0.20.3) From 9a115afd4fddbb5b3cb591f67b8dcde9cc5b7242 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 19 Apr 2020 11:03:52 +0100 Subject: [PATCH 228/507] Remove bars around product description and border around product image --- app/assets/javascripts/templates/product_modal.html.haml | 2 -- app/assets/stylesheets/darkswarm/images.css.scss | 3 --- 2 files changed, 5 deletions(-) diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 6282bc439e..94f4ebf553 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -15,9 +15,7 @@ %filter-selector{ 'selector-set' => "productPropertySelectors", objects: "[product] | propertiesWithValuesOf" } %div{"ng-if" => "product.description_html"} - %hr %p.text-small{"ng-bind-html" => "::product.description_html"} - %hr .columns.small-12.large-6 %img.product-img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"} diff --git a/app/assets/stylesheets/darkswarm/images.css.scss b/app/assets/stylesheets/darkswarm/images.css.scss index cd939e3b42..2e94bbab47 100644 --- a/app/assets/stylesheets/darkswarm/images.css.scss +++ b/app/assets/stylesheets/darkswarm/images.css.scss @@ -5,9 +5,6 @@ .product-img { padding: 5px; margin-bottom: 10px; - outline: 1px solid #ccc; - - @include box-shadow(0 1px 2px 1px rgba(0, 0, 0, 0.15)); // placeholder for when no product images &.placeholder { From fee03c410164900e22ddb002794b0f3f17c93d40 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 19 Apr 2020 18:06:43 +0100 Subject: [PATCH 229/507] Remove repeated/dead rules --- app/assets/stylesheets/darkswarm/_shop-filters.css.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-filters.css.scss b/app/assets/stylesheets/darkswarm/_shop-filters.css.scss index 5bb8b5e381..91bb5c7933 100644 --- a/app/assets/stylesheets/darkswarm/_shop-filters.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-filters.css.scss @@ -27,13 +27,11 @@ a, a.button { display: block; - padding-top: 0.5rem; @include border-radius(0.5em); border: 1px solid $border-clr; padding: 0.5em 0.625em; - font-size: 0.875em; color: $base-clr; font-size: 0.75em; background: white; From 59a13adff05c3ac9d5f15fc837f34510f0aafd11 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 19 Apr 2020 18:08:48 +0100 Subject: [PATCH 230/507] Remove product category from product modal --- .../controllers/products/product_node_controller.js.coffee | 1 - app/assets/javascripts/templates/product_modal.html.haml | 3 --- 2 files changed, 4 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index a692af3fb5..fb8ac8d288 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -2,6 +2,5 @@ Darkswarm.controller "ProductNodeCtrl", ($scope, $modal, FilterSelectorsService) $scope.enterprise = $scope.product.supplier # For the modal, so it's consistent $scope.triggerProductModal = -> - $scope.productTaxonSelectors = FilterSelectorsService.createSelectors() $scope.productPropertySelectors = FilterSelectorsService.createSelectors() $modal.open(templateUrl: "product_modal.html", scope: $scope) diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 94f4ebf553..47d57c2ea2 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -8,9 +8,6 @@ %br - .filter-shopfront.taxon-selectors.inline-block - %filter-selector{ 'selector-set' => "productTaxonSelectors", objects: "[product] | taxonsOf" } - .filter-shopfront.property-selectors.inline-block %filter-selector{ 'selector-set' => "productPropertySelectors", objects: "[product] | propertiesWithValuesOf" } From 14478d5fc1d26a25f2a7f0519d5dbbb760565d8f Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 19 Apr 2020 18:09:27 +0100 Subject: [PATCH 231/507] Style producer name and properties in product modal --- .../darkswarm/_shop-modals.css.scss | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss index 6215e22c9f..24df37c1b0 100644 --- a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss @@ -3,7 +3,22 @@ margin: 0; } - hr { - margin: 0.5em 0; + span { + color: $grey-500; + } + + .property-selectors li { + margin: 0 0.25rem 0.25rem 0; + padding: 0.4rem 0 1.1rem 0; + + a { + border: 1px solid $grey-300; + font-weight: normal; + padding: 0.2em 0.625em; + } + + span { + color: $grey-600; + } } } From 39e47998e1f8a83f41f11ad2dbb9cfcedaf21263 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 23 Apr 2020 15:23:53 +0100 Subject: [PATCH 232/507] Make the background opacity of modals in the FrontOffice a litle darker according to design --- app/assets/stylesheets/darkswarm/animations.scss | 4 ++-- app/assets/stylesheets/darkswarm/modals.css.scss | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/animations.scss b/app/assets/stylesheets/darkswarm/animations.scss index b3848777ba..d7fb952907 100644 --- a/app/assets/stylesheets/darkswarm/animations.scss +++ b/app/assets/stylesheets/darkswarm/animations.scss @@ -143,8 +143,8 @@ } .reveal-modal-bg.in { - filter: alpha(opacity = 50); - opacity: 0.5; + filter: alpha(opacity = 75); + opacity: 0.75; } .animate-repeat { diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index 734d388acf..99c485b963 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -34,7 +34,7 @@ dialog } .reveal-modal-bg { - background-color: rgba(0, 0, 0, 0.85); + background-color: $black; position: fixed; } From 35ac5e093eb3aded1602a43ac68c3799b8241869 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 23 Apr 2020 15:45:44 +0100 Subject: [PATCH 233/507] Adapt modal size to leave some background visible so that user can click to disable modal --- app/assets/stylesheets/darkswarm/modals.css.scss | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index 99c485b963..e4048808f8 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -18,15 +18,15 @@ dialog // Reveal.js break point: // @media only screen and (max-width: 40.063em) - // Small - when modal IS full screen + // Small - smaller outside area @media only screen and (max-width: 640px) { - left: 0; - max-height: 100%; - position: absolute !important; - top: 0; + left: 4%; + max-height: 92%; + max-width: 92%; + top: 4%; } - // Medium and up - when modal IS NOT full screen + // Medium and up - larger outside area @media only screen and (min-width: 641px) { max-height: 90%; top: 5%; From 0a378a897bdcbd633ca094af5ea289b889c45d28 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 23 Apr 2020 16:46:37 +0100 Subject: [PATCH 234/507] Add close button to mobile product modal, this can be reused in other modals later --- .../javascripts/templates/product_modal.html.haml | 5 ++++- app/assets/stylesheets/darkswarm/modals.css.scss | 13 +++++++++++++ config/locales/en.yml | 4 ++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 47d57c2ea2..e6f591a9ab 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -1,5 +1,4 @@ .row - .columns.small-12.large-6.product-header %h3{"ng-bind" => "::product.name"} %span @@ -19,3 +18,7 @@ %img.product-img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"} %ng-include{src: "'partials/close.html'"} + +.buttons + .button.bottom-close-button{"ng-click" => "$close()"} + = t('js.shop.products.product_modal.close') diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index e4048808f8..9c80e13007 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -72,6 +72,19 @@ dialog .mobile-close-reveal-modal } } +.reveal-modal .buttons { + margin: 0 auto; + text-align: center; + + .bottom-close-button { + background-color: $orange-500; + + @media only screen and (min-width: 640px) { + display: none; + } + } +} + // Prevent body from scrolling when a modal is open body.modal-open { overflow: hidden; diff --git a/config/locales/en.yml b/config/locales/en.yml index 01ba7cebd2..7692ef1531 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2736,6 +2736,10 @@ See the %{link} to find out more about %{sitename}'s features and to start using signup_or_login: "Start By Signing Up (or logging in)" have_an_account: "Already have an account?" action_login: "Log in now." + shop: + products: + product_modal: + close: "Close" # Singular and plural forms of commonly used words. # We use these entries to pluralize unit names in every language. From cbfaaabb72e50a59895f14a138c26033d5d99e77 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 23 Apr 2020 17:25:17 +0100 Subject: [PATCH 235/507] Adjust different paddings and margins to make mobile product modal contents similar to required design --- .../javascripts/templates/product_modal.html.haml | 2 +- .../stylesheets/darkswarm/_shop-modals.css.scss | 10 ++++++++-- app/assets/stylesheets/darkswarm/images.css.scss | 13 ++++++------- app/assets/stylesheets/darkswarm/modals.css.scss | 6 ++++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index e6f591a9ab..5ce84d622b 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -10,7 +10,7 @@ .filter-shopfront.property-selectors.inline-block %filter-selector{ 'selector-set' => "productPropertySelectors", objects: "[product] | propertiesWithValuesOf" } - %div{"ng-if" => "product.description_html"} + .product-description{"ng-if" => "product.description_html"} %p.text-small{"ng-bind-html" => "::product.description_html"} .columns.small-12.large-6 diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss index 24df37c1b0..73a488dddd 100644 --- a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss @@ -1,15 +1,21 @@ .product-header { + padding-left: 1.5rem; + h1, h2, h3, h4, h5, h6 { - margin: 0; + margin: 0.2rem 0 0 0; } span { color: $grey-500; } + .product-description { + margin: 1rem 0.25rem 0.25rem 0; + } + .property-selectors li { margin: 0 0.25rem 0.25rem 0; - padding: 0.4rem 0 1.1rem 0; + padding: 0.4rem 0 0 0; a { border: 1px solid $grey-300; diff --git a/app/assets/stylesheets/darkswarm/images.css.scss b/app/assets/stylesheets/darkswarm/images.css.scss index 2e94bbab47..81d6804dfa 100644 --- a/app/assets/stylesheets/darkswarm/images.css.scss +++ b/app/assets/stylesheets/darkswarm/images.css.scss @@ -14,6 +14,12 @@ display: none; } } + + @media only screen and (max-width: 1024px) { + margin-top: 0; + margin-bottom: 1em; + padding: 5px; + } } .hero-img { @@ -46,10 +52,3 @@ .producer-logo { max-width: 220px; } - -@media only screen and (max-width: 1024px) { - .product-img { - margin-top: 2em; - margin-bottom: 1em; - } -} diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index 9c80e13007..e903409d41 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -5,8 +5,6 @@ dialog , .reveal-modal { border: none; outline: none; - padding: 30px 20px 0 20px; - border-bottom: 30px solid white; overflow-y: scroll; overflow-x: hidden; min-height: 260px; @@ -23,12 +21,15 @@ dialog left: 4%; max-height: 92%; max-width: 92%; + padding: 15px 0 0 0; top: 4%; } // Medium and up - larger outside area @media only screen and (min-width: 641px) { + border-bottom: 30px solid white; max-height: 90%; + padding: 30px 20px 0 20px; top: 5%; } } @@ -78,6 +79,7 @@ dialog .mobile-close-reveal-modal .bottom-close-button { background-color: $orange-500; + margin: 0 0 1rem; @media only screen and (min-width: 640px) { display: none; From 50fa4fc93d660c17ef77f199c19badf4ef0f2748 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 23 Apr 2020 18:40:47 +0100 Subject: [PATCH 236/507] Make modal close buttons a little darker with a white cross --- app/assets/stylesheets/darkswarm/modals.css.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index e903409d41..bcd4b127bc 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -59,6 +59,10 @@ dialog dialog .close-reveal-modal , .reveal-modal .close-reveal-modal { @include close-button(0.25rem); + + background-color: $grey-500; + color: $white; + font-size: 1.5rem; right: 0.25rem; } From 4b6389337759bef171a6a26f76a1d46de50ed8b6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 28 Apr 2020 18:01:53 +0100 Subject: [PATCH 237/507] Improve mobile login modal with a margin --- app/assets/stylesheets/darkswarm/pages/login_modal.css.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss b/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss index e6baba3393..cd76a7a338 100644 --- a/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss +++ b/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss @@ -23,6 +23,12 @@ text-decoration: underline; } } + + @media only screen and (max-width: 640px) { + .tabbable { + margin: 0 15px 0 15px; + } + } } @media only screen and (min-width: 1025px) { From 3a512478d6cbd8efcecde02997b0a5d38bb6d31d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 28 Apr 2020 18:13:41 +0100 Subject: [PATCH 238/507] Improve the mobile registration modal by adding a margin --- app/assets/stylesheets/darkswarm/registration.css.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/registration.css.scss b/app/assets/stylesheets/darkswarm/registration.css.scss index 1f80038f18..3602f759d5 100644 --- a/app/assets/stylesheets/darkswarm/registration.css.scss +++ b/app/assets/stylesheets/darkswarm/registration.css.scss @@ -2,6 +2,10 @@ @import "mixins"; #registration-modal { + @media only screen and (max-width: 640px) { + margin: 0 15px 0 15px; + } + header { text-align: center; From e239bb33f8e51b13b9695e4e2b55d71f57d2e2fd Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 28 Apr 2020 18:41:01 +0100 Subject: [PATCH 239/507] Improve the mobile cookies policy modal with a margin --- .../stylesheets/web/pages/cookies_policy_modal.css.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss b/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss index 4c3706d8d7..f941c00d82 100644 --- a/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss +++ b/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss @@ -4,6 +4,10 @@ background: $cookies-policy-modal-background-color; border-bottom-color: $cookies-policy-modal-border-bottom-color; + @media only screen and (max-width: 640px) { + padding: 15px 15px 0 15px; + } + table { width: 100%; From 30fe457cb56bd4f9c6fce6ff38444bb50041108e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 29 Apr 2020 15:57:13 +0100 Subject: [PATCH 240/507] Make product modal show close button only if there is a scroll bar --- .../product_node_controller.js.coffee | 6 ++++++ .../templates/product_modal.html.haml | 2 +- .../product_node_controller_spec.js.coffee | 21 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index fb8ac8d288..2faeaec3bb 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -4,3 +4,9 @@ Darkswarm.controller "ProductNodeCtrl", ($scope, $modal, FilterSelectorsService) $scope.triggerProductModal = -> $scope.productPropertySelectors = FilterSelectorsService.createSelectors() $modal.open(templateUrl: "product_modal.html", scope: $scope) + + $scope.hasVerticalScrollBar = (selector) -> + elem = angular.element(document.querySelector(selector)) + return false unless elem[0] + + elem[0].scrollHeight > elem[0].clientHeight diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 5ce84d622b..8c6ec7a282 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -19,6 +19,6 @@ %ng-include{src: "'partials/close.html'"} -.buttons +.buttons{ "ng-show": "hasVerticalScrollBar('.reveal-modal')" } .button.bottom-close-button{"ng-click" => "$close()"} = t('js.shop.products.product_modal.close') diff --git a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee index fa99b2d1ec..f33e144ae9 100644 --- a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee @@ -16,3 +16,24 @@ describe "ProductNodeCtrl", -> it "puts a reference to supplier in the scope", -> expect(scope.enterprise).toBe product.supplier + + describe "#hasVerticalScrollBar", -> + it "returns false if modal element is not found", -> + spyOn(angular, 'element').and.returnValue([]) + + expect(scope.hasVerticalScrollBar()).toBe false + + it "returns false if scrollHeight is equal to clientHeight", -> + spyOn(angular, 'element').and.returnValue([{ scrollHeight: 100, clientHeight: 100 }]) + + expect(scope.hasVerticalScrollBar()).toBe false + + it "returns false if scrollHeight is smaller than clientHeight", -> + spyOn(angular, 'element').and.returnValue([{ scrollHeight: 50, clientHeight: 100 }]) + + expect(scope.hasVerticalScrollBar()).toBe false + + it "returns true if scrollHeight is bigger than clientHeight", -> + spyOn(angular, 'element').and.returnValue([{ scrollHeight: 100, clientHeight: 50 }]) + + expect(scope.hasVerticalScrollBar()).toBe true From 38bc076c777f2ec886d345e6e629658e1db2c968 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 29 Apr 2020 19:43:56 +0100 Subject: [PATCH 241/507] Fix some rubocop issues --- app/assets/stylesheets/darkswarm/_shop-modals.css.scss | 4 ++-- app/assets/stylesheets/darkswarm/modals.css.scss | 2 +- app/assets/stylesheets/darkswarm/pages/login_modal.css.scss | 2 +- app/assets/stylesheets/darkswarm/registration.css.scss | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss index 73a488dddd..2175def3b0 100644 --- a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss @@ -2,7 +2,7 @@ padding-left: 1.5rem; h1, h2, h3, h4, h5, h6 { - margin: 0.2rem 0 0 0; + margin: 0.2rem 0 0; } span { @@ -15,7 +15,7 @@ .property-selectors li { margin: 0 0.25rem 0.25rem 0; - padding: 0.4rem 0 0 0; + padding: 0.4rem 0 0; a { border: 1px solid $grey-300; diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index bcd4b127bc..4e8063698a 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -21,7 +21,7 @@ dialog left: 4%; max-height: 92%; max-width: 92%; - padding: 15px 0 0 0; + padding: 15px 0 0; top: 4%; } diff --git a/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss b/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss index cd76a7a338..265c74519c 100644 --- a/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss +++ b/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss @@ -26,7 +26,7 @@ @media only screen and (max-width: 640px) { .tabbable { - margin: 0 15px 0 15px; + margin: 0 15px; } } } diff --git a/app/assets/stylesheets/darkswarm/registration.css.scss b/app/assets/stylesheets/darkswarm/registration.css.scss index 3602f759d5..f97f2b9271 100644 --- a/app/assets/stylesheets/darkswarm/registration.css.scss +++ b/app/assets/stylesheets/darkswarm/registration.css.scss @@ -3,7 +3,7 @@ #registration-modal { @media only screen and (max-width: 640px) { - margin: 0 15px 0 15px; + margin: 0 15px; } header { From edaf419857450c31d3fa170d8aeb880637bb7848 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 8 May 2020 10:32:19 +0100 Subject: [PATCH 242/507] Use rem instead of px or em --- app/assets/stylesheets/darkswarm/_shop-modals.css.scss | 2 +- app/assets/stylesheets/darkswarm/images.css.scss | 2 -- app/assets/stylesheets/darkswarm/modals.css.scss | 2 +- .../assets/stylesheets/web/pages/cookies_policy_modal.css.scss | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss index 2175def3b0..ee380177d4 100644 --- a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss @@ -20,7 +20,7 @@ a { border: 1px solid $grey-300; font-weight: normal; - padding: 0.2em 0.625em; + padding: 0.15rem 0.5rem; } span { diff --git a/app/assets/stylesheets/darkswarm/images.css.scss b/app/assets/stylesheets/darkswarm/images.css.scss index 81d6804dfa..73b59be151 100644 --- a/app/assets/stylesheets/darkswarm/images.css.scss +++ b/app/assets/stylesheets/darkswarm/images.css.scss @@ -4,7 +4,6 @@ .product-img { padding: 5px; - margin-bottom: 10px; // placeholder for when no product images &.placeholder { @@ -17,7 +16,6 @@ @media only screen and (max-width: 1024px) { margin-top: 0; - margin-bottom: 1em; padding: 5px; } } diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index 4e8063698a..54f8c57dd1 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -27,7 +27,7 @@ dialog // Medium and up - larger outside area @media only screen and (min-width: 641px) { - border-bottom: 30px solid white; + border-bottom: 30px solid $white; max-height: 90%; padding: 30px 20px 0 20px; top: 5%; diff --git a/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss b/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss index f941c00d82..583c10525a 100644 --- a/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss +++ b/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss @@ -5,7 +5,7 @@ border-bottom-color: $cookies-policy-modal-border-bottom-color; @media only screen and (max-width: 640px) { - padding: 15px 15px 0 15px; + padding: .9rem; } table { From d95b2a97b0107cadbd50b313655c936ca6c9cef2 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 11 May 2020 14:29:49 +0100 Subject: [PATCH 243/507] Add missing padding above close button (both for the case with image or just with text) and also below product image --- app/assets/stylesheets/darkswarm/images.css.scss | 5 ++--- app/assets/stylesheets/darkswarm/modals.css.scss | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/images.css.scss b/app/assets/stylesheets/darkswarm/images.css.scss index 73b59be151..ba3c34cde3 100644 --- a/app/assets/stylesheets/darkswarm/images.css.scss +++ b/app/assets/stylesheets/darkswarm/images.css.scss @@ -3,7 +3,7 @@ @import "branding"; .product-img { - padding: 5px; + padding: 0.3rem; // placeholder for when no product images &.placeholder { @@ -15,8 +15,7 @@ } @media only screen and (max-width: 1024px) { - margin-top: 0; - padding: 5px; + margin: 0 0 0.5rem; } } diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index 54f8c57dd1..266afa2417 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -83,7 +83,7 @@ dialog .mobile-close-reveal-modal .bottom-close-button { background-color: $orange-500; - margin: 0 0 1rem; + margin: 0.5rem 0 1rem 0; @media only screen and (min-width: 640px) { display: none; From 4292636e70a29d68a8cfff195eb7cb5a894180a7 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 15 May 2020 12:16:19 +0100 Subject: [PATCH 244/507] Remove close button in product modal --- .../product_node_controller.js.coffee | 6 ------ .../templates/product_modal.html.haml | 4 ---- .../stylesheets/darkswarm/modals.css.scss | 14 ------------- config/locales/en.yml | 4 ---- .../product_node_controller_spec.js.coffee | 21 ------------------- 5 files changed, 49 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index 2faeaec3bb..fb8ac8d288 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -4,9 +4,3 @@ Darkswarm.controller "ProductNodeCtrl", ($scope, $modal, FilterSelectorsService) $scope.triggerProductModal = -> $scope.productPropertySelectors = FilterSelectorsService.createSelectors() $modal.open(templateUrl: "product_modal.html", scope: $scope) - - $scope.hasVerticalScrollBar = (selector) -> - elem = angular.element(document.querySelector(selector)) - return false unless elem[0] - - elem[0].scrollHeight > elem[0].clientHeight diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 8c6ec7a282..974c4cba71 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -18,7 +18,3 @@ %img.product-img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"} %ng-include{src: "'partials/close.html'"} - -.buttons{ "ng-show": "hasVerticalScrollBar('.reveal-modal')" } - .button.bottom-close-button{"ng-click" => "$close()"} - = t('js.shop.products.product_modal.close') diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index 266afa2417..5f9cebc067 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -77,20 +77,6 @@ dialog .mobile-close-reveal-modal } } -.reveal-modal .buttons { - margin: 0 auto; - text-align: center; - - .bottom-close-button { - background-color: $orange-500; - margin: 0.5rem 0 1rem 0; - - @media only screen and (min-width: 640px) { - display: none; - } - } -} - // Prevent body from scrolling when a modal is open body.modal-open { overflow: hidden; diff --git a/config/locales/en.yml b/config/locales/en.yml index 7692ef1531..01ba7cebd2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2736,10 +2736,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using signup_or_login: "Start By Signing Up (or logging in)" have_an_account: "Already have an account?" action_login: "Log in now." - shop: - products: - product_modal: - close: "Close" # Singular and plural forms of commonly used words. # We use these entries to pluralize unit names in every language. diff --git a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee index f33e144ae9..fa99b2d1ec 100644 --- a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee @@ -16,24 +16,3 @@ describe "ProductNodeCtrl", -> it "puts a reference to supplier in the scope", -> expect(scope.enterprise).toBe product.supplier - - describe "#hasVerticalScrollBar", -> - it "returns false if modal element is not found", -> - spyOn(angular, 'element').and.returnValue([]) - - expect(scope.hasVerticalScrollBar()).toBe false - - it "returns false if scrollHeight is equal to clientHeight", -> - spyOn(angular, 'element').and.returnValue([{ scrollHeight: 100, clientHeight: 100 }]) - - expect(scope.hasVerticalScrollBar()).toBe false - - it "returns false if scrollHeight is smaller than clientHeight", -> - spyOn(angular, 'element').and.returnValue([{ scrollHeight: 50, clientHeight: 100 }]) - - expect(scope.hasVerticalScrollBar()).toBe false - - it "returns true if scrollHeight is bigger than clientHeight", -> - spyOn(angular, 'element').and.returnValue([{ scrollHeight: 100, clientHeight: 50 }]) - - expect(scope.hasVerticalScrollBar()).toBe true From 0b8771ccf0c2a5df62133307a84db1d57008ceeb Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Sat, 18 Apr 2020 10:43:43 -0300 Subject: [PATCH 245/507] Add connect with us footer to order cancelation email --- app/views/spree/order_mailer/cancel_email.html.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index 47b577e79d..5d539b74d7 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -9,3 +9,4 @@ = t(".order_summary_canceled") = render 'order_summary' = render 'signoff' += render 'shared/mailers/social_and_contact' From 1c1200125e8e9563836bd37b1fd1e9fc050e85e2 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Sun, 19 Apr 2020 22:53:02 -0300 Subject: [PATCH 246/507] Add new greeting table in order cancel mail --- .../spree/order_mailer/cancel_email.html.haml | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index 5d539b74d7..3a4b9e4608 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -1,8 +1,18 @@ -%h3 - = t(".customer_greeting", name: @order.bill_address.firstname) -%h4 - = t(".instructions") -%span.clear +%table.social.white-bg{:width => "100%"} + %tr + %td + %table.column{:align => "left"} + %tr + %td + %h3 + = t(".customer_greeting", name: @order.bill_address.firstname) + %h4 + = t(".instructions_html", distributor: @order.distributor.name ) + %img.float-left{:src => "#{@order.distributor.logo.url(:medium)}"}/ + %span.clear + +%p.callout + = t(".dont_cancel", email: @order.distributor.contact.email) %p   From 42012d648222af1f87fa68f8fe3e5fa2bebc98d7 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Sun, 19 Apr 2020 22:54:17 -0300 Subject: [PATCH 247/507] Add new order sumary in order cancel mail --- app/views/spree/order_mailer/cancel_email.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index 3a4b9e4608..fdbda6e730 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -15,8 +15,11 @@ = t(".dont_cancel", email: @order.distributor.contact.email) %p   +%h4 + = t(".order_summary_canceled_html", number: @order.number) +%p + = t(".details") -= t(".order_summary_canceled") = render 'order_summary' = render 'signoff' = render 'shared/mailers/social_and_contact' From f72da4abe4ffcde729bf0347435389d589332e8a Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Sun, 19 Apr 2020 22:54:35 -0300 Subject: [PATCH 248/507] Add refund message in order cancel mail --- app/views/spree/order_mailer/cancel_email.html.haml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index fdbda6e730..9d01d8ec87 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -21,5 +21,12 @@ = t(".details") = render 'order_summary' + +%p + - if @order.paid? + = t(".paid_order", distributor: @order.distributor.name) + - else + = t(".unpaid_order") + = render 'signoff' = render 'shared/mailers/social_and_contact' From 5d286cb3496853aadd9ac6153eb34d1774c68869 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Sun, 19 Apr 2020 23:29:48 -0300 Subject: [PATCH 249/507] Add i18n of new symbols for order cancel mail --- config/locales/en.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 01ba7cebd2..cd68a575ab 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3437,9 +3437,14 @@ See the %{link} to find out more about %{sitename}'s features and to start using invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" + customer_greeting: "Dear %{name}," + instructions_html: "Your order with %{distributor} has been CANCELED. Please retain this cancellation information for your records." + dont_cancel: "If you have changed your mind or don't wish to cancel this order please contact %{email}" + order_summary_canceled_html: "Order Summary #%{number} [CANCELED]" + details: "Here are the details of what you ordered:" + unpaid_order: "Your order was unpaid so no refund has been made" + paid_order: "Your order was paid so %{distributor} has refunded the full amount" + credit_order: "Your order was paid so your account has been credited" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" From 0caa91d0576bf63cabecb531f86fdde610d03c77 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Sat, 2 May 2020 09:37:16 -0300 Subject: [PATCH 250/507] Remove second table of cancel email instructions style --- .../spree/order_mailer/cancel_email.html.haml | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index 9d01d8ec87..e1b390996f 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -1,15 +1,12 @@ -%table.social.white-bg{:width => "100%"} - %tr - %td - %table.column{:align => "left"} - %tr - %td - %h3 - = t(".customer_greeting", name: @order.bill_address.firstname) - %h4 - = t(".instructions_html", distributor: @order.distributor.name ) - %img.float-left{:src => "#{@order.distributor.logo.url(:medium)}"}/ - %span.clear +%table.social.white-bg{width: "100%"} + %table.column{align: "left"} + %tr + %td + %h3 + = t(".customer_greeting", name: @order.bill_address.firstname) + %h4 + = t(".instructions_html", distributor: @order.distributor.name ) + %img.float-left{src: "#{@order.distributor.logo.url(:medium)}"} %p.callout = t(".dont_cancel", email: @order.distributor.contact.email) From 98cbe5762a2682245a7afafdb7660e9593c78f97 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Wed, 13 May 2020 21:13:29 -0300 Subject: [PATCH 251/507] Remove unused css property from image in cancel email --- app/views/spree/order_mailer/cancel_email.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index e1b390996f..b708251420 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -6,7 +6,7 @@ = t(".customer_greeting", name: @order.bill_address.firstname) %h4 = t(".instructions_html", distributor: @order.distributor.name ) - %img.float-left{src: "#{@order.distributor.logo.url(:medium)}"} + %img{src: "#{@order.distributor.logo.url(:medium)}"} %p.callout = t(".dont_cancel", email: @order.distributor.contact.email) From 6c81c19f0098865fc03dea4360b771dea7b265ba Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 16 May 2020 14:19:25 +0100 Subject: [PATCH 252/507] Remove dead code --- .../side_menu/services/side_menu.js.coffee | 9 -------- .../side_menu/services/side_menu.js.coffee | 22 ------------------- 2 files changed, 31 deletions(-) diff --git a/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee b/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee index 4f6fe5ab59..4e1ae9abbb 100644 --- a/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee +++ b/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee @@ -4,7 +4,6 @@ angular.module("admin.side_menu") items: [] selected: null - # Checks for path and uses it to set the view # If no path, loads first view init: => @@ -31,11 +30,3 @@ angular.module("admin.side_menu") for item in @items when item.name is name return item null - - hide_item_by_name: (name) => - item = @find_by_name(name) - item.visible = false if item - - show_item_by_name: (name) => - item = @find_by_name(name) - item.visible = true if item diff --git a/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee b/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee index 0840d69c28..74c802c7d4 100644 --- a/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee +++ b/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee @@ -69,25 +69,3 @@ describe "SideMenu service", -> it "returns null if no items are found", -> SideMenu.items = [ { name: "Name 1"}, { name: "Name 2"} ] expect(SideMenu.find_by_name("Name 3")).toBe null - - describe "hiding an item by name", -> - it "sets visible to false on the response from find_by_name", -> - mockItem = { visible: true } - spyOn(SideMenu, 'find_by_name').and.returnValue mockItem - SideMenu.hide_item_by_name() - expect(mockItem.visible).toBe false - - it "doesn't crash if null is returned from find_by_name", -> - spyOn(SideMenu, 'find_by_name').and.returnValue null - SideMenu.hide_item_by_name() - - describe "showing an item by name", -> - it "sets visible to false on the response from find_by_name", -> - mockItem = { visible: false } - spyOn(SideMenu, 'find_by_name').and.returnValue mockItem - SideMenu.show_item_by_name() - expect(mockItem.visible).toBe true - - it "doesn't crash if null is returned from find_by_name", -> - spyOn(SideMenu, 'find_by_name').and.returnValue null - SideMenu.show_item_by_name() From a0334953dbe15e383d04dcd06336d7d5d7173e47 Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Mon, 18 May 2020 17:06:07 +1000 Subject: [PATCH 253/507] Added 14 translation keys for PayPalExpress payment method --- config/locales/en.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 01ba7cebd2..ffb45a5d7d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2380,6 +2380,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using shipping: "Shipping" shipping_methods: "Shipping Methods" payment_methods: "Payment Methods" + provider_settings: "Provider Settings" + active: "Active" + description: "Description" + tags: "Tags" + provider: "Provider" payment_method_fee: "Transaction fee" payment_processing_failed: "Payment could not be processed, please check the details you entered" payment_method_not_supported: "That payment method is unsupported. Please choose another one." @@ -2952,6 +2957,14 @@ See the %{link} to find out more about %{sitename}'s features and to start using new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" + signature: "Signature" + solution: "Solution" + landing_page: "Landing Page" + server: "Server" + test_mode: "Test Mode" + logourl: "Logourl" configurations: "Configurations" general_settings: "General Settings" From 473b4c63c4bcd180cc2bac5241e93120b38097c9 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Tue, 5 May 2020 20:38:07 -0300 Subject: [PATCH 254/507] add Shipping Method filter to admin/orders page --- .../admin/orders/controllers/orders_controller.js.coffee | 1 + app/views/spree/admin/orders/_filters.html.haml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index f6d4c964d6..751ddf8866 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -37,6 +37,7 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $timeout, Reque 'q[distributor_id_in][]': $scope['q']['distributor_id_in'], 'q[order_cycle_id_in][]': $scope['q']['order_cycle_id_in'], 'q[s]': $scope.sorting || 'completed_at desc', + shipping_method_id: $scope.shipping_method_id, per_page: $scope.per_page, page: page } diff --git a/app/views/spree/admin/orders/_filters.html.haml b/app/views/spree/admin/orders/_filters.html.haml index b41c2d194a..63c65fd488 100644 --- a/app/views/spree/admin/orders/_filters.html.haml +++ b/app/views/spree/admin/orders/_filters.html.haml @@ -32,6 +32,11 @@ %label = check_box_tag "q[completed_at_not_null]", 1, true, {'ng-model' => 'q.completed_at_not_null'} = t(:show_only_complete_orders) + .field + = label_tag nil, t(:shipping_method) + = select_tag("shipping_method_id", + options_for_select(Spree::ShippingMethod.managed_by(spree_current_user).collect {|s| [t("spree.shipping_method.#{s.name}"), s.id]}), + {include_blank: true, class: 'select2', 'ng-model' => 'shipping_method_id'}) .field-block.alpha.eight.columns = label_tag nil, t(:distributors) = select_tag("q[distributor_id_in]", From 6d54e6d4a0f947d773303c12bd0cefc7a97fbe2f Mon Sep 17 00:00:00 2001 From: Eduardo Date: Tue, 5 May 2020 20:38:34 -0300 Subject: [PATCH 255/507] change SearchOrders service to search with shipping_method --- app/services/search_orders.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/services/search_orders.rb b/app/services/search_orders.rb index 4ff0f717da..30afb964a7 100644 --- a/app/services/search_orders.rb +++ b/app/services/search_orders.rb @@ -24,13 +24,25 @@ class SearchOrders attr_reader :params, :current_user def fetch_orders - @search = ::Permissions::Order.new(current_user).editable_orders.ransack(params[:q]) + @search = search_query.ransack(params[:q]) return paginated_results if using_pagination? @search.result(distinct: true) end + def search_query + base_query = ::Permissions::Order.new(current_user).editable_orders + return base_query unless params[:shipping_method_id] + + base_query + .joins(shipments: :shipping_rates) + .where(spree_shipping_rates: { + selected: true, + shipping_method_id: params[:shipping_method_id] + }) + end + def paginated_results @search.result(distinct: true) .page(params[:page]) From 049b1b463842d926f92f40e030e4ef70273e4d8b Mon Sep 17 00:00:00 2001 From: Steve Roberts Date: Tue, 19 May 2020 10:14:26 +1000 Subject: [PATCH 256/507] Split up the specs again. This now shows that there is one consistent spec erroring, spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb: Capybara::ElementNotFound: Unable to find visible checkbox "order_cycle_incoming_exchange_0_select_all_variants" that is not disabled --- .../complex_creating_specific_time_spec.rb | 136 ++++++ ...x_editing_exchange_same_enterprise_spec.rb | 33 ++ ...lex_editing_multiple_product_pages_spec.rb | 49 ++ .../order_cycles/complex_editing_spec.rb | 95 ++++ .../complex_updating_specific_time_spec.rb | 166 +++++++ .../list_spec.rb} | 0 .../simple_spec.rb} | 0 .../admin/order_cycles_complex_spec.rb | 438 ------------------ 8 files changed, 479 insertions(+), 438 deletions(-) create mode 100644 spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb create mode 100644 spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb create mode 100644 spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb create mode 100644 spec/features/admin/order_cycles/complex_editing_spec.rb create mode 100644 spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb rename spec/features/admin/{order_cycles_list_spec.rb => order_cycles/list_spec.rb} (100%) rename spec/features/admin/{order_cycles_simple_spec.rb => order_cycles/simple_spec.rb} (100%) delete mode 100644 spec/features/admin/order_cycles_complex_spec.rb diff --git a/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb b/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb new file mode 100644 index 0000000000..69774fb043 --- /dev/null +++ b/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to create/update complex order cycles with a specific time +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } + let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } + + scenario "creating an order cycle with full interface", js: true do + # Given coordinating, supplying and distributing enterprises with some products with variants + coordinator = create(:distributor_enterprise, name: 'My coordinator') + supplier = create(:supplier_enterprise, name: 'My supplier') + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) + + # And some enterprise fees + supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') + coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') + distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') + + # When I go to the new order cycle page + quick_login_as_admin + visit admin_order_cycles_path + click_link 'New Order Cycle' + + # Select a coordinator since there are two available + select2_select 'My coordinator', from: 'coordinator_id' + click_button "Continue >" + + # I cannot save before filling in the required fields + expect(page).to have_button("Create", disabled: true) + + # The Create button is enabled once Name is entered + fill_in 'order_cycle_name', with: 'Plums & Avos' + expect(page).to have_button("Create", disabled: false) + + # If I fill in the basic fields + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time + + # And I add a coordinator fee + click_button 'Add coordinator fee' + select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' + + click_button 'Create' + expect(page).to have_content 'Your order cycle has been created.' + + # I should not be able to add a blank supplier + expect(page).to have_select 'new_supplier_id', selected: '' + expect(page).to have_button 'Add supplier', disabled: true + + # And I add a supplier and some products + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' + page.find('table.exchanges tr.supplier td.products').click + check "order_cycle_incoming_exchange_0_variants_#{v1.id}" + check "order_cycle_incoming_exchange_0_variants_#{v2.id}" + + # I should not be able to re-add the supplier + expect(page).not_to have_select 'new_supplier_id', with_options: ['My supplier'] + expect(page).to have_button 'Add supplier', disabled: true + expect(page.all("td.supplier_name").map(&:text)).to eq(['My supplier']) + + # And I add a supplier fee + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' + select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Next' + + # And I add a distributor with the same products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' + + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' + + page.find('table.exchanges tr.distributor td.products').click + check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" + + page.find('table.exchanges tr.distributor td.tags').click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + # And I add a distributor fee + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' + select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Back to List' + + oc = OrderCycle.last + toggle_columns "Producers", "Shops" + + expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" + expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time + expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time + expect(page).to have_content "My coordinator" + + expect(page).to have_selector 'td.producers', text: 'My supplier' + expect(page).to have_selector 'td.shops', text: 'My distributor' + + # And it should have some fees + expect(oc.exchanges.incoming.first.enterprise_fees).to eq([supplier_fee]) + expect(oc.coordinator_fees).to eq([coordinator_fee]) + expect(oc.exchanges.outgoing.first.enterprise_fees).to eq([distributor_fee]) + + # And it should have some variants selected + expect(oc.exchanges.first.variants.count).to eq(2) + expect(oc.exchanges.last.variants.count).to eq(2) + + # And my receival and pickup time and instructions should have been saved + exchange = oc.exchanges.incoming.first + expect(exchange.receival_instructions).to eq('receival instructions') + + exchange = oc.exchanges.outgoing.first + expect(exchange.pickup_time).to eq('pickup time') + expect(exchange.pickup_instructions).to eq('pickup instructions') + expect(exchange.tag_list).to eq(['wholesale']) + end +end diff --git a/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb b/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb new file mode 100644 index 0000000000..d6ef3554fa --- /dev/null +++ b/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to manage complex order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + scenario "editing an order cycle with an exchange between the same enterprise" do + c = create(:distributor_enterprise, is_primary_producer: true) + + # Given two order cycles, one with a mono-enterprise incoming exchange... + oc_incoming = create(:simple_order_cycle, suppliers: [c], coordinator: c) + + # And the other with a mono-enterprise outgoing exchange + oc_outgoing = create(:simple_order_cycle, coordinator: c, distributors: [c]) + + # When I edit the first order cycle, the exchange should appear as incoming + quick_login_as_admin + visit admin_order_cycle_incoming_path(oc_incoming) + expect(page).to have_selector 'table.exchanges tr.supplier' + visit admin_order_cycle_outgoing_path(oc_incoming) + expect(page).not_to have_selector 'table.exchanges tr.distributor' + + # And when I edit the second order cycle, the exchange should appear as outgoing + visit admin_order_cycle_outgoing_path(oc_outgoing) + expect(page).to have_selector 'table.exchanges tr.distributor' + visit admin_order_cycle_incoming_path(oc_outgoing) + expect(page).not_to have_selector 'table.exchanges tr.supplier' + end +end diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb new file mode 100644 index 0000000000..005dedfe5e --- /dev/null +++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to manage complex order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + describe "editing an order cycle with multiple pages of products", js: true do + let(:order_cycle) { create(:order_cycle) } + let(:supplier_enterprise) { order_cycle.exchanges.incoming.first.sender } + let!(:new_product) { create(:product, supplier: supplier_enterprise) } + + before do + stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) + + quick_login_as_admin + visit admin_order_cycle_incoming_path(order_cycle) + expect(page).to have_content "1 / 2 selected" + + page.find("tr.supplier-#{supplier_enterprise.id} td.products").click + expect(page).to have_selector ".exchange-product-details" + + expect(page).to have_content "1 of 2 Variants Loaded" + expect(page).to_not have_content new_product.name + end + + scenario "load all products" do + page.find(".exchange-load-all-variants a").click + + expect_all_products_loaded + end + + scenario "select all products" do + check "order_cycle_incoming_exchange_0_select_all_variants" + + expect_all_products_loaded + + expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{new_product.variants.first.id}", disabled: false + end + + def expect_all_products_loaded + expect(page).to have_content new_product.name.upcase + expect(page).to have_content "2 of 2 Variants Loaded" + end + end +end diff --git a/spec/features/admin/order_cycles/complex_editing_spec.rb b/spec/features/admin/order_cycles/complex_editing_spec.rb new file mode 100644 index 0000000000..0b6b9d8ac0 --- /dev/null +++ b/spec/features/admin/order_cycles/complex_editing_spec.rb @@ -0,0 +1,95 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to manage complex order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + scenario "editing an order cycle" do + # Given an order cycle with all the settings + oc = create(:order_cycle) + oc.suppliers.first.update_attribute :name, 'AAA' + oc.suppliers.last.update_attribute :name, 'ZZZ' + oc.distributors.first.update_attribute :name, 'AAAA' + oc.distributors.last.update_attribute :name, 'ZZZZ' + + # When I edit it + quick_login_as_admin + visit edit_admin_order_cycle_path(oc) + + wait_for_edit_form_to_load_order_cycle(oc) + + # Then I should see the basic settings + expect(page.find('#order_cycle_name').value).to eq(oc.name) + expect(page.find('#order_cycle_orders_open_at').value).to eq(oc.orders_open_at.to_s) + expect(page.find('#order_cycle_orders_close_at').value).to eq(oc.orders_close_at.to_s) + expect(page).to have_content "COORDINATOR #{oc.coordinator.name}" + + click_button 'Next' + + # And I should see the suppliers + expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.first.name + expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.last.name + + expect(page).to have_field 'order_cycle_incoming_exchange_0_receival_instructions', with: 'instructions 0' + expect(page).to have_field 'order_cycle_incoming_exchange_1_receival_instructions', with: 'instructions 1' + + # And the suppliers should have products + page.all('table.exchanges tbody tr.supplier').each_with_index do |row, i| + row.find('td.products').click + + products_panel = page.all('table.exchanges tr.panel-row .exchange-supplied-products').select(&:visible?).first + expect(products_panel).to have_selector "input[name='order_cycle_incoming_exchange_#{i}_select_all_variants']" + + row.find('td.products').click + end + + # And the suppliers should have fees + supplier = oc.suppliers.min_by(&:name) + expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id', selected: supplier.name + expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name + + supplier = oc.suppliers.max_by(&:name) + expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id', selected: supplier.name + expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name + + click_button 'Next' + + # And I should see the distributors + expect(page).to have_selector 'td.distributor_name', text: oc.distributors.first.name + expect(page).to have_selector 'td.distributor_name', text: oc.distributors.last.name + + expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'time 0' + expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'instructions 0' + expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_time', with: 'time 1' + expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'instructions 1' + + # And the distributors should have products + page.all('table.exchanges tbody tr.distributor').each_with_index do |row, i| + row.find('td.products').click + + products_panel = page.all('table.exchanges tr.panel-row .exchange-distributed-products').select(&:visible?).first + expect(products_panel).to have_selector "input[name='order_cycle_outgoing_exchange_#{i}_select_all_variants']" + + row.find('td.products').click + end + + # And the distributors should have fees + distributor = oc.distributors.min_by(&:id) + expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id', selected: distributor.name + expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name + + distributor = oc.distributors.max_by(&:id) + expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id', selected: distributor.name + expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name + end + + private + + def wait_for_edit_form_to_load_order_cycle(order_cycle) + expect(page).to have_field "order_cycle_name", with: order_cycle.name + end +end diff --git a/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb b/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb new file mode 100644 index 0000000000..2e569fc0ce --- /dev/null +++ b/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb @@ -0,0 +1,166 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to create/update complex order cycles with a specific time +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } + let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } + + scenario "updating an order cycle", js: true do + # Given an order cycle with all the settings + oc = create(:order_cycle) + initial_variants = oc.variants.sort_by(&:id) + + # And a coordinating, supplying and distributing enterprise with some products with variants + coordinator = oc.coordinator + supplier = create(:supplier_enterprise, name: 'My supplier') + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) + + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) + + # And some enterprise fees + supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') + supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') + coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') + coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') + distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') + distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') + + # When I go to its edit page + quick_login_as_admin + visit admin_order_cycles_path + within "tr.order-cycle-#{oc.id}" do + find("a.edit-order-cycle").click + end + + wait_for_edit_form_to_load_order_cycle(oc) + + # And I update it + fill_in 'order_cycle_name', with: 'Plums & Avos' + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time + + # And I configure some coordinator fees + click_button 'Add coordinator fee' + select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' + click_button 'Add coordinator fee' + click_button 'Add coordinator fee' + click_link 'order_cycle_coordinator_fee_2_remove' + select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' + + click_button 'Save and Next' + expect(page).to have_content 'Your order cycle has been updated.' + + # And I add a supplier and some products + expect(page).to have_selector("table.exchanges tr.supplier") + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + expect(page).to have_selector("table.exchanges tr.supplier", text: "My supplier") + page.all("table.exchanges tr.supplier td.products").each(&:click) + + expect(page).to have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true + page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) + check "order_cycle_incoming_exchange_2_variants_#{v1.id}" + check "order_cycle_incoming_exchange_2_variants_#{v2.id}" + + # And I configure some supplier fees + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Next' + + # And I add a distributor and some products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' + expect(page).to have_field("order_cycle_outgoing_exchange_2_pickup_time") + + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' + fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' + fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' + fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' + fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' + + page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + exchange_rows = page.all("table.exchanges tbody") + exchange_rows.each do |exchange_row| + exchange_row.find("td.products").click + # Wait for the products panel to be visible. + expect(exchange_row).to have_selector "tr", count: 2 + end + + uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" + + # And I configure some distributor fees + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + + expect(page).to have_selector "#save-bar" + click_button 'Save and Back to List' + + oc = OrderCycle.last + toggle_columns "Producers", "Shops" + + expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" + expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time + expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time + expect(page).to have_content coordinator.name + + expect(page).to have_selector 'td.producers', text: 'My supplier' + expect(page).to have_selector 'td.shops', text: 'My distributor' + + # And my coordinator fees should have been configured + expect(oc.coordinator_fee_ids).to match_array [coordinator_fee1.id, coordinator_fee2.id] + + # And my supplier fees should have been configured + expect(oc.exchanges.incoming.last.enterprise_fee_ids).to eq([supplier_fee2.id]) + + # And my distributor fees should have been configured + expect(oc.exchanges.outgoing.last.enterprise_fee_ids).to eq([distributor_fee2.id]) + + # And my tags should have been save + expect(oc.exchanges.outgoing.last.tag_list).to eq(['wholesale']) + + # And it should have some variants selected + selected_initial_variants = initial_variants.take initial_variants.size - 1 + expect(oc.variants.map(&:id)).to match_array((selected_initial_variants.map(&:id) + [v1.id, v2.id])) + + # And the collection details should have been updated + expect(oc.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0')).to be_present + expect(oc.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1')).to be_present + end + + private + + def wait_for_edit_form_to_load_order_cycle(order_cycle) + expect(page).to have_field "order_cycle_name", with: order_cycle.name + end +end diff --git a/spec/features/admin/order_cycles_list_spec.rb b/spec/features/admin/order_cycles/list_spec.rb similarity index 100% rename from spec/features/admin/order_cycles_list_spec.rb rename to spec/features/admin/order_cycles/list_spec.rb diff --git a/spec/features/admin/order_cycles_simple_spec.rb b/spec/features/admin/order_cycles/simple_spec.rb similarity index 100% rename from spec/features/admin/order_cycles_simple_spec.rb rename to spec/features/admin/order_cycles/simple_spec.rb diff --git a/spec/features/admin/order_cycles_complex_spec.rb b/spec/features/admin/order_cycles_complex_spec.rb deleted file mode 100644 index cca8c0ea10..0000000000 --- a/spec/features/admin/order_cycles_complex_spec.rb +++ /dev/null @@ -1,438 +0,0 @@ -require 'spec_helper' - -feature ' - As an administrator - I want to manage complex order cycles -', js: true do - include AdminHelper - include AuthenticationWorkflow - include WebHelper - - context "with specific time" do - let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } - let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } - - scenario "creating an order cycle with full interface", js: true do - # Given coordinating, supplying and distributing enterprises with some products with variants - coordinator = create(:distributor_enterprise, name: 'My coordinator') - supplier = create(:supplier_enterprise, name: 'My supplier') - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - - # And some enterprise fees - supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') - coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') - distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') - - # When I go to the new order cycle page - quick_login_as_admin - visit admin_order_cycles_path - click_link 'New Order Cycle' - - # Select a coordinator since there are two available - select2_select 'My coordinator', from: 'coordinator_id' - click_button "Continue >" - - # I cannot save before filling in the required fields - expect(page).to have_button("Create", disabled: true) - - # The Create button is enabled once Name is entered - fill_in 'order_cycle_name', with: 'Plums & Avos' - expect(page).to have_button("Create", disabled: false) - - # If I fill in the basic fields - fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time - fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - - # And I add a coordinator fee - click_button 'Add coordinator fee' - select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' - - click_button 'Create' - expect(page).to have_content 'Your order cycle has been created.' - - # I should not be able to add a blank supplier - expect(page).to have_select 'new_supplier_id', selected: '' - expect(page).to have_button 'Add supplier', disabled: true - - # And I add a supplier and some products - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' - page.find('table.exchanges tr.supplier td.products').click - check "order_cycle_incoming_exchange_0_variants_#{v1.id}" - check "order_cycle_incoming_exchange_0_variants_#{v2.id}" - - # I should not be able to re-add the supplier - expect(page).not_to have_select 'new_supplier_id', with_options: ['My supplier'] - expect(page).to have_button 'Add supplier', disabled: true - expect(page.all("td.supplier_name").map(&:text)).to eq(['My supplier']) - - # And I add a supplier fee - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' - select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Next' - - # And I add a distributor with the same products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' - - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' - - page.find('table.exchanges tr.distributor td.products').click - check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" - - page.find('table.exchanges tr.distributor td.tags').click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" - end - - # And I add a distributor fee - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' - select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Back to List' - - oc = OrderCycle.last - toggle_columns "Producers", "Shops" - - expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" - expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time - expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time - expect(page).to have_content "My coordinator" - - expect(page).to have_selector 'td.producers', text: 'My supplier' - expect(page).to have_selector 'td.shops', text: 'My distributor' - - # And it should have some fees - expect(oc.exchanges.incoming.first.enterprise_fees).to eq([supplier_fee]) - expect(oc.coordinator_fees).to eq([coordinator_fee]) - expect(oc.exchanges.outgoing.first.enterprise_fees).to eq([distributor_fee]) - - # And it should have some variants selected - expect(oc.exchanges.first.variants.count).to eq(2) - expect(oc.exchanges.last.variants.count).to eq(2) - - # And my receival and pickup time and instructions should have been saved - exchange = oc.exchanges.incoming.first - expect(exchange.receival_instructions).to eq('receival instructions') - - exchange = oc.exchanges.outgoing.first - expect(exchange.pickup_time).to eq('pickup time') - expect(exchange.pickup_instructions).to eq('pickup instructions') - expect(exchange.tag_list).to eq(['wholesale']) - end - - scenario "updating an order cycle", js: true do - # Given an order cycle with all the settings - oc = create(:order_cycle) - initial_variants = oc.variants.sort_by(&:id) - - # And a coordinating, supplying and distributing enterprise with some products with variants - coordinator = oc.coordinator - supplier = create(:supplier_enterprise, name: 'My supplier') - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - - # And some enterprise fees - supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') - supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') - coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') - coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') - distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') - distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') - - # When I go to its edit page - quick_login_as_admin - visit admin_order_cycles_path - within "tr.order-cycle-#{oc.id}" do - find("a.edit-order-cycle").click - end - - wait_for_edit_form_to_load_order_cycle(oc) - - # And I update it - fill_in 'order_cycle_name', with: 'Plums & Avos' - fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time - fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - - # And I configure some coordinator fees - click_button 'Add coordinator fee' - select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' - click_button 'Add coordinator fee' - click_button 'Add coordinator fee' - click_link 'order_cycle_coordinator_fee_2_remove' - select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' - - click_button 'Save and Next' - expect(page).to have_content 'Your order cycle has been updated.' - - # And I add a supplier and some products - expect(page).to have_selector("table.exchanges tr.supplier") - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - expect(page).to have_selector("table.exchanges tr.supplier", text: "My supplier") - page.all("table.exchanges tr.supplier td.products").each(&:click) - - - expect(page).to have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true - page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) - check "order_cycle_incoming_exchange_2_variants_#{v1.id}" - check "order_cycle_incoming_exchange_2_variants_#{v2.id}" - - # And I configure some supplier fees - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Next' - - # And I add a distributor and some products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' - expect(page).to have_field("order_cycle_outgoing_exchange_2_pickup_time") - - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' - fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' - fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' - fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' - fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' - - page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" - end - - exchange_rows = page.all("table.exchanges tbody") - exchange_rows.each do |exchange_row| - exchange_row.find("td.products").click - # Wait for the products panel to be visible. - expect(exchange_row).to have_selector "tr", count: 2 - end - - uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" - - # And I configure some distributor fees - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - - expect(page).to have_selector "#save-bar" - click_button 'Save and Back to List' - - oc = OrderCycle.last - toggle_columns "Producers", "Shops" - - expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" - expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time - expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time - expect(page).to have_content coordinator.name - - expect(page).to have_selector 'td.producers', text: 'My supplier' - expect(page).to have_selector 'td.shops', text: 'My distributor' - - # And my coordinator fees should have been configured - expect(oc.coordinator_fee_ids).to match_array [coordinator_fee1.id, coordinator_fee2.id] - - # And my supplier fees should have been configured - expect(oc.exchanges.incoming.last.enterprise_fee_ids).to eq([supplier_fee2.id]) - - # And my distributor fees should have been configured - expect(oc.exchanges.outgoing.last.enterprise_fee_ids).to eq([distributor_fee2.id]) - - # And my tags should have been save - expect(oc.exchanges.outgoing.last.tag_list).to eq(['wholesale']) - - # And it should have some variants selected - selected_initial_variants = initial_variants.take initial_variants.size - 1 - expect(oc.variants.map(&:id)).to match_array((selected_initial_variants.map(&:id) + [v1.id, v2.id])) - - # And the collection details should have been updated - expect(oc.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0')).to be_present - expect(oc.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1')).to be_present - end - end - - scenario "editing an order cycle" do - # Given an order cycle with all the settings - oc = create(:order_cycle) - oc.suppliers.first.update_attribute :name, 'AAA' - oc.suppliers.last.update_attribute :name, 'ZZZ' - oc.distributors.first.update_attribute :name, 'AAAA' - oc.distributors.last.update_attribute :name, 'ZZZZ' - - # When I edit it - quick_login_as_admin - visit edit_admin_order_cycle_path(oc) - - wait_for_edit_form_to_load_order_cycle(oc) - - # Then I should see the basic settings - expect(page.find('#order_cycle_name').value).to eq(oc.name) - expect(page.find('#order_cycle_orders_open_at').value).to eq(oc.orders_open_at.to_s) - expect(page.find('#order_cycle_orders_close_at').value).to eq(oc.orders_close_at.to_s) - expect(page).to have_content "COORDINATOR #{oc.coordinator.name}" - - click_button 'Next' - - # And I should see the suppliers - expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.first.name - expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.last.name - - expect(page).to have_field 'order_cycle_incoming_exchange_0_receival_instructions', with: 'instructions 0' - expect(page).to have_field 'order_cycle_incoming_exchange_1_receival_instructions', with: 'instructions 1' - - # And the suppliers should have products - page.all('table.exchanges tbody tr.supplier').each_with_index do |row, i| - row.find('td.products').click - - products_panel = page.all('table.exchanges tr.panel-row .exchange-supplied-products').select(&:visible?).first - expect(products_panel).to have_selector "input[name='order_cycle_incoming_exchange_#{i}_select_all_variants']" - - row.find('td.products').click - end - - # And the suppliers should have fees - supplier = oc.suppliers.min_by(&:name) - expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id', selected: supplier.name - expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name - - supplier = oc.suppliers.max_by(&:name) - expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id', selected: supplier.name - expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name - - click_button 'Next' - - # And I should see the distributors - expect(page).to have_selector 'td.distributor_name', text: oc.distributors.first.name - expect(page).to have_selector 'td.distributor_name', text: oc.distributors.last.name - - expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'time 0' - expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'instructions 0' - expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_time', with: 'time 1' - expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'instructions 1' - - # And the distributors should have products - page.all('table.exchanges tbody tr.distributor').each_with_index do |row, i| - row.find('td.products').click - - products_panel = page.all('table.exchanges tr.panel-row .exchange-distributed-products').select(&:visible?).first - expect(products_panel).to have_selector "input[name='order_cycle_outgoing_exchange_#{i}_select_all_variants']" - - row.find('td.products').click - end - - # And the distributors should have fees - distributor = oc.distributors.min_by(&:id) - expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id', selected: distributor.name - expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name - - distributor = oc.distributors.max_by(&:id) - expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id', selected: distributor.name - expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name - end - - scenario "editing an order cycle with an exchange between the same enterprise" do - c = create(:distributor_enterprise, is_primary_producer: true) - - # Given two order cycles, one with a mono-enterprise incoming exchange... - oc_incoming = create(:simple_order_cycle, suppliers: [c], coordinator: c) - - # And the other with a mono-enterprise outgoing exchange - oc_outgoing = create(:simple_order_cycle, coordinator: c, distributors: [c]) - - # When I edit the first order cycle, the exchange should appear as incoming - quick_login_as_admin - visit admin_order_cycle_incoming_path(oc_incoming) - expect(page).to have_selector 'table.exchanges tr.supplier' - visit admin_order_cycle_outgoing_path(oc_incoming) - expect(page).not_to have_selector 'table.exchanges tr.distributor' - - # And when I edit the second order cycle, the exchange should appear as outgoing - visit admin_order_cycle_outgoing_path(oc_outgoing) - expect(page).to have_selector 'table.exchanges tr.distributor' - visit admin_order_cycle_incoming_path(oc_outgoing) - expect(page).not_to have_selector 'table.exchanges tr.supplier' - end - - describe "editing an order cycle with multiple pages of products", js: true do - let(:order_cycle) { create(:order_cycle) } - let(:supplier_enterprise) { order_cycle.exchanges.incoming.first.sender } - let!(:new_product) { create(:product, supplier: supplier_enterprise) } - - before do - stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) - - quick_login_as_admin - visit admin_order_cycle_incoming_path(order_cycle) - expect(page).to have_content "1 / 2 selected" - - page.find("tr.supplier-#{supplier_enterprise.id} td.products").click - expect(page).to have_selector ".exchange-product-details" - - expect(page).to have_content "1 of 2 Variants Loaded" - expect(page).to_not have_content new_product.name - end - - scenario "load all products" do - page.find(".exchange-load-all-variants a").click - - expect_all_products_loaded - end - - scenario "select all products" do - check "order_cycle_incoming_exchange_0_select_all_variants" - - expect_all_products_loaded - - expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{new_product.variants.first.id}", disabled: false - end - - def expect_all_products_loaded - expect(page).to have_content new_product.name.upcase - expect(page).to have_content "2 of 2 Variants Loaded" - end - end - - private - - def wait_for_edit_form_to_load_order_cycle(order_cycle) - expect(page).to have_field "order_cycle_name", with: order_cycle.name - end - - def select_incoming_variant(supplier, exchange_no, variant) - page.find("table.exchanges tr.supplier-#{supplier.id} td.products").click - check "order_cycle_incoming_exchange_#{exchange_no}_variants_#{variant.id}" - end -end \ No newline at end of file From ba30f55e70a41dcc5dba2ea5219a77aa87c56f93 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Mon, 18 May 2020 22:53:46 -0300 Subject: [PATCH 257/507] Add fullwidth for table selector --- app/assets/stylesheets/mail/email.css.scss | 4 ++++ app/views/spree/order_mailer/cancel_email.html.haml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/mail/email.css.scss b/app/assets/stylesheets/mail/email.css.scss index bb1006c9ea..dee2738ead 100644 --- a/app/assets/stylesheets/mail/email.css.scss +++ b/app/assets/stylesheets/mail/email.css.scss @@ -68,6 +68,10 @@ table.social { background-color: white !important; border: 1px solid #ebebeb; } + + &.fullwidth { + width: 100%; + } } table.order-summary { diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index b708251420..0965d522b8 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -1,5 +1,5 @@ -%table.social.white-bg{width: "100%"} - %table.column{align: "left"} +%table.social.white-bg.fullwidth + %table.column %tr %td %h3 From 446bf268b4316c325fbaa7386851a3a5e177875f Mon Sep 17 00:00:00 2001 From: Steve Roberts Date: Tue, 19 May 2020 14:16:45 +1000 Subject: [PATCH 258/507] scroll_to substitute --- .../complex_editing_multiple_product_pages_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb index 005dedfe5e..7a9bd7317f 100644 --- a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb +++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb @@ -34,7 +34,10 @@ feature ' end scenario "select all products" do - check "order_cycle_incoming_exchange_0_select_all_variants" + # replace with scroll_to method when upgrading to Capybara >= 3.13.0 + cb_id = "order_cycle_incoming_exchange_0_select_all_variants" + page.execute_script("document.getElementById('#{cb_id}').scrollIntoView()") + check cb_id expect_all_products_loaded From 2e9f911958f15fd472571b6bff6affcb39657845 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 19 May 2020 12:06:24 +0100 Subject: [PATCH 259/507] Add actionpack-action_caching to support action caching --- Gemfile | 1 + Gemfile.lock | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index ae833df9f7..bee9c8a336 100644 --- a/Gemfile +++ b/Gemfile @@ -60,6 +60,7 @@ gem 'sass-rails' gem 'truncate_html' gem 'unicorn' +gem 'actionpack-action_caching' # AMS is pinned to 0.8.4 because 0.9.x is a complete re-write, as is 0.10.x # Once Rails is updated to 5.x we should bump directly to 0.10.x gem "active_model_serializers", "0.8.4" diff --git a/Gemfile.lock b/Gemfile.lock index 90cd4a831d..8c15cadb3d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -90,6 +90,8 @@ GEM erubis (~> 2.7.0) rack (~> 1.5.2) rack-test (~> 0.6.2) + actionpack-action_caching (1.2.1) + actionpack (>= 4.0.0) active_model_serializers (0.8.4) activemodel (>= 3.0) activemerchant (1.78.0) @@ -687,6 +689,7 @@ PLATFORMS ruby DEPENDENCIES + actionpack-action_caching active_model_serializers (= 0.8.4) activemerchant (~> 1.78.0) activerecord-import From 758d7c82f77047e6f487fbe6a735044a3b39b051 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 19 May 2020 12:20:23 +0100 Subject: [PATCH 260/507] Rename order_cycle.accessible_by to remove name clash with active record --- app/controllers/admin/order_cycles_controller.rb | 2 +- app/controllers/spree/admin/reports_controller.rb | 2 +- app/models/order_cycle.rb | 2 +- app/models/spree/ability_decorator.rb | 4 ++-- .../reports/enterprise_fee_summary/permissions.rb | 2 +- spec/models/order_cycle_spec.rb | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 4a3ad149cb..b9e0d97b48 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -145,7 +145,7 @@ module Admin preload(:schedules). ransack(params[:q]). result. - accessible_by(spree_current_user) + visible_by(spree_current_user) end def load_data_for_index diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index 9583fe7134..54f2868610 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -255,7 +255,7 @@ module Spree def my_order_cycles OrderCycle. active_or_complete. - accessible_by(spree_current_user). + visible_by(spree_current_user). order('orders_close_at DESC') end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 7b4d8f2161..cadf222c34 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -70,7 +70,7 @@ class OrderCycle < ActiveRecord::Base } # Return order cycles that user coordinates, sends to or receives from - scope :accessible_by, lambda { |user| + scope :visible_by, lambda { |user| if user.has_spree_role?('admin') scoped else diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index dccfd4d756..f5e4e5f8b4 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -39,7 +39,7 @@ class AbilityDecorator # OR if they manage a producer which is included in any order cycles def can_manage_order_cycles?(user) can_manage_orders?(user) || - OrderCycle.accessible_by(user).any? + OrderCycle.visible_by(user).any? end # Users can manage orders if they have a sells own/any enterprise. @@ -193,7 +193,7 @@ class AbilityDecorator def add_order_cycle_management_abilities(user) can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle| - OrderCycle.accessible_by(user).include? order_cycle + OrderCycle.visible_by(user).include? order_cycle end can [:admin, :index, :create], Schedule can [:admin, :update, :destroy], Schedule do |schedule| diff --git a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb index 2077931627..95ce055f24 100644 --- a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb +++ b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb @@ -3,7 +3,7 @@ module OrderManagement module EnterpriseFeeSummary class Permissions < ::Reports::Permissions def allowed_order_cycles - @allowed_order_cycles ||= OrderCycle.accessible_by(user) + @allowed_order_cycles ||= OrderCycle.visible_by(user) end def allowed_distributors diff --git a/spec/models/order_cycle_spec.rb b/spec/models/order_cycle_spec.rb index 22cfeb2b70..505718a8ba 100644 --- a/spec/models/order_cycle_spec.rb +++ b/spec/models/order_cycle_spec.rb @@ -65,8 +65,8 @@ describe OrderCycle do oc_received = create(:simple_order_cycle, distributors: [e2]) oc_not_accessible = create(:simple_order_cycle, coordinator: e1) - expect(OrderCycle.accessible_by(user)).to include(oc_coordinated, oc_sent, oc_received) - expect(OrderCycle.accessible_by(user)).not_to include(oc_not_accessible) + expect(OrderCycle.visible_by(user)).to include(oc_coordinated, oc_sent, oc_received) + expect(OrderCycle.visible_by(user)).not_to include(oc_not_accessible) end it "finds the most recently closed order cycles" do From 16f2c8d7d1461e9130f07671f8505b76c4cff3ea Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Wed, 20 May 2020 14:13:42 +1000 Subject: [PATCH 261/507] Removed 5 keys per change request in ref to pr5425 --- config/locales/en.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index ffb45a5d7d..a41dec9d7d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2380,11 +2380,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using shipping: "Shipping" shipping_methods: "Shipping Methods" payment_methods: "Payment Methods" - provider_settings: "Provider Settings" - active: "Active" - description: "Description" - tags: "Tags" - provider: "Provider" payment_method_fee: "Transaction fee" payment_processing_failed: "Payment could not be processed, please check the details you entered" payment_method_not_supported: "That payment method is unsupported. Please choose another one." From ed14a92c7b7a9792de574a391f895bda1bfb6dcb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 11 May 2020 17:28:51 +0100 Subject: [PATCH 262/507] Make OC selector wider to support more characters where there is enough space for that --- app/assets/stylesheets/darkswarm/_shop-navigation.css.scss | 6 +++++- .../stylesheets/darkswarm/distributor_header.css.scss | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index 95bd6b1059..04deec214c 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -71,7 +71,7 @@ ordercycle { select, p { - width: inherit; + width: 200px; display: inline-block; color: $white; background-color: transparent; @@ -89,6 +89,10 @@ ordercycle { width: 100%; min-width: 0; } + + @media all and (min-width: 640px) and (max-width: 1024px), (min-width: 1200px) { + width: 250px; + } } option { diff --git a/app/assets/stylesheets/darkswarm/distributor_header.css.scss b/app/assets/stylesheets/darkswarm/distributor_header.css.scss index 8e9ebf769b..7df15dfcc4 100644 --- a/app/assets/stylesheets/darkswarm/distributor_header.css.scss +++ b/app/assets/stylesheets/darkswarm/distributor_header.css.scss @@ -20,10 +20,6 @@ section { padding: 30px 0 0; position: relative; - select { - width: 200px; - } - img { display: block; height: 100px; From b2bfe28173e930ee44784ce9979a9114d6e64b25 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 11 May 2020 17:35:03 +0100 Subject: [PATCH 263/507] Remove extra right pad on OC selector, in mobile, this will make the selector be centered --- app/assets/stylesheets/darkswarm/_shop-navigation.css.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index 04deec214c..355b84b8ac 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -111,6 +111,7 @@ ordercycle { @include breakpoint(mobile) { display: flex; + margin-right: 0; } } From 12f512e98b4ebbc36d6400ef94978b4005164e4f Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 11 May 2020 17:56:27 +0100 Subject: [PATCH 264/507] Move arrow on OC selector a little to the right so it's centered between end of text (if max length reached) and border --- app/assets/stylesheets/darkswarm/_shop-navigation.css.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index 355b84b8ac..2f1d919db6 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -76,13 +76,14 @@ ordercycle { color: $white; background-color: transparent; border: 0; + border-radius: 0 $radius-small $radius-small 0; margin-bottom: 0; font-size: 1em; line-height: 1.3em; padding: 0.5em 1.25em 0.5em 0.75em; height: 2.35em; - background-size: 30px auto; - border-radius: 0 $radius-small $radius-small 0; + background-position-x: 102%; + background-size: 30px auto; min-width: 13em; @include breakpoint(mobile) { From 53c0bcbd0bdda1bfef740dfd0b32dd306b352a72 Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Fri, 22 May 2020 13:22:57 +1000 Subject: [PATCH 265/507] Changed translation syntax to normal t() call and lazy lookup. --- app/views/spree/admin/variants/_autocomplete.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/admin/variants/_autocomplete.js.erb b/app/views/spree/admin/variants/_autocomplete.js.erb index 527b55568c..d4bd8a68b5 100644 --- a/app/views/spree/admin/variants/_autocomplete.js.erb +++ b/app/views/spree/admin/variants/_autocomplete.js.erb @@ -57,7 +57,7 @@ {{else}} - <%= Spree.t(:out_of_stock) %> + <%= t('admin.subscriptions.stock.out_of_stock') %> 0 {{/if}} From 04ffe7b91118b9a54889f86780e382821c20fbb1 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 14:20:49 +0200 Subject: [PATCH 266/507] Fix expectations and mock responses for Rails 4 Mocking these objects is working differently in Rails 4, and utilising `#and_call_original` helped to ensure different parts of the codebase were receiving the correct response objects (AR relations, etc). --- spec/features/consumer/caching/darkwarm_caching_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/consumer/caching/darkwarm_caching_spec.rb b/spec/features/consumer/caching/darkwarm_caching_spec.rb index d32ebb8b9e..a8e1eabbbe 100644 --- a/spec/features/consumer/caching/darkwarm_caching_spec.rb +++ b/spec/features/consumer/caching/darkwarm_caching_spec.rb @@ -18,8 +18,8 @@ feature "Darkswarm data caching", js: true, caching: true do describe "caching injected taxons and properties" do it "caches taxons and properties" do - expect(Spree::Taxon).to receive(:all) { [taxon] } - expect(Spree::Property).to receive(:all) { [property] } + expect(Spree::Taxon).to receive(:all).at_least(:once).and_call_original + expect(Spree::Property).to receive(:all).at_least(:once).and_call_original visit shops_path From a9abe48edef98d0097e72541a0c39628a79121c1 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 14:21:24 +0200 Subject: [PATCH 267/507] Re-enable cache invalidation test --- spec/features/consumer/caching/darkwarm_caching_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/consumer/caching/darkwarm_caching_spec.rb b/spec/features/consumer/caching/darkwarm_caching_spec.rb index a8e1eabbbe..026039e686 100644 --- a/spec/features/consumer/caching/darkwarm_caching_spec.rb +++ b/spec/features/consumer/caching/darkwarm_caching_spec.rb @@ -29,7 +29,7 @@ feature "Darkswarm data caching", js: true, caching: true do visit shops_path end - xit "invalidates caches for taxons and properties" do + it "invalidates caches for taxons and properties" do visit shops_path taxon_timestamp1 = CacheService.latest_timestamp_by_class(Spree::Taxon) From b00fbd69aecfe9aa1d439e89eb185f3dca887db1 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 13:44:27 +0200 Subject: [PATCH 268/507] Update Fragment Caching for Rails 4 Rails 4 introduced "automagically" modified cache keys, that included a digest in the key on any cache entry related to views. This is not what we want at all, fixed here with the `skip_digest: true` option. --- app/services/cache_service.rb | 18 ++++++++++++------ app/views/layouts/darkswarm.html.haml | 4 ++-- .../consumer/caching/darkwarm_caching_spec.rb | 8 ++++---- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/app/services/cache_service.rb b/app/services/cache_service.rb index 1963b2f1dc..dc3a7fac0e 100644 --- a/app/services/cache_service.rb +++ b/app/services/cache_service.rb @@ -37,25 +37,31 @@ class CacheService # Rails' caching in views is called "Fragment Caching" and uses some slightly different logic. # Note: keys supplied here are actually prepended with "views/" under the hood. - def self.ams_all_taxons_key - "inject-all-taxons-#{CacheService.latest_timestamp_by_class(Spree::Taxon)}" + def self.ams_all_taxons + [ + "inject-all-taxons-#{CacheService.latest_timestamp_by_class(Spree::Taxon)}", + { skip_digest: true } + ] end - def self.ams_all_properties_key - "inject-all-properties-#{CacheService.latest_timestamp_by_class(Spree::Property)}" + def self.ams_all_properties + [ + "inject-all-properties-#{CacheService.latest_timestamp_by_class(Spree::Property)}", + { skip_digest: true } + ] end def self.ams_shops [ "shops/index/inject_enterprises", - { expires_in: SHOPS_EXPIRY } + { expires_in: SHOPS_EXPIRY, skip_digest: true } ] end def self.ams_shop(enterprise) [ "enterprises/shop/inject_enterprise_shopfront-#{enterprise.id}", - { expires_in: SHOPS_EXPIRY } + { expires_in: SHOPS_EXPIRY, skip_digest: true } ] end end diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index 3986d9ace8..fc282d5c6e 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -48,9 +48,9 @@ = inject_current_hub = inject_current_user = inject_rails_flash - - cache CacheService::FragmentCaching.ams_all_taxons_key do + - cache(*CacheService::FragmentCaching.ams_all_taxons) do = inject_taxons - - cache CacheService::FragmentCaching.ams_all_properties_key do + - cache(*CacheService::FragmentCaching.ams_all_properties) do = inject_properties = inject_current_order = inject_currency_config diff --git a/spec/features/consumer/caching/darkwarm_caching_spec.rb b/spec/features/consumer/caching/darkwarm_caching_spec.rb index 026039e686..e53f63ed32 100644 --- a/spec/features/consumer/caching/darkwarm_caching_spec.rb +++ b/spec/features/consumer/caching/darkwarm_caching_spec.rb @@ -33,10 +33,10 @@ feature "Darkswarm data caching", js: true, caching: true do visit shops_path taxon_timestamp1 = CacheService.latest_timestamp_by_class(Spree::Taxon) - expect_cached "views/#{CacheService::FragmentCaching.ams_all_taxons_key}" + expect_cached "views/#{CacheService::FragmentCaching.ams_all_taxons[0]}" property_timestamp1 = CacheService.latest_timestamp_by_class(Spree::Property) - expect_cached "views/#{CacheService::FragmentCaching.ams_all_properties_key}" + expect_cached "views/#{CacheService::FragmentCaching.ams_all_properties[0]}" toggle_filters @@ -54,10 +54,10 @@ feature "Darkswarm data caching", js: true, caching: true do visit shops_path taxon_timestamp2 = CacheService.latest_timestamp_by_class(Spree::Taxon) - expect_cached "views/#{CacheService::FragmentCaching.ams_all_taxons_key}" + expect_cached "views/#{CacheService::FragmentCaching.ams_all_taxons[0]}" property_timestamp2 = CacheService.latest_timestamp_by_class(Spree::Property) - expect_cached "views/#{CacheService::FragmentCaching.ams_all_properties_key}" + expect_cached "views/#{CacheService::FragmentCaching.ams_all_properties[0]}" expect(taxon_timestamp1).to_not eq taxon_timestamp2 expect(property_timestamp1).to_not eq property_timestamp2 From e339a37cd5bbf1fe4d1197832a29471ee12c7aed Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 22 May 2020 14:10:23 +0200 Subject: [PATCH 269/507] Allow to create order_cycle_schedules There's no way we can create an order_cycle_schedules if the schedule doesn't have an id, which we can't get if to persist it we need an OC first, which in turn, will create an order_cycle_schedules. --- app/models/schedule.rb | 3 +-- spec/factories.rb | 11 ++++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/models/schedule.rb b/app/models/schedule.rb index c28b9ae029..5fe5da3205 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -3,9 +3,8 @@ class Schedule < ActiveRecord::Base has_many :order_cycles, through: :order_cycle_schedules has_many :order_cycle_schedules, dependent: :destroy - has_many :coordinators, -> { uniq }, through: :order_cycles - validates :order_cycles, presence: true + has_many :coordinators, -> { uniq }, through: :order_cycles scope :with_coordinator, lambda { |enterprise| joins(:order_cycles).where('coordinator_id = ?', enterprise.id).select('DISTINCT schedules.*') } diff --git a/spec/factories.rb b/spec/factories.rb index 32caef0f4f..d13757cb2a 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -28,7 +28,16 @@ FactoryBot.define do factory :schedule, class: Schedule do sequence(:name) { |n| "Schedule #{n}" } - order_cycles { [OrderCycle.first || FactoryBot.create(:simple_order_cycle)] } + + transient do + order_cycles { [OrderCycle.first || create(:simple_order_cycle)] } + end + + before(:create) do |schedule, evaluator| + evaluator.order_cycles.each do |order_cycle| + order_cycle.schedules << schedule + end + end end factory :proxy_order, class: ProxyOrder do From f0525b861c4d701101cc7a2fb2eee8fa4353af29 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 14:54:57 +0200 Subject: [PATCH 270/507] Update expectations in API caching test Rails 4 has slightly changed the format of the cache keys here, so the response was not as expected. --- spec/features/consumer/caching/shops_caching_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/consumer/caching/shops_caching_spec.rb b/spec/features/consumer/caching/shops_caching_spec.rb index 654a2f4524..c525e569d9 100644 --- a/spec/features/consumer/caching/shops_caching_spec.rb +++ b/spec/features/consumer/caching/shops_caching_spec.rb @@ -47,8 +47,8 @@ feature "Shops caching", js: true, caching: true do let(:exchange) { order_cycle.exchanges.to_enterprises(distributor).outgoing.first } let(:test_domain) { "#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}" } - let(:taxons_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/taxons?distributor=#{distributor.id}" } - let(:properties_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/properties?distributor=#{distributor.id}" } + let(:taxons_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/taxons?distributor=#{distributor.id}.json" } + let(:properties_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/properties?distributor=#{distributor.id}.json" } let(:options) { { expires_in: CacheService::FILTERS_EXPIRY } } before do From d9686d698238ae3473ed92310fab0d23fa181704 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 22 May 2020 15:54:30 +0200 Subject: [PATCH 271/507] Enable spec files to be executed alone This fixes the annoying error ``` NameError: uninitialized constant OrderManagement::Subscriptions::Whatever ``` and let's you execute the spec file in isolation. It slows down way too much having the run the entire engine test suite while developing. And it makes me nervous too. --- .../spec/services/order_management/subscriptions/count_spec.rb | 2 ++ .../services/order_management/subscriptions/estimator_spec.rb | 2 ++ .../order_management/subscriptions/proxy_order_syncer_spec.rb | 2 ++ .../services/order_management/subscriptions/summary_spec.rb | 2 ++ 4 files changed, 8 insertions(+) diff --git a/engines/order_management/spec/services/order_management/subscriptions/count_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/count_spec.rb index 14b5a8c041..75b4e47111 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/count_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/count_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'spec_helper' + module OrderManagement module Subscriptions describe Count do diff --git a/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb index e8fe7bf957..63032465d6 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'spec_helper' + module OrderManagement module Subscriptions describe Estimator do diff --git a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb index 501f6fa67e..fc14e7ff4b 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'spec_helper' + module OrderManagement module Subscriptions describe ProxyOrderSyncer do diff --git a/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb index 5e6360c542..454e2e5ba3 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'spec_helper' + module OrderManagement module Subscriptions describe Summary do From a33396984f49fc28011e0cd1289eab230bd2f6cc Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 22 May 2020 17:56:01 +0200 Subject: [PATCH 272/507] Fix and DRY specs --- .../subscriptions/proxy_order_syncer_spec.rb | 162 +++++++++++++----- 1 file changed, 120 insertions(+), 42 deletions(-) diff --git a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb index fc14e7ff4b..5a352f49ec 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -18,59 +18,51 @@ module OrderManagement describe "#sync!" do let(:now) { Time.zone.now } - let(:schedule) { create(:schedule) } - let(:closed_oc) { # Closed - create(:simple_order_cycle, schedules: [schedule], - orders_open_at: now - 1.minute, - orders_close_at: now) + let(:schedule) { create(:schedule, order_cycles: [oc]) } + + let(:closed_oc) { + create(:simple_order_cycle, orders_open_at: now - 1.minute, orders_close_at: now) } let(:open_oc_closes_before_begins_at_oc) { # Open, but closes before begins at - create(:simple_order_cycle, schedules: [schedule], - orders_open_at: now - 1.minute, - orders_close_at: now + 59.seconds) + create(:simple_order_cycle, orders_open_at: now - 1.minute, orders_close_at: now + 59.seconds) } let(:open_oc) { # Open & closes between begins at and ends at - create(:simple_order_cycle, schedules: [schedule], - orders_open_at: now - 1.minute, - orders_close_at: now + 90.seconds) + create(:simple_order_cycle, orders_open_at: now - 1.minute, orders_close_at: now + 90.seconds) } let(:upcoming_closes_before_begins_at_oc) { # Upcoming, but closes before begins at - create(:simple_order_cycle, schedules: [schedule], - orders_open_at: now + 30.seconds, - orders_close_at: now + 59.seconds) + create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 59.seconds) } let(:upcoming_closes_on_begins_at_oc) { # Upcoming & closes on begins at - create(:simple_order_cycle, schedules: [schedule], - orders_open_at: now + 30.seconds, - orders_close_at: now + 1.minute) + create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 1.minute) } let(:upcoming_closes_on_ends_at_oc) { # Upcoming & closes on ends at - create(:simple_order_cycle, schedules: [schedule], - orders_open_at: now + 30.seconds, - orders_close_at: now + 2.minutes) + create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 2.minutes) } let(:upcoming_closes_after_ends_at_oc) { # Upcoming & closes after ends at - create(:simple_order_cycle, schedules: [schedule], - orders_open_at: now + 30.seconds, - orders_close_at: now + 121.seconds) + create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 121.seconds) } + let(:subscription) { - build(:subscription, schedule: schedule, - begins_at: now + 1.minute, - ends_at: now + 2.minutes) + build(:subscription, begins_at: now + 1.minute, ends_at: now + 2.minutes) } let(:proxy_orders) { subscription.reload.proxy_orders } let(:order_cycles) { proxy_orders.map(&:order_cycle) } let(:syncer) { ProxyOrderSyncer.new(subscription) } context "when the subscription is not persisted" do - before do - oc # Ensure oc is created before we attempt to sync - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) + let(:schedule) { create(:schedule, order_cycles: [oc]) } + let(:subscription) do + build( + :subscription, + begins_at: now + 1.minute, + ends_at: now + 2.minutes, + schedule: schedule + ) end context "and the schedule includes a closed oc (ie. closed before opens_at)" do - let(:oc) { closed_oc } + let!(:oc) { closed_oc } + it "does not create a new proxy order for that oc" do expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc @@ -78,7 +70,8 @@ module OrderManagement end context "and the schedule includes an open oc that closes before begins_at" do - let(:oc) { open_oc_closes_before_begins_at_oc } + let!(:oc) { open_oc_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc @@ -86,15 +79,19 @@ module OrderManagement end context "and the schedule has an open OC that closes between begins_at and ends_at" do - let(:oc) { open_oc } + let!(:oc) { open_oc } + it "creates a new proxy order for that oc" do + syncer.sync! + expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc + expect(subscription.reload.proxy_orders.map(&:order_cycle)).to include oc end end context "and the schedule includes upcoming oc that closes before begins_at" do - let(:oc) { upcoming_closes_before_begins_at_oc } + let!(:oc) { upcoming_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc @@ -102,23 +99,50 @@ module OrderManagement end context "and the schedule includes upcoming oc that closes on begins_at" do - let(:oc) { upcoming_closes_on_begins_at_oc } + let!(:oc) { upcoming_closes_on_begins_at_oc } + + let(:schedule) { create(:schedule, order_cycles: [oc]) } + let(:subscription) do + build( + :subscription, + begins_at: now + 1.minute, + ends_at: now + 2.minutes, + schedule: schedule + ) + end + let(:syncer) { ProxyOrderSyncer.new(subscription) } + it "creates a new proxy order for that oc" do + syncer.sync! + expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc + expect(subscription.reload.proxy_orders.map(&:order_cycle)).to include oc end end context "and the schedule includes upcoming oc that closes after ends_at" do - let(:oc) { upcoming_closes_on_ends_at_oc } + let!(:oc) { upcoming_closes_on_ends_at_oc } + it "creates a new proxy order for that oc" do + schedule = create(:schedule, order_cycles: [oc]) + subscription = build( + :subscription, + begins_at: now + 1.minute, + ends_at: now + 2.minutes, + schedule: schedule + ) + + syncer = ProxyOrderSyncer.new(subscription) + syncer.sync! + expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc + expect(subscription.reload.proxy_orders.map(&:order_cycle)).to include oc end end context "and the schedule includes upcoming oc that closes after ends_at" do - let(:oc) { upcoming_closes_after_ends_at_oc } + let!(:oc) { upcoming_closes_after_ends_at_oc } + it "does not create a new proxy order for that oc" do expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc @@ -212,7 +236,19 @@ module OrderManagement context "and the oc is open and closes between begins_at and ends_at" do let(:oc) { open_oc } + it "keeps the proxy order" do + schedule = create(:schedule, order_cycles: [oc]) + subscription = build( + :subscription, + begins_at: now + 1.minute, + ends_at: now + 2.minutes, + schedule: schedule + ) + + syncer = ProxyOrderSyncer.new(subscription) + syncer.sync! + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) expect(proxy_orders).to include proxy_order end @@ -228,7 +264,19 @@ module OrderManagement context "and the oc is upcoming and closes on begins_at" do let(:oc) { upcoming_closes_on_begins_at_oc } + it "keeps the proxy order" do + schedule = create(:schedule, order_cycles: [oc]) + subscription = build( + :subscription, + begins_at: now + 1.minute, + ends_at: now + 2.minutes, + schedule: schedule + ) + + syncer = ProxyOrderSyncer.new(subscription) + syncer.sync! + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) expect(proxy_orders).to include proxy_order end @@ -236,7 +284,19 @@ module OrderManagement context "and the oc is upcoming and closes on ends_at" do let(:oc) { upcoming_closes_on_ends_at_oc } + it "keeps the proxy order" do + schedule = create(:schedule, order_cycles: [oc]) + subscription = build( + :subscription, + begins_at: now + 1.minute, + ends_at: now + 2.minutes, + schedule: schedule + ) + + syncer = ProxyOrderSyncer.new(subscription) + syncer.sync! + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) expect(proxy_orders).to include proxy_order end @@ -376,8 +436,20 @@ module OrderManagement end context "when a proxy order does not exist" do + let(:schedule) { create(:schedule, order_cycles: [oc]) } + let(:subscription) do + create( + :subscription, + begins_at: now + 1.minute, + ends_at: now + 2.minutes, + schedule: schedule + ) + end + let(:syncer) { ProxyOrderSyncer.new(subscription) } + context "and the schedule includes a closed oc (ie. closed before opens_at)" do let!(:oc) { closed_oc } + it "does not create a new proxy order for that oc" do expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc @@ -386,6 +458,7 @@ module OrderManagement context "and the schedule includes an open oc that closes before begins_at" do let(:oc) { open_oc_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc @@ -394,14 +467,16 @@ module OrderManagement context "and the schedule has an open oc that closes between begins_at and ends_at" do let!(:oc) { open_oc } + it "creates a new proxy order for that oc" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc + expect(subscription.reload.proxy_orders.map(&:order_cycle)).to include oc end end context "and the schedule includes upcoming oc that closes before begins_at" do let!(:oc) { upcoming_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc @@ -410,22 +485,25 @@ module OrderManagement context "and the schedule includes upcoming oc that closes on begins_at" do let!(:oc) { upcoming_closes_on_begins_at_oc } + it "creates a new proxy order for that oc" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc + expect(subscription.reload.proxy_orders.map(&:order_cycle)).to include oc end end context "and the schedule includes upcoming oc that closes on ends_at" do let!(:oc) { upcoming_closes_on_ends_at_oc } + it "creates a new proxy order for that oc" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc + expect(subscription.reload.proxy_orders.map(&:order_cycle)).to include oc end end context "and the schedule includes upcoming oc that closes after ends_at" do let!(:oc) { upcoming_closes_after_ends_at_oc } + it "does not create a new proxy order for that oc" do expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) expect(order_cycles).to_not include oc From b2b988b0636eb5b7200ba4805bae48df1cb973e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Sun, 24 May 2020 14:41:40 +0200 Subject: [PATCH 273/507] Apply new order directly inside service --- app/services/bulk_invoice_service.rb | 7 +++++-- spec/services/bulk_invoice_service_spec.rb | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/services/bulk_invoice_service.rb b/app/services/bulk_invoice_service.rb index 18921bd413..ab69df03ca 100644 --- a/app/services/bulk_invoice_service.rb +++ b/app/services/bulk_invoice_service.rb @@ -7,9 +7,8 @@ class BulkInvoiceService def start_pdf_job(order_ids) pdf = CombinePDF.new - orders = Spree::Order.where(id: order_ids) - orders.each do |order| + orders_from(order_ids).each do |order| invoice = renderer.render_to_string(order) pdf << CombinePDF.parse(invoice) @@ -29,6 +28,10 @@ class BulkInvoiceService private + def orders_from(order_ids) + Spree::Order.where(id: order_ids).order("completed_at DESC") + end + def new_invoice_id Time.zone.now.to_i.to_s end diff --git a/spec/services/bulk_invoice_service_spec.rb b/spec/services/bulk_invoice_service_spec.rb index 4056a1b88f..1874a0fcb4 100644 --- a/spec/services/bulk_invoice_service_spec.rb +++ b/spec/services/bulk_invoice_service_spec.rb @@ -47,4 +47,11 @@ describe BulkInvoiceService do expect(filepath).to eq 'tmp/invoices/1234567.pdf' end end + + describe "#orders_from" do + it "orders with completed desc" do + expect(service.send(:orders_from, [1, 2]).to_sql) + .to include('ORDER BY completed_at DESC') + end + end end From e03005ed568369c97fd1a369a05b2cafe237c8c4 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 25 May 2020 13:52:56 +0200 Subject: [PATCH 274/507] Fix maps and tidy up groups map code --- .../darkswarm/controllers/group_page_controller.js.coffee | 5 +---- app/views/groups/show.html.haml | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee index 7b44cb749b..ff7a695777 100644 --- a/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee @@ -1,6 +1,3 @@ -Darkswarm.controller "GroupPageCtrl", ($scope, enterprises, Enterprises, MapConfiguration, OfnMap) -> +Darkswarm.controller "GroupPageCtrl", ($scope, enterprises, Enterprises) -> $scope.Enterprises = Enterprises - - $scope.map = angular.copy MapConfiguration.options - $scope.mapMarkers = OfnMap.enterprise_markers enterprises $scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1 diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index e8318faef9..654dfac11e 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -33,11 +33,11 @@ active: "tabs.map.active", select: "select(\'map\')"} .map-container - %map{"ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"} + %map{"ng-controller" => "MapCtrl", "ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"} %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} %map-osm-tiles %map-search - %ui-gmap-markers{models: "mapMarkers", fit: "true", + %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", coords: "'self'", icon: "'icon'", click: "'reveal'"} %tab{heading: t(:groups_about), From a3660dfe377d9577706970dee6817d23582eef2e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 25 May 2020 14:04:11 +0200 Subject: [PATCH 275/507] Extract repeated map code to new partial --- app/views/groups/show.html.haml | 9 ++------- app/views/map/index.html.haml | 8 +------- app/views/shared/_map.html.haml | 8 ++++++++ 3 files changed, 11 insertions(+), 14 deletions(-) create mode 100644 app/views/shared/_map.html.haml diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 654dfac11e..fba9eb9005 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -32,13 +32,8 @@ %tab{heading: t(:label_map), active: "tabs.map.active", select: "select(\'map\')"} - .map-container - %map{"ng-controller" => "MapCtrl", "ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"} - %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} - %map-osm-tiles - %map-search - %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", - coords: "'self'", icon: "'icon'", click: "'reveal'"} + %div{"ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"} + = render partial: "shared/map" %tab{heading: t(:groups_about), active: "tabs.about.active", diff --git a/app/views/map/index.html.haml b/app/views/map/index.html.haml index 294fa45f8e..6f50bf757c 100644 --- a/app/views/map/index.html.haml +++ b/app/views/map/index.html.haml @@ -4,13 +4,7 @@ - content_for :injection_data do = inject_enterprise_shopfront_list -.map-container{"fill-vertical" => true} - %map{"ng-controller" => "MapCtrl"} - %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} - %map-osm-tiles - %map-search - %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", - coords: "'self'", icon: "'icon'", click: "'reveal'"} += render partial: "shared/map" .map-footer %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors diff --git a/app/views/shared/_map.html.haml b/app/views/shared/_map.html.haml new file mode 100644 index 0000000000..6f8016c81e --- /dev/null +++ b/app/views/shared/_map.html.haml @@ -0,0 +1,8 @@ +.map-container + %map{"ng-controller" => "MapCtrl"} + %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", + styles: "map.styles", draggable: "true"} + %map-osm-tiles + %map-search + %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", + coords: "'self'", icon: "'icon'", click: "'reveal'"} From 80953713044577390be6be8ab5ce24263d8d92eb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 25 May 2020 14:12:12 +0200 Subject: [PATCH 276/507] Ensure OpenStreetMap credits are aways shown with map and fix credits positioning for /groups page map display --- app/assets/stylesheets/darkswarm/map.css.scss | 5 +++++ app/views/map/index.html.haml | 3 --- app/views/shared/_map.html.haml | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/map.css.scss b/app/assets/stylesheets/darkswarm/map.css.scss index b0df5b66da..2af782f187 100644 --- a/app/assets/stylesheets/darkswarm/map.css.scss +++ b/app/assets/stylesheets/darkswarm/map.css.scss @@ -63,3 +63,8 @@ left: 0px; } } + +.tabs-content .map-footer { + position: relative; + bottom: 30px; +} diff --git a/app/views/map/index.html.haml b/app/views/map/index.html.haml index 6f50bf757c..9d074d31a9 100644 --- a/app/views/map/index.html.haml +++ b/app/views/map/index.html.haml @@ -5,6 +5,3 @@ = inject_enterprise_shopfront_list = render partial: "shared/map" - -.map-footer - %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors diff --git a/app/views/shared/_map.html.haml b/app/views/shared/_map.html.haml index 6f8016c81e..69f781a78c 100644 --- a/app/views/shared/_map.html.haml +++ b/app/views/shared/_map.html.haml @@ -6,3 +6,6 @@ %map-search %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", coords: "'self'", icon: "'icon'", click: "'reveal'"} + +.map-footer + %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors From 1e0e3a063dbb2a1cbd896cb8f6eda958ce0447af Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 25 May 2020 19:14:40 +0100 Subject: [PATCH 277/507] Add margin right to product modal title so that the close button doesnt overlap with it --- app/assets/stylesheets/darkswarm/_shop-modals.css.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss index ee380177d4..bb6b6480dc 100644 --- a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss @@ -2,7 +2,7 @@ padding-left: 1.5rem; h1, h2, h3, h4, h5, h6 { - margin: 0.2rem 0 0; + margin: 0.2rem 1.5rem 0 0; } span { From 513ee6393a997a5792a5ebcf3844e386a055601a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 25 May 2020 19:31:02 +0100 Subject: [PATCH 278/507] Make product modal display image on the right for medium screens like it was doing for large screens --- app/assets/javascripts/templates/product_modal.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 974c4cba71..77cff60e5f 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -1,5 +1,5 @@ .row - .columns.small-12.large-6.product-header + .columns.small-12.medium-6.large-6.product-header %h3{"ng-bind" => "::product.name"} %span %em {{'products_from' | t}} @@ -13,7 +13,7 @@ .product-description{"ng-if" => "product.description_html"} %p.text-small{"ng-bind-html" => "::product.description_html"} - .columns.small-12.large-6 + .columns.small-12.medium-6.large-6 %img.product-img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"} %img.product-img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"} From 2bb3cf1c54faff885a828202f9f2d0287273c4b8 Mon Sep 17 00:00:00 2001 From: Steve Roberts Date: Tue, 26 May 2020 09:53:51 +1000 Subject: [PATCH 279/507] Name checkbox element id var more informatively --- .../complex_editing_multiple_product_pages_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb index 7a9bd7317f..c74630121d 100644 --- a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb +++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb @@ -35,9 +35,9 @@ feature ' scenario "select all products" do # replace with scroll_to method when upgrading to Capybara >= 3.13.0 - cb_id = "order_cycle_incoming_exchange_0_select_all_variants" - page.execute_script("document.getElementById('#{cb_id}').scrollIntoView()") - check cb_id + checkbox_id = "order_cycle_incoming_exchange_0_select_all_variants" + page.execute_script("document.getElementById('#{checkbox_id}').scrollIntoView()") + check checkbox_id expect_all_products_loaded From 50a63139e3fb8d2bf8703ed76fb2911f1d2ba99b Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Tue, 26 May 2020 15:14:26 +1000 Subject: [PATCH 280/507] Changed translation syntax to normal t() call and lazy lookup. --- app/views/spree/admin/variants/_autocomplete.js.erb | 2 +- config/locales/en.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/spree/admin/variants/_autocomplete.js.erb b/app/views/spree/admin/variants/_autocomplete.js.erb index d4bd8a68b5..5ef095925c 100644 --- a/app/views/spree/admin/variants/_autocomplete.js.erb +++ b/app/views/spree/admin/variants/_autocomplete.js.erb @@ -57,7 +57,7 @@ {{else}} - <%= t('admin.subscriptions.stock.out_of_stock') %> + <%= t('.out_of_stock') %> 0 {{/if}} diff --git a/config/locales/en.yml b/config/locales/en.yml index e2a70ff412..2973475cae 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3368,6 +3368,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: From 953e1f8ff467bafe3b158f818fda5788367b4241 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 26 May 2020 12:59:51 +0200 Subject: [PATCH 281/507] Adjust z-index on overlapping elements to fix missing drop-shadow regression --- app/assets/stylesheets/darkswarm/distributor_header.css.scss | 2 +- app/assets/stylesheets/darkswarm/shop_tabs.css.scss | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/distributor_header.css.scss b/app/assets/stylesheets/darkswarm/distributor_header.css.scss index 8e9ebf769b..be64ef3914 100644 --- a/app/assets/stylesheets/darkswarm/distributor_header.css.scss +++ b/app/assets/stylesheets/darkswarm/distributor_header.css.scss @@ -11,7 +11,7 @@ section { display: block; background: $white; position: relative; - z-index: 2; + z-index: 20; .details { box-sizing: border-box; diff --git a/app/assets/stylesheets/darkswarm/shop_tabs.css.scss b/app/assets/stylesheets/darkswarm/shop_tabs.css.scss index e0ce5cc7b9..66bbb8998e 100644 --- a/app/assets/stylesheets/darkswarm/shop_tabs.css.scss +++ b/app/assets/stylesheets/darkswarm/shop_tabs.css.scss @@ -9,6 +9,7 @@ color: $dark-grey; box-shadow: $distributor-header-shadow; position: relative; + z-index: 10; .columns { display: flex; From bde4acd22f8dd60afbf214a7ff21287a935179ea Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 26 May 2020 15:19:45 +0200 Subject: [PATCH 282/507] Update get calls in DFC controller spec --- .../dfc_provider/api/products_controller_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb b/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb index c3f40a16a0..dfc0e076d6 100644 --- a/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb +++ b/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb @@ -31,7 +31,7 @@ describe DfcProvider::Api::ProductsController, type: :controller do context 'with an enterprise' do context 'given with an id' do context 'related to the user' do - before { get :index, enterprise_id: 'default' } + before { api_get :index, enterprise_id: 'default' } it 'is successful' do expect(response.status).to eq 200 @@ -47,14 +47,14 @@ describe DfcProvider::Api::ProductsController, type: :controller do let(:enterprise) { create(:enterprise) } it 'returns not_found head' do - get :index, enterprise_id: enterprise.id + api_get :index, enterprise_id: enterprise.id expect(response.status).to eq 404 end end end context 'as default' do - before { get :index, enterprise_id: 'default' } + before { api_get :index, enterprise_id: 'default' } it 'is successful' do expect(response.status).to eq 200 @@ -71,7 +71,7 @@ describe DfcProvider::Api::ProductsController, type: :controller do let(:enterprise) { create(:enterprise) } it 'returns not_found head' do - get :index, enterprise_id: 'default' + api_get :index, enterprise_id: 'default' expect(response.status).to eq 404 end end @@ -83,7 +83,7 @@ describe DfcProvider::Api::ProductsController, type: :controller do .to receive(:process) .and_return(nil) - get :index, enterprise_id: 'default' + api_get :index, enterprise_id: 'default' expect(response.status).to eq 401 end end @@ -91,7 +91,7 @@ describe DfcProvider::Api::ProductsController, type: :controller do context 'without an authorization token' do it 'returns unprocessable_entity head' do - get :index, enterprise_id: enterprise.id + api_get :index, enterprise_id: enterprise.id expect(response.status).to eq 422 end end From 89dd7ddb862f7a9a765f2d92022931ef164c3a01 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 26 May 2020 15:32:07 +0200 Subject: [PATCH 283/507] Update setting of request headers in DFC controller spec --- .../controllers/dfc_provider/api/products_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb b/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb index dfc0e076d6..6bbf9a1ab9 100644 --- a/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb +++ b/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb @@ -18,7 +18,7 @@ describe DfcProvider::Api::ProductsController, type: :controller do describe('.index') do context 'with authorization token' do before do - request.env['Authorization'] = 'Bearer 123456.abcdef.123456' + request.headers['Authorization'] = 'Bearer 123456.abcdef.123456' end context 'with an authenticated user' do From 6f0106251ef3328a7c29e5d3ca9a1a8da6e3bbe7 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 27 May 2020 19:16:31 +0100 Subject: [PATCH 284/507] Move product-img css class to parent div so we can center align it and keep existing img styling --- .../templates/product_modal.html.haml | 6 ++--- .../stylesheets/darkswarm/images.css.scss | 22 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 77cff60e5f..9c65bbbad7 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -13,8 +13,8 @@ .product-description{"ng-if" => "product.description_html"} %p.text-small{"ng-bind-html" => "::product.description_html"} - .columns.small-12.medium-6.large-6 - %img.product-img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"} - %img.product-img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"} + .columns.small-12.medium-6.large-6.product-img + %img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"} + %img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"} %ng-include{src: "'partials/close.html'"} diff --git a/app/assets/stylesheets/darkswarm/images.css.scss b/app/assets/stylesheets/darkswarm/images.css.scss index ba3c34cde3..739914d709 100644 --- a/app/assets/stylesheets/darkswarm/images.css.scss +++ b/app/assets/stylesheets/darkswarm/images.css.scss @@ -3,19 +3,23 @@ @import "branding"; .product-img { - padding: 0.3rem; + text-align: center; - // placeholder for when no product images - &.placeholder { - opacity: 0.35; + img { + padding: 0.3rem; - @include breakpoint(desktop) { - display: none; + // placeholder for when no product images + &.placeholder { + opacity: 0.35; + + @include breakpoint(desktop) { + display: none; + } } - } - @media only screen and (max-width: 1024px) { - margin: 0 0 0.5rem; + @media only screen and (max-width: 1024px) { + margin: 0 0 0.5rem; + } } } From 8632383e60c89bd886bb8e63a7fd1e8c5c3cb525 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 27 May 2020 20:23:11 +0000 Subject: [PATCH 285/507] Bump ddtrace from 0.35.2 to 0.36.0 Bumps [ddtrace](https://github.com/DataDog/dd-trace-rb) from 0.35.2 to 0.36.0. - [Release notes](https://github.com/DataDog/dd-trace-rb/releases) - [Changelog](https://github.com/DataDog/dd-trace-rb/blob/master/CHANGELOG.md) - [Commits](https://github.com/DataDog/dd-trace-rb/compare/v0.35.2...v0.36.0) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 12760634af..9d9abea37e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -203,7 +203,7 @@ GEM activerecord (>= 3.2.0, < 5.0) fog (~> 1.0) rails (>= 3.2.0, < 5.0) - ddtrace (0.35.2) + ddtrace (0.36.0) msgpack debugger-linecache (1.2.0) delayed_job (4.1.8) From ea7a2c91ee1153cf2a8d4bca138bf6edcc834b6c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 28 May 2020 13:12:12 +0200 Subject: [PATCH 286/507] Update all locales with the latest Transifex translations --- config/locales/en_CA.yml | 8 +++--- config/locales/fil_PH.yml | 60 +++++++++++++++++++-------------------- config/locales/fr.yml | 2 +- config/locales/pt_BR.yml | 30 ++++++++++---------- config/locales/tr.yml | 20 ++++++------- 5 files changed, 60 insertions(+), 60 deletions(-) diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 8071cfb4a9..754329f66f 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -1213,7 +1213,7 @@ en_CA: menu_2_url: "/map" menu_3_title: "Producers" menu_3_url: "/producers" - menu_4_title: "Markets" + menu_4_title: "Groups" menu_4_url: "/groups" menu_5_title: "About" menu_5_url: "https://about.openfoodnetwork.ca" @@ -1269,7 +1269,7 @@ en_CA: label_map: "Map" label_producer: "Producer" label_producers: "Producers" - label_groups: "Groups" + label_groups: "Markets" label_about: "About" label_connect: "Connect" label_learn: "Learn" @@ -1567,9 +1567,9 @@ en_CA: components_profiles_show: "Show profiles" components_filters_nofilters: "No filters" components_filters_clearfilters: "Clear all filters" - groups_title: Groups + groups_title: Markets groups_headline: 'Markets / Regions ' - groups_text: "Every producer is unique. Every business has something different to offer. Our groups are collectives of producers, hubs and distributors who share something in common like location, farmers market or philosophy. This makes your shopping experience easier. So explore our groups and have the curating done for you." + groups_text: "Markets are collectives of producers, hubs and distributors who share something in common like location, farmers market or philosophy. This makes your shopping experience easier. So explore our groups and have the curating done for you." groups_search: "Search name or keyword" groups_no_groups: "No groups found" groups_about: "About Us" diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index 25d2da2a32..5a0a66e6df 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -1982,14 +1982,14 @@ fil_PH: spree_admin_overview_enterprises_header: "ang aking mga enterprise" spree_admin_overview_enterprises_footer: "PAMAHALAAN ANG AKING MGA ENTERPRISE" spree_admin_enterprises_hubs_name: "pangalan" - spree_admin_enterprises_create_new: "GUMAWA NG BAGO" + spree_admin_enterprises_create_new: "LUMIKHA NG BAGO" spree_admin_enterprises_shipping_methods: "mga paraan ng pagpapadala" spree_admin_enterprises_fees: "bayad para sa enterprise" - spree_admin_enterprises_none_create_a_new_enterprise: "GUMAWA NG BAGONG ENTERPRISE" + spree_admin_enterprises_none_create_a_new_enterprise: "LUMIKHA NG BAGONG ENTERPRISE" spree_admin_enterprises_none_text: "wala ka pang mga enterprise" spree_admin_enterprises_tabs_hubs: "MGA HUB" spree_admin_enterprises_producers_manage_products: "PAMAHALAAN ANG MGA PRODUKTO" - spree_admin_enterprises_create_new_product: "GUMAWA NG BAGONG PRODUKTO" + spree_admin_enterprises_create_new_product: "LUMIKHA NG BAGONG PRODUKTO" spree_admin_single_enterprise_alert_mail_confirmation: "kumpirmahin ang email address para sa/kay" spree_admin_single_enterprise_alert_mail_sent: "naipadala na ang email sa" spree_admin_overview_action_required: "kailangan ng aksyon" @@ -2004,8 +2004,8 @@ fil_PH: unit_name: "pangalan ng yunit" change_package: "palitan ang package" spree_admin_single_enterprise_hint: "payo: para mahanap ka ng mga tao, i-turn on ang visibility sa ilalim ng" - spree_admin_eg_pickup_from_school: "hal. 'Pick-up from Primary School'" - spree_admin_eg_collect_your_order: "hal. 'Please collect your order from 123 Imaginary St, Northcote, 3070'" + spree_admin_eg_pickup_from_school: "hal. 'Pick-up mula sa Primary School'" + spree_admin_eg_collect_your_order: "hal. 'Kolektahin ang inyong order sa 123 Kapayapaan St., Tobias Fornier, Antique 5716'" spree_classification_primary_taxon_error: "ang Tax sa%{taxon}ay ang pangunahing tax ng %{product}at hindi maaaring tanggalin" spree_order_availability_error: "ang distributor o order cycle ay hindi kayang ibigay ang mga produkto sa inyong cart" spree_order_populator_error: "ang distributor o order cycle na ito ay hindi kayang ibigay lahat ng mga produkto sa inyong cart. pumili ng iba." @@ -2023,10 +2023,10 @@ fil_PH: add_and_manage_order_cycles: "magdagdag at pamahalaan ang mga order cycle" manage_order_cycles: "pamahalaan ang mga order cycle" manage_products: "pamahalaan ang mga produkto" - edit_profile_details: "ayusin ang mga detalye ng profile" - edit_profile_details_etc: "palitan ang paglalarawan, larawan at iba pa ng iyong profile" + edit_profile_details: "i-edit ang mga detalye ng profile" + edit_profile_details_etc: "palitan ang paglalarawan ng profile, larawan at iba pa" order_cycle: "order cycle" - order_cycles: "order cycles" + order_cycles: "mga order cycle" enterprise_relationships: "mga permiso ng enterprise" remove_tax: "alisin ang tax" first_name_begins_with: "ang pangalan ay nagsisimula sa" @@ -2037,20 +2037,20 @@ fil_PH: enterprise_tos_agree: "ako ay sumasang-ayon sa palatuntunan ng serbisyo na nasa itaas." tax_settings: "settings ng tax" products_require_tax_category: "ang mga produkto ay kailangang may kategorya ng tax" - admin_shared_address_1: "tirahan" + admin_shared_address_1: "address" admin_shared_address_2: "address (pagpapatuloy)" admin_share_city: "Lungsod" admin_share_zipcode: "Postcode" admin_share_country: "Bansa" admin_share_state: "Status" - hub_sidebar_hubs: "Hubs" + hub_sidebar_hubs: "Mga Hub" hub_sidebar_none_available: "walang available" hub_sidebar_manage: "pamahalaan" hub_sidebar_at_least: "pumili ng kahit isa sa mga Hub" hub_sidebar_blue: "bughaw" hub_sidebar_red: "pula" report_customers_distributor: "Distributor" - report_customers_supplier: "Suuplier" + report_customers_supplier: "Supplier" report_customers_cycle: "order cycle" report_customers_type: "uri ng ulat" report_customers_csv: "i-download bilang csv" @@ -2077,7 +2077,7 @@ fil_PH: report_header_last_name: Apelyido report_header_phone: telepono report_header_suburb: lungsod - report_header_address: tirahan + report_header_address: address report_header_billing_address: Billing Address report_header_relationship: relasyon report_header_hub: Hub @@ -2185,7 +2185,7 @@ fil_PH: report_header_total_cost: "Kabuuang Gastos" report_header_total_ordered: Kabuuang na-order report_header_total_max: kabuuang pinakamataas na limit - report_header_total_units: kabuuang yunit + report_header_total_units: kabuuang mga yunit report_header_sum_max_total: "kabuuan" report_header_total_excl_vat: "Kabuuang tax na hindi kasama (%{currency_symbol})" report_header_total_incl_vat: "Kabuuang tax na kasama (%{currency_symbol})" @@ -2217,8 +2217,8 @@ fil_PH: failure: "pagkabigo" unsaved_changes_confirmation: "ang mga hindi na-save na pagbabago ay mawawala. magpatuloy pa rin?" one_product_unsaved: "ang mga pagbabagong ginawa sa isang produkto ay hindi pa nase-save." - products_unsaved: "ang mga pagbabagong ginawa sa%{n} produkto ay hindi pa nase-save." - is_already_manager: "ay isa nang tagapamahala" + products_unsaved: "ang mga pagbabagong ginawa sa%{n} mga produkto ay hindi pa nase-save." + is_already_manager: "ay isa nang tagapamahala!" no_change_to_save: "walang pagbabagong ise-save" user_invited: "%{email}ay naimbitahan na para pamahalaan ang enterprise na ito." add_manager: "magdagdag ng gumagamit" @@ -2431,7 +2431,7 @@ fil_PH: producer sa mga mamili, maaaring sa pamamagitan ng pagsasama sama, pagmamarka, pagbabalot, pagbebenta o pagde-deliver ng pagkain. producer_desc: mga producer ng pagkain - producer_example: hal. NAGPAPATUBO, PANADERO, MANGANGALAKAL, YUMAYARI + producer_example: hal. NAGTATANIM, PANADERO, MANGANGALAKAL, YUMAYARI non_producer_desc: Iba pang mga enterprise ng pagkain non_producer_example: hal. Grocery, Food co-ops, Buying groups enterprise_status: @@ -2447,13 +2447,13 @@ fil_PH: loading_variants: "nilo-load ang Variants" tag_rules: shipping_method_tagged_top: "naka-tag ng mga paraan ng pagpapadala" - shipping_method_tagged_bottom: "ay:" - payment_method_tagged_top: "naka-tag na paraan ng pagbabayad" - payment_method_tagged_bottom: "ay:" + shipping_method_tagged_bottom: "ay ang mga:" + payment_method_tagged_top: "naka-tag na mga paraan ng pagbabayad" + payment_method_tagged_bottom: "ay ang mga:" order_cycle_tagged_top: "naka-tag na mga Order Cycle" - order_cycle_tagged_bottom: "ay:" + order_cycle_tagged_bottom: "ay ang mga:" inventory_tagged_top: "nakatag- na mga uri ng imbentaryo" - inventory_tagged_bottom: "ay:" + inventory_tagged_bottom: "ay ang mga:" new_tag_rule_dialog: select_rule_type: "pumili ng uri ng panuntunan:" add_rule: "magdagdag ng panuntunan" @@ -2463,12 +2463,12 @@ fil_PH: index: per_page: "%{results}kada pahina" view_file: "tignan ang file" - compiling_invoices: "tipunin ang mga invoice" + compiling_invoices: "tinitipon ang mga invoice" bulk_invoice_created: "nagawa ang maramihang invoice" bulk_invoice_failed: "hindi nagtagumpay na gumawa ng maramihang invoice" please_wait: "hintayin na maihanda ang PDF bago isara ang modal na ito." order_state: - address: "tirahan" + address: "address" adjustments: "mga pagsasaayos" awaiting_return: "naghihintay ng pagbalik" canceled: "kanselado" @@ -2507,23 +2507,23 @@ fil_PH: failed: "hindi matagumpay ang muling pagpapadala ✗" order_cycles: schedules: - adding_a_new_schedule: "Pagdadagdag ng Bagong Iskedyul" - updating_a_schedule: "pag-update sa iskedyul" - create_schedule: "Gumawa ng iskedyul" + adding_a_new_schedule: "nagdadagdag ng Bagong Iskedyul" + updating_a_schedule: "ina-update ang iskedyul" + create_schedule: "Lumikha ng iskedyul" update_schedule: "i-update ang iskedyul" - delete_schedule: "burahin ang iskedyul" + delete_schedule: "tanggalin ang iskedyul" schedule_name_placeholder: "pangalan ng iskedyul" - created_schedule: "nakagawa ng iskedyul" + created_schedule: "nakalikha ng iskedyul" updated_schedule: "na-update na iskedyul" deleted_schedule: "binurang iskedyul" - name_required_error: "Maglagay ng name para sa iskedyul na ito" + name_required_error: "Maglagay ng pangalan para sa iskedyul na ito" no_order_cycles_error: "pumili kahit isang order cycle (i-drag at i-drop)" available: "Available" selected: "napili" customers: index: add_customer: "magdagdag ng Customer" - add_a_new_customer_for: "magdadag ng customer para sa%{shop_name}" + add_a_new_customer_for: "magdadag ng bagong customer para sa%{shop_name}" customer_placeholder: "customer@example.org" valid_email_error: "maglagay ng valid na email address" subscriptions: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 9e2bd0597e..13053455c0 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -2477,7 +2477,7 @@ fr: load_more_variants: "Afficher plus de variantes" load_all_variants: "Afficher toutes les variantes" select_all_variants: "Sélectionnez toutes les %{total_number_of_variants} variantes" - variants_loaded: " %{num_of_variants_loaded}sur %{total_number_of_variants} variantes" + variants_loaded: " %{num_of_variants_loaded} sur %{total_number_of_variants} variantes" loading_variants: "Chargement des variantes" tag_rules: shipping_method_tagged_top: "Les méthodes de livraison taguées" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 718dd700c5..36c5b27531 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -219,7 +219,7 @@ pt_BR: edit: Editar clone: Cópia distributors: Distribuidores - bulk_order_management: Gerenciamento de Pedidos em Atacado + bulk_order_management: Gestão de Pedidos em Atacado enterprises: Iniciativas enterprise_groups: Grupos reports: Relatórios @@ -450,7 +450,7 @@ pt_BR: editing_product: "Editando Produto" tabs: product_details: "Detalhes do Produto" - group_buy_options: "Opções de Grupo de Compras" + group_buy_options: "Opções de Compra em Grupo" images: "Imagens" variants: "Variantes" product_properties: "Propriedades do produto" @@ -583,18 +583,18 @@ pt_BR: order_no: "Pedido nº" order_date: "Concluído em" max: "Máximo" - product_unit: "Produto: unidade" + product_unit: "Produto: Unidade" weight_volume: "Peso/Volume" ask: "Perguntar?" - page_title: "Gestão de Pedidos em Atacado" + page_title: "Gestão de Pedidos em Atacado" actions_delete: "Deletar selecionado" loading: "Carregando pedidos" no_results: "Nenhum pedido encontrado. " - group_buy_unit_size: "Unidade de Medida para Grupo de Compras" + group_buy_unit_size: "Unidade de Medida para Compra em Grupo" total_qtt_ordered: "Quantidade total do pedido" max_qtt_ordered: "Quantidade máxima do pedido" - current_fulfilled_units: "Unidades completadas no momento" - max_fulfilled_units: "Máximo de unidades completadas " + current_fulfilled_units: "Pedidos / Limite Mínimo (Atual)" + max_fulfilled_units: "Pedidos / Limite Mínimo (Max)" order_error: "Alguns erros devem ser corrigidos antes de atualizar os pedidos.\nOs campos com bordas vermelhas contém erros." variants_without_unit_value: "AVISO: Algumas variantes não possuem unidade de medida" select_variant: "Selecione uma variante" @@ -1248,7 +1248,7 @@ pt_BR: city_placeholder: 'ex: República' postcode: CEP postcode_placeholder: 'ex: 05429-130' - suburb: Bairro + suburb: Cidade state: Estado country: País unauthorized: Não autorizado @@ -1927,7 +1927,7 @@ pt_BR: admin_enterprise_groups_contact: "Contato" admin_enterprise_groups_contact_phone_placeholder: "ex: 987654321" admin_enterprise_groups_contact_address1_placeholder: "ex: Rua Alta, 123" - admin_enterprise_groups_contact_city: "Bairro" + admin_enterprise_groups_contact_city: "Cidade" admin_enterprise_groups_contact_city_placeholder: "ex: República" admin_enterprise_groups_contact_zipcode: "CEP" admin_enterprise_groups_contact_zipcode_placeholder: "ex: 02341-001" @@ -2085,7 +2085,7 @@ pt_BR: report_header_first_name: Nome report_header_last_name: Sobrenome report_header_phone: Telefone - report_header_suburb: Bairro + report_header_suburb: Cidade report_header_address: Endereço report_header_billing_address: Endereço de cobrança report_header_relationship: Relação @@ -2143,7 +2143,7 @@ pt_BR: report_header_producer: Produtor report_header_producer_suburb: Subúrbio do produtor report_header_unit: Unidade - report_header_group_buy_unit_quantity: Quantidade da Unidade para Grupo de Compras + report_header_group_buy_unit_quantity: Quantidade da Unidade para Compra em Grupo report_header_cost: Custo report_header_shipping_cost: ' Custo de envio' report_header_curr_cost_per_unit: Custo unitário atual @@ -2159,7 +2159,7 @@ pt_BR: report_header_distributor_postcode: CEP do distribuidor report_header_delivery_address: Endereço para entrega report_header_delivery_postcode: CEP para entrega - report_header_bulk_unit_size: Unidade de Medida para atacado + report_header_bulk_unit_size: Quantidade Mínima para Compra em Atacado report_header_weight: Peso report_header_sum_total: Soma total report_header_date_of_order: Data do pedido @@ -2939,7 +2939,7 @@ pt_BR: tab: dashboard: "Painel" orders: "Encomendas" - bulk_order_management: "Gestão de Pedidos em Atacado" + bulk_order_management: "Gestão de Pedidos em Atacado" subscriptions: "Assinaturas" products: "Produtos" option_types: "Tipos de opção" @@ -3147,8 +3147,8 @@ pt_BR: primary_taxon_form: product_category: Categoria de Produto group_buy_form: - group_buy: "Grupo de Compras?" - bulk_unit_size: Tamanho da unidade em massa + group_buy: "Compra em Grupo?" + bulk_unit_size: Quantidade Mínima para Compra em Atacado display_as: display_as: Mostrar como reports: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index f850080a53..c5cfd803d9 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -691,7 +691,7 @@ tr: create_one_button: "Şimdi Oluştur" no_method_yet: "Henüz herhangi bir teslimat yönteminiz yok." shop_preferences: - shopfront_requires_login: "MAĞAZANIZ HARİTADA GÖRÜNÜR OLSUN MU?" + shopfront_requires_login: "MAĞAZANIZ HERKESE AÇIK MI?" shopfront_requires_login_tip: "Mağazanızın yalnızca üyelerinize mi yoksa herkese mi açık olduğunu seçin." shopfront_requires_login_false: "Herkese açık" shopfront_requires_login_true: "Yalnızca kayıtlı müşteriler tarafından görülebilir" @@ -2452,14 +2452,14 @@ tr: variants_loaded: "%{total_number_of_variants} Varyanttan %{num_of_variants_loaded} Tanesi Yüklendi" loading_variants: "Varyantlar Yükleniyor" tag_rules: - shipping_method_tagged_top: "Teslimat yöntemleri etiketlendi" - shipping_method_tagged_bottom: "şunlardır:" - payment_method_tagged_top: "Ödeme yöntemleri etiketleri" - payment_method_tagged_bottom: "şunlardır:" - order_cycle_tagged_top: "Sipariş Dönemleri etiketlendi" - order_cycle_tagged_bottom: "şunlardır:" - inventory_tagged_top: "Stok varyantları etiketlendi" - inventory_tagged_bottom: "şunlardır:" + shipping_method_tagged_top: "Teslimat Yöntemi etiketi" + shipping_method_tagged_bottom: "ise durumu:" + payment_method_tagged_top: "Ödeme Yönteml etiketi" + payment_method_tagged_bottom: "ise durumu:" + order_cycle_tagged_top: "Sipariş Dönemi etiketi" + order_cycle_tagged_bottom: "ise durumu:" + inventory_tagged_top: "Stok varyant etiketi" + inventory_tagged_bottom: "ise durumu:" new_tag_rule_dialog: select_rule_type: "Bir kural türü seçin:" add_rule: "Kural Ekle" @@ -2748,7 +2748,7 @@ tr: temperature_controlled: "Soğuk Sevkiyat" new_product: "Yeni ürün" administration: "yönetim" - logged_in_as: "olarak giriş yapıldı" + logged_in_as: "Giriş yapıldı" account: "Hesap" logout: "Çıkış Yap" date_range: "Tarih aralığı" From 06b7a95fb167df7c077a8a8e398241be31db9308 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Thu, 28 May 2020 14:00:53 +0200 Subject: [PATCH 287/507] DRY duplicate subscription declaration --- .../subscriptions/proxy_order_syncer_spec.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb index 5a352f49ec..2413667b9c 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -102,14 +102,6 @@ module OrderManagement let!(:oc) { upcoming_closes_on_begins_at_oc } let(:schedule) { create(:schedule, order_cycles: [oc]) } - let(:subscription) do - build( - :subscription, - begins_at: now + 1.minute, - ends_at: now + 2.minutes, - schedule: schedule - ) - end let(:syncer) { ProxyOrderSyncer.new(subscription) } it "creates a new proxy order for that oc" do From c428b2f133cbd389a63d2d827d1ae32f8c7e9547 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 28 May 2020 23:07:06 +1000 Subject: [PATCH 288/507] Updating translations for config/locales/tr.yml --- config/locales/tr.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/config/locales/tr.yml b/config/locales/tr.yml index c5cfd803d9..54f646ce9f 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -686,6 +686,7 @@ tr: ofn_uid_tip: Açık Gıda Ağı'na kayıtlı işletmenize özel tanımlanan kimlik numarası shipping_methods: name: "Ad" + applies: "Aktif?" manage: "Teslimat Yöntemlerini Yönet" create_button: "Yeni Teslimat Yöntemi Oluştur" create_one_button: "Şimdi Oluştur" @@ -1637,9 +1638,9 @@ tr: sell_hubs_detail: "AGA üzerinden gıda işletmeniz veya topluluğunuz için bir profil oluşturun. İstediğiniz zaman profilinizi çok üreticili bir pazara yükseltebilirsiniz." sell_groups_detail: "Bölgenizdeki veya ağınızdaki işletmelerin (üreticilerin, pazarların veya diğer grupların) detaylı rehber listesini oluşturun." sell_user_guide: "Kullanım kılavuzumuzda daha fazla bilgi edinin." - sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkında bağlantısını kullanarak Yazılım Platformu bölümünü ziyaret edin." - sell_embed: "Açık Gıda Ağı üzerinden oluşturduğunuz tezgahınızı kendi web siteniz üzerinden de kullanmanıza yardımcı olabiliriz. Müşterileriniz mevcut internet siteniz üzerinden de aynı şekilde sipariş verebilirler. " - sell_ask_services: "Bize AGA hizmetleri hakkında soru sorun." + sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Platform üzerinden satış yapan işletmeler için işlem başına uygulanan ücretlendirme %5'tir. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkımızda bağlantısını kullanarak Fiyatlandırma bölümünü ziyaret edin." + sell_embed: "Kendi e-ticaret siteniz olsa bile Açık Gıda Ağı size hikayenizi anlatmanız ve ürünlerinizi satmanız için yeni ve farklı bir seçenek sunuyor. Siz de bu ailenin bir parçası olun, hep beraber büyüyelim!" + sell_ask_services: "Detaylar için bizimle iletişime geçin." shops_title: Mağazalar shops_headline: Alışveriş biçim değiştiriyor shops_text: Gıda dönemsel yetiştirilir, dönemsel hasat edilir ve dönemsel sipariş edilir. Aradığınız mağazanın sipariş dönemi kapalı ise kısa süre sonra tekrar kontrol edin. @@ -3067,6 +3068,8 @@ tr: zone: "bölge" calculator: "Hesaplama" display: "Görüntüle" + both: "Ödeme Sayfası ve Panel" + back_end: "Sadece panel" no_shipping_methods_found: "Hiçbir teslimat yöntemi bulunamadı" new: new_shipping_method: "Yeni Teslimat Yöntemi" @@ -3078,6 +3081,9 @@ tr: form: categories: "Kategoriler" zones: "bölgeler" + both: "Ödeme Sayfası ve Panel" + back_end: "Sadece panel" + deactivation_warning: "Bir teslimat yöntemini etkisiz hale getirmek listenizden kaldırılmasına sebep olabilir. Alternatif olarak, ayarlarınızı 'Göster' yerine 'sadece panel' olarak değiştirerek teslimat yöntemini ödeme sayfasında gizleyebilirsiniz." payment_methods: new: new_payment_method: "Yeni Ödeme Yöntemi" @@ -3237,6 +3243,7 @@ tr: format: '% Y-% A-%d' js_format: 'yy-aa-gg' orders: + error_flash_for_unavailable_items: "Sepetinizdeki ürünlerden biri bitti veya azaldı. Lütfen seçili miktarı güncelleyin." edit: login_to_view_order: "Siparişinizi görmek için lütfen giriş yapın." bought: From 29f266d3a55406d72535e7d25ae57eb90df7819e Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 28 May 2020 23:17:00 +1000 Subject: [PATCH 289/507] Updating translations for config/locales/tr.yml --- config/locales/tr.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 54f646ce9f..cf263190d6 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1175,8 +1175,8 @@ tr: contact: "İLETİŞİM" require_customer_login: "Yalnızca onaylı müşteriler buradan alışveriş yapabilir." require_login_html: "Zaten onaylanmış bir müşteri iseniz, devam etmek için %{login} veya %{signup}" - require_login_2_html: "Buradan alışveriş mi yapmak istiyorsunuz? Lütfen katılmak için %{contact}%{enterprise} ile iletişime geçin!" - require_customer_html: "Buradan alışveriş yapmaya başlamak istiyorsanız, katılmak için lütfen %{contact} %{enterprise} 'a sorun." + require_login_2_html: "Buradan alışveriş mi yapmak istiyorsunuz? Lütfen katılmak için sorun: %{contact}%{enterprise} " + require_customer_html: "Buradan alışveriş yapmaya başlamak istiyorsanız, katılmak için lütfen sorun: %{contact} %{enterprise} " select_oc: select_oc_html: "Hangi ürünlerin uygun olduğunu görmek için lütfen ne zaman için sipariş vermek istediğinizi seçin " card_could_not_be_updated: Kart güncellenemedi @@ -1913,10 +1913,10 @@ tr: outstanding_balance: "Ödenmemiş bakiye" admin_enterprise_relationships: "İŞLETME İZİNLERİ" admin_enterprise_relationships_everything: "her şey" - admin_enterprise_relationships_permits: "izinler" + admin_enterprise_relationships_permits: "izin veriyor" admin_enterprise_relationships_seach_placeholder: "Ara" admin_enterprise_relationships_button_create: "Oluştur" - admin_enterprise_relationships_to: "'a" + admin_enterprise_relationships_to: "-" admin_enterprise_groups: "İşletme Grupları" admin_enterprise_groups_name: "Ad" admin_enterprise_groups_owner: "Sahip" @@ -3224,7 +3224,7 @@ tr: privacy_policy_url: "Gizlilik Politikası URLsi" enterprises_require_tos: "İşletmeler Üyelik Sözleşmesini kabul etmelidir" cookies_policy_matomo_section: "Çerez politikası sayfasında Matomo bölümünü görüntüle" - footer_tos_url: "Üyelik Sözleşmesi URLsi" + footer_tos_url: "Kullanıcı Sözleşmesi URLsi" checkout: payment: stripe: From 9a29e634fc07eab9c09b27a2e79456272bef316e Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Thu, 28 May 2020 17:49:36 +0200 Subject: [PATCH 290/507] Deal with Schedule creation in its own controller This way it can assign the order cycles to the schedule when this is persisted. An OrderCycleSchedule (the join table) can't be created until both schedule and order_cycle got an id. Also, we do not call `#adapt_params` when creating the Schedule as that assigns `order_cycle_ids` to `@object.attributes` thus, attempting to create the OrderCycleSchedule without a schedule_id. --- app/controllers/admin/schedules_controller.rb | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 44ccb48d64..59528cf158 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -3,7 +3,7 @@ require 'order_management/subscriptions/proxy_order_syncer' module Admin class SchedulesController < ResourceController - before_filter :adapt_params, only: [:create, :update] + before_filter :adapt_params, only: [:update] before_filter :check_editable_order_cycle_ids, only: [:create, :update] before_filter :check_dependent_subscriptions, only: [:destroy] create.after :sync_subscriptions @@ -28,6 +28,25 @@ module Admin end end + def create + invoke_callbacks(:create, :before) + @object.attributes = permitted_resource_params + @object.save! + + @object.order_cycle_ids = params[:order_cycle_ids] + if @object.save + invoke_callbacks(:create, :after) + flash[:success] = flash_message_for(@object, :successfully_created) + respond_with(@object) do |format| + format.html { redirect_to location_after_save } + format.js { render layout: false } + end + else + invoke_callbacks(:create, :fails) + respond_with(@object) + end + end + private def collection @@ -95,11 +114,7 @@ module Admin end def permitted_resource_params - params.require(:schedule).permit( - :id, - :name, - order_cycle_ids: [] - ) + params.require(:schedule).permit(:id, :name) end end end From 26f1dfb08009b2a210fd8d6d508d5ca5db9b2a6b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 13 May 2020 16:28:48 +0100 Subject: [PATCH 291/507] Move payment_method display field translations to OFN and adapt them to changes on same field in shipping method --- app/views/spree/admin/payment_methods/_form.html.haml | 2 +- app/views/spree/admin/payment_methods/index.html.haml | 2 +- config/locales/en.yml | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/views/spree/admin/payment_methods/_form.html.haml b/app/views/spree/admin/payment_methods/_form.html.haml index 8ab592fd81..371e4cd0b5 100644 --- a/app/views/spree/admin/payment_methods/_form.html.haml +++ b/app/views/spree/admin/payment_methods/_form.html.haml @@ -21,7 +21,7 @@ .alpha.three.columns = label_tag nil, t(:display) .omega.eight.columns - = select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [t(display), display == :both ? nil : display.to_s] }, {}, {class: 'select2 fullwidth'}) + = select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [t('.' + display.to_s), display == :both ? nil : display.to_s] }, {}, {class: 'select2 fullwidth'}) .row .alpha.three.columns = label_tag nil, t(:active) diff --git a/app/views/spree/admin/payment_methods/index.html.haml b/app/views/spree/admin/payment_methods/index.html.haml index 4e79bf1c9d..983d91ded5 100644 --- a/app/views/spree/admin/payment_methods/index.html.haml +++ b/app/views/spree/admin/payment_methods/index.html.haml @@ -34,7 +34,7 @@ %br/ %td= method.type %td.align-center= method.environment.to_s.titleize - %td.align-center= method.display_on.blank? ? Spree.t(:both) : Spree.t(method.display_on) + %td.align-center= method.display_on.blank? ? t('.both') : t('.' + method.display_on.to_s) %td.align-center= method.active ? Spree.t(:say_yes) : Spree.t(:say_no) %td.actions = link_to_edit method, no_text: true diff --git a/config/locales/en.yml b/config/locales/en.yml index 158e964b89..bb15d37476 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3248,6 +3248,10 @@ See the %{link} to find out more about %{sitename}'s features and to start using back_end: "Back office only" deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + both: "Both" + front_end: "Checkout only" + back_end: "Back office only" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" @@ -3267,6 +3271,10 @@ See the %{link} to find out more about %{sitename}'s features and to start using account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + both: "Both Checkout and Back office" + front_end: "Checkout only" + back_end: "Back office only" payments: source_forms: stripe: From fe6bcb50934b76a8a52fb111adc6e311dcf28c13 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 13 May 2020 16:32:51 +0100 Subject: [PATCH 292/507] Add de-activation warning to payment methods edit page --- app/views/spree/admin/payment_methods/_form.html.haml | 4 +++- config/locales/en.yml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/spree/admin/payment_methods/_form.html.haml b/app/views/spree/admin/payment_methods/_form.html.haml index 371e4cd0b5..a6fa7f41cd 100644 --- a/app/views/spree/admin/payment_methods/_form.html.haml +++ b/app/views/spree/admin/payment_methods/_form.html.haml @@ -1,6 +1,8 @@ = admin_inject_payment_method = admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::BasicEnterpriseSerializer -%div.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" } +.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" } + .row + = t '.deactivation_warning' .row .alpha.three.columns = label_tag nil, t(:name) diff --git a/config/locales/en.yml b/config/locales/en.yml index bb15d37476..a77f8f4e7d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3275,6 +3275,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using both: "Both Checkout and Back office" front_end: "Checkout only" back_end: "Back office only" + deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." payments: source_forms: stripe: From bec798c6c97eae48f2d926d72ae4812cbdf2501e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 13 May 2020 16:52:31 +0100 Subject: [PATCH 293/507] Bring some spree translations to ofn in payment methods pages --- .../admin/payment_methods/_form.html.haml | 16 +++++++------- .../payment_methods/_providers.html.haml | 2 +- .../admin/payment_methods/edit.html.haml | 2 +- .../admin/payment_methods/index.html.haml | 20 ++++++++--------- config/locales/en.yml | 22 +++++++++++++++++++ 5 files changed, 42 insertions(+), 20 deletions(-) diff --git a/app/views/spree/admin/payment_methods/_form.html.haml b/app/views/spree/admin/payment_methods/_form.html.haml index a6fa7f41cd..7c2e1c4085 100644 --- a/app/views/spree/admin/payment_methods/_form.html.haml +++ b/app/views/spree/admin/payment_methods/_form.html.haml @@ -5,40 +5,40 @@ = t '.deactivation_warning' .row .alpha.three.columns - = label_tag nil, t(:name) + = label_tag nil, t('.name') .omega.eight.columns = text_field :payment_method, :name, class: 'fullwidth' .row .alpha.three.columns - = label_tag nil, t(:description) + = label_tag nil, t('.description') .omega.eight.columns = text_area :payment_method, :description, {cols: 60, rows: 6, class: 'fullwidth'} - if spree_current_user.admin? .row .alpha.three.columns - = label_tag nil, t(:environment) + = label_tag nil, t('.environment') .omega.eight.columns = collection_select(:payment_method, :environment, Rails.configuration.database_configuration.keys.sort, :to_s, :titleize, {}, {id: 'gtwy-env', class: 'select2 fullwidth'}) .row .alpha.three.columns - = label_tag nil, t(:display) + = label_tag nil, t('.display') .omega.eight.columns = select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [t('.' + display.to_s), display == :both ? nil : display.to_s] }, {}, {class: 'select2 fullwidth'}) .row .alpha.three.columns - = label_tag nil, t(:active) + = label_tag nil, t('.active') .two.columns = radio_button :payment_method, :active, true   - = label_tag nil, t(:say_yes) + = label_tag nil, t('.active_yes') .omega.six.columns = radio_button :payment_method, :active, false   - = label_tag nil, t(:say_no) + = label_tag nil, t('.active_no') .row .alpha.three.columns - = label(:payment_method, :tags, t(:tags)) + = label(:payment_method, :tags, t('.tags')) .omega.eight.columns = hidden_field(:payment_method, :tag_list, "ng-value" => "paymentMethod.tag_list") %tags-with-translation#something{ object: "paymentMethod" } diff --git a/app/views/spree/admin/payment_methods/_providers.html.haml b/app/views/spree/admin/payment_methods/_providers.html.haml index 657e21029e..2311eaa78f 100644 --- a/app/views/spree/admin/payment_methods/_providers.html.haml +++ b/app/views/spree/admin/payment_methods/_providers.html.haml @@ -1,7 +1,7 @@ #provider-settings{ ng: { controller: "ProvidersCtrl" } } .row .alpha.three.columns - = label :payment_method, :type, t(:provider) + = label :payment_method, :type, t('.provider') .omega.eight.columns = collection_select(:payment_method, :type, @providers, :to_s, :clean_name, (!@object.persisted? ? { :selected => "Spree::PaymentMethod::Check"} : {}), { class: 'select2 fullwidth', 'provider-prefs-for' => "#{@object.id}"}) diff --git a/app/views/spree/admin/payment_methods/edit.html.haml b/app/views/spree/admin/payment_methods/edit.html.haml index 9d8f6b147d..f1c98aeb43 100644 --- a/app/views/spree/admin/payment_methods/edit.html.haml +++ b/app/views/spree/admin/payment_methods/edit.html.haml @@ -4,7 +4,7 @@ = @payment_method.name - content_for :page_actions do %li - = button_link_to t(:new), spree.new_admin_payment_method_path, icon: 'icon-plus' + = button_link_to t('.new'), spree.new_admin_payment_method_path, icon: 'icon-plus' %li = button_link_to t('.back_to_payment_methods_list'), spree.admin_payment_methods_path, icon: 'icon-arrow-left' = render partial: 'spree/shared/error_messages', locals: { target: @payment_method } diff --git a/app/views/spree/admin/payment_methods/index.html.haml b/app/views/spree/admin/payment_methods/index.html.haml index 983d91ded5..ab1333f2c5 100644 --- a/app/views/spree/admin/payment_methods/index.html.haml +++ b/app/views/spree/admin/payment_methods/index.html.haml @@ -1,9 +1,9 @@ - content_for :page_title do - = Spree.t(:payment_methods) + = t('.payment_methods') - content_for :page_actions do %li - = button_link_to Spree.t(:new_payment_method), new_object_url, icon: 'icon-plus', id: 'admin_new_payment_methods_link' + = button_link_to t('.new_payment_method'), new_object_url, icon: 'icon-plus', id: 'admin_new_payment_methods_link' - if @payment_methods.any? %table#listing_payment_methods.index @@ -17,12 +17,12 @@ %col{style: "width: 11%"} %thead %tr - %th= Spree.t(:name) - %th= t(:products_distributor) - %th= Spree.t(:provider) - %th= Spree.t(:environment) - %th= Spree.t(:display) - %th= Spree.t(:active) + %th= t('.name') + %th= t('.products_distributor') + %th= t('.provider') + %th= t('.environment') + %th= t('.display') + %th= t('.active') %th.actions %tbody - @payment_methods.each do |method| @@ -35,9 +35,9 @@ %td= method.type %td.align-center= method.environment.to_s.titleize %td.align-center= method.display_on.blank? ? t('.both') : t('.' + method.display_on.to_s) - %td.align-center= method.active ? Spree.t(:say_yes) : Spree.t(:say_no) + %td.align-center= method.active ? t('.active_yes') : t('.active_no') %td.actions = link_to_edit method, no_text: true = link_to_delete method, no_text: true - else - .alpha.twelve.columns.no-objects-found= Spree.t(:no_payment_methods_found) + .alpha.twelve.columns.no-objects-found= t('.no_payment_methods_found') diff --git a/config/locales/en.yml b/config/locales/en.yml index a77f8f4e7d..e3845c53da 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3249,13 +3249,25 @@ See the %{link} to find out more about %{sitename}'s features and to start using deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" both: "Both" front_end: "Checkout only" back_end: "Back office only" + active_yes: "Yes" + active_no: "No" + no_payment_methods_found: "No payment methods found" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3272,10 +3284,20 @@ See the %{link} to find out more about %{sitename}'s features and to start using business_name: Business Name charges_enabled: Charges Enabled form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" both: "Both Checkout and Back office" front_end: "Checkout only" back_end: "Back office only" + tags: "Tags" deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." + providers: + provider: "Provider" payments: source_forms: stripe: From bd5de9d82f046a20f6095eb614d3567f92ec7548 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 13 May 2020 16:55:10 +0100 Subject: [PATCH 294/507] Delete unused translations --- config/locales/en.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index e3845c53da..e8e13cd8ed 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3025,8 +3025,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" From 11f33bd911de90e93c99c2c3bf169f7608f7a70a Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 29 May 2020 08:12:24 +1000 Subject: [PATCH 295/507] Updating translations for config/locales/pt_BR.yml --- config/locales/pt_BR.yml | 89 +++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 36c5b27531..0fad5eb3a9 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -53,7 +53,7 @@ pt_BR: producer_ids: "Produtores" order_cycle_ids: "Ciclos de pedidos" enterprise_fee_ids: "Nomes das taxas" - shipping_method_ids: "Métodos de envio" + shipping_method_ids: "Método de Envio" payment_method_ids: "Métodos de pagamento" errors: messages: @@ -204,7 +204,7 @@ pt_BR: ongoing: Em progresso bill_address: Endereço de Cobrança ship_address: Endereço de Entrega - sort_order_cycles_on_shopfront_by: "Ordenar Ciclo de Pedidos na Loja Virtual Por" + sort_order_cycles_on_shopfront_by: "Ordenar Ciclos de Pedidos na Loja Virtual Por" required_fields: Campos obrigatórios são indicados com um asterisco select_continue: Selecionar e continuar remove: Remover @@ -303,7 +303,7 @@ pt_BR: shop: Loja sku: SKU status_state: Estado - tags: Etiqueta + tags: Tags variant: Variante weight: Peso volume: Tamanho @@ -329,7 +329,7 @@ pt_BR: viewing: "Visualizando: %{current_view_name}" description: Descrição whats_this: O que é isso? - tag_has_rules: "Regras existentes para essa etiqueta: %{num}" + tag_has_rules: "Regras existentes para essa tag: %{num}" has_one_rule: "possui uma regra" has_n_rules: "tem %{num} regras" unsaved_confirm_leave: "Existem alterações não salvas nesta página. Continuar sem salvar? " @@ -687,12 +687,12 @@ pt_BR: shipping_methods: name: "Nome" applies: "Ativo?" - manage: "Gerenciar formas de envio" + manage: "Gerenciar métodos de envio" create_button: "Criar nova forma de envio" create_one_button: "Criar um agora" - no_method_yet: "Você ainda não tem nenhuma forma de envio." + no_method_yet: "Você ainda não tem nenhum método de envio." shop_preferences: - shopfront_requires_login: "Loja virtual visível publicamente?" + shopfront_requires_login: "Loja virtual visível ao público?" shopfront_requires_login_tip: "Escolha se os clientes precisarão fazer o login para ver os produtos da loja virtual, ou se eles estarão visíveis para todos." shopfront_requires_login_false: "Publico" shopfront_requires_login_true: "Disponível somente para clientes registrados" @@ -702,7 +702,7 @@ pt_BR: allow_guest_orders_false: "Requisitar o login para fazer pedidos" allow_guest_orders_true: "Permitir checkout de convidados" allow_order_changes: "Mudar pedidos" - allow_order_changes_tip: "Permitir que os consumidores mudem seus pedidos enquanto a compra estiver aberta." + allow_order_changes_tip: "Permitir que os consumidores mudem seus pedidos enquanto o ciclo de pedidos estiver aberto." allow_order_changes_false: "Pedidos enviados não podem ser mudados ou cancelados." allow_order_changes_true: "Consumidor pode mudar ou cancelar pedidos enquanto a compra estiver aberta." enable_subscriptions: "Assinaturas" @@ -721,7 +721,7 @@ pt_BR: Uma mensagem que forneça uma explicação detalhada sobre o porque de a loja estar fechada e quando os consumidores podem esperar que abra novamente, a ser exibida quando não houver nenhum ciclo de pedidos ativo. - shopfront_category_ordering: "Organização das Categorias da Loja Virtual" + shopfront_category_ordering: "Organização da Loja Virtual por Categorias" open_date: "Dia de abertura" close_date: "Dia de fechamento" social: @@ -746,11 +746,11 @@ pt_BR: by_default: Por padrão no_rules_yet: Ainda não existe nenhuma regra padrão add_new_button: '+ Adicionar nova regra padrão' - no_tags_yet: Nenhuma etiqueta foi aplicada a esta iniciativa - no_rules_yet: Nenhuma regra foi aplicada a essa etiqueta + no_tags_yet: Nenhuma tag foi aplicada a esta iniciativa + no_rules_yet: Nenhuma regra foi aplicada a essa tag for_customers_tagged: 'Para consumidores marcados:' add_new_rule: '+ Adicionar nova regra' - add_new_tag: '+ Adicionar nova etiqueta' + add_new_tag: '+ Adicionar nova tag' users: email_confirmation_notice_html: "Confirmação de e-mail está pendente. Enviamos um e-mail de confirmação para %{email}." resend: Reenviar @@ -774,8 +774,8 @@ pt_BR: properties: Propriedades payment_methods: Formas de pagamento payment_methods_tip: Essa iniciativa não tem formas de pagamento - shipping_methods: Formas de entrega - shipping_methods_tip: Essa iniciativa não tem formas de entrega + shipping_methods: Métodos de envio + shipping_methods_tip: Essa iniciativa não tem métodos de envio enterprise_fees: Taxas da iniciativa enterprise_fees_tip: Essa iniciativa não tem taxas admin_index: @@ -875,7 +875,7 @@ pt_BR: outgoing: "Saída" distributor: "Distribuidor" products: "Produtos" - tags: "Etiqueta" + tags: "Tag" delivery_details: "Sobre a Entrega" fees: "Taxas" previous: "Anterior" @@ -921,8 +921,8 @@ pt_BR: outgoing: Saída distributor: Distribuidor products: Produtos - tags: Etiquetas - add_a_tag: Adicionar etiqueta + tags: Tags + add_a_tag: Adicionar tag delivery_details: Detalhes de entrega/retirada index: schedule: Cronograma @@ -948,7 +948,7 @@ pt_BR: orders_present: Esse ciclo de pedidos foi selecionado por um cliente e não pode ser excluído. Para impedir que os clientes acessem, feche-o. schedule_present: Esse ciclo de pedidos está vinculado a um cronograma e não pode ser excluído. Desvincule ou exclua o cronograma primeiro. bulk_update: - no_data: Hum, algo deu errado. Não foram encontrados dados do ciclo do pedido. + no_data: Hum, algo deu errado. Não foram encontrados dados do ciclo do pedidos. date_warning: msg: Esse ciclo de pedidos está vinculado a %{n}de pedidos abertos. Alterar essa data agora não afetará nenhum pedido que já tenha sido feito, mas deve ser evitado, se possível. Tem certeza de que deseja continuar? cancel: Cancelar @@ -1080,7 +1080,7 @@ pt_BR: details: Detalhes address: Endereço products: Produtos - no_open_or_upcoming_order_cycle: "Nenhum ciclo de pedido futuro" + no_open_or_upcoming_order_cycle: "Nenhum ciclo de pedidos agendado" products_panel: save: "SALVAR" saving: "SALVANDO" @@ -1145,7 +1145,7 @@ pt_BR: cart: "Carrinho" joyride: checkout: "Fechar pedido agora" - already_ordered_products: "Já pediu neste ciclo de pedido" + already_ordered_products: "Já pediu neste ciclo de pedidos" register_call: selling_on_ofn: "Interessado em registrar a sua iniciativa na Open Food Brasil?" register: "Registre-se aqui" @@ -1688,11 +1688,11 @@ pt_BR: products_cart_distributor_change: "O distribuidor para este pedido será trocado para %{name} se você adicionar este produto no carrinho." products_cart_distributor_is: "O distribuidor para este pedido é %{name}." products_distributor_error: "Por favor complete seu pedido no %{link} antes de comprar com outro distribuidor." - products_oc: "Ciclo de pedido para seu pedido:" - products_oc_change: "O ciclo de pedido para esse pedido será trocada para %{name} se você adicionar este produto ao carrinho." - products_oc_is: "O ciclo de pedido para este pedido é %{name}." + products_oc: "Ciclo de pedidos para seu pedido:" + products_oc_change: "O ciclo de pedidos para esse pedido será trocado para %{name} se você adicionar este produto ao carrinho." + products_oc_is: "O ciclo de pedidos para este pedido é %{name}." products_oc_error: "Por favor complete seu pedido no %{link} antes de comprar em outro ciclo de pedido." - products_oc_current: "seu ciclo de pedido atual" + products_oc_current: "seu ciclo de pedidos atual" products_max_quantity: Quantidade máxima products_distributor: Distribuidor products_distributor_info: Quando você selecionar um distribuidor para seu pedido, o endereço e data para retirada serão exibidos aqui. @@ -1961,8 +1961,8 @@ pt_BR: flat_rate_per_order: "Taxa fixa ( por pedido)" flexible_rate: "Tarifa flexível" price_sack: "Preço da saca" - new_order_cycles: "Novo ciclo de pedidos" - new_order_cycle: "Novo ciclo de pedido" + new_order_cycles: "Novos ciclos de pedidos" + new_order_cycle: "Novo ciclo de pedidos" select_a_coordinator_for_your_order_cycle: "Selecione um coordenador para o seu ciclo de pedidos" notify_producers: 'Notificar produtores' edit_order_cycle: "Editar ciclo de pedidos" @@ -1992,7 +1992,7 @@ pt_BR: spree_admin_overview_enterprises_footer: "GERENCIAR MINHAS INICIATIVAS" spree_admin_enterprises_hubs_name: "Nome" spree_admin_enterprises_create_new: "CRIAR NOVA" - spree_admin_enterprises_shipping_methods: "Métodos de entrega" + spree_admin_enterprises_shipping_methods: "Métodos de envio" spree_admin_enterprises_fees: "Taxas da iniciativa" spree_admin_enterprises_none_create_a_new_enterprise: "CRIAR NOVA INICIATIVA" spree_admin_enterprises_none_text: "Você ainda não possui nenhuma iniciativa" @@ -2016,7 +2016,7 @@ pt_BR: spree_admin_eg_pickup_from_school: "ex: 'Buscar na Escola'" spree_admin_eg_collect_your_order: "ex: 'Por favor, colete seu pedido na Rua dos Sonhos, 123, casa 5, Bairro Liberdade" spree_classification_primary_taxon_error: "O táxon %{taxon} é o táxon principal de %{product} e não pode ser excluído" - spree_order_availability_error: "O ciclo do distribuidor ou do pedido não pode fornecer os produtos no seu carrinho" + spree_order_availability_error: "O distribuidor ou o ciclo de pedidos não pode fornecer os produtos no seu carrinho" spree_order_populator_error: "Distribuidor ou ciclo de pedidos não pode fornecer os produtos no seu carrinho. Por favor, escolha outro." spree_order_populator_availability_error: "Esse produto não está disponível no distribuidor escolhido ou no ciclo de pedidos." spree_distributors_error: "Pelo menos uma central deve ser selecionado" @@ -2029,7 +2029,7 @@ pt_BR: manage: "Gerenciar" resend: "Re-enviar" add_and_manage_products: "Adicionar e gerenciar produtos" - add_and_manage_order_cycles: "Adicione e gerenciar ciclos de pedidos" + add_and_manage_order_cycles: "Adicionar e gerenciar ciclos de pedidos" manage_order_cycles: "Gerenciar ciclos de pedidos" manage_products: "Gerenciar produtos" edit_profile_details: "Editar detalhes de perfil " @@ -2116,7 +2116,7 @@ pt_BR: report_header_order_number: Número do pedido report_header_date: Data report_header_confirmation_date: Data de Confirmação - report_header_tags: Etiqueta + report_header_tags: Tags report_header_items: Itens report_header_items_total: "Total de itens%{currency_symbol}" report_header_taxable_items_total: "Total de itens tributáveis ​​(%{currency_symbol})" @@ -2337,18 +2337,18 @@ pt_BR: overview: Visão geral overview_text: > As regras de tag fornecem uma maneira para descrever quais itens são - visíveis ou não e para quais clientes, como formas de pagamento, formas + visíveis ou não e para quais clientes, como métodos de pagamento, método de entrega, produtos e ciclos de pedidos. by_default_rules: "Regras \"Padrão ...\"" by_default_rules_text: > As regras padrão permitem ocultar itens para que eles não estejam visíveis por padrão. Esse comportamento pode ser substituído por regras não padrão - para clientes com etiquetas específicas. + para clientes com tags específicas. customer_tagged_rules: "Regras de \"Clientes marcados ...\"" customer_tagged_rules_text: > - Ao criar regras relacionadas a uma etiqueta de cliente específica, você - pode substituir o comportamento padrão (seja para mostrar ou para ocultar - itens) para clientes com a etiqueta especificada. + Ao criar regras relacionadas a uma tag de cliente específica, você pode + substituir o comportamento padrão (seja para mostrar ou para ocultar + itens) para clientes com a tagespecificada. panels: save: SALVAR saved: SALVO @@ -2460,7 +2460,7 @@ pt_BR: payment_method_tagged_bottom: "são:" order_cycle_tagged_top: "Ciclos de pedidos marcados" order_cycle_tagged_bottom: "são:" - inventory_tagged_top: "Variantes de inventário marcadas" + inventory_tagged_top: "Variantes do inventário marcadas com tag" inventory_tagged_bottom: "são:" new_tag_rule_dialog: select_rule_type: "Selecione um tipo de regra:" @@ -2525,7 +2525,7 @@ pt_BR: updated_schedule: "Lista atualizada" deleted_schedule: "Lista excluída" name_required_error: "Digite um nome para esta lista" - no_order_cycles_error: "Selecione pelo menos um ciclo de pedido (arraste e solte)" + no_order_cycles_error: "Selecione pelo menos um ciclo de pedidos (arraste e solte)" available: "Disponível" selected: "Selecionado" customers: @@ -2589,9 +2589,9 @@ pt_BR: Isso ajustará o nível de estoque para zero em todos os produtos para esta iniciativa que não está presente no arquivo carregado. order_cycles: - create_failure: "Falha ao criar o ciclo do pedido" + create_failure: "Falha ao criar o ciclo do pedidos" update_success: 'O seu ciclo de pedidos foi atualizado.' - update_failure: "Falha ao atualizar o ciclo do pedido" + update_failure: "Falha ao atualizar o ciclo do pedidos" no_distributors: Não há distribuidores neste ciclo de pedidos. Este ciclo de pedidos não será visível para os clientes até você adicionar um. Você gostaria de continuar salvando esse ciclo de pedidos? enterprises: producer: "Produtor" @@ -3040,7 +3040,7 @@ pt_BR: distribution_fields: title: "Distribuição" distributor: "Distribuidor:" - order_cycle: "Ciclo de pedido:" + order_cycle: "Ciclo de pedidos:" line_item_adjustments: "Ajustes de itens de linha" order_adjustments: "Ajustes de Pedidos" order_total: "total de pedidos" @@ -3057,7 +3057,7 @@ pt_BR: order_cycles_tip: "Os ciclos de pedidos determinam quando e onde seus produtos estão disponíveis para os clientes." you_have_active: zero: "Você não possui ciclos de pedidos ativos." - one: "Você tem um ciclo de pedido ativo." + one: "Você tem um ciclo de pedidos ativo." other: "Você tem %{count} ciclos de pedidos ativos." manage_order_cycles: "GERENCIAR CICLOS DE PEDIDOS" shipping_methods: @@ -3069,6 +3069,8 @@ pt_BR: zone: "Zona" calculator: "Calculadora" display: "Exibição" + both: "Tanto Checkout quanto Área Administrativa" + back_end: "Somente Área Administrativa" no_shipping_methods_found: "Nenhum método de envio encontrado" new: new_shipping_method: "Novo método de envio" @@ -3080,6 +3082,8 @@ pt_BR: form: categories: "Categorias" zones: "Zonas" + both: "Tanto Checkout quanto Área Administrativa" + back_end: "Somente Área Administrativa" deactivation_warning: "Desativar um método de envio pode fazer com que ele desapareça da sua lista. Como alternativa, você pode esconder um método de envio da página de checkout s" payment_methods: new: @@ -3240,10 +3244,11 @@ pt_BR: format: '%A-%m-' js_format: 'aa-mm-dd' orders: + error_flash_for_unavailable_items: "Um item no seu carrinho ficou indisponível. Por favor atualize as quantidades selecionadas. " edit: login_to_view_order: "Faça o login para visualizar seu pedido." bought: - item: "Já pediu neste ciclo de pedido" + item: "Já pediu neste ciclo de pedidos" line_item: insufficient_stock: "Estoque disponível insuficiente, apenas %{on_hand} restante" out_of_stock: "Fora de estoque" From 9fbd8b4fe1cedcf739953b5736f63f5a0051910f Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 29 May 2020 16:46:33 +1000 Subject: [PATCH 296/507] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 267ab53b2a..0701634c52 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -3269,9 +3269,14 @@ en_FR: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" + customer_greeting: "Bonjour %{name}," + instructions_html: "Votre commande avec%{distributor} a été annulée. Merci de conserver cet email." + dont_cancel: "Si vous avez changé d'avis ou vous ne souhaitez pas annuler cette commande, merci de contacter %{email}." + order_summary_canceled_html: "[ANNULATION] Commande #%{number}" + details: "Voici les produits que vous aviez commandé:" + unpaid_order: "Votre commande n'avait pas été réglée donc aucun remboursement n'a été effectué." + paid_order: "Votre commande avait été réglée, ainsi %{distributor} a remboursé la totalité de votre commande." + credit_order: "Votre commande avait été payée, votre compte a donc été crédité" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" From 5e0e88bf2c5b218bee33acdf874fffc9fae60bb6 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 29 May 2020 17:24:01 +1000 Subject: [PATCH 297/507] Updating translations for config/locales/fr.yml --- config/locales/fr.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 13053455c0..9289365e81 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -2134,7 +2134,7 @@ fr: report_header_customer_code: Code acheteur report_header_product: Produit report_header_product_properties: Propriétés / labels Produits - report_header_quantity: Nb commandé + report_header_quantity: Quantité report_header_max_quantity: Quantité Max report_header_variant: Variante report_header_variant_value: Nb Unités Variante @@ -2193,7 +2193,7 @@ fr: report_header_eft_price: "TEF / Transfert Electronique (%{currency})" report_header_paypal_price: "Paypal (%{currency})" report_header_sku: Référence Produit - report_header_amount: Quantité + report_header_amount: Montant report_header_balance: Solde report_header_total_cost: "Coût Total" report_header_total_ordered: Total Commandé @@ -3299,9 +3299,14 @@ fr: invalid: invalide order_mailer: cancel_email: - customer_greeting: "Bonjour %{name} !" - instructions: "Votre commande a été ANNULÉE. Vous trouverez ci-dessous les informations concernant cette commande. " - order_summary_canceled: "Résumé de la commande [ANNULEE]" + customer_greeting: "Bonjour %{name}," + instructions_html: "Votre commande avec %{distributor}a été annulée. Merci de conserver cet email." + dont_cancel: "Si vous avez changé d'avis ou l'annulation a été réalisée par erreur, merci de contacter %{email}" + order_summary_canceled_html: "[ANNULATION] Commande #%{number}" + details: "Voici le détail des produits commandés:" + unpaid_order: "Votre commande n'avait pas été réglée, aucun remboursement n'a donc été effectué" + paid_order: "Votre commande avait été réglée, ainsi %{distributor}a remboursé la totalité du montant" + credit_order: "Votre commande avait été payée, votre compte a donc été crédité" subject: "Annulation de Commande" confirm_email: subject: "Confirmation de commande" From 4f635339e365229ab17cc63a40ac62d56d611cb7 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 09:39:12 +0200 Subject: [PATCH 298/507] Fix schedule creation and subs syncing --- app/controllers/admin/schedules_controller.rb | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 59528cf158..59fedaf839 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -4,9 +4,9 @@ require 'order_management/subscriptions/proxy_order_syncer' module Admin class SchedulesController < ResourceController before_filter :adapt_params, only: [:update] - before_filter :check_editable_order_cycle_ids, only: [:create, :update] + before_filter :check_editable_order_cycle_ids_create, only: [:create] + before_filter :check_editable_order_cycle_ids, only: [:update] before_filter :check_dependent_subscriptions, only: [:destroy] - create.after :sync_subscriptions update.after :sync_subscriptions respond_to :json @@ -30,12 +30,19 @@ module Admin def create invoke_callbacks(:create, :before) + + if params[:order_cycle_ids].blank? + invoke_callbacks(:create, :fails) + return respond_with(@object) + end + @object.attributes = permitted_resource_params @object.save! @object.order_cycle_ids = params[:order_cycle_ids] if @object.save - invoke_callbacks(:create, :after) + sync_subscriptions_create + flash[:success] = flash_message_for(@object, :successfully_created) respond_with(@object) do |format| format.html { redirect_to location_after_save } @@ -76,8 +83,24 @@ module Admin params[:schedule][:order_cycle_ids] = params[:order_cycle_ids] end + def check_editable_order_cycle_ids_create + return unless params[:order_cycle_ids] + + requested = params[:order_cycle_ids] + + @existing_order_cycle_ids = @schedule.persisted? ? @schedule.order_cycle_ids : [] + + permitted = OrderCycle.where(id: params[:order_cycle_ids] | @existing_order_cycle_ids).merge(OrderCycle.managed_by(spree_current_user)).pluck(:id) + + result = @existing_order_cycle_ids + result |= (requested & permitted) # add any requested & permitted ids + result -= ((result & permitted) - requested) # remove any existing and permitted ids that were not specifically requested + + params[:order_cycle_ids] = result + end + def check_editable_order_cycle_ids - return unless params[:schedule][:order_cycle_ids] + return unless params[:schedule][:order_cycle_ids] || params[:order_cycle_ids] requested = params[:schedule][:order_cycle_ids] @existing_order_cycle_ids = @schedule.persisted? ? @schedule.order_cycle_ids : [] @@ -113,6 +136,18 @@ module Admin syncer.sync! end + def sync_subscriptions_create + return unless params[:order_cycle_ids] + + removed_ids = @existing_order_cycle_ids - @schedule.order_cycle_ids + new_ids = @schedule.order_cycle_ids - @existing_order_cycle_ids + return unless removed_ids.any? || new_ids.any? + + subscriptions = Subscription.where(schedule_id: @schedule) + syncer = OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscriptions) + syncer.sync! + end + def permitted_resource_params params.require(:schedule).permit(:id, :name) end From 862364ebbb6db86768ebf7f1f2d10eda83028258 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 09:39:23 +0200 Subject: [PATCH 299/507] Fix schedule destroy spec --- spec/features/admin/schedules_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/features/admin/schedules_spec.rb b/spec/features/admin/schedules_spec.rb index 0a457e1d2a..f017596e53 100644 --- a/spec/features/admin/schedules_spec.rb +++ b/spec/features/admin/schedules_spec.rb @@ -129,10 +129,10 @@ feature 'Schedules', js: true do end expect(Schedule.find_by(id: weekly_schedule.id)).to be_nil - expect(oc1.schedules).to eq [] - expect(oc2.schedules).to eq [] - expect(oc3.schedules).to eq [] - expect(oc4.schedules).to eq [] + expect(oc1.reload.schedules).to eq [] + expect(oc2.reload.schedules).to eq [] + expect(oc3.reload.schedules).to eq [] + expect(oc4.reload.schedules).to eq [] end end end From f25ee8c99841fde47aa3acf8014dedb4413175ff Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 10:16:03 +0200 Subject: [PATCH 300/507] Extract `#editable_order_cycles` This makes it far easier to spot what's the difference between create and update regarding the editable order cycles. I stop here before a slightly deeper refactor which would make the PR quite hard to review. This will come an upcoming one. --- app/controllers/admin/schedules_controller.rb | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 59fedaf839..a16cc673a9 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -5,7 +5,7 @@ module Admin class SchedulesController < ResourceController before_filter :adapt_params, only: [:update] before_filter :check_editable_order_cycle_ids_create, only: [:create] - before_filter :check_editable_order_cycle_ids, only: [:update] + before_filter :check_editable_order_cycle_ids_update, only: [:update] before_filter :check_dependent_subscriptions, only: [:destroy] update.after :sync_subscriptions @@ -87,29 +87,34 @@ module Admin return unless params[:order_cycle_ids] requested = params[:order_cycle_ids] + @existing_order_cycle_ids = [] - @existing_order_cycle_ids = @schedule.persisted? ? @schedule.order_cycle_ids : [] - - permitted = OrderCycle.where(id: params[:order_cycle_ids] | @existing_order_cycle_ids).merge(OrderCycle.managed_by(spree_current_user)).pluck(:id) - - result = @existing_order_cycle_ids - result |= (requested & permitted) # add any requested & permitted ids - result -= ((result & permitted) - requested) # remove any existing and permitted ids that were not specifically requested + result = editable_order_cycles(requested) params[:order_cycle_ids] = result end - def check_editable_order_cycle_ids - return unless params[:schedule][:order_cycle_ids] || params[:order_cycle_ids] + def check_editable_order_cycle_ids_update + return unless params[:schedule][:order_cycle_ids] requested = params[:schedule][:order_cycle_ids] - @existing_order_cycle_ids = @schedule.persisted? ? @schedule.order_cycle_ids : [] - permitted = OrderCycle.where(id: params[:schedule][:order_cycle_ids] | @existing_order_cycle_ids).merge(OrderCycle.managed_by(spree_current_user)).pluck(:id) + @existing_order_cycle_ids = @schedule.order_cycle_ids + + result = editable_order_cycles(requested) + + params[:schedule][:order_cycle_ids] = result + @object.order_cycle_ids = result + end + + def editable_order_cycles(requested) + permitted = OrderCycle + .where(id: params[:order_cycle_ids] | @existing_order_cycle_ids) + .merge(OrderCycle.managed_by(spree_current_user)) + .pluck(:id) result = @existing_order_cycle_ids result |= (requested & permitted) # add any requested & permitted ids result -= ((result & permitted) - requested) # remove any existing and permitted ids that were not specifically requested - params[:schedule][:order_cycle_ids] = result - @object.order_cycle_ids = result + result end def check_dependent_subscriptions From 65c53df2ef0541ba4c90da9ec849273afec6616e Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 10:21:51 +0200 Subject: [PATCH 301/507] Remove unnecessary callback invocations There are no registered callback methods to execute. --- app/controllers/admin/schedules_controller.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index a16cc673a9..35df2c4190 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -29,10 +29,7 @@ module Admin end def create - invoke_callbacks(:create, :before) - if params[:order_cycle_ids].blank? - invoke_callbacks(:create, :fails) return respond_with(@object) end @@ -49,7 +46,6 @@ module Admin format.js { render layout: false } end else - invoke_callbacks(:create, :fails) respond_with(@object) end end From 56b590a6f8d8a331827de50f905048ac01cbeeec Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 10:41:17 +0200 Subject: [PATCH 302/507] Extract `#sync_subscription` This makes it far easier to spot what's the difference between create and update regarding subs syncing without having to mess with `#update` and its callbacks (for now). --- app/controllers/admin/schedules_controller.rb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 35df2c4190..4debb5f91f 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -7,7 +7,7 @@ module Admin before_filter :check_editable_order_cycle_ids_create, only: [:create] before_filter :check_editable_order_cycle_ids_update, only: [:update] before_filter :check_dependent_subscriptions, only: [:destroy] - update.after :sync_subscriptions + update.after :sync_subscriptions_update respond_to :json @@ -125,21 +125,19 @@ module Admin @permissions = OpenFoodNetwork::Permissions.new(spree_current_user) end - def sync_subscriptions + def sync_subscriptions_update return unless params[:schedule][:order_cycle_ids] - removed_ids = @existing_order_cycle_ids - @schedule.order_cycle_ids - new_ids = @schedule.order_cycle_ids - @existing_order_cycle_ids - return unless removed_ids.any? || new_ids.any? - - subscriptions = Subscription.where(schedule_id: @schedule) - syncer = OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscriptions) - syncer.sync! + sync_subscriptions end def sync_subscriptions_create return unless params[:order_cycle_ids] + sync_subscriptions + end + + def sync_subscriptions removed_ids = @existing_order_cycle_ids - @schedule.order_cycle_ids new_ids = @schedule.order_cycle_ids - @existing_order_cycle_ids return unless removed_ids.any? || new_ids.any? From 4f3d01bd93090231565baf7cd00ec38295c83dab Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 10:43:16 +0200 Subject: [PATCH 303/507] Remove unused HTML response format --- app/controllers/admin/schedules_controller.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 4debb5f91f..e1980e86c5 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -41,10 +41,7 @@ module Admin sync_subscriptions_create flash[:success] = flash_message_for(@object, :successfully_created) - respond_with(@object) do |format| - format.html { redirect_to location_after_save } - format.js { render layout: false } - end + respond_with(@object) else respond_with(@object) end From 768568c75c839ef184eed290fb65c1975d69ca74 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 10:44:06 +0200 Subject: [PATCH 304/507] Rename @object to @schedule This level of abstraction makes sense in the framework-like code in ResourceController but here it just makes things more difficult. --- app/controllers/admin/schedules_controller.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index e1980e86c5..7b356701c9 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -30,20 +30,20 @@ module Admin def create if params[:order_cycle_ids].blank? - return respond_with(@object) + return respond_with(@schedule) end - @object.attributes = permitted_resource_params - @object.save! + @schedule.attributes = permitted_resource_params + @schedule.save! - @object.order_cycle_ids = params[:order_cycle_ids] - if @object.save + @schedule.order_cycle_ids = params[:order_cycle_ids] + if @schedule.save sync_subscriptions_create - flash[:success] = flash_message_for(@object, :successfully_created) - respond_with(@object) + flash[:success] = flash_message_for(@schedule, :successfully_created) + respond_with(@schedule) else - respond_with(@object) + respond_with(@schedule) end end @@ -96,7 +96,7 @@ module Admin result = editable_order_cycles(requested) params[:schedule][:order_cycle_ids] = result - @object.order_cycle_ids = result + @schedule.order_cycle_ids = result end def editable_order_cycles(requested) From 032dce1a8876597ab58306a53f54f9b4a87e7324 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 10:46:29 +0200 Subject: [PATCH 305/507] Move OC save within success block This makes more evident there are two scenarios: schedule save success or failure. We deal with OCs failures raising an exception. --- app/controllers/admin/schedules_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 7b356701c9..39e1ffc625 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -34,10 +34,11 @@ module Admin end @schedule.attributes = permitted_resource_params - @schedule.save! - @schedule.order_cycle_ids = params[:order_cycle_ids] if @schedule.save + @schedule.order_cycle_ids = params[:order_cycle_ids] + @schedule.save! + sync_subscriptions_create flash[:success] = flash_message_for(@schedule, :successfully_created) From 815cd73ff3e5833b0cd1afa4b1ad4916f7585eef Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 11:15:47 +0200 Subject: [PATCH 306/507] DRY specs --- .../subscriptions/proxy_order_syncer_spec.rb | 96 +++++++------------ 1 file changed, 34 insertions(+), 62 deletions(-) diff --git a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb index 2413667b9c..304eae01ef 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -101,9 +101,6 @@ module OrderManagement context "and the schedule includes upcoming oc that closes on begins_at" do let!(:oc) { upcoming_closes_on_begins_at_oc } - let(:schedule) { create(:schedule, order_cycles: [oc]) } - let(:syncer) { ProxyOrderSyncer.new(subscription) } - it "creates a new proxy order for that oc" do syncer.sync! @@ -116,15 +113,6 @@ module OrderManagement let!(:oc) { upcoming_closes_on_ends_at_oc } it "creates a new proxy order for that oc" do - schedule = create(:schedule, order_cycles: [oc]) - subscription = build( - :subscription, - begins_at: now + 1.minute, - ends_at: now + 2.minutes, - schedule: schedule - ) - - syncer = ProxyOrderSyncer.new(subscription) syncer.sync! expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) @@ -212,6 +200,7 @@ module OrderManagement context "and the proxy order has not already been placed" do context "the oc is closed (ie. closed before opens_at)" do let(:oc) { closed_oc } + it "removes the proxy order" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) expect(proxy_orders).to_not include proxy_order @@ -220,82 +209,65 @@ module OrderManagement context "and the schedule includes an open oc that closes before begins_at" do let(:oc) { open_oc_closes_before_begins_at_oc } + it "removes the proxy order" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) expect(proxy_orders).to_not include proxy_order end end - context "and the oc is open and closes between begins_at and ends_at" do - let(:oc) { open_oc } - - it "keeps the proxy order" do - schedule = create(:schedule, order_cycles: [oc]) - subscription = build( + context 'and the proxy orders are already synced' do + let(:subscription) do + build( :subscription, begins_at: now + 1.minute, ends_at: now + 2.minutes, schedule: schedule ) + end - syncer = ProxyOrderSyncer.new(subscription) - syncer.sync! + before { syncer.sync! } - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order + context "and the oc is open and closes between begins_at and ends_at" do + let(:oc) { open_oc } + + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes on begins_at" do + let(:oc) { upcoming_closes_on_begins_at_oc } + + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes on ends_at" do + let(:oc) { upcoming_closes_on_ends_at_oc } + + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end end end context "and the oc is upcoming and closes before begins_at" do let(:oc) { upcoming_closes_before_begins_at_oc } + it "removes the proxy order" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) expect(proxy_orders).to_not include proxy_order end end - context "and the oc is upcoming and closes on begins_at" do - let(:oc) { upcoming_closes_on_begins_at_oc } - - it "keeps the proxy order" do - schedule = create(:schedule, order_cycles: [oc]) - subscription = build( - :subscription, - begins_at: now + 1.minute, - ends_at: now + 2.minutes, - schedule: schedule - ) - - syncer = ProxyOrderSyncer.new(subscription) - syncer.sync! - - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes on ends_at" do - let(:oc) { upcoming_closes_on_ends_at_oc } - - it "keeps the proxy order" do - schedule = create(:schedule, order_cycles: [oc]) - subscription = build( - :subscription, - begins_at: now + 1.minute, - ends_at: now + 2.minutes, - schedule: schedule - ) - - syncer = ProxyOrderSyncer.new(subscription) - syncer.sync! - - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - context "and the oc is upcoming and closes after ends_at" do let(:oc) { upcoming_closes_after_ends_at_oc } + it "removes the proxy order" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) expect(proxy_orders).to_not include proxy_order From a376a17f64583d56bf41061422f48498bfaf295d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 11 May 2020 17:59:03 +0100 Subject: [PATCH 307/507] Group related properties together --- .../stylesheets/darkswarm/_shop-navigation.css.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index 2f1d919db6..d54464d921 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -63,6 +63,8 @@ ordercycle { select { background-image: url('/assets/white-caret.svg'); + background-size: 30px auto; + background-position-x: 102%; } p { @@ -71,20 +73,18 @@ ordercycle { select, p { - width: 200px; display: inline-block; color: $white; background-color: transparent; border: 0; border-radius: 0 $radius-small $radius-small 0; margin-bottom: 0; + padding: 0.5em 1.25em 0.5em 0.75em; font-size: 1em; line-height: 1.3em; - padding: 0.5em 1.25em 0.5em 0.75em; height: 2.35em; - background-position-x: 102%; - background-size: 30px auto; min-width: 13em; + width: 200px; @include breakpoint(mobile) { width: 100%; From 2c55bef544b8e5753cd0f5ab3259b562c4543e8b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 12 May 2020 13:01:00 +0100 Subject: [PATCH 308/507] Remove unnecessary padding This is looking broken in ipad mini 3 --- app/assets/stylesheets/darkswarm/_shop-navigation.css.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index d54464d921..a360c8f606 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -168,7 +168,7 @@ shop ordercycle { @include breakpoint(tablet) { float: none; - padding: 0 0 10px; + padding: 0; } } From 3e0839de73b42fe774f4494c776dc2d04d4cfc2c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 12 May 2020 13:32:38 +0100 Subject: [PATCH 309/507] Increase warning sign line height so that it renders correctly on smaller screens --- app/assets/stylesheets/darkswarm/shop.css.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss index 6c477acb48..0c46523184 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.scss +++ b/app/assets/stylesheets/darkswarm/shop.css.scss @@ -234,6 +234,7 @@ $sidebar-footer-height: 5em; .warning-sign { margin: 0 10px 0 5px; display: inline-block; + line-height: 1.9rem; strong { color: $grey-650; From 6e842212eac021f116a8ab277fb0acca49abdfdd Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 29 May 2020 14:29:49 +0100 Subject: [PATCH 310/507] Always throw back error even if there is an error loading the flash for example translating the error message --- .../javascripts/darkswarm/services/checkout.js.coffee | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index f0da646ebe..569382d52e 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -21,8 +21,10 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE try @handle_checkout_error_response(response) catch error - @loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error - throw error # generate a BugsnagJS alert + try + @loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error + finally + throw error # generate a BugsnagJS alert handle_checkout_error_response: (response) => if response.data.path From 538c53fe9ed8079e498dc37d1b7958fd5a3eb0ec Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 15:30:33 +0200 Subject: [PATCH 311/507] Improve code readability Also removing an useless vars --- app/controllers/admin/schedules_controller.rb | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 39e1ffc625..d0728ebc18 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -4,10 +4,10 @@ require 'order_management/subscriptions/proxy_order_syncer' module Admin class SchedulesController < ResourceController before_filter :adapt_params, only: [:update] - before_filter :check_editable_order_cycle_ids_create, only: [:create] - before_filter :check_editable_order_cycle_ids_update, only: [:update] + before_filter :editable_order_cycle_ids_for_create, only: [:create] + before_filter :editable_order_cycle_ids_for_update, only: [:update] before_filter :check_dependent_subscriptions, only: [:destroy] - update.after :sync_subscriptions_update + update.after :sync_subscriptions_for_update respond_to :json @@ -39,7 +39,7 @@ module Admin @schedule.order_cycle_ids = params[:order_cycle_ids] @schedule.save! - sync_subscriptions_create + sync_subscriptions_for_create flash[:success] = flash_message_for(@schedule, :successfully_created) respond_with(@schedule) @@ -77,24 +77,20 @@ module Admin params[:schedule][:order_cycle_ids] = params[:order_cycle_ids] end - def check_editable_order_cycle_ids_create + def editable_order_cycle_ids_for_create return unless params[:order_cycle_ids] - requested = params[:order_cycle_ids] @existing_order_cycle_ids = [] - - result = editable_order_cycles(requested) + result = editable_order_cycles(params[:order_cycle_ids]) params[:order_cycle_ids] = result end - def check_editable_order_cycle_ids_update + def editable_order_cycle_ids_for_update return unless params[:schedule][:order_cycle_ids] - requested = params[:schedule][:order_cycle_ids] @existing_order_cycle_ids = @schedule.order_cycle_ids - - result = editable_order_cycles(requested) + result = editable_order_cycles(params[:schedule][:order_cycle_ids]) params[:schedule][:order_cycle_ids] = result @schedule.order_cycle_ids = result @@ -123,13 +119,13 @@ module Admin @permissions = OpenFoodNetwork::Permissions.new(spree_current_user) end - def sync_subscriptions_update + def sync_subscriptions_for_update return unless params[:schedule][:order_cycle_ids] sync_subscriptions end - def sync_subscriptions_create + def sync_subscriptions_for_create return unless params[:order_cycle_ids] sync_subscriptions From 24e897d145dd9729ab4671ea387cc10167ce2eb0 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 29 May 2020 15:44:31 +0200 Subject: [PATCH 312/507] Do not build OC with schedules at the same time It's not possible when neither the OC nor the schedule has an id due to the new join table order_cycle_schedules. --- app/services/order_cycle_form.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/services/order_cycle_form.rb b/app/services/order_cycle_form.rb index f83b2c57e2..87292a8a0c 100644 --- a/app/services/order_cycle_form.rb +++ b/app/services/order_cycle_form.rb @@ -8,14 +8,17 @@ class OrderCycleForm @order_cycle_params = order_cycle_params @user = user @permissions = OpenFoodNetwork::Permissions.new(user) + @schedule_ids = order_cycle_params.delete(:schedule_ids) end def save - build_schedule_ids + schedule_ids = build_schedule_ids order_cycle.assign_attributes(order_cycle_params) return false unless order_cycle.valid? order_cycle.transaction do + order_cycle.save! + order_cycle.schedule_ids = schedule_ids order_cycle.save! apply_exchange_changes sync_subscriptions @@ -42,7 +45,7 @@ class OrderCycleForm end def schedule_ids? - order_cycle_params[:schedule_ids].present? + @schedule_ids.present? end def build_schedule_ids @@ -51,7 +54,7 @@ class OrderCycleForm result = existing_schedule_ids result |= (requested_schedule_ids & permitted_schedule_ids) # Add permitted and requested result -= ((result & permitted_schedule_ids) - requested_schedule_ids) # Remove permitted but not requested - order_cycle_params[:schedule_ids] = result + result end def sync_subscriptions @@ -70,7 +73,7 @@ class OrderCycleForm end def requested_schedule_ids - order_cycle_params[:schedule_ids].map(&:to_i) + @schedule_ids.map(&:to_i) end def permitted_schedule_ids From e6fa296d034f6a7dd78fd07ac280fbccd2423440 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 29 May 2020 17:26:06 +0100 Subject: [PATCH 313/507] Remove spinjs-rails dependency and use spinning-circles.svg instead. For https://github.com/openfoodfoundation/openfoodnetwork/issues/3491 The spinjs-rails gem provides a CSS3 a spinning activity indicator. This commit removes the gem so we don't have to keep the gem up-to-date and uses the spinning-circles.svg which is used already in other places. The spinjs spinner can be seen when viewing or editing taxonomies in /admin/taxonomies. It is loaded from the .ajaxStart call in app/assets/javascripts/admin/spree/progress.coffee To test or restyle this spinner you can change the display property of the #progress element in app/assets/stylesheets/admin/components/progress.scss to 'block'. --- Gemfile | 1 - Gemfile.lock | 3 - app/assets/javascripts/admin/all.js | 1 - .../javascripts/admin/spree/progress.coffee | 22 +- .../javascripts/darkswarm/all.js.coffee | 1 - .../admin/components/progress.scss | 48 ++- app/views/spree/layouts/_admin_body.html.haml | 8 +- app/views/spree/layouts/bare_admin.html.haml | 8 +- vendor/assets/javascripts/spin.js | 319 ------------------ 9 files changed, 27 insertions(+), 384 deletions(-) delete mode 100644 vendor/assets/javascripts/spin.js diff --git a/Gemfile b/Gemfile index c2d772e8d3..55ce987155 100644 --- a/Gemfile +++ b/Gemfile @@ -78,7 +78,6 @@ gem 'paperclip', '~> 3.4.1' gem 'rack-rewrite' gem 'rack-ssl', require: 'rack/ssl' gem 'roadie-rails', '~> 1.3.0' -gem 'spinjs-rails' gem 'combine_pdf' gem 'wicked_pdf' diff --git a/Gemfile.lock b/Gemfile.lock index 12760634af..c001883a08 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -624,8 +624,6 @@ GEM rack (~> 1.4) rack-protection (~> 1.4) tilt (>= 1.3, < 3) - spinjs-rails (1.4) - rails (>= 3.1) spring (1.7.2) spring-commands-rspec (1.0.4) spring (>= 0.9.1) @@ -771,7 +769,6 @@ DEPENDENCIES selenium-webdriver shoulda-matchers simplecov - spinjs-rails spree_core! spree_i18n! spree_paypal_express! diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 2bb2176233..eee8a874c9 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -30,7 +30,6 @@ //= require spree //= require admin/spree/spree-select2 //= require modernizr -//= require spin //= require equalize //= require css_browser_selector_dev //= require responsive-tables diff --git a/app/assets/javascripts/admin/spree/progress.coffee b/app/assets/javascripts/admin/spree/progress.coffee index edc20a541b..f099e40842 100644 --- a/app/assets/javascripts/admin/spree/progress.coffee +++ b/app/assets/javascripts/admin/spree/progress.coffee @@ -1,27 +1,7 @@ $(document).ready -> - opts = - lines: 11 - length: 2 - width: 3 - radius: 9 - corners: 1 - rotate: 0 - color: '#fff' - speed: 0.8 - trail: 48 - shadow: false - hwaccel: true - className: 'spinner' - zIndex: 2e9 - top: 'auto' - left: 'auto' - - target = document.getElementById("spinner") - $(document).ajaxStart -> $("#progress").fadeIn() - spinner = new Spinner(opts).spin(target) $(document).ajaxStop -> - $("#progress").fadeOut() + $("#progress").fadeOut() diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index aa0fafa058..d384494ddc 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -1,7 +1,6 @@ #= require jquery #= require jquery_ujs #= require jquery.ui.all -#= require spin # #= require angular #= require angular-cookies diff --git a/app/assets/stylesheets/admin/components/progress.scss b/app/assets/stylesheets/admin/components/progress.scss index 189689c764..f595b54072 100644 --- a/app/assets/stylesheets/admin/components/progress.scss +++ b/app/assets/stylesheets/admin/components/progress.scss @@ -1,38 +1,30 @@ @import 'admin/globals/variables'; @import 'admin/globals/mixins'; -#progress { - display: none; +#progress { + @include border-radius(10px); position: fixed; - top: 0; + top: -10px; + left: 50%; z-index: 1000; opacity: 0.8; - width: 100%; + width: 200px; + background-color: $spree-blue; + color: $color-1; + display: none; + font-size: 120%; + font-weight: bold; + line-height: 40px; + margin-left: -100px; + padding-top: 15px; + text-align: center; + text-transform: uppercase; - .wrapper { - @include border-radius(10px); - top: -10px; + img { position: absolute; + height: 30px; left: 50%; - width: 200px; - margin-left: -100px; - padding: 11px 0; - background-color: $color-3; - color: $color-1; - text-align: center; + top: -5px; + margin-left: -15px; } - - #spinner { - position: absolute; - top: 10px; - left: 50%; - margin-left: -5px; - } - - .progress-message { - font-size: 120%; - font-weight: $font-weight-bold; - margin-top: 20px; - text-transform: uppercase; - } -} \ No newline at end of file +} diff --git a/app/views/spree/layouts/_admin_body.html.haml b/app/views/spree/layouts/_admin_body.html.haml index 6fb035c825..d4d8058c7a 100644 --- a/app/views/spree/layouts/_admin_body.html.haml +++ b/app/views/spree/layouts/_admin_body.html.haml @@ -10,11 +10,9 @@ .flash.success= flash[:success] #progress - .wrapper - #spinner - .progress-message - = Spree.t(:loading) - \... + %img.spinner{ src: "/assets/spinning-circles.svg" } + = Spree.t(:loading) + \... %header#header{"data-hook" => ""} .container diff --git a/app/views/spree/layouts/bare_admin.html.haml b/app/views/spree/layouts/bare_admin.html.haml index a6e4c895ba..1289f9c01b 100644 --- a/app/views/spree/layouts/bare_admin.html.haml +++ b/app/views/spree/layouts/bare_admin.html.haml @@ -9,11 +9,9 @@ - if flash[:success] .flash.success= flash[:success] #progress - .wrapper - #spinner - .progress-message - = t(:loading) - \... + %img.spinner{ src: "/assets/spinning-circles.svg" } + = Spree.t(:loading) + \... %header#header{"data-hook" => ""} .container diff --git a/vendor/assets/javascripts/spin.js b/vendor/assets/javascripts/spin.js deleted file mode 100644 index 2a8642f311..0000000000 --- a/vendor/assets/javascripts/spin.js +++ /dev/null @@ -1,319 +0,0 @@ -//fgnass.github.com/spin.js#v1.2.6 -!function(window, document, undefined) { - - /** - * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de] - * Licensed under the MIT license - */ - - var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */ - , animations = {} /* Animation rules keyed by their name */ - , useCssAnimations - - /** - * Utility function to create elements. If no tag name is given, - * a DIV is created. Optionally properties can be passed. - */ - function createEl(tag, prop) { - var el = document.createElement(tag || 'div') - , n - - for(n in prop) el[n] = prop[n] - return el - } - - /** - * Appends children and returns the parent. - */ - function ins(parent /* child1, child2, ...*/) { - for (var i=1, n=arguments.length; i> 1) : parseInt(o.left, 10) + mid) + 'px', - top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px' - }) - } - - el.setAttribute('aria-role', 'progressbar') - self.lines(el, self.opts) - - if (!useCssAnimations) { - // No CSS animation support, use setTimeout() instead - var i = 0 - , fps = o.fps - , f = fps/o.speed - , ostep = (1-o.opacity) / (f*o.trail / 100) - , astep = f/o.lines - - ;(function anim() { - i++; - for (var s=o.lines; s; s--) { - var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity) - self.opacity(el, o.lines-s, alpha, o) - } - self.timeout = self.el && setTimeout(anim, ~~(1000/fps)) - })() - } - return self - }, - - stop: function() { - var el = this.el - if (el) { - clearTimeout(this.timeout) - if (el.parentNode) el.parentNode.removeChild(el) - this.el = undefined - } - return this - }, - - lines: function(el, o) { - var i = 0 - , seg - - function fill(color, shadow) { - return css(createEl(), { - position: 'absolute', - width: (o.length+o.width) + 'px', - height: o.width + 'px', - background: color, - boxShadow: shadow, - transformOrigin: 'left', - transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)', - borderRadius: (o.corners * o.width>>1) + 'px' - }) - } - - for (; i < o.lines; i++) { - seg = css(createEl(), { - position: 'absolute', - top: 1+~(o.width/2) + 'px', - transform: o.hwaccel ? 'translate3d(0,0,0)' : '', - opacity: o.opacity, - animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite' - }) - - if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'})) - - ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)'))) - } - return el - }, - - opacity: function(el, i, val) { - if (i < el.childNodes.length) el.childNodes[i].style.opacity = val - } - - }) - - ///////////////////////////////////////////////////////////////////////// - // VML rendering for IE - ///////////////////////////////////////////////////////////////////////// - - /** - * Check and init VML support - */ - ;(function() { - - function vml(tag, attr) { - return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr) - } - - var s = css(createEl('group'), {behavior: 'url(#default#VML)'}) - - if (!vendor(s, 'transform') && s.adj) { - - // VML support detected. Insert CSS rule ... - sheet.addRule('.spin-vml', 'behavior:url(#default#VML)') - - Spinner.prototype.lines = function(el, o) { - var r = o.length+o.width - , s = 2*r - - function grp() { - return css( - vml('group', { - coordsize: s + ' ' + s, - coordorigin: -r + ' ' + -r - }), - { width: s, height: s } - ) - } - - var margin = -(o.width+o.length)*2 + 'px' - , g = css(grp(), {position: 'absolute', top: margin, left: margin}) - , i - - function seg(i, dx, filter) { - ins(g, - ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}), - ins(css(vml('roundrect', {arcsize: o.corners}), { - width: r, - height: o.width, - left: o.radius, - top: -o.width>>1, - filter: filter - }), - vml('fill', {color: o.color, opacity: o.opacity}), - vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change - ) - ) - ) - } - - if (o.shadow) - for (i = 1; i <= o.lines; i++) - seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)') - - for (i = 1; i <= o.lines; i++) seg(i) - return ins(el, g) - } - - Spinner.prototype.opacity = function(el, i, val, o) { - var c = el.firstChild - o = o.shadow && o.lines || 0 - if (c && i+o < c.childNodes.length) { - c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild - if (c) c.opacity = val - } - } - } - else - useCssAnimations = vendor(s, 'animation') - })() - - if (typeof define == 'function' && define.amd) - define(function() { return Spinner }) - else - window.Spinner = Spinner - -}(window, document) From f773e57dee6ded8548abde08cffc943e3febb1b1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 29 May 2020 19:20:40 +0000 Subject: [PATCH 314/507] Bump i18n-js from 3.6.0 to 3.7.0 Bumps [i18n-js](https://github.com/fnando/i18n-js) from 3.6.0 to 3.7.0. - [Release notes](https://github.com/fnando/i18n-js/releases) - [Changelog](https://github.com/fnando/i18n-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/fnando/i18n-js/compare/v3.6.0...v3.7.0) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index c2d772e8d3..a013adb436 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ ruby "2.3.7" git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" } gem 'i18n', '~> 0.6.11' -gem 'i18n-js', '~> 3.6.0' +gem 'i18n-js', '~> 3.7.0' gem 'rails', '~> 3.2.22' gem 'rails-i18n', '~> 3.0.0' gem 'rails_safe_tasks', '~> 1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 12760634af..57d92ba007 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -414,7 +414,7 @@ GEM httparty (0.16.2) multi_xml (>= 0.5.2) i18n (0.6.11) - i18n-js (3.6.0) + i18n-js (3.7.0) i18n (>= 0.6.6) immigrant (0.3.6) activerecord (>= 3.0) @@ -730,7 +730,7 @@ DEPENDENCIES gmaps4rails haml i18n (~> 0.6.11) - i18n-js (~> 3.6.0) + i18n-js (~> 3.7.0) immigrant jquery-migrate-rails jquery-rails (= 3.1.5) From 19ef66f3ad323c049ed4c87509dd2b01bed83a55 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Fri, 29 May 2020 21:51:57 -0300 Subject: [PATCH 315/507] Change mail method config route --- app/controllers/spree/admin/mail_methods_controller.rb | 2 +- app/views/spree/admin/mail_methods/edit.html.haml | 4 ++-- app/views/spree/admin/shared/_configuration_menu.html.haml | 2 +- config/routes/spree.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/spree/admin/mail_methods_controller.rb b/app/controllers/spree/admin/mail_methods_controller.rb index e95739148d..a21e3afe7d 100644 --- a/app/controllers/spree/admin/mail_methods_controller.rb +++ b/app/controllers/spree/admin/mail_methods_controller.rb @@ -23,7 +23,7 @@ module Spree rescue StandardError => e flash[:error] = Spree.t('admin.mail_methods.testmail.error') % { e: e } ensure - redirect_to edit_admin_mail_method_url + redirect_to edit_admin_mail_methods_url end private diff --git a/app/views/spree/admin/mail_methods/edit.html.haml b/app/views/spree/admin/mail_methods/edit.html.haml index 90938e4542..9e79403270 100644 --- a/app/views/spree/admin/mail_methods/edit.html.haml +++ b/app/views/spree/admin/mail_methods/edit.html.haml @@ -5,11 +5,11 @@ - content_for :page_actions do %li - = link_to_with_icon 'icon-envelope-alt', t("spree.admin.mail_methods.send_testmail"), testmail_admin_mail_method_path, method: :post, title: t("spree.admin.mail_methods.send_testmail"), class: 'send_mail button no-text' + = link_to_with_icon 'icon-envelope-alt', t("spree.admin.mail_methods.send_testmail"), testmail_admin_mail_methods_path, method: :post, title: t("spree.admin.mail_methods.send_testmail"), class: 'send_mail button no-text' = render partial: 'spree/shared/error_messages', locals: { target: @mail_method } -= form_tag admin_mail_method_path, method: :put do |f| += form_tag admin_mail_methods_path, method: :put do |f| %fieldset.no-border-top = render partial: 'form', locals: { f: f } .form-buttons.filter-actions.actions= button t("spree.actions.update"), 'icon-refresh' diff --git a/app/views/spree/admin/shared/_configuration_menu.html.haml b/app/views/spree/admin/shared/_configuration_menu.html.haml index 5810cc97b2..c5f302f0db 100644 --- a/app/views/spree/admin/shared/_configuration_menu.html.haml +++ b/app/views/spree/admin/shared/_configuration_menu.html.haml @@ -6,7 +6,7 @@ %ul.sidebar = configurations_sidebar_menu_item Spree.t(:general_settings), edit_admin_general_settings_path - if Spree::Config[:override_actionmailer_config] - = configurations_sidebar_menu_item Spree.t(:mail_method_settings), edit_admin_mail_method_path + = configurations_sidebar_menu_item Spree.t(:mail_method_settings), edit_admin_mail_methods_path = configurations_sidebar_menu_item Spree.t(:image_settings), edit_admin_image_settings_path = configurations_sidebar_menu_item Spree.t(:tax_categories), admin_tax_categories_path = configurations_sidebar_menu_item Spree.t(:tax_rates), admin_tax_rates_path diff --git a/config/routes/spree.rb b/config/routes/spree.rb index fc0de19a10..bf5294be34 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -131,7 +131,7 @@ Spree::Core::Engine.routes.draw do # Configuration section resource :general_settings - resource :mail_method, :only => [:edit, :update] do + resource :mail_methods, :only => [:edit, :update] do post :testmail, :on => :collection end From 528db54f361d8b1fe08ec7d793fef82835c3d94f Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Fri, 29 May 2020 22:24:41 -0300 Subject: [PATCH 316/507] Correct controller name for matching --- app/views/spree/admin/shared/_tabs.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/admin/shared/_tabs.html.haml b/app/views/spree/admin/shared/_tabs.html.haml index 920480fc8b..e0134ee272 100644 --- a/app/views/spree/admin/shared/_tabs.html.haml +++ b/app/views/spree/admin/shared/_tabs.html.haml @@ -3,7 +3,7 @@ = tab :order_cycles, url: main_app.admin_order_cycles_path, icon: 'icon-refresh' = tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path('q[s]' => 'completed_at desc'), icon: 'icon-shopping-cart' = tab :reports, icon: 'icon-file' -= tab :general_settings, :mail_method, :image_settings, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path += tab :general_settings, :mail_methods, :image_settings, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path = tab :enterprises, :enterprise_relationships, url: main_app.admin_enterprises_path = tab :customers, url: main_app.admin_customers_path = tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups' From deafe3235455024d51184a7c39e811a474894d47 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 8 May 2020 15:40:04 +0100 Subject: [PATCH 317/507] Add support for using Open Street Map on the Map and Group pages. The map is displayed using https://leafletjs.com/ To enable Open Street Map go to the Admin -> Configuration -> Content section and click 'Open Street Map Enabled'. The 'Open Street Map Provider Name' setting can be used to configure different tile providers thanks to the Leaflet-providers extension (https://github.com/leaflet-extras/leaflet-providers) Some tile providers require an API key, this can provided in JSON format e.g. '{ apiKey: 123 }' in the 'Open Street Map Provider Options' setting. Each tile provider has their own usage policy so this should be checked before enabling Open Street Map. The search field for the Open Street Map works differently than searching on Google Maps. It matches producers by their name or address because it was easier to implement instead of matching place names all over the world. --- .../javascripts/darkswarm/all.js.coffee | 3 + .../directives/open_street_map.js.coffee | 100 ++ app/assets/stylesheets/darkswarm/all.scss | 3 + app/assets/stylesheets/darkswarm/map.css.scss | 22 + app/controllers/admin/contents_controller.rb | 3 +- app/helpers/injection_helper.rb | 4 + app/models/content_configuration.rb | 5 + app/models/preference_sections/map_section.rb | 15 + .../api/open_street_map_config_serializer.rb | 15 + app/views/groups/show.html.haml | 4 +- app/views/layouts/darkswarm.html.haml | 3 +- app/views/map/index.html.haml | 2 + app/views/shared/_map.html.haml | 20 +- config/locales/en.yml | 1 + vendor/assets/javascripts/autocomplete.min.js | 1 + vendor/assets/javascripts/leaflet-1.6.0.js | 5 + .../assets/javascripts/leaflet-providers.js | 1006 +++++++++++++++++ vendor/assets/stylesheets/autocomplete.css | 1 + vendor/assets/stylesheets/leaflet.css | 640 +++++++++++ 19 files changed, 1843 insertions(+), 10 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee create mode 100644 app/models/preference_sections/map_section.rb create mode 100644 app/serializers/api/open_street_map_config_serializer.rb create mode 100644 vendor/assets/javascripts/autocomplete.min.js create mode 100644 vendor/assets/javascripts/leaflet-1.6.0.js create mode 100644 vendor/assets/javascripts/leaflet-providers.js create mode 100644 vendor/assets/stylesheets/autocomplete.css create mode 100644 vendor/assets/stylesheets/leaflet.css diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index aa0fafa058..b697546b4d 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -8,6 +8,9 @@ #= require angular-sanitize #= require angular-animate #= require angular-resource +#= require autocomplete.min.js +#= require leaflet-1.6.0.js +#= require leaflet-providers.js #= require lodash.underscore.js # bluebird.js is a dependency of angular-google-maps.js 2.0.0 #= require bluebird.js diff --git a/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee b/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee new file mode 100644 index 0000000000..7dbdc73669 --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee @@ -0,0 +1,100 @@ +Darkswarm.directive 'ofnOpenStreetMap', ($window, Enterprises, EnterpriseModal, availableCountries, openStreetMapConfig) -> + restrict: 'E' + replace: true + scope: true + template: "
" + + link: (scope, element, attrs, ctrl, transclude)-> + map = null + markers = [] + enterpriseNames = [] + openStreetMapProviderName = openStreetMapConfig.open_street_map_provider_name + openStreetMapProviderOptions = JSON.parse(openStreetMapConfig.open_street_map_provider_options) + + average = (values) -> + total = values.reduce (sum, value) -> + sum = sum + value + , 0 + total / values.length + + averageAngle = (angleName) -> + positiveAngles = [] + negativeAngles = [] + for enterprise in Enterprises.enterprises + if enterprise.latitude? && enterprise.longitude? + if enterprise[angleName] > 0 + positiveAngles.push(enterprise[angleName]) + else + negativeAngles.push(enterprise[angleName]) + + averageNegativeAngle = average(negativeAngles) + averagePositiveAngle = average(positiveAngles) + + if negativeAngles.length == 0 + averagePositiveAngle + else if positiveAngles.length == 0 + averageNegativeAngle + else if averagePositiveAngle > averageNegativeAngle + averagePositiveAngle - averageNegativeAngle + else + averageNegativeAngle - averagePositiveAngle + + buildMarker = (enterprise, latlng, title) -> + icon = L.icon + iconUrl: enterprise.icon + marker = L.marker latlng, + draggable: true, + icon: icon, + riseOnHover: true, + title: title + marker.on "click", -> + EnterpriseModal.open enterprise + marker + + enterpriseName = (enterprise) -> + return enterprise.name + " (" + enterprise.address.address1 + ", " + enterprise.address.city + ", " + enterprise.address.state_name + ")"; + + goToEnterprise = (selectedEnterpriseName) -> + enterprise = Enterprises.enterprises.find (enterprise) -> + enterpriseName(enterprise) == selectedEnterpriseName + map.setView([enterprise.latitude, enterprise.longitude], 12) + + displayMap = -> + setMapDimensions() + averageLatitude = averageAngle("latitude") + averageLongitude = averageAngle("longitude") + zoomLevel = 6 + map = L.map('open-street-map') + L.tileLayer.provider(openStreetMapProviderName, openStreetMapProviderOptions).addTo(map) + map.setView([averageLatitude, averageLongitude], zoomLevel) + + displayEnterprises = -> + for enterprise in Enterprises.enterprises + if enterprise.latitude? && enterprise.longitude? + marker = buildMarker(enterprise, { lat: enterprise.latitude, lng: enterprise.longitude }, enterprise.name).addTo(map) + enterpriseNames.push(enterpriseName(enterprise)) + markers.push(marker) + + displaySearchField = () -> + new Autocomplete('#open-street-map--search', + onSubmit: goToEnterprise + search: searchEnterprises + ) + overwriteInlinePositionRelativeToPositionSearchField = -> + $('#open-street-map--search').css("position", "absolute") + overwriteInlinePositionRelativeToPositionSearchField() + + searchEnterprises = (input) -> + if input.length < 1 + return [] + enterpriseNames.filter (country) -> + country.toLowerCase().includes input.toLowerCase() + + setMapDimensions = -> + height = $window.innerHeight - element.offset().top + element.css "width", "100%" + element.css "height", (height + "px") + + displayMap() + displayEnterprises() + displaySearchField() diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index ee1c4fc690..11dceea0ad 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -3,6 +3,9 @@ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at * the top of the compiled file, but it's generally better to create a new file per style scope. + *= require autocomplete + *= require leaflet + *= require_self */ @import 'variables'; diff --git a/app/assets/stylesheets/darkswarm/map.css.scss b/app/assets/stylesheets/darkswarm/map.css.scss index 2af782f187..70d28a5f6b 100644 --- a/app/assets/stylesheets/darkswarm/map.css.scss +++ b/app/assets/stylesheets/darkswarm/map.css.scss @@ -6,6 +6,7 @@ .map-container { width: 100%; + position: relative; map, .angular-google-map-container, google-map, .angular-google-map { display: block; @@ -38,6 +39,27 @@ background: rgba(255, 255, 255, 1); } } + + #open-street-map { + z-index: 1; + } + + #open-street-map--search { + top: 16px; + left: 54px; + width: 50%; + z-index: 1000; + .autocomplete-input, + .autocomplete-result-list { + border: 2px solid #888; + &:hover, &:active, &:focus { + border-color: $clr-brick; + } + } + .autocomplete-result-list { + border-top: 1px dotted #888; + } + } } .map-footer { diff --git a/app/controllers/admin/contents_controller.rb b/app/controllers/admin/contents_controller.rb index 7443ac6717..1769732ec4 100644 --- a/app/controllers/admin/contents_controller.rb +++ b/app/controllers/admin/contents_controller.rb @@ -32,7 +32,8 @@ module Admin PreferenceSections::GroupSignupPageSection.new, PreferenceSections::MainLinksSection.new, PreferenceSections::FooterAndExternalLinksSection.new, - PreferenceSections::UserGuideSection.new + PreferenceSections::UserGuideSection.new, + PreferenceSections::MapSection.new ] end end diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb index 508a984920..5fbae69a40 100644 --- a/app/helpers/injection_helper.rb +++ b/app/helpers/injection_helper.rb @@ -100,6 +100,10 @@ module InjectionHelper inject_json_ams "currencyConfig", {}, Api::CurrencyConfigSerializer end + def inject_open_street_map_config + inject_json_ams "openStreetMapConfig", {}, Api::OpenStreetMapConfigSerializer + end + def inject_spree_api_key render partial: "json/injection_ams", locals: { name: 'spreeApiKey', json: "'#{@spree_api_key}'" } end diff --git a/app/models/content_configuration.rb b/app/models/content_configuration.rb index 9c29a70576..29ab8f3308 100644 --- a/app/models/content_configuration.rb +++ b/app/models/content_configuration.rb @@ -17,6 +17,11 @@ class ContentConfiguration < Spree::Preferences::FileConfiguration preference :home_show_stats, :boolean, default: true has_attached_file :home_hero, default_url: "/assets/home/home.jpg" + # Map + preference :open_street_map_enabled, :boolean, default: false + preference :open_street_map_provider_name, :string, default: "OpenStreetMap.Mapnik" + preference :open_street_map_provider_options, :text, default: "{}" + # Producer sign-up page # All the following defaults using I18n don't work. # https://github.com/openfoodfoundation/openfoodnetwork/issues/3816 diff --git a/app/models/preference_sections/map_section.rb b/app/models/preference_sections/map_section.rb new file mode 100644 index 0000000000..9fc8112cac --- /dev/null +++ b/app/models/preference_sections/map_section.rb @@ -0,0 +1,15 @@ +module PreferenceSections + class MapSection + def name + I18n.t('admin.contents.edit.map') + end + + def preferences + [ + :open_street_map_enabled, + :open_street_map_provider_name, + :open_street_map_provider_options + ] + end + end +end diff --git a/app/serializers/api/open_street_map_config_serializer.rb b/app/serializers/api/open_street_map_config_serializer.rb new file mode 100644 index 0000000000..37d6a8bd36 --- /dev/null +++ b/app/serializers/api/open_street_map_config_serializer.rb @@ -0,0 +1,15 @@ +class Api::OpenStreetMapConfigSerializer < ActiveModel::Serializer + attributes :open_street_map_enabled, :open_street_map_provider_name, :open_street_map_provider_options + + def open_street_map_enabled + ContentConfig.open_street_map_enabled + end + + def open_street_map_provider_name + ContentConfig.open_street_map_provider_name + end + + def open_street_map_provider_options + ContentConfig.open_street_map_provider_options.to_json + end +end diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index fba9eb9005..3d5af8f08e 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -6,7 +6,9 @@ = @group.logo.url - content_for :injection_data do + = inject_available_countries = inject_group_enterprises + = inject_open_street_map_config #group-page.row.pad-top.footer-pad{"ng-controller" => "GroupPageCtrl"} .small-12.columns.pad-top @@ -117,4 +119,4 @@ %span = t 'title' -= render "shared/footer" \ No newline at end of file += render "shared/footer" diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index 3986d9ace8..8e7bfd512a 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -39,7 +39,8 @@ = render "layouts/bugsnag_js" %script{:src => "https://js.stripe.com/v3/", :type => "text/javascript"} - %script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "} + - if !ContentConfig.open_street_map_enabled + %script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "} = javascript_include_tag "darkswarm/all" = javascript_include_tag "web/all" = render "layouts/i18n_script" diff --git a/app/views/map/index.html.haml b/app/views/map/index.html.haml index 9d074d31a9..741fa67064 100644 --- a/app/views/map/index.html.haml +++ b/app/views/map/index.html.haml @@ -2,6 +2,8 @@ = t :label_map - content_for :injection_data do + = inject_available_countries = inject_enterprise_shopfront_list + = inject_open_street_map_config = render partial: "shared/map" diff --git a/app/views/shared/_map.html.haml b/app/views/shared/_map.html.haml index 69f781a78c..5aa88d635c 100644 --- a/app/views/shared/_map.html.haml +++ b/app/views/shared/_map.html.haml @@ -1,11 +1,17 @@ .map-container - %map{"ng-controller" => "MapCtrl"} - %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", - styles: "map.styles", draggable: "true"} - %map-osm-tiles - %map-search - %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", - coords: "'self'", icon: "'icon'", click: "'reveal'"} + - if ContentConfig.open_street_map_enabled + %ofn-open-street-map#open-street-map + %div#open-street-map--search + %input.autocomplete-input + %ul.autocomplete-result-list + - else + %map{"ng-controller" => "MapCtrl"} + %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", + styles: "map.styles", draggable: "true"} + %map-osm-tiles + %map-search + %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", + coords: "'self'", icon: "'icon'", click: "'reveal'"} .map-footer %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors diff --git a/config/locales/en.yml b/config/locales/en.yml index 158e964b89..23b096e7ac 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -452,6 +452,7 @@ en: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: diff --git a/vendor/assets/javascripts/autocomplete.min.js b/vendor/assets/javascripts/autocomplete.min.js new file mode 100644 index 0000000000..a86832e175 --- /dev/null +++ b/vendor/assets/javascripts/autocomplete.min.js @@ -0,0 +1 @@ +var Autocomplete=function(){"use strict";function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},a=u.search,l=u.autoSelect,r=void 0!==l&&l,d=u.setValue,c=void 0===d?function(){}:d,h=u.setAttribute,p=void 0===h?function(){}:h,f=u.onUpdate,b=void 0===f?function(){}:f,v=u.onSubmit,g=void 0===v?function(){}:v,L=u.onShow,y=void 0===L?function(){}:L,w=u.onHide,m=void 0===w?function(){}:w,S=u.onLoading,x=void 0===S?function(){}:S,R=u.onLoaded,A=void 0===R?function(){}:R;t(this,e),n(this,"value",""),n(this,"searchCounter",0),n(this,"results",[]),n(this,"selectedIndex",-1),n(this,"handleInput",(function(t){var e=t.target.value;i.updateResults(e),i.value=e})),n(this,"handleKeyDown",(function(t){var e=t.key;switch(e){case"Up":case"Down":case"ArrowUp":case"ArrowDown":var n="ArrowUp"===e||"Up"===e?i.selectedIndex-1:i.selectedIndex+1;t.preventDefault(),i.handleArrows(n);break;case"Tab":i.selectResult();break;case"Enter":var s=i.results[i.selectedIndex];i.selectResult(),i.onSubmit(s);break;case"Esc":case"Escape":i.hideResults(),i.setValue();break;default:return}})),n(this,"handleFocus",(function(t){var e=t.target.value;i.updateResults(e),i.value=e})),n(this,"handleBlur",(function(){i.hideResults()})),n(this,"handleResultMouseDown",(function(t){t.preventDefault()})),n(this,"handleResultClick",(function(t){var e=t.target,n=s(e,"[data-result-index]");if(n){i.selectedIndex=parseInt(n.dataset.resultIndex,10);var o=i.results[i.selectedIndex];i.selectResult(),i.onSubmit(o)}})),n(this,"handleArrows",(function(t){var e=i.results.length;i.selectedIndex=(t%e+e)%e,i.onUpdate(i.results,i.selectedIndex)})),n(this,"selectResult",(function(){var t=i.results[i.selectedIndex];t&&i.setValue(t),i.hideResults()})),n(this,"updateResults",(function(t){var e=++i.searchCounter;i.onLoading(),i.search(t).then((function(t){e===i.searchCounter&&(i.results=t,i.onLoaded(),0!==i.results.length?(i.selectedIndex=i.autoSelect?0:-1,i.onUpdate(i.results,i.selectedIndex),i.showResults()):i.hideResults())}))})),n(this,"showResults",(function(){i.setAttribute("aria-expanded",!0),i.onShow()})),n(this,"hideResults",(function(){i.selectedIndex=-1,i.results=[],i.setAttribute("aria-expanded",!1),i.setAttribute("aria-activedescendant",""),i.onUpdate(i.results,i.selectedIndex),i.onHide()})),n(this,"checkSelectedResultVisible",(function(t){var e=t.querySelector('[data-result-index="'.concat(i.selectedIndex,'"]'));if(e){var n=t.getBoundingClientRect(),s=e.getBoundingClientRect();s.topn.bottom&&(t.scrollTop+=s.bottom-n.bottom)}})),this.search=o(a)?a:function(t){return Promise.resolve(a(t))},this.autoSelect=r,this.setValue=c,this.setAttribute=p,this.onUpdate=b,this.onSubmit=g,this.onShow=y,this.onHide=m,this.onLoading=x,this.onLoaded=A},a=0,l=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return"".concat(t).concat(++a)},r=function(t,e){var n=t.getBoundingClientRect(),i=e.getBoundingClientRect();return n.bottom+i.height>window.innerHeight&&window.innerHeight-n.bottom0?"above":"below"},d=function(t,e,n){var i;return function(){var s=this,o=arguments,u=function(){i=null,n||t.apply(s,o)},a=n&&!i;clearTimeout(i),i=setTimeout(u,e),a&&t.apply(s,o)}},c=function(){function n(e,i,s){t(this,n),this.id="".concat(s,"-result-").concat(e),this.class="".concat(s,"-result"),this["data-result-index"]=e,this.role="option",e===i&&(this["aria-selected"]="true")}var i,s,o;return i=n,(s=[{key:"toString",value:function(){var t=this;return Object.keys(this).reduce((function(e,n){return"".concat(e," ").concat(n,'="').concat(t[n],'"')}),"")}}])&&e(i.prototype,s),o&&e(i,o),n}();return function e(i){var s=this,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=o.search,h=o.onSubmit,p=void 0===h?function(){}:h,f=o.baseClass,b=void 0===f?"autocomplete":f,v=o.autoSelect,g=o.getResultValue,L=void 0===g?function(t){return t}:g,y=o.renderResult,w=o.debounceTime,m=void 0===w?0:w;t(this,e),n(this,"expanded",!1),n(this,"loading",!1),n(this,"position",{}),n(this,"resetPosition",!0),n(this,"initialize",(function(){s.root.style.position="relative",s.input.setAttribute("role","combobox"),s.input.setAttribute("autocomplete","off"),s.input.setAttribute("autocapitalize","off"),s.input.setAttribute("autocorrect","off"),s.input.setAttribute("spellcheck","false"),s.input.setAttribute("aria-autocomplete","list"),s.input.setAttribute("aria-haspopup","listbox"),s.input.setAttribute("aria-expanded","false"),s.resultList.setAttribute("role","listbox"),s.resultList.style.position="absolute",s.resultList.style.zIndex="1",s.resultList.style.width="100%",s.resultList.style.boxSizing="border-box",s.resultList.id||(s.resultList.id=l("".concat(s.baseClass,"-result-list-"))),s.input.setAttribute("aria-owns",s.resultList.id),document.body.addEventListener("click",s.handleDocumentClick),s.input.addEventListener("input",s.core.handleInput),s.input.addEventListener("keydown",s.core.handleKeyDown),s.input.addEventListener("focus",s.core.handleFocus),s.input.addEventListener("blur",s.core.handleBlur),s.resultList.addEventListener("mousedown",s.core.handleResultMouseDown),s.resultList.addEventListener("click",s.core.handleResultClick),s.updateStyle()})),n(this,"setAttribute",(function(t,e){s.input.setAttribute(t,e)})),n(this,"setValue",(function(t){s.input.value=t?s.getResultValue(t):""})),n(this,"renderResult",(function(t,e){return"
  • ").concat(s.getResultValue(t),"
  • ")})),n(this,"handleUpdate",(function(t,e){s.resultList.innerHTML="",t.forEach((function(t,n){var i=new c(n,e,s.baseClass),o=s.renderResult(t,i);"string"==typeof o?s.resultList.insertAdjacentHTML("beforeend",o):s.resultList.insertAdjacentElement("beforeend",o)})),s.input.setAttribute("aria-activedescendant",e>-1?"".concat(s.baseClass,"-result-").concat(e):""),s.resetPosition&&(s.resetPosition=!1,s.position=r(s.input,s.resultList),s.updateStyle()),s.core.checkSelectedResultVisible(s.resultList)})),n(this,"handleShow",(function(){s.expanded=!0,s.updateStyle()})),n(this,"handleHide",(function(){s.expanded=!1,s.resetPosition=!0,s.updateStyle()})),n(this,"handleLoading",(function(){s.loading=!0,s.updateStyle()})),n(this,"handleLoaded",(function(){s.loading=!1,s.updateStyle()})),n(this,"handleDocumentClick",(function(t){s.root.contains(t.target)||s.core.hideResults()})),n(this,"updateStyle",(function(){s.root.dataset.expanded=s.expanded,s.root.dataset.loading=s.loading,s.root.dataset.position=s.position,s.resultList.style.visibility=s.expanded?"visible":"hidden",s.resultList.style.pointerEvents=s.expanded?"auto":"none","below"===s.position?(s.resultList.style.bottom=null,s.resultList.style.top="100%"):(s.resultList.style.top=null,s.resultList.style.bottom="100%")})),this.root="string"==typeof i?document.querySelector(i):i,this.input=this.root.querySelector("input"),this.resultList=this.root.querySelector("ul"),this.baseClass=b,this.getResultValue=L,"function"==typeof y&&(this.renderResult=y);var S=new u({search:a,autoSelect:v,setValue:this.setValue,setAttribute:this.setAttribute,onUpdate:this.handleUpdate,onSubmit:p,onShow:this.handleShow,onHide:this.handleHide,onLoading:this.handleLoading,onLoaded:this.handleLoaded});m>0&&(S.handleInput=d(S.handleInput,m)),this.core=S,this.initialize()}}(); diff --git a/vendor/assets/javascripts/leaflet-1.6.0.js b/vendor/assets/javascripts/leaflet-1.6.0.js new file mode 100644 index 0000000000..bc9ef0f551 --- /dev/null +++ b/vendor/assets/javascripts/leaflet-1.6.0.js @@ -0,0 +1,5 @@ +/* @preserve + * Leaflet 1.6.0+Detached: 0c81bdf904d864fd12a286e3d1979f47aba17991.0c81bdf, a JS library for interactive maps. http://leafletjs.com + * (c) 2010-2019 Vladimir Agafonkin, (c) 2010-2011 CloudMade + */ +!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";var i=Object.freeze;function h(t){var i,e,n,o;for(e=1,n=arguments.length;e=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=R(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=R(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=D(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=D(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}();function Bt(t){return 0<=navigator.userAgent.toLowerCase().indexOf(t)}var At=(Object.freeze||Object)({ie:it,ielt9:et,edge:nt,webkit:ot,android:st,android23:rt,androidStock:ht,opera:ut,chrome:lt,gecko:ct,safari:_t,phantom:dt,opera12:pt,win:mt,ie3d:ft,webkit3d:gt,gecko3d:vt,any3d:yt,mobile:xt,mobileWebkit:wt,mobileWebkit3d:Pt,msPointer:Lt,pointer:bt,touch:Tt,mobileOpera:zt,mobileGecko:Mt,retina:Ct,passiveEvents:Et,canvas:St,svg:Zt,vml:kt}),It=Lt?"MSPointerDown":"pointerdown",Ot=Lt?"MSPointerMove":"pointermove",Rt=Lt?"MSPointerUp":"pointerup",Nt=Lt?"MSPointerCancel":"pointercancel",Dt=["INPUT","SELECT","OPTION"],jt={},Wt=!1,Ht=0;function Ft(t,i,e,n){return"touchstart"===i?function(t,i,e){var n=a(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(Dt.indexOf(t.target.tagName)<0))return;ji(t)}Gt(t,i)});t["_leaflet_touchstart"+e]=n,t.addEventListener(It,n,!1),Wt||(document.documentElement.addEventListener(It,Ut,!0),document.documentElement.addEventListener(Ot,Vt,!0),document.documentElement.addEventListener(Rt,qt,!0),document.documentElement.addEventListener(Nt,qt,!0),Wt=!0)}(t,e,n):"touchmove"===i?function(t,i,e){function n(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&Gt(t,i)}t["_leaflet_touchmove"+e]=n,t.addEventListener(Ot,n,!1)}(t,e,n):"touchend"===i&&function(t,i,e){function n(t){Gt(t,i)}t["_leaflet_touchend"+e]=n,t.addEventListener(Rt,n,!1),t.addEventListener(Nt,n,!1)}(t,e,n),this}function Ut(t){jt[t.pointerId]=t,Ht++}function Vt(t){jt[t.pointerId]&&(jt[t.pointerId]=t)}function qt(t){delete jt[t.pointerId],Ht--}function Gt(t,i){for(var e in t.touches=[],jt)t.touches.push(jt[e]);t.changedTouches=[t],i(t)}var Kt=Lt?"MSPointerDown":bt?"pointerdown":"touchstart",Yt=Lt?"MSPointerUp":bt?"pointerup":"touchend",Xt="_leaflet_";function Jt(t,o,i){var s,r,a=!1;function e(t){var i;if(bt){if(!nt||"mouse"===t.pointerType)return;i=Ht}else i=t.touches.length;if(!(1this.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,D(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},panInside:function(t,i){var e=I((i=i||{}).paddingTopLeft||i.padding||[0,0]),n=I(i.paddingBottomRight||i.padding||[0,0]),o=this.getCenter(),s=this.project(o),r=this.project(t),a=this.getPixelBounds(),h=a.getSize().divideBy(2),u=R([a.min.add(e),a.max.subtract(n)]);if(!u.contains(r)){this._enforcingBounds=!0;var l=s.subtract(r),c=I(r.x+l.x,r.y+l.y);(r.xu.max.x)&&(c.x=s.x-l.x,0u.max.y)&&(c.y=s.y-l.y,0=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,n=[],o="mouseout"===i||"mouseover"===i,s=t.target||t.srcElement,r=!1;s;){if((e=this._targets[u(s)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){r=!0;break}if(e&&e.listens(i,!0)){if(o&&!Yi(s,t))break;if(n.push(e),o)break}if(s===this._container)break;s=s.parentNode}return n.length||r||o||!Yi(s,t)||(n=[this]),n},_handleDOMEvent:function(t){if(this._loaded&&!Ki(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i&&"keyup"!==i&&"keydown"!==i||Mi(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,i,e){if("click"===t.type){var n=h({},t);n.type="preclick",this._fireDOMEvent(n,n.type,e)}if(!t._stopped&&(e=(e||[]).concat(this._findEventTargets(t,i))).length){var o=e[0];"contextmenu"===i&&o.listens(i,!0)&&ji(t);var s={originalEvent:t};if("keypress"!==t.type&&"keydown"!==t.type&&"keyup"!==t.type){var r=o.getLatLng&&(!o._radius||o._radius<=10);s.containerPoint=r?this.latLngToContainerPoint(o.getLatLng()):this.mouseEventToContainerPoint(t),s.layerPoint=this.containerPointToLayerPoint(s.containerPoint),s.latlng=r?o.getLatLng():this.layerPointToLatLng(s.layerPoint)}for(var a=0;athis.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(M(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,e,n){this._mapPane&&(e&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,mi(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:n}),setTimeout(a(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&fi(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),M(function(){this._moveEnd(!0)},this))}});function Qi(t){return new te(t)}var te=S.extend({options:{position:"topright"},initialize:function(t){p(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return mi(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this._map.on("unload",this.remove,this),this},remove:function(){return this._map&&(li(this._container),this.onRemove&&this.onRemove(this._map),this._map.off("unload",this.remove,this),this._map=null),this},_refocusOnMap:function(t){this._map&&t&&0",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),n=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=n):i=this._createRadioElement("leaflet-base-layers_"+u(this),n),this._layerControlInputs.push(i),i.layerId=u(t.layer),ki(i,"click",this._onInputClick,this);var o=document.createElement("span");o.innerHTML=" "+t.name;var s=document.createElement("div");return e.appendChild(s),s.appendChild(i),s.appendChild(o),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;0<=s;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;si.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),ee=te.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=ui("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=ui("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),Di(s),ki(s,"click",Wi),ki(s,"click",o,this),ki(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";fi(this._zoomInButton,i),fi(this._zoomOutButton,i),!this._disabled&&t._zoom!==t.getMinZoom()||mi(this._zoomOutButton,i),!this._disabled&&t._zoom!==t.getMaxZoom()||mi(this._zoomInButton,i)}});$i.mergeOptions({zoomControl:!0}),$i.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new ee,this.addControl(this.zoomControl))});var ne=te.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i="leaflet-control-scale",e=ui("div",i),n=this.options;return this._addScales(n,i+"-line",e),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),e},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=ui("div",i,e)),t.imperial&&(this._iScale=ui("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;5280Leaflet'},initialize:function(t){p(this,t),this._attributions={}},onAdd:function(t){for(var i in(t.attributionControl=this)._container=ui("div","leaflet-control-attribution"),Di(this._container),t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t&&(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update()),this},removeAttribution:function(t){return t&&this._attributions[t]&&(this._attributions[t]--,this._update()),this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});$i.mergeOptions({attributionControl:!0}),$i.addInitHook(function(){this.options.attributionControl&&(new oe).addTo(this)});te.Layers=ie,te.Zoom=ee,te.Scale=ne,te.Attribution=oe,Qi.layers=function(t,i,e){return new ie(t,i,e)},Qi.zoom=function(t){return new ee(t)},Qi.scale=function(t){return new ne(t)},Qi.attribution=function(t){return new oe(t)};var se=S.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled||(this._enabled=!0,this.addHooks()),this},disable:function(){return this._enabled&&(this._enabled=!1,this.removeHooks()),this},enabled:function(){return!!this._enabled}});se.addTo=function(t,i){return t.addHandler(i,this),this};var re,ae={Events:Z},he=Tt?"touchstart mousedown":"mousedown",ue={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},le={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},ce=k.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){p(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(ki(this._dragStartTarget,he,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(ce._dragging===this&&this.finishDrag(),Ai(this._dragStartTarget,he,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!pi(this._element,"leaflet-zoom-anim")&&!(ce._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||((ce._dragging=this)._preventOutline&&Mi(this._element),Ti(),Qt(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t,e=Ei(this._element);this._startPoint=new B(i.clientX,i.clientY),this._parentScale=Si(e),ki(document,le[t.type],this._onMove,this),ki(document,ue[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&1i.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function ge(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return 0this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()t.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||je.prototype._containsPoint.call(this,t,!0)}});var He=ke.extend({initialize:function(t,i){p(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=v(t)?t:t.features;if(o){for(i=0,e=o.length;iu.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Wi(t)},_getAnchor:function(){return I(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});$i.mergeOptions({closePopupOnClick:!0}),$i.include({openPopup:function(t,i,e){return t instanceof sn||(t=new sn(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),Se.include({bindPopup:function(t,i){return t instanceof sn?(p(t,i),(this._popup=t)._source=this):(this._popup&&!i||(this._popup=new sn(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){return this._popup&&this._map&&(i=this._popup._prepareOpen(this,t,i),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Wi(t),i instanceof Re?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var rn=on.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){on.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){on.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=on.prototype.getEvents.call(this);return Tt&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=ui("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=I(this.options.offset),u=this._getAnchor();t="top"===s?t.add(I(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t.subtract(I(r/2-h.x,-h.y,!0)):"center"===s?t.subtract(I(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.xthis.options.maxZoom||ethis.options.maxZoom||void 0!==this.options.minZoom&&oe.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return D(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new N(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new B(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(li(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){mi(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=l,t.onmousemove=l,et&&this.options.opacity<1&&yi(t,this.options.opacity),st&&!rt&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var e=this._getTilePos(t),n=this._tileCoordsToKey(t),o=this.createTile(this._wrapCoords(t),a(this._tileReady,this,t));this._initTile(o),this.createTile.length<2&&M(a(this._tileReady,this,t,null,o)),Pi(o,e),this._tiles[n]={el:o,coords:t,current:!0},i.appendChild(o),this.fire("tileloadstart",{tile:o,coords:t})},_tileReady:function(t,i,e){i&&this.fire("tileerror",{error:i,tile:e,coords:t});var n=this._tileCoordsToKey(t);(e=this._tiles[n])&&(e.loaded=+new Date,this._map._fadeAnimated?(yi(e.el,0),C(this._fadeFrame),this._fadeFrame=M(this._updateOpacity,this)):(e.active=!0,this._pruneTiles()),i||(mi(e.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:e.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),et||!this._map._fadeAnimated?M(this._pruneTiles,this):setTimeout(a(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new B(this._wrapX?r(t.x,this._wrapX):t.x,this._wrapY?r(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new O(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}});var un=hn.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=p(this,i)).detectRetina&&Ct&&0')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),fn={_initContainer:function(){this._container=ui("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(_n.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=mn("shape");mi(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=mn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[u(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;li(i),t.removeInteractiveTarget(i),delete this._layers[u(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=mn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=v(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=mn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){_i(t._container)},_bringToBack:function(t){di(t._container)}},gn=kt?mn:$,vn=_n.extend({getEvents:function(){var t=_n.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=gn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=gn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){li(this._container),Ai(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){_n.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),Pi(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=gn("path");t.options.className&&mi(i,t.options.className),t.options.interactive&&mi(i,"leaflet-interactive"),this._updateStyle(t),this._layers[u(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){li(t._path),t.removeInteractiveTarget(t._path),delete this._layers[u(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,Q(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){_i(t._path)},_bringToBack:function(t){di(t._path)}});function yn(t){return Zt||kt?new vn(t):null}kt&&vn.include(fn),$i.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this._createRenderer()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=this._createRenderer({pane:t}),this._paneRenderers[t]=i),i},_createRenderer:function(t){return this.options.preferCanvas&&pn(t)||yn(t)}});var xn=We.extend({initialize:function(t,i){We.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return[(t=D(t)).getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});vn.create=gn,vn.pointsToPath=Q,He.geometryToLayer=Fe,He.coordsToLatLng=Ve,He.coordsToLatLngs=qe,He.latLngToCoords=Ge,He.latLngsToCoords=Ke,He.getFeature=Ye,He.asFeature=Xe,$i.mergeOptions({boxZoom:!0});var wn=se.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){ki(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){Ai(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){li(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),Qt(),Ti(),this._startPoint=this._map.mouseEventToContainerPoint(t),ki(document,{contextmenu:Wi,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=ui("div","leaflet-zoom-box",this._container),mi(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new O(this._point,this._startPoint),e=i.getSize();Pi(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(li(this._box),fi(this._container,"leaflet-crosshair")),ti(),zi(),Ai(document,{contextmenu:Wi,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(a(this._resetState,this),0);var i=new N(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});$i.addInitHook("addHandler","boxZoom",wn),$i.mergeOptions({doubleClickZoom:!0});var Pn=se.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});$i.addInitHook("addHandler","doubleClickZoom",Pn),$i.mergeOptions({dragging:!0,inertia:!rt,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var Ln=se.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new ce(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}mi(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){fi(this._map._container,"leaflet-grab"),fi(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=D(this._map.options.maxBounds);this._offsetLimit=R(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;1i.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)i.getMaxZoom()&&1OpenStreetMap contributors' + }, + variants: { + Mapnik: {}, + DE: { + url: 'https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', + options: { + maxZoom: 18 + } + }, + CH: { + url: 'https://tile.osm.ch/switzerland/{z}/{x}/{y}.png', + options: { + maxZoom: 18, + bounds: [[45, 5], [48, 11]] + } + }, + France: { + url: 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', + options: { + maxZoom: 20, + attribution: '© Openstreetmap France | {attribution.OpenStreetMap}' + } + }, + HOT: { + url: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', + options: { + attribution: + '{attribution.OpenStreetMap}, ' + + 'Tiles style by Humanitarian OpenStreetMap Team ' + + 'hosted by OpenStreetMap France' + } + }, + BZH: { + url: 'https://tile.openstreetmap.bzh/br/{z}/{x}/{y}.png', + options: { + attribution: '{attribution.OpenStreetMap}, Tiles courtesy of Breton OpenStreetMap Team', + bounds: [[46.2, -5.5], [50, 0.7]] + } + } + } + }, + OpenSeaMap: { + url: 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', + options: { + attribution: 'Map data: © OpenSeaMap contributors' + } + }, + OpenPtMap: { + url: 'http://openptmap.org/tiles/{z}/{x}/{y}.png', + options: { + maxZoom: 17, + attribution: 'Map data: © OpenPtMap contributors' + } + }, + OpenTopoMap: { + url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', + options: { + maxZoom: 17, + attribution: 'Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA)' + } + }, + OpenRailwayMap: { + url: 'https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © OpenRailwayMap (CC-BY-SA)' + } + }, + OpenFireMap: { + url: 'http://openfiremap.org/hytiles/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © OpenFireMap (CC-BY-SA)' + } + }, + SafeCast: { + url: 'https://s3.amazonaws.com/te512.safecast.org/{z}/{x}/{y}.png', + options: { + maxZoom: 16, + attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © SafeCast (CC-BY-SA)' + } + }, + Stadia: { + url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png', + options: { + maxZoom: 20, + attribution: '© Stadia Maps, © OpenMapTiles © OpenStreetMap contributors' + }, + variants: { + AlidadeSmooth: { + url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png' + }, + AlidadeSmoothDark: { + url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png' + }, + OSMBright: { + url: 'https://tiles.stadiamaps.com/tiles/osm_bright/{z}/{x}/{y}{r}.png' + }, + Outdoors: { + url: 'https://tiles.stadiamaps.com/tiles/outdoors/{z}/{x}/{y}{r}.png' + } + } + }, + Thunderforest: { + url: 'https://{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png?apikey={apikey}', + options: { + attribution: + '© Thunderforest, {attribution.OpenStreetMap}', + variant: 'cycle', + apikey: '', + maxZoom: 22 + }, + variants: { + OpenCycleMap: 'cycle', + Transport: { + options: { + variant: 'transport' + } + }, + TransportDark: { + options: { + variant: 'transport-dark' + } + }, + SpinalMap: { + options: { + variant: 'spinal-map' + } + }, + Landscape: 'landscape', + Outdoors: 'outdoors', + Pioneer: 'pioneer', + MobileAtlas: 'mobile-atlas', + Neighbourhood: 'neighbourhood' + } + }, + CyclOSM: { + url: 'https://dev.{s}.tile.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', + options: { + maxZoom: 20, + attribution: 'CyclOSM | Map data: {attribution.OpenStreetMap}' + } + }, + OpenMapSurfer: { + url: 'https://maps.heigit.org/openmapsurfer/tiles/{variant}/webmercator/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + variant: 'roads', + attribution: 'Imagery from GIScience Research Group @ University of Heidelberg | Map data ' + }, + variants: { + Roads: { + options: { + variant: 'roads', + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + }, + Hybrid: { + options: { + variant: 'hybrid', + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + }, + AdminBounds: { + options: { + variant: 'adminb', + maxZoom: 18, + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + }, + ContourLines: { + options: { + variant: 'asterc', + maxZoom: 18, + minZoom: 13, + attribution: '{attribution.OpenMapSurfer} ASTER GDEM' + } + }, + Hillshade: { + options: { + variant: 'asterh', + maxZoom: 18, + attribution: '{attribution.OpenMapSurfer} ASTER GDEM, SRTM' + } + }, + ElementsAtRisk: { + options: { + variant: 'elements_at_risk', + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + } + } + }, + Hydda: { + url: 'https://{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png', + options: { + maxZoom: 18, + variant: 'full', + attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}' + }, + variants: { + Full: 'full', + Base: 'base', + RoadsAndLabels: 'roads_and_labels' + } + }, + MapBox: { + url: 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}{r}.png?access_token={accessToken}', + options: { + attribution: + '© Mapbox ' + + '{attribution.OpenStreetMap} ' + + 'Improve this map', + subdomains: 'abcd', + id: 'mapbox.streets', + accessToken: '', + } + }, + Stamen: { + url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}{r}.{ext}', + options: { + attribution: + 'Map tiles by Stamen Design, ' + + 'CC BY 3.0 — ' + + 'Map data {attribution.OpenStreetMap}', + subdomains: 'abcd', + minZoom: 0, + maxZoom: 20, + variant: 'toner', + ext: 'png' + }, + variants: { + Toner: 'toner', + TonerBackground: 'toner-background', + TonerHybrid: 'toner-hybrid', + TonerLines: 'toner-lines', + TonerLabels: 'toner-labels', + TonerLite: 'toner-lite', + Watercolor: { + url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', + options: { + variant: 'watercolor', + ext: 'jpg', + minZoom: 1, + maxZoom: 16 + } + }, + Terrain: { + options: { + variant: 'terrain', + minZoom: 0, + maxZoom: 18 + } + }, + TerrainBackground: { + options: { + variant: 'terrain-background', + minZoom: 0, + maxZoom: 18 + } + }, + TerrainLabels: { + options: { + variant: 'terrain-labels', + minZoom: 0, + maxZoom: 18 + } + }, + TopOSMRelief: { + url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', + options: { + variant: 'toposm-color-relief', + ext: 'jpg', + bounds: [[22, -132], [51, -56]] + } + }, + TopOSMFeatures: { + options: { + variant: 'toposm-features', + bounds: [[22, -132], [51, -56]], + opacity: 0.9 + } + } + } + }, + TomTom: { + url: 'https://{s}.api.tomtom.com/map/1/tile/{variant}/{style}/{z}/{x}/{y}.{ext}?key={apikey}', + options: { + variant: 'basic', + maxZoom: 22, + attribution: + '© 1992 - ' + new Date().getFullYear() + ' TomTom. ', + subdomains: 'abcd', + style: 'main', + ext: 'png', + apikey: '', + }, + variants: { + Basic: 'basic', + Hybrid: 'hybrid', + Labels: 'labels' + } + }, + Esri: { + url: 'https://server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}', + options: { + variant: 'World_Street_Map', + attribution: 'Tiles © Esri' + }, + variants: { + WorldStreetMap: { + options: { + attribution: + '{attribution.Esri} — ' + + 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' + } + }, + DeLorme: { + options: { + variant: 'Specialty/DeLorme_World_Base_Map', + minZoom: 1, + maxZoom: 11, + attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme' + } + }, + WorldTopoMap: { + options: { + variant: 'World_Topo_Map', + attribution: + '{attribution.Esri} — ' + + 'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community' + } + }, + WorldImagery: { + options: { + variant: 'World_Imagery', + attribution: + '{attribution.Esri} — ' + + 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' + } + }, + WorldTerrain: { + options: { + variant: 'World_Terrain_Base', + maxZoom: 13, + attribution: + '{attribution.Esri} — ' + + 'Source: USGS, Esri, TANA, DeLorme, and NPS' + } + }, + WorldShadedRelief: { + options: { + variant: 'World_Shaded_Relief', + maxZoom: 13, + attribution: '{attribution.Esri} — Source: Esri' + } + }, + WorldPhysical: { + options: { + variant: 'World_Physical_Map', + maxZoom: 8, + attribution: '{attribution.Esri} — Source: US National Park Service' + } + }, + OceanBasemap: { + options: { + variant: 'Ocean_Basemap', + maxZoom: 13, + attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri' + } + }, + NatGeoWorldMap: { + options: { + variant: 'NatGeo_World_Map', + maxZoom: 16, + attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC' + } + }, + WorldGrayCanvas: { + options: { + variant: 'Canvas/World_Light_Gray_Base', + maxZoom: 16, + attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ' + } + } + } + }, + OpenWeatherMap: { + url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png?appid={apiKey}', + options: { + maxZoom: 19, + attribution: 'Map data © OpenWeatherMap', + apiKey:'', + opacity: 0.5 + }, + variants: { + Clouds: 'clouds', + CloudsClassic: 'clouds_cls', + Precipitation: 'precipitation', + PrecipitationClassic: 'precipitation_cls', + Rain: 'rain', + RainClassic: 'rain_cls', + Pressure: 'pressure', + PressureContour: 'pressure_cntr', + Wind: 'wind', + Temperature: 'temp', + Snow: 'snow' + } + }, + HERE: { + /* + * HERE maps, formerly Nokia maps. + * These basemaps are free, but you need an api id and app key. Please sign up at + * https://developer.here.com/plans + */ + url: + 'https://{s}.{base}.maps.api.here.com/maptile/2.1/' + + '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' + + 'app_id={app_id}&app_code={app_code}&lg={language}', + options: { + attribution: + 'Map © 1987-' + new Date().getFullYear() + ' HERE', + subdomains: '1234', + mapID: 'newest', + 'app_id': '', + 'app_code': '', + base: 'base', + variant: 'normal.day', + maxZoom: 20, + type: 'maptile', + language: 'eng', + format: 'png8', + size: '256' + }, + variants: { + normalDay: 'normal.day', + normalDayCustom: 'normal.day.custom', + normalDayGrey: 'normal.day.grey', + normalDayMobile: 'normal.day.mobile', + normalDayGreyMobile: 'normal.day.grey.mobile', + normalDayTransit: 'normal.day.transit', + normalDayTransitMobile: 'normal.day.transit.mobile', + normalDayTraffic: { + options: { + variant: 'normal.traffic.day', + base: 'traffic', + type: 'traffictile' + } + }, + normalNight: 'normal.night', + normalNightMobile: 'normal.night.mobile', + normalNightGrey: 'normal.night.grey', + normalNightGreyMobile: 'normal.night.grey.mobile', + normalNightTransit: 'normal.night.transit', + normalNightTransitMobile: 'normal.night.transit.mobile', + reducedDay: 'reduced.day', + reducedNight: 'reduced.night', + basicMap: { + options: { + type: 'basetile' + } + }, + mapLabels: { + options: { + type: 'labeltile', + format: 'png' + } + }, + trafficFlow: { + options: { + base: 'traffic', + type: 'flowtile' + } + }, + carnavDayGrey: 'carnav.day.grey', + hybridDay: { + options: { + base: 'aerial', + variant: 'hybrid.day' + } + }, + hybridDayMobile: { + options: { + base: 'aerial', + variant: 'hybrid.day.mobile' + } + }, + hybridDayTransit: { + options: { + base: 'aerial', + variant: 'hybrid.day.transit' + } + }, + hybridDayGrey: { + options: { + base: 'aerial', + variant: 'hybrid.grey.day' + } + }, + hybridDayTraffic: { + options: { + variant: 'hybrid.traffic.day', + base: 'traffic', + type: 'traffictile' + } + }, + pedestrianDay: 'pedestrian.day', + pedestrianNight: 'pedestrian.night', + satelliteDay: { + options: { + base: 'aerial', + variant: 'satellite.day' + } + }, + terrainDay: { + options: { + base: 'aerial', + variant: 'terrain.day' + } + }, + terrainDayMobile: { + options: { + base: 'aerial', + variant: 'terrain.day.mobile' + } + } + } + }, + HEREv3: { + /* + * HERE maps API Version 3. + * These basemaps are free, but you need an API key. Please sign up at + * https://developer.here.com/plans + * Version 3 deprecates the app_id and app_code access in favor of apiKey + * + * Supported access methods as of 2019/12/21: + * @see https://developer.here.com/faqs#access-control-1--how-do-you-control-access-to-here-location-services + */ + url: + 'https://{s}.{base}.maps.ls.hereapi.com/maptile/2.1/' + + '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' + + 'apiKey={apiKey}&lg={language}', + options: { + attribution: + 'Map © 1987-' + new Date().getFullYear() + ' HERE', + subdomains: '1234', + mapID: 'newest', + apiKey: '', + base: 'base', + variant: 'normal.day', + maxZoom: 20, + type: 'maptile', + language: 'eng', + format: 'png8', + size: '256' + }, + variants: { + normalDay: 'normal.day', + normalDayCustom: 'normal.day.custom', + normalDayGrey: 'normal.day.grey', + normalDayMobile: 'normal.day.mobile', + normalDayGreyMobile: 'normal.day.grey.mobile', + normalDayTransit: 'normal.day.transit', + normalDayTransitMobile: 'normal.day.transit.mobile', + normalNight: 'normal.night', + normalNightMobile: 'normal.night.mobile', + normalNightGrey: 'normal.night.grey', + normalNightGreyMobile: 'normal.night.grey.mobile', + normalNightTransit: 'normal.night.transit', + normalNightTransitMobile: 'normal.night.transit.mobile', + reducedDay: 'reduced.day', + reducedNight: 'reduced.night', + basicMap: { + options: { + type: 'basetile' + } + }, + mapLabels: { + options: { + type: 'labeltile', + format: 'png' + } + }, + trafficFlow: { + options: { + base: 'traffic', + type: 'flowtile' + } + }, + carnavDayGrey: 'carnav.day.grey', + hybridDay: { + options: { + base: 'aerial', + variant: 'hybrid.day' + } + }, + hybridDayMobile: { + options: { + base: 'aerial', + variant: 'hybrid.day.mobile' + } + }, + hybridDayTransit: { + options: { + base: 'aerial', + variant: 'hybrid.day.transit' + } + }, + hybridDayGrey: { + options: { + base: 'aerial', + variant: 'hybrid.grey.day' + } + }, + pedestrianDay: 'pedestrian.day', + pedestrianNight: 'pedestrian.night', + satelliteDay: { + options: { + base: 'aerial', + variant: 'satellite.day' + } + }, + terrainDay: { + options: { + base: 'aerial', + variant: 'terrain.day' + } + }, + terrainDayMobile: { + options: { + base: 'aerial', + variant: 'terrain.day.mobile' + } + } + } + }, + FreeMapSK: { + url: 'http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg', + options: { + minZoom: 8, + maxZoom: 16, + subdomains: '1234', + bounds: [[47.204642, 15.996093], [49.830896, 22.576904]], + attribution: + '{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk' + } + }, + MtbMap: { + url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png', + options: { + attribution: + '{attribution.OpenStreetMap} & USGS' + } + }, + CartoDB: { + url: 'https://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}{r}.png', + options: { + attribution: '{attribution.OpenStreetMap} © CARTO', + subdomains: 'abcd', + maxZoom: 19, + variant: 'light_all' + }, + variants: { + Positron: 'light_all', + PositronNoLabels: 'light_nolabels', + PositronOnlyLabels: 'light_only_labels', + DarkMatter: 'dark_all', + DarkMatterNoLabels: 'dark_nolabels', + DarkMatterOnlyLabels: 'dark_only_labels', + Voyager: 'rastertiles/voyager', + VoyagerNoLabels: 'rastertiles/voyager_nolabels', + VoyagerOnlyLabels: 'rastertiles/voyager_only_labels', + VoyagerLabelsUnder: 'rastertiles/voyager_labels_under' + } + }, + HikeBike: { + url: 'https://tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: '{attribution.OpenStreetMap}', + variant: 'hikebike' + }, + variants: { + HikeBike: {}, + HillShading: { + options: { + maxZoom: 15, + variant: 'hillshading' + } + } + } + }, + BasemapAT: { + url: 'https://maps{s}.wien.gv.at/basemap/{variant}/{type}/google3857/{z}/{y}/{x}.{format}', + options: { + maxZoom: 19, + attribution: 'Datenquelle: basemap.at', + subdomains: ['', '1', '2', '3', '4'], + type: 'normal', + format: 'png', + bounds: [[46.358770, 8.782379], [49.037872, 17.189532]], + variant: 'geolandbasemap' + }, + variants: { + basemap: { + options: { + maxZoom: 20, // currently only in Vienna + variant: 'geolandbasemap' + } + }, + grau: 'bmapgrau', + overlay: 'bmapoverlay', + terrain: { + options: { + variant: 'bmapgelaende', + type: 'grau', + format: 'jpeg' + } + }, + surface: { + options: { + variant: 'bmapoberflaeche', + type: 'grau', + format: 'jpeg' + } + }, + highdpi: { + options: { + variant: 'bmaphidpi', + format: 'jpeg' + } + }, + orthofoto: { + options: { + maxZoom: 20, // currently only in Vienna + variant: 'bmaporthofoto30cm', + format: 'jpeg' + } + } + } + }, + nlmaps: { + url: 'https://geodata.nationaalgeoregister.nl/tiles/service/wmts/{variant}/EPSG:3857/{z}/{x}/{y}.png', + options: { + minZoom: 6, + maxZoom: 19, + bounds: [[50.5, 3.25], [54, 7.6]], + attribution: 'Kaartgegevens © Kadaster' + }, + variants: { + 'standaard': 'brtachtergrondkaart', + 'pastel': 'brtachtergrondkaartpastel', + 'grijs': 'brtachtergrondkaartgrijs', + 'luchtfoto': { + 'url': 'https://geodata.nationaalgeoregister.nl/luchtfoto/rgb/wmts/2018_ortho25/EPSG:3857/{z}/{x}/{y}.png', + } + } + }, + NASAGIBS: { + url: 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}', + options: { + attribution: + 'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ' + + '(ESDIS) with funding provided by NASA/HQ.', + bounds: [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]], + minZoom: 1, + maxZoom: 9, + format: 'jpg', + time: '', + tilematrixset: 'GoogleMapsCompatible_Level' + }, + variants: { + ModisTerraTrueColorCR: 'MODIS_Terra_CorrectedReflectance_TrueColor', + ModisTerraBands367CR: 'MODIS_Terra_CorrectedReflectance_Bands367', + ViirsEarthAtNight2012: { + options: { + variant: 'VIIRS_CityLights_2012', + maxZoom: 8 + } + }, + ModisTerraLSTDay: { + options: { + variant: 'MODIS_Terra_Land_Surface_Temp_Day', + format: 'png', + maxZoom: 7, + opacity: 0.75 + } + }, + ModisTerraSnowCover: { + options: { + variant: 'MODIS_Terra_Snow_Cover', + format: 'png', + maxZoom: 8, + opacity: 0.75 + } + }, + ModisTerraAOD: { + options: { + variant: 'MODIS_Terra_Aerosol', + format: 'png', + maxZoom: 6, + opacity: 0.75 + } + }, + ModisTerraChlorophyll: { + options: { + variant: 'MODIS_Terra_Chlorophyll_A', + format: 'png', + maxZoom: 7, + opacity: 0.75 + } + } + } + }, + NLS: { + // NLS maps are copyright National library of Scotland. + // http://maps.nls.uk/projects/api/index.html + // Please contact NLS for anything other than non-commercial low volume usage + // + // Map sources: Ordnance Survey 1:1m to 1:63K, 1920s-1940s + // z0-9 - 1:1m + // z10-11 - quarter inch (1:253440) + // z12-18 - one inch (1:63360) + url: 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', + options: { + attribution: 'National Library of Scotland Historic Maps', + bounds: [[49.6, -12], [61.7, 3]], + minZoom: 1, + maxZoom: 18, + subdomains: '0123', + } + }, + JusticeMap: { + // Justice Map (http://www.justicemap.org/) + // Visualize race and income data for your community, county and country. + // Includes tools for data journalists, bloggers and community activists. + url: 'http://www.justicemap.org/tile/{size}/{variant}/{z}/{x}/{y}.png', + options: { + attribution: 'Justice Map', + // one of 'county', 'tract', 'block' + size: 'county', + // Bounds for USA, including Alaska and Hawaii + bounds: [[14, -180], [72, -56]] + }, + variants: { + income: 'income', + americanIndian: 'indian', + asian: 'asian', + black: 'black', + hispanic: 'hispanic', + multi: 'multi', + nonWhite: 'nonwhite', + white: 'white', + plurality: 'plural' + } + }, + Wikimedia: { + url: 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}{r}.png', + options: { + attribution: 'Wikimedia', + minZoom: 1, + maxZoom: 19 + } + }, + GeoportailFrance: { + url: 'https://wxs.ign.fr/{apikey}/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE={style}&TILEMATRIXSET=PM&FORMAT={format}&LAYER={variant}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}', + options: { + attribution: 'Geoportail France', + bounds: [[-75, -180], [81, 180]], + minZoom: 2, + maxZoom: 18, + // Get your own geoportail apikey here : http://professionnels.ign.fr/ign/contrats/ + // NB : 'choisirgeoportail' is a demonstration key that comes with no guarantee + apikey: 'choisirgeoportail', + format: 'image/jpeg', + style : 'normal', + variant: 'GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD' + }, + variants: { + parcels: { + options : { + variant: 'CADASTRALPARCELS.PARCELS', + maxZoom: 20, + style : 'bdparcellaire', + format: 'image/png' + } + }, + ignMaps: 'GEOGRAPHICALGRIDSYSTEMS.MAPS', + maps: 'GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD', + orthos: { + options: { + maxZoom: 19, + variant: 'ORTHOIMAGERY.ORTHOPHOTOS' + } + } + } + }, + OneMapSG: { + url: 'https://maps-{s}.onemap.sg/v3/{variant}/{z}/{x}/{y}.png', + options: { + variant: 'Default', + minZoom: 11, + maxZoom: 18, + bounds: [[1.56073, 104.11475], [1.16, 103.502]], + attribution: ' New OneMap | Map data © contributors, Singapore Land Authority' + }, + variants: { + Default: 'Default', + Night: 'Night', + Original: 'Original', + Grey: 'Grey', + LandLot: 'LandLot' + } + } + }; + + L.tileLayer.provider = function (provider, options) { + return new L.TileLayer.Provider(provider, options); + }; + + return L; +})); diff --git a/vendor/assets/stylesheets/autocomplete.css b/vendor/assets/stylesheets/autocomplete.css new file mode 100644 index 0000000000..2af8d808ba --- /dev/null +++ b/vendor/assets/stylesheets/autocomplete.css @@ -0,0 +1 @@ +.autocomplete-input{border:1px solid #eee;border-radius:8px;width:100%;padding:12px 12px 12px 48px;box-sizing:border-box;position:relative;font-size:16px;line-height:1.5;flex:1;background-color:#eee;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNjY2IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-input:focus,.autocomplete-input[aria-expanded=true]{border-color:rgba(0,0,0,.12);background-color:#fff;outline:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-input[aria-expanded=true]{border-bottom-color:transparent;border-radius:8px 8px 0 0}[data-position=above] .autocomplete-input[aria-expanded=true]{border-top-color:transparent;border-radius:0 0 8px 8px;z-index:2}.autocomplete[data-loading=true]:after{content:"";border:3px solid rgba(0,0,0,.12);border-right-color:rgba(0,0,0,.48);border-radius:100%;width:20px;height:20px;position:absolute;right:12px;top:50%;transform:translateY(-50%);animation:rotate 1s linear infinite}.autocomplete-result-list{margin:0;border:1px solid rgba(0,0,0,.12);padding:0;box-sizing:border-box;max-height:296px;overflow-y:auto;background:#fff;list-style:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-result-list{margin-top:-1px;border-top-color:transparent;border-radius:0 0 8px 8px;padding-bottom:8px}[data-position=above] .autocomplete-result-list{margin-bottom:-1px;border-bottom-color:transparent;border-radius:8px 8px 0 0;padding-top:8px}.autocomplete-result{cursor:default;padding:12px 12px 12px 48px;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjY2NjIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-result:hover,.autocomplete-result[aria-selected=true]{background-color:rgba(0,0,0,.06)}@keyframes rotate{0%{transform:translateY(-50%) rotate(0deg)}to{transform:translateY(-50%) rotate(359deg)}} \ No newline at end of file diff --git a/vendor/assets/stylesheets/leaflet.css b/vendor/assets/stylesheets/leaflet.css new file mode 100644 index 0000000000..983d60592b --- /dev/null +++ b/vendor/assets/stylesheets/leaflet.css @@ -0,0 +1,640 @@ +/* required styles */ + +.leaflet-pane, +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-tile-container, +.leaflet-pane > svg, +.leaflet-pane > canvas, +.leaflet-zoom-box, +.leaflet-image-layer, +.leaflet-layer { + position: absolute; + left: 0; + top: 0; + } +.leaflet-container { + overflow: hidden; + } +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-user-drag: none; + } +/* Prevents IE11 from highlighting tiles in blue */ +.leaflet-tile::selection { + background: transparent; +} +/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ +.leaflet-safari .leaflet-tile { + image-rendering: -webkit-optimize-contrast; + } +/* hack that prevents hw layers "stretching" when loading new tiles */ +.leaflet-safari .leaflet-tile-container { + width: 1600px; + height: 1600px; + -webkit-transform-origin: 0 0; + } +.leaflet-marker-icon, +.leaflet-marker-shadow { + display: block; + } +/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ +/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ +.leaflet-container .leaflet-overlay-pane svg, +.leaflet-container .leaflet-marker-pane img, +.leaflet-container .leaflet-shadow-pane img, +.leaflet-container .leaflet-tile-pane img, +.leaflet-container img.leaflet-image-layer, +.leaflet-container .leaflet-tile { + max-width: none !important; + max-height: none !important; + } + +.leaflet-container.leaflet-touch-zoom { + -ms-touch-action: pan-x pan-y; + touch-action: pan-x pan-y; + } +.leaflet-container.leaflet-touch-drag { + -ms-touch-action: pinch-zoom; + /* Fallback for FF which doesn't support pinch-zoom */ + touch-action: none; + touch-action: pinch-zoom; +} +.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { + -ms-touch-action: none; + touch-action: none; +} +.leaflet-container { + -webkit-tap-highlight-color: transparent; +} +.leaflet-container a { + -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); +} +.leaflet-tile { + filter: inherit; + visibility: hidden; + } +.leaflet-tile-loaded { + visibility: inherit; + } +.leaflet-zoom-box { + width: 0; + height: 0; + -moz-box-sizing: border-box; + box-sizing: border-box; + z-index: 800; + } +/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ +.leaflet-overlay-pane svg { + -moz-user-select: none; + } + +.leaflet-pane { z-index: 400; } + +.leaflet-tile-pane { z-index: 200; } +.leaflet-overlay-pane { z-index: 400; } +.leaflet-shadow-pane { z-index: 500; } +.leaflet-marker-pane { z-index: 600; } +.leaflet-tooltip-pane { z-index: 650; } +.leaflet-popup-pane { z-index: 700; } + +.leaflet-map-pane canvas { z-index: 100; } +.leaflet-map-pane svg { z-index: 200; } + +.leaflet-vml-shape { + width: 1px; + height: 1px; + } +.lvml { + behavior: url(#default#VML); + display: inline-block; + position: absolute; + } + + +/* control positioning */ + +.leaflet-control { + position: relative; + z-index: 800; + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } +.leaflet-top, +.leaflet-bottom { + position: absolute; + z-index: 1000; + pointer-events: none; + } +.leaflet-top { + top: 0; + } +.leaflet-right { + right: 0; + } +.leaflet-bottom { + bottom: 0; + } +.leaflet-left { + left: 0; + } +.leaflet-control { + float: left; + clear: both; + } +.leaflet-right .leaflet-control { + float: right; + } +.leaflet-top .leaflet-control { + margin-top: 10px; + } +.leaflet-bottom .leaflet-control { + margin-bottom: 10px; + } +.leaflet-left .leaflet-control { + margin-left: 10px; + } +.leaflet-right .leaflet-control { + margin-right: 10px; + } + + +/* zoom and fade animations */ + +.leaflet-fade-anim .leaflet-tile { + will-change: opacity; + } +.leaflet-fade-anim .leaflet-popup { + opacity: 0; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } +.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { + opacity: 1; + } +.leaflet-zoom-animated { + -webkit-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + will-change: transform; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); + -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); + transition: transform 0.25s cubic-bezier(0,0,0.25,1); + } +.leaflet-zoom-anim .leaflet-tile, +.leaflet-pan-anim .leaflet-tile { + -webkit-transition: none; + -moz-transition: none; + transition: none; + } + +.leaflet-zoom-anim .leaflet-zoom-hide { + visibility: hidden; + } + + +/* cursors */ + +.leaflet-interactive { + cursor: pointer; + } +.leaflet-grab { + cursor: -webkit-grab; + cursor: -moz-grab; + cursor: grab; + } +.leaflet-crosshair, +.leaflet-crosshair .leaflet-interactive { + cursor: crosshair; + } +.leaflet-popup-pane, +.leaflet-control { + cursor: auto; + } +.leaflet-dragging .leaflet-grab, +.leaflet-dragging .leaflet-grab .leaflet-interactive, +.leaflet-dragging .leaflet-marker-draggable { + cursor: move; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; + } + +/* marker & overlays interactivity */ +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-image-layer, +.leaflet-pane > svg path, +.leaflet-tile-container { + pointer-events: none; + } + +.leaflet-marker-icon.leaflet-interactive, +.leaflet-image-layer.leaflet-interactive, +.leaflet-pane > svg path.leaflet-interactive, +svg.leaflet-image-layer.leaflet-interactive path { + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } + +/* visual tweaks */ + +.leaflet-container { + background: #ddd; + outline: 0; + } +.leaflet-container a { + color: #0078A8; + } +.leaflet-container a.leaflet-active { + outline: 2px solid orange; + } +.leaflet-zoom-box { + border: 2px dotted #38f; + background: rgba(255,255,255,0.5); + } + + +/* general typography */ +.leaflet-container { + font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; + } + + +/* general toolbar styles */ + +.leaflet-bar { + box-shadow: 0 1px 5px rgba(0,0,0,0.65); + border-radius: 4px; + } +.leaflet-bar a, +.leaflet-bar a:hover { + background-color: #fff; + border-bottom: 1px solid #ccc; + width: 26px; + height: 26px; + line-height: 26px; + display: block; + text-align: center; + text-decoration: none; + color: black; + } +.leaflet-bar a, +.leaflet-control-layers-toggle { + background-position: 50% 50%; + background-repeat: no-repeat; + display: block; + } +.leaflet-bar a:hover { + background-color: #f4f4f4; + } +.leaflet-bar a:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + } +.leaflet-bar a:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-bottom: none; + } +.leaflet-bar a.leaflet-disabled { + cursor: default; + background-color: #f4f4f4; + color: #bbb; + } + +.leaflet-touch .leaflet-bar a { + width: 30px; + height: 30px; + line-height: 30px; + } +.leaflet-touch .leaflet-bar a:first-child { + border-top-left-radius: 2px; + border-top-right-radius: 2px; + } +.leaflet-touch .leaflet-bar a:last-child { + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + } + +/* zoom control */ + +.leaflet-control-zoom-in, +.leaflet-control-zoom-out { + font: bold 18px 'Lucida Console', Monaco, monospace; + text-indent: 1px; + } + +.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { + font-size: 22px; + } + + +/* layers control */ + +.leaflet-control-layers { + box-shadow: 0 1px 5px rgba(0,0,0,0.4); + background: #fff; + border-radius: 5px; + } +.leaflet-control-layers-toggle { + background-image: url(images/layers.png); + width: 36px; + height: 36px; + } +.leaflet-retina .leaflet-control-layers-toggle { + background-image: url(images/layers-2x.png); + background-size: 26px 26px; + } +.leaflet-touch .leaflet-control-layers-toggle { + width: 44px; + height: 44px; + } +.leaflet-control-layers .leaflet-control-layers-list, +.leaflet-control-layers-expanded .leaflet-control-layers-toggle { + display: none; + } +.leaflet-control-layers-expanded .leaflet-control-layers-list { + display: block; + position: relative; + } +.leaflet-control-layers-expanded { + padding: 6px 10px 6px 6px; + color: #333; + background: #fff; + } +.leaflet-control-layers-scrollbar { + overflow-y: scroll; + overflow-x: hidden; + padding-right: 5px; + } +.leaflet-control-layers-selector { + margin-top: 2px; + position: relative; + top: 1px; + } +.leaflet-control-layers label { + display: block; + } +.leaflet-control-layers-separator { + height: 0; + border-top: 1px solid #ddd; + margin: 5px -10px 5px -6px; + } + +/* Default icon URLs */ +.leaflet-default-icon-path { + background-image: url(images/marker-icon.png); + } + + +/* attribution and scale controls */ + +.leaflet-container .leaflet-control-attribution { + background: #fff; + background: rgba(255, 255, 255, 0.7); + margin: 0; + } +.leaflet-control-attribution, +.leaflet-control-scale-line { + padding: 0 5px; + color: #333; + } +.leaflet-control-attribution a { + text-decoration: none; + } +.leaflet-control-attribution a:hover { + text-decoration: underline; + } +.leaflet-container .leaflet-control-attribution, +.leaflet-container .leaflet-control-scale { + font-size: 11px; + } +.leaflet-left .leaflet-control-scale { + margin-left: 5px; + } +.leaflet-bottom .leaflet-control-scale { + margin-bottom: 5px; + } +.leaflet-control-scale-line { + border: 2px solid #777; + border-top: none; + line-height: 1.1; + padding: 2px 5px 1px; + font-size: 11px; + white-space: nowrap; + overflow: hidden; + -moz-box-sizing: border-box; + box-sizing: border-box; + + background: #fff; + background: rgba(255, 255, 255, 0.5); + } +.leaflet-control-scale-line:not(:first-child) { + border-top: 2px solid #777; + border-bottom: none; + margin-top: -2px; + } +.leaflet-control-scale-line:not(:first-child):not(:last-child) { + border-bottom: 2px solid #777; + } + +.leaflet-touch .leaflet-control-attribution, +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + box-shadow: none; + } +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + border: 2px solid rgba(0,0,0,0.2); + background-clip: padding-box; + } + + +/* popup */ + +.leaflet-popup { + position: absolute; + text-align: center; + margin-bottom: 20px; + } +.leaflet-popup-content-wrapper { + padding: 1px; + text-align: left; + border-radius: 12px; + } +.leaflet-popup-content { + margin: 13px 19px; + line-height: 1.4; + } +.leaflet-popup-content p { + margin: 18px 0; + } +.leaflet-popup-tip-container { + width: 40px; + height: 20px; + position: absolute; + left: 50%; + margin-left: -20px; + overflow: hidden; + pointer-events: none; + } +.leaflet-popup-tip { + width: 17px; + height: 17px; + padding: 1px; + + margin: -10px auto 0; + + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + } +.leaflet-popup-content-wrapper, +.leaflet-popup-tip { + background: white; + color: #333; + box-shadow: 0 3px 14px rgba(0,0,0,0.4); + } +.leaflet-container a.leaflet-popup-close-button { + position: absolute; + top: 0; + right: 0; + padding: 4px 4px 0 0; + border: none; + text-align: center; + width: 18px; + height: 14px; + font: 16px/14px Tahoma, Verdana, sans-serif; + color: #c3c3c3; + text-decoration: none; + font-weight: bold; + background: transparent; + } +.leaflet-container a.leaflet-popup-close-button:hover { + color: #999; + } +.leaflet-popup-scrolled { + overflow: auto; + border-bottom: 1px solid #ddd; + border-top: 1px solid #ddd; + } + +.leaflet-oldie .leaflet-popup-content-wrapper { + zoom: 1; + } +.leaflet-oldie .leaflet-popup-tip { + width: 24px; + margin: 0 auto; + + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; + filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); + } +.leaflet-oldie .leaflet-popup-tip-container { + margin-top: -1px; + } + +.leaflet-oldie .leaflet-control-zoom, +.leaflet-oldie .leaflet-control-layers, +.leaflet-oldie .leaflet-popup-content-wrapper, +.leaflet-oldie .leaflet-popup-tip { + border: 1px solid #999; + } + + +/* div icon */ + +.leaflet-div-icon { + background: #fff; + border: 1px solid #666; + } + + +/* Tooltip */ +/* Base styles for the element that has a tooltip */ +.leaflet-tooltip { + position: absolute; + padding: 6px; + background-color: #fff; + border: 1px solid #fff; + border-radius: 3px; + color: #222; + white-space: nowrap; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + pointer-events: none; + box-shadow: 0 1px 3px rgba(0,0,0,0.4); + } +.leaflet-tooltip.leaflet-clickable { + cursor: pointer; + pointer-events: auto; + } +.leaflet-tooltip-top:before, +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + position: absolute; + pointer-events: none; + border: 6px solid transparent; + background: transparent; + content: ""; + } + +/* Directions */ + +.leaflet-tooltip-bottom { + margin-top: 6px; +} +.leaflet-tooltip-top { + margin-top: -6px; +} +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-top:before { + left: 50%; + margin-left: -6px; + } +.leaflet-tooltip-top:before { + bottom: 0; + margin-bottom: -12px; + border-top-color: #fff; + } +.leaflet-tooltip-bottom:before { + top: 0; + margin-top: -12px; + margin-left: -6px; + border-bottom-color: #fff; + } +.leaflet-tooltip-left { + margin-left: -6px; +} +.leaflet-tooltip-right { + margin-left: 6px; +} +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + top: 50%; + margin-top: -6px; + } +.leaflet-tooltip-left:before { + right: 0; + margin-right: -12px; + border-left-color: #fff; + } +.leaflet-tooltip-right:before { + left: 0; + margin-left: -12px; + border-right-color: #fff; + } From 94b85fb9e38bd37895d655a27848b77d8f55ea2f Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Thu, 28 May 2020 20:52:47 +0100 Subject: [PATCH 318/507] Fix up Code Climate issues with Open Street Map code. --- app/assets/stylesheets/darkswarm/map.css.scss | 7 +++-- app/models/preference_sections/map_section.rb | 2 ++ .../api/open_street_map_config_serializer.rb | 26 ++++++++++++------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/map.css.scss b/app/assets/stylesheets/darkswarm/map.css.scss index 70d28a5f6b..8f9ee717f9 100644 --- a/app/assets/stylesheets/darkswarm/map.css.scss +++ b/app/assets/stylesheets/darkswarm/map.css.scss @@ -49,15 +49,18 @@ left: 54px; width: 50%; z-index: 1000; + .autocomplete-input, .autocomplete-result-list { - border: 2px solid #888; + border: 2px solid $grey-500; + &:hover, &:active, &:focus { border-color: $clr-brick; } } + .autocomplete-result-list { - border-top: 1px dotted #888; + border-top: 1px dotted $grey-500; } } } diff --git a/app/models/preference_sections/map_section.rb b/app/models/preference_sections/map_section.rb index 9fc8112cac..cc16939c36 100644 --- a/app/models/preference_sections/map_section.rb +++ b/app/models/preference_sections/map_section.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module PreferenceSections class MapSection def name diff --git a/app/serializers/api/open_street_map_config_serializer.rb b/app/serializers/api/open_street_map_config_serializer.rb index 37d6a8bd36..8c5aec5dbb 100644 --- a/app/serializers/api/open_street_map_config_serializer.rb +++ b/app/serializers/api/open_street_map_config_serializer.rb @@ -1,15 +1,21 @@ -class Api::OpenStreetMapConfigSerializer < ActiveModel::Serializer - attributes :open_street_map_enabled, :open_street_map_provider_name, :open_street_map_provider_options +# frozen_string_literal: true - def open_street_map_enabled - ContentConfig.open_street_map_enabled - end +module Api + class OpenStreetMapConfigSerializer < ActiveModel::Serializer + attributes :open_street_map_enabled, + :open_street_map_provider_name, + :open_street_map_provider_options - def open_street_map_provider_name - ContentConfig.open_street_map_provider_name - end + def open_street_map_enabled + ContentConfig.open_street_map_enabled + end - def open_street_map_provider_options - ContentConfig.open_street_map_provider_options.to_json + def open_street_map_provider_name + ContentConfig.open_street_map_provider_name + end + + def open_street_map_provider_options + ContentConfig.open_street_map_provider_options.to_json + end end end From 8e57f9d92900a6f83ac315c808ed4f4debaf3a14 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 31 May 2020 19:21:20 +0200 Subject: [PATCH 319/507] Adjust shared map partial --- app/views/shared/_map.html.haml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/views/shared/_map.html.haml b/app/views/shared/_map.html.haml index 5aa88d635c..c7df6d5b2b 100644 --- a/app/views/shared/_map.html.haml +++ b/app/views/shared/_map.html.haml @@ -1,10 +1,12 @@ -.map-container - - if ContentConfig.open_street_map_enabled +- if ContentConfig.open_street_map_enabled + .map-container %ofn-open-street-map#open-street-map %div#open-street-map--search %input.autocomplete-input %ul.autocomplete-result-list - - else + +- else + .map-container %map{"ng-controller" => "MapCtrl"} %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} @@ -13,5 +15,5 @@ %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", coords: "'self'", icon: "'icon'", click: "'reveal'"} -.map-footer - %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors + .map-footer + %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors From fb45cb602e519c54c58d1d3a42795d0dac843929 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 31 May 2020 21:07:52 +0100 Subject: [PATCH 320/507] Remove duplication from CONTRIBUTING --- CONTRIBUTING.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 779fce90ae..cac1468c67 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,9 @@ # Contributing -We love pull requests from everyone. Any contribution is valuable, but there are two issue streams that we especially love people to work on: +We love pull requests from everyone. Any contribution is valuable! -1) Our delivery backlog, is managed via a ZenHub board (ZenHub extensions are available for most major browsers). We use a Kanban-style approach, whereby devs pick issues from the top of the backlog which has been organised according to current priorities. If you have some time and are interested in working on some issues from the backlog, please make yourself known on the [#dev][slack-dev] channel on Slack and we can direct you to the most appropriate issue to pick up. +If you have some time and are interested in working on some issues please make yourself known on the [#dev][slack-dev] channel on Slack. -2) Our list of bugs and other self-contained issues that we consider to be a good starting point for new contributors, or devs who aren’t able to commit to seeing a whole feature through. These issues are marked with the `# good first issue` label. +We have curated all issues we consider to be a good starting point for new members of the community within the [Welcome New Developers project board][welcome-dev]. Have a look and pick the one you would prefer working on! ## Set up @@ -19,10 +19,6 @@ If you want to run the whole test suite, we recommend using a free CI service to bundle exec rspec spec -## Which issue to pick first? - -We have curated all issues interesting for new members of the community within the [Welcome New Developers project board][welcome-dev]. Have a look and pick the one you would prefer working on! - ## Internationalisation (i18n) The locale `en` is maintained in the source code, but other locales are managed at [Transifex][ofn-transifex]. Read more about [internationalisation][i18n] in the developer wiki. From 5d9e88a3bc382cb7f58ed870fa13501a6de5394e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 31 May 2020 21:40:36 +0100 Subject: [PATCH 321/507] Restructure GETTING STARTED to make it clear what the wiki pages are for --- GETTING_STARTED.md | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index 67f38e7390..b252993215 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -2,21 +2,17 @@ This is a general guide to setting up an Open Food Network development environment on your local machine. -The fastest way to make it work locally is to use Docker, see the [Docker setup guide](DOCKER.md). +### Requirements -The following guides are located in the wiki and provide more OS-specific step-by-step instructions: - -- [Ubuntu Setup Guide][ubuntu] -- [macOS Sierra Setup Guide][sierra] -- [OSX El Capitan Setup Guide][el-capitan] - -### Dependencies - -* Rails 3.2.x -* Ruby 2.3.7 +The fastest way to make it work locally is to use Docker, you only need to setup git, see the [Docker setup guide](DOCKER.md). +Otherwise, for a local setup you will need: +* Ruby 2.3.7 and bundler * PostgreSQL database -* PhantomJS (for testing) -* See Gemfile for a list of gems required +* Chrome (for testing) + +The following guides will provide OS-specific step-by-step instructions to get these requirements installed: +- [Ubuntu Setup Guide][ubuntu] +- [OSX Setup Guide][osx] If you are likely to need to manage multiple version of ruby on your local machine, we recommend version managers such as [rbenv](https://github.com/rbenv/rbenv) or [RVM](https://rvm.io/). @@ -52,14 +48,12 @@ This will create the "ofn" user as superuser and allowing it to create databases Once done, run `script/setup`. If the script succeeds you're ready to start developing. If not, take a look at the output as it should be informative enough to help you troubleshoot. -If you run into any other issues getting your local environment up and running please consult [the wiki][wiki]. - -If still you get stuck do not hesitate to open an issue reporting the full output of the script. - Now, your dreams of spinning up a development server can be realised: bundle exec rails server +Go to [http://localhost:3000](http://localhost:3000) to play around! + To login as the default user, use: email: ofn@example.com @@ -79,7 +73,7 @@ The tests of all custom engines can be run with: bundle exec rake ofn:specs:engines:rspec -Note: If your OS is not explicitly supported in the setup guides then not all tests may pass. However, you may still be able to develop. Get in touch with the [#dev][slack-dev] channel on Slack to troubleshoot issues and determine if they will preclude you from contributing to OFN. +Note: If your OS is not explicitly supported in the setup guides then not all tests may pass. However, you may still be able to develop. Note: The time zone on your machine should match the one defined in `config/application.yml`. @@ -120,8 +114,7 @@ $ createdb open_food_network_test --owner=ofn If these commands succeed, you should be able to [continue the setup process](#get-it-running). [developer-wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki -[sierra]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup%3A-macOS-%28Sierra%2C-HighSierra%2C-Mojave-and-Catalina%29 -[el-capitan]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X-(El-Capitan) +[osx]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X [ubuntu]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Ubuntu [wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki [zeus]: https://github.com/burke/zeus From e5cc425662efeea08499c5b1dc08742943facf1b Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Mon, 1 Jun 2020 16:39:17 +1000 Subject: [PATCH 322/507] Updating translations for config/locales/tr.yml --- config/locales/tr.yml | 51 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/config/locales/tr.yml b/config/locales/tr.yml index cf263190d6..01e6b5b3bf 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -703,8 +703,8 @@ tr: allow_guest_orders_true: "Misafir alışverişine izin ver" allow_order_changes: "Siparişleri düzenle" allow_order_changes_tip: "Sipariş dönemi açık olduğu sürece müşterilerin siparişlerini düzenlemelerine izin verin." - allow_order_changes_false: "Oluşturulan siparişler değiştirilemez / iptal edilemez" - allow_order_changes_true: "Müşteriler sipariş dönemi açıkken siparişleri değiştirebilir / iptal edebilir" + allow_order_changes_false: "Oluşturulan siparişler değiştirilemez/iptal edilemez" + allow_order_changes_true: "Müşteriler sipariş dönemi açıkken siparişleri değiştirebilir/iptal edebilir" enable_subscriptions: "Üyelikler" enable_subscriptions_tip: "Üyelik işlevselliği etkinleştirilsin mi?" enable_subscriptions_false: "Kapalı" @@ -714,7 +714,7 @@ tr: Müşterilerinize merhaba diyebilir, tezgahınız ve alışveriş şartlarınız ile ilgili bilgi verebilirsiniz. Yazdıklarınız, müşteriler mağazanızı ziyaret ettiğinde görünür olacak. - shopfront_message_link_tooltip: "Bağlantı ekle / düzenle" + shopfront_message_link_tooltip: "Bağlantı ekle/düzenle" shopfront_message_link_prompt: "Lütfen eklemek için bir URL girin" shopfront_closed_message: "KAPALI MAĞAZA MESAJI" shopfront_closed_message_placeholder: > @@ -858,7 +858,7 @@ tr: next: "Sonrakİ" cancel: "İptal et" back_to_list: "Listeye geri dön" - save_and_back_to_list: "Kaydet ve Listeye Dön" + save_and_back_to_list: "KAYDET VE LİSTEYE DÖN" choose_products_from: "Ürünlerİ Buradan SeÇ:" incoming: incoming: "Gelen" @@ -880,7 +880,7 @@ tr: fees: "Ücretler" previous: "Önceki" save: "Kaydet" - save_and_back_to_list: "Kaydet ve Listeye Dön" + save_and_back_to_list: "KAYDET VE LİSTEYE DÖN" cancel: "İptal et" back_to_list: "Listeye geri dön" wizard_progress: @@ -904,7 +904,7 @@ tr: choose_product_tip: Gelen ve giden ürünleri sadece stokların %{inventory} 'i ile kısıtlayabilirsiniz. preferred_product_selection_from_coordinator_inventory_only_here: Yalnızca Koordinatör Stokları preferred_product_selection_from_coordinator_inventory_only_all: Tüm Mevcut Ürünler - save_reload: Sayfayı Kaydet ve Yeniden Yükle + save_reload: SAYFAYI KAYDET VE YENİDEN YÜKLE coordinator_fees: add: Koordinatör ücreti ekle filters: @@ -923,7 +923,7 @@ tr: products: Ürünler tags: Etiketler add_a_tag: Etiket ekle - delivery_details: Teslimat / Gönderim Bilgileri + delivery_details: Teslimat/Gönderim Bilgileri index: schedule: Takvim schedules: Takvimler @@ -939,7 +939,7 @@ tr: variants: Varyantlar simple_form: ready_for: ŞU TARİHTE HAZIR - ready_for_placeholder: Tarih / saat + ready_for_placeholder: Tarih/saat customer_instructions: Müşteri talimatları customer_instructions_placeholder: Teslimat / Gönderim Notları products: Ürünler @@ -1165,8 +1165,8 @@ tr: footer_legal_text_html: "Açık Gıda Ağı ücretsiz ve açık kaynaklı bir yazılım platformudur. İçeriklerimiz %{content_license} ve kodumuz %{code_license} ile lisanslıdır." footer_data_text_with_privacy_policy_html: "Verilerinize iyi bakıyoruz. Bkz. %{privacy_policy} ve %{cookies_policy}" footer_data_text_without_privacy_policy_html: "Verilerinize iyi bakıyoruz. Bkz. %{cookies_policy}" - footer_data_privacy_policy: "Gizlilik Politikası" - footer_data_cookies_policy: "çerez politikası" + footer_data_privacy_policy: "Gizlilik ve Kişisel Verilerin Korunması Politikası " + footer_data_cookies_policy: "Çerez Politikası" shop: messages: customer_required: @@ -1215,11 +1215,11 @@ tr: menu_4_title: "Gruplar" menu_4_url: "/groups" menu_5_title: "hakkında" - menu_5_url: "https://acikgida.com" + menu_5_url: "https://hakkimizda.acikgida.com" menu_6_title: "Bağlan" - menu_6_url: "https://acikgida.com" + menu_6_url: "https://acikgida.com/connect" menu_7_title: "öğren" - menu_7_url: "https://acikgida.com" + menu_7_url: "https://acikgida.com/learn" logo: "Logo (640x130)" logo_mobile: "Cep telefonu logosu (75x26)" logo_mobile_svg: "Cep Telefonu logo (SVG)" @@ -1269,7 +1269,7 @@ tr: label_producer: "ÜRETİCİ" label_producers: "ÜRETİCİLER" label_groups: "Gruplar" - label_about: "HAKKINDA" + label_about: "HAKKIMIZDA" label_connect: "Bağlan" label_learn: "Öğren" label_blog: "Blog" @@ -1567,7 +1567,7 @@ tr: components_filters_nofilters: "Filtresiz" components_filters_clearfilters: "Tüm filtreleri temizle" groups_title: Gruplar - groups_headline: Gruplar / bölgeler + groups_headline: Gruplar groups_text: "Her üretici özeldir ve her işletmenin ortaya koyabileceği farklı bir değer vardır. Üyelerimiz, ürünlerini ve emeklerini, ya da sadece gıdanın ortak değerleri paylaşan üretici, türetici ve dağıtımcı kolektifleridir. Bu bileşenler, adil ve temiz gıdaya ulaşım yollarını kolaylaştırır ve bozulmuş gıda sistemini hep beraber düzeltmemize yardımcı olur." groups_search: "İsim veya anahtar kelime ile ara" groups_no_groups: "Grup bulunamadı" @@ -1637,7 +1637,7 @@ tr: sell_producers_detail: "AGA üzerinden işletmeniz adına bir profil oluşturun. Dilediğiniz zaman profilinizi bir tezgaha yükseltebilir ve ürünlerinizi müşterilerinize doğrudan satabilirsiniz." sell_hubs_detail: "AGA üzerinden gıda işletmeniz veya topluluğunuz için bir profil oluşturun. İstediğiniz zaman profilinizi çok üreticili bir pazara yükseltebilirsiniz." sell_groups_detail: "Bölgenizdeki veya ağınızdaki işletmelerin (üreticilerin, pazarların veya diğer grupların) detaylı rehber listesini oluşturun." - sell_user_guide: "Kullanım kılavuzumuzda daha fazla bilgi edinin." + sell_user_guide: "Kullanım kılavuzumuzdan daha fazla bilgi edinin." sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Platform üzerinden satış yapan işletmeler için işlem başına uygulanan ücretlendirme %5'tir. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkımızda bağlantısını kullanarak Fiyatlandırma bölümünü ziyaret edin." sell_embed: "Kendi e-ticaret siteniz olsa bile Açık Gıda Ağı size hikayenizi anlatmanız ve ürünlerinizi satmanız için yeni ve farklı bir seçenek sunuyor. Siz de bu ailenin bir parçası olun, hep beraber büyüyelim!" sell_ask_services: "Detaylar için bizimle iletişime geçin." @@ -1986,7 +1986,7 @@ tr: price: "Fiyat" on_hand: "Mevcut" review: "gözden geçir" - save_changes: "Değişiklikleri Kaydet" + save_changes: "DEĞİŞİKLİKLERİ KAYDET" order_saved: "Sipariş Kaydedildi" no_products: Ürün yok spree_admin_overview_enterprises_header: "İşletmelerim" @@ -2042,7 +2042,7 @@ tr: first_name_begins_with: "Adının BAŞ HARFİ" last_name_begins_with: "Soyadının BAŞ HARFİ" enterprise_tos_link: "İşletme Üyelik Sözleşmesi bağlantısı" - enterprise_tos_message: "Amaçlarımızı ve değerlerimizi paylaşan insanlarla çalışmak istiyoruz. Bu nedenle yeni işletmelerden bunu kabul etmesini istiyoruz:" + enterprise_tos_message: "Amaçlarımızı ve değerlerimizi paylaşan insanlarla çalışmak istiyoruz. Yasal zorunluluk gereği de yeni işletmelerden kabul etmesini istiyoruz:" enterprise_tos_link_text: "Üyelik Sözleşmesi" enterprise_tos_agree: "Yukarıdaki Üyelik Sözleşmesini kabul ediyorum" tax_settings: "Vergi Ayarları" @@ -2785,7 +2785,7 @@ tr: cannot_set_shipping_method_without_address: "Müşteri bilgileri girilmeden teslimat yöntemi belirlenemez.." no_tracking_present: "Hiçbir takip detayı sağlanmadı." order_total: "sipariş toplamı" - customer_details: "Müşteri detayları" + customer_details: "MÜŞTERİ DETAYLARI" customer_search: "Müşteri Arama" choose_a_customer: "Bir müşteri seçin" account: "Hesap" @@ -3224,7 +3224,7 @@ tr: privacy_policy_url: "Gizlilik Politikası URLsi" enterprises_require_tos: "İşletmeler Üyelik Sözleşmesini kabul etmelidir" cookies_policy_matomo_section: "Çerez politikası sayfasında Matomo bölümünü görüntüle" - footer_tos_url: "Kullanıcı Sözleşmesi URLsi" + footer_tos_url: "Üyelik Sözleşmesi URLsi" checkout: payment: stripe: @@ -3271,9 +3271,14 @@ tr: invalid: geçersiz order_mailer: cancel_email: - customer_greeting: "Merhaba %{name}!" - instructions: "Siparişiniz iptal edildi. Lütfen kayıtlarınız için bu iptal bilgilerini saklayın." - order_summary_canceled: "Sipariş Özeti [İPTAL EDİLDİ]" + customer_greeting: "Sevgili %{name}," + instructions_html: "%{distributor} siparişiniz İPTAL EDİLDİ. Lütfen not edin." + dont_cancel: "Eğer fikrinizi değiştirdiyseniz ve siparişi iptal etmek istemiyorsanız lütfen %{email} ile iletişime geçin." + order_summary_canceled_html: "Sipariş Özeti #%{number}(İPTAL EDİLDİ)" + details: "İşte siparişinizin özeti:" + unpaid_order: "Sipariş ödemeniz yapılmadığı için iade işlemi yapılmadı" + paid_order: "Siparişinizin ödemesi yapılmıştı, bu sebeple %{distributor}iade işlemi gerçekleştirdi." + credit_order: "Siparişinizin ödemesi yapılmıştı, bu sebeple hesabınızdan düşüldü." subject: "Sipariş İptali" confirm_email: subject: "Sipariş Onayı" From 069241f30784c67910e083584a9aea394be45aa0 Mon Sep 17 00:00:00 2001 From: romale Date: Mon, 1 Jun 2020 15:25:46 +0300 Subject: [PATCH 323/507] Missing translation key "return_authorizations" return_authorizations: Return Authorizations --- config/locales/en.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 158e964b89..a5d6dd3398 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2904,7 +2904,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using first: "First" previous: "Previous" last: "Last" - + + return_authorizations: "Return Authorizations" spree: your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" From e77d9aba7b452441ce8e785c65dbf5e03f08d5ab Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 13 May 2020 12:12:32 +0100 Subject: [PATCH 324/507] Add missing strong params to less important controllers not tested in specs --- app/controllers/spree/admin/countries_controller.rb | 5 +++++ .../spree/admin/return_authorizations_controller.rb | 5 +++++ .../spree/admin/shipping_categories_controller.rb | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/app/controllers/spree/admin/countries_controller.rb b/app/controllers/spree/admin/countries_controller.rb index 4314e54b37..f6a90bf567 100644 --- a/app/controllers/spree/admin/countries_controller.rb +++ b/app/controllers/spree/admin/countries_controller.rb @@ -1,6 +1,11 @@ module Spree module Admin class CountriesController < ResourceController + def permitted_resource_params + params.require(:country). + permit(:name, :iso_name, :states_required) + end + def collection super.order(:name) end diff --git a/app/controllers/spree/admin/return_authorizations_controller.rb b/app/controllers/spree/admin/return_authorizations_controller.rb index 9696835315..0411cd5b1b 100644 --- a/app/controllers/spree/admin/return_authorizations_controller.rb +++ b/app/controllers/spree/admin/return_authorizations_controller.rb @@ -19,6 +19,11 @@ module Spree @return_authorization.add_variant(variant_id.to_i, qty.to_i) end end + + def permitted_resource_params + params.require(:return_authorization). + permit(:amount, :reason, :stock_location_id) + end end end end diff --git a/app/controllers/spree/admin/shipping_categories_controller.rb b/app/controllers/spree/admin/shipping_categories_controller.rb index e9d1677027..7fa77bcc9c 100644 --- a/app/controllers/spree/admin/shipping_categories_controller.rb +++ b/app/controllers/spree/admin/shipping_categories_controller.rb @@ -1,6 +1,10 @@ module Spree module Admin class ShippingCategoriesController < ResourceController + def permitted_resource_params + params.require(:shipping_category). + permit(:name, :temperature_controlled) + end end end end From 73f2844fe31abda5a96501ef839a555981ee1d29 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 16 May 2020 15:13:29 +0100 Subject: [PATCH 325/507] Add spec for shipping categories --- .../shipping_categories_controller_spec.rb | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 spec/controllers/spree/admin/shipping_categories_controller_spec.rb diff --git a/spec/controllers/spree/admin/shipping_categories_controller_spec.rb b/spec/controllers/spree/admin/shipping_categories_controller_spec.rb new file mode 100644 index 0000000000..531b175072 --- /dev/null +++ b/spec/controllers/spree/admin/shipping_categories_controller_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module Spree + module Admin + describe ShippingCategoriesController, type: :controller do + include AuthenticationWorkflow + + describe "#create and #update" do + before { login_as_admin } + + it "creates a shipping shipping category" do + expect { + spree_post :create, shipping_category: { name: "Frozen" } + }.to change(Spree::ShippingCategory.all, :count).by(1) + + expect(response).to redirect_to spree.admin_shipping_categories_url + end + + it "updates an existing shipping category" do + shipping_category = create(:shipping_category) + spree_put :update, id: shipping_category.id, + shipping_category: { name: "Super Frozen" } + + expect(response).to redirect_to spree.admin_shipping_categories_url + expect(shipping_category.reload.name).to eq "Super Frozen" + end + end + end + end +end From 583b4a1df72df53f39426d7a692525c2eeb36382 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 16 May 2020 15:17:09 +0100 Subject: [PATCH 326/507] Add spec to countries_controller --- .../spree/admin/countries_controller_spec.rb | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 spec/controllers/spree/admin/countries_controller_spec.rb diff --git a/spec/controllers/spree/admin/countries_controller_spec.rb b/spec/controllers/spree/admin/countries_controller_spec.rb new file mode 100644 index 0000000000..4146a506de --- /dev/null +++ b/spec/controllers/spree/admin/countries_controller_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module Spree + module Admin + describe CountriesController, type: :controller do + include AuthenticationWorkflow + + describe "#update" do + before { login_as_admin } + + it "updates the name of an existing country" do + country = create(:country) + spree_put :update, id: country.id, + country: { name: "Kyrgyzstan" } + + expect(response).to redirect_to spree.admin_countries_url + expect(country.reload.name).to eq "Kyrgyzstan" + end + end + end + end +end From bae128738bf4ee0781b6cef0f8d7bd4bc6dde9b9 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 16 May 2020 16:25:18 +0100 Subject: [PATCH 327/507] Add spec for return authorizations controller --- .../return_authorizations_controller_spec.rb | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 spec/controllers/spree/admin/return_authorizations_controller_spec.rb diff --git a/spec/controllers/spree/admin/return_authorizations_controller_spec.rb b/spec/controllers/spree/admin/return_authorizations_controller_spec.rb new file mode 100644 index 0000000000..6c28642da5 --- /dev/null +++ b/spec/controllers/spree/admin/return_authorizations_controller_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module Spree + module Admin + describe ReturnAuthorizationsController, type: :controller do + include AuthenticationWorkflow + + let(:order) do + create(:order, :with_line_item, :completed, + distributor: create(:distributor_enterprise) ) + end + + before do + login_as_admin + + # Pay the order + order.payments.first.complete + order.updater.update_payment_state + + # Ship the order + order.reload.shipment.ship! + end + + it "creates and updates a return authorization" do + # Create return authorization + spree_post :create, order_id: order.number, + return_authorization: { amount: "20.2", reason: "broken" } + + expect(response).to redirect_to spree.admin_order_return_authorizations_url(order.number) + return_authorization = order.return_authorizations.first + expect(return_authorization.amount.to_s).to eq "20.2" + expect(return_authorization.reason.to_s).to eq "broken" + + # Update return authorization + spree_put :update, id: return_authorization.id, + return_authorization: { amount: "10.2", reason: "half broken" } + + expect(response).to redirect_to spree.admin_order_return_authorizations_url(order.number) + return_authorization.reload + expect(return_authorization.amount.to_s).to eq "10.2" + expect(return_authorization.reason.to_s).to eq "half broken" + end + end + end +end From 754b657f81b378306269c900fcfe7efb036b57e5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 18 May 2020 15:13:03 +0100 Subject: [PATCH 328/507] Move controller methods to protected to keeep consitency and isolation --- app/controllers/spree/admin/countries_controller.rb | 3 +++ app/controllers/spree/admin/shipping_categories_controller.rb | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/controllers/spree/admin/countries_controller.rb b/app/controllers/spree/admin/countries_controller.rb index f6a90bf567..9dc2cc00a3 100644 --- a/app/controllers/spree/admin/countries_controller.rb +++ b/app/controllers/spree/admin/countries_controller.rb @@ -1,6 +1,9 @@ module Spree module Admin class CountriesController < ResourceController + + protected + def permitted_resource_params params.require(:country). permit(:name, :iso_name, :states_required) diff --git a/app/controllers/spree/admin/shipping_categories_controller.rb b/app/controllers/spree/admin/shipping_categories_controller.rb index 7fa77bcc9c..91f476e12f 100644 --- a/app/controllers/spree/admin/shipping_categories_controller.rb +++ b/app/controllers/spree/admin/shipping_categories_controller.rb @@ -1,6 +1,9 @@ module Spree module Admin class ShippingCategoriesController < ResourceController + + protected + def permitted_resource_params params.require(:shipping_category). permit(:name, :temperature_controlled) From c6842ada7f680025b6a2f08346e8c604f0e1005c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 13 May 2020 10:56:20 +0100 Subject: [PATCH 329/507] Add variant_unit_name to the list of fields to be ignored when creating a variant, it's a product field --- app/models/product_import/entry_validator.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/product_import/entry_validator.rb b/app/models/product_import/entry_validator.rb index 1f27ed7af7..0dbbac1468 100644 --- a/app/models/product_import/entry_validator.rb +++ b/app/models/product_import/entry_validator.rb @@ -64,7 +64,8 @@ module ProductImport def mark_as_new_variant(entry, product_id) new_variant = Spree::Variant.new( entry.assignable_attributes.except('id', 'product_id', 'on_hand', 'on_demand', - 'variant_unit', 'variant_unit_scale', 'primary_taxon_id') + 'variant_unit', 'variant_unit_name', + 'variant_unit_scale', 'primary_taxon_id') ) new_variant.save new_variant.on_demand = entry.attributes['on_demand'] if entry.attributes['on_demand'].present? @@ -311,7 +312,8 @@ module ProductImport def mark_as_existing_variant(entry, existing_variant) existing_variant.assign_attributes( - entry.assignable_attributes.except('id', 'product_id', 'variant_unit', 'variant_unit_scale', 'primary_taxon_id') + entry.assignable_attributes.except('id', 'product_id', 'variant_unit', 'variant_unit_name', + 'variant_unit_scale', 'primary_taxon_id') ) check_on_hand_nil(entry, existing_variant) From 48985bbcd19f65641c233848a1e03217a6b203c1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 7 May 2020 19:59:47 +0100 Subject: [PATCH 330/507] Use patch instead of put, because it's rails 4 Extend the registration process spec to cover package selection --- config/routes/admin.rb | 2 +- spec/features/consumer/registration_spec.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 3456248e25..931015e302 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -27,7 +27,7 @@ Openfoodnetwork::Application.routes.draw do member do get :welcome - put :register + patch :register end resources :producer_properties do diff --git a/spec/features/consumer/registration_spec.rb b/spec/features/consumer/registration_spec.rb index e4bf198637..ed0c2f96b1 100644 --- a/spec/features/consumer/registration_spec.rb +++ b/spec/features/consumer/registration_spec.rb @@ -124,6 +124,10 @@ feature "Registration", js: true do click_link "Go to Enterprise Dashboard" expect(page).to have_content "CHOOSE YOUR PACKAGE" + + page.find('.full_hub h3').click + click_button "Select and Continue" + expect(page).to have_content "Your profile live" end context "when the user has no more remaining enterprises" do From a4a6431faf05ac29a3de54c784c892a434892e79 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 7 May 2020 16:44:05 +0100 Subject: [PATCH 331/507] Fix strong params problem where order object is not sent to controller --- app/controllers/spree/admin/orders_controller.rb | 2 ++ spec/controllers/spree/admin/orders_controller_spec.rb | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/app/controllers/spree/admin/orders_controller.rb b/app/controllers/spree/admin/orders_controller.rb index 2e7701a614..9625ebe29d 100644 --- a/app/controllers/spree/admin/orders_controller.rb +++ b/app/controllers/spree/admin/orders_controller.rb @@ -109,6 +109,8 @@ module Spree private def order_params + return params[:order] if params[:order].blank? + params.require(:order).permit(:distributor_id, :order_cycle_id) end diff --git a/spec/controllers/spree/admin/orders_controller_spec.rb b/spec/controllers/spree/admin/orders_controller_spec.rb index aa54f46264..8ab20c385a 100644 --- a/spec/controllers/spree/admin/orders_controller_spec.rb +++ b/spec/controllers/spree/admin/orders_controller_spec.rb @@ -46,6 +46,14 @@ describe Spree::Admin::OrdersController, type: :controller do context "complete order" do let(:order) { create :completed_order_with_totals } + it "does not throw an error if no order object is given in params" do + params = { id: order } + + spree_put :update, params + + expect(response.status).to eq 302 + end + it "updates distribution charges and redirects to order details page" do expect_any_instance_of(Spree::Order).to receive(:update_distribution_charge!) From e7828e107b3d078afb20e7cd9a28a1331f865d5a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 1 Jun 2020 14:07:34 +0100 Subject: [PATCH 332/507] Delete dead methods from product_decorator --- app/models/spree/product_decorator.rb | 12 ------- spec/models/spree/product_spec.rb | 51 --------------------------- 2 files changed, 63 deletions(-) diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index fe20fe5194..4b99aff8f2 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -158,18 +158,6 @@ Spree::Product.class_eval do self.class.in_order_cycle(order_cycle).include? self end - # overriding to check self.on_demand as well - def has_stock? - has_variants? ? variants.any?(&:in_stock?) : (on_demand || master.in_stock?) - end - - def has_stock_for_distribution?(order_cycle, distributor) - # This product has stock for a distribution if it is available on-demand - # or if one of its variants in the distribution is in stock - (!has_variants? && on_demand) || - variants_distributed_by(order_cycle, distributor).any?(&:in_stock?) - end - def variants_distributed_by(order_cycle, distributor) order_cycle.variants_distributed_by(distributor).where(product_id: self) end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index a8c6368a70..15d79596ee 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -579,57 +579,6 @@ module Spree end end - describe "stock filtering" do - it "considers products that are on_demand as being in stock" do - product = create(:simple_product, on_demand: true) - product.master.update_attribute(:on_hand, 0) - expect(product.has_stock?).to eq(true) - end - - describe "finding products in stock for a particular distribution" do - it "returns on-demand products" do - p = create(:simple_product, on_demand: true) - p.variants.first.update_attributes!(on_hand: 0, on_demand: true) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - oc.exchanges.outgoing.first.variants << p.variants.first - - expect(p).to have_stock_for_distribution(oc, d) - end - - it "returns products with in-stock variants" do - p = create(:simple_product) - v = create(:variant, product: p) - v.update_attribute(:on_hand, 1) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - oc.exchanges.outgoing.first.variants << v - - expect(p).to have_stock_for_distribution(oc, d) - end - - it "returns products with on-demand variants" do - p = create(:simple_product) - v = create(:variant, product: p, on_demand: true) - v.update_attribute(:on_hand, 0) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - oc.exchanges.outgoing.first.variants << v - - expect(p).to have_stock_for_distribution(oc, d) - end - - it "does not return products that have stock not in the distribution" do - p = create(:simple_product) - p.master.update_attribute(:on_hand, 1) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - - expect(p).not_to have_stock_for_distribution(oc, d) - end - end - end - describe "taxons" do let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } From 072da7316e6a8ad1210088dc91e8737a9d60bc89 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 1 Jun 2020 14:09:14 +0100 Subject: [PATCH 333/507] Remove views code that tests for the existence of product variants A product always has the standard variant, the only case where a product will not have variants is immediatly after creation and before being saved --- app/views/spree/admin/images/index.html.haml | 9 +-- .../spree/admin/products/_form.html.haml | 31 ---------- .../spree/admin/variants/index.html.haml | 58 ++++++++----------- 3 files changed, 28 insertions(+), 70 deletions(-) diff --git a/app/views/spree/admin/images/index.html.haml b/app/views/spree/admin/images/index.html.haml index 89124383e2..37cc53c70b 100644 --- a/app/views/spree/admin/images/index.html.haml +++ b/app/views/spree/admin/images/index.html.haml @@ -15,15 +15,13 @@ %colgroup %col{ style: "width: 5%" }/ %col{ style: "width: 10%" }/ - - if @product.has_variants? - %col{ style: "width: 25%" }/ + %col{ style: "width: 25%" }/ %col{ style: "width: 45%" }/ %col{ style: "width: 15%" }/ %thead %tr %th{:colspan => "2"}= t('spree.thumbnail') - - if @product.has_variants? - %th= Spree::Variant.model_name.human + %th= Spree::Variant.model_name.human %th= t('spree.alt_text') %th.actions %tbody @@ -35,8 +33,7 @@ %span.handle %td = link_to image_tag(image.attachment.url(:mini)), image.attachment.url(:product) - - if @product.has_variants? - %td= options_text_for(image) + %td= options_text_for(image) %td= image.alt %td.actions = link_to_with_icon 'icon-edit', t('spree.edit'), edit_admin_product_image_url(@product, image), no_text: true, data: { action: 'edit'} diff --git a/app/views/spree/admin/products/_form.html.haml b/app/views/spree/admin/products/_form.html.haml index 616f7977f3..08386e10dd 100644 --- a/app/views/spree/admin/products/_form.html.haml +++ b/app/views/spree/admin/products/_form.html.haml @@ -43,37 +43,6 @@ .clear - - unless @product.has_variants? - = f.field_container :sku do - = f.label :sku, t(:sku) - = f.text_field :sku, :size => 16 - - .alpha.two.columns - = f.field_container :on_hand do - = f.label :on_hand, t(:on_hand) - = f.number_field :on_hand, :min => 0 - .omega.two.columns - = f.field_container :on_demand, :class => ['checkbox'] do - %label - = f.check_box :on_demand - = t(:on_demand) - - .clear - - %ul#shipping_specs - %li#shipping_specs_weight_field.field.alpha.two.columns - = f.label :weight, t(:weight) - = f.text_field :weight, :size => 4 - %li#shipping_specs_height_field.field.omega.two.columns - = f.label :height, t(:height) - = f.text_field :height, :size => 4 - %li#shipping_specs_width_field.field.alpha.two.columns - = f.label :width, t(:width) - = f.text_field :width, :size => 4 - %li#shipping_specs_depth_field.field.omega.two.columns - = f.label :depth, t(:depth) - = f.text_field :depth, :size => 4 - = f.field_container :shipping_categories do = f.label :shipping_category_id, t(:shipping_categories) = f.collection_select(:shipping_category_id, @shipping_categories, :id, :name, { :include_blank => 'None' }, { :class => 'select2' }) diff --git a/app/views/spree/admin/variants/index.html.haml b/app/views/spree/admin/variants/index.html.haml index 199bcc0501..ce9c1edd86 100644 --- a/app/views/spree/admin/variants/index.html.haml +++ b/app/views/spree/admin/variants/index.html.haml @@ -3,40 +3,32 @@ = render partial: 'spree/admin/shared/product_tabs', locals: {current: 'Variants'} #new_variant -- if @variants.any? - %table.index.sortable{"data-sortable-link" => update_positions_admin_product_variants_path(@product)} - %colgroup - %col{style: "width: 5%"}/ - %col{style: "width: 25%"}/ - %col{style: "width: 20%"}/ - %col{style: "width: 20%"}/ - %col{style: "width: 15%"}/ - %col{style: "width: 15%"}/ - %thead - %tr - %th{colspan: "2"}= t('.options') - %th= t('.price') - %th= t('.sku') - %th.actions - %tbody - - @variants.each do |variant| - %tr{id: spree_dom_id(variant), class: cycle('odd', 'even'), style: "#{"color:red;" if variant.deleted? }" } - %td.no-border - %span.handle - %td= variant.full_name - %td.align-center= variant.display_price.to_html - %td.align-center= variant.sku - %td.actions - = link_to_edit(variant, no_text: true) unless variant.deleted? - = link_to_delete(variant, no_text: true) unless variant.deleted? - - unless @product.has_variants? - %tr - %td{colspan: "5"}= t(:none) -- else - .alpha.twelve.columns.no-objects-found - = t('.no_results') - \. +%table.index.sortable{"data-sortable-link" => update_positions_admin_product_variants_path(@product)} + %colgroup + %col{style: "width: 5%"}/ + %col{style: "width: 25%"}/ + %col{style: "width: 20%"}/ + %col{style: "width: 20%"}/ + %col{style: "width: 15%"}/ + %col{style: "width: 15%"}/ + %thead + %tr + %th{colspan: "2"}= t('.options') + %th= t('.price') + %th= t('.sku') + %th.actions + %tbody + - @variants.each do |variant| + %tr{id: spree_dom_id(variant), class: cycle('odd', 'even'), style: "#{"color:red;" if variant.deleted? }" } + %td.no-border + %span.handle + %td= variant.full_name + %td.align-center= variant.display_price.to_html + %td.align-center= variant.sku + %td.actions + = link_to_edit(variant, no_text: true) unless variant.deleted? + = link_to_delete(variant, no_text: true) unless variant.deleted? - if @product.empty_option_values? %p.first_add_option_types.no-objects-found From 2d7f1ce283bfff962d57dd40c10ea52f6f78f85d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 1 Jun 2020 20:36:07 +0100 Subject: [PATCH 334/507] Delete all variants from test product not just the first one --- spec/models/concerns/product_stock_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/concerns/product_stock_spec.rb b/spec/models/concerns/product_stock_spec.rb index cf91b4d671..5b5a21efb4 100644 --- a/spec/models/concerns/product_stock_spec.rb +++ b/spec/models/concerns/product_stock_spec.rb @@ -5,7 +5,7 @@ describe ProductStock do context "when product has no variants" do before do - product.variants.first.destroy + product.variants.destroy product.variants.reload end From f4a64e89c22c26581e745c0a8a6c6119b8cb286b Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Fri, 22 May 2020 16:42:28 +1000 Subject: [PATCH 335/507] Added translation keys to error messages partial and en.yml file to add translation to error messages --- app/views/spree/shared/_error_messages.html.haml | 5 ++--- config/locales/en.yml | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/views/spree/shared/_error_messages.html.haml b/app/views/spree/shared/_error_messages.html.haml index 54fabd313e..b0ced1b317 100644 --- a/app/views/spree/shared/_error_messages.html.haml +++ b/app/views/spree/shared/_error_messages.html.haml @@ -1,10 +1,9 @@ - if target && target.errors.any? #errorExplanation.errorExplanation %h2 - = Spree.t(:errors_prohibited_this_record_from_being_saved, count: target.errors.count) - \: + = t(".errors_prohibited_this_record_from_being_saved", count: target.errors.count) %p - = Spree.t(:there_were_problems_with_the_following_fields) + = t(".there_were_problems_with_the_following_fields") \: %ul - target.errors.full_messages.each do |msg| diff --git a/config/locales/en.yml b/config/locales/en.yml index 158e964b89..d3b0f022aa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3089,6 +3089,12 @@ See the %{link} to find out more about %{sitename}'s features and to start using actions: update: "Update" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 error prohibited this record from being saved:" + other: "%{count} errors prohibited this record from being saved:" + there_were_problems_with_the_following_fields: "There were problems with the following fields" errors: messages: blank: "can't be blank" From b21904ada1f65fdf948a4fb5c4b1821d0ce6ec7b Mon Sep 17 00:00:00 2001 From: romale Date: Tue, 2 Jun 2020 10:38:36 +0300 Subject: [PATCH 336/507] moved to 2882 --- config/locales/en.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index a5d6dd3398..5145fee5c4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2879,7 +2879,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" - + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" @@ -2905,7 +2905,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using previous: "Previous" last: "Last" - return_authorizations: "Return Authorizations" spree: your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" From 35648025df6f01ff4b356557ed5164753c8a6a73 Mon Sep 17 00:00:00 2001 From: romale Date: Tue, 2 Jun 2020 12:09:38 +0300 Subject: [PATCH 337/507] formating --- config/locales/en.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5145fee5c4..2e20b6d85f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2879,6 +2879,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" From 9d3f010173ad4014cd959baf72765008838ded8b Mon Sep 17 00:00:00 2001 From: romale Date: Tue, 2 Jun 2020 14:42:50 +0300 Subject: [PATCH 338/507] formating --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 2e20b6d85f..02d96f1bd6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2879,8 +2879,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" - return_authorizations: "Return Authorizations" + payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" From d16bfe3779d77b42c7dd9f61bdd4306ddd838a26 Mon Sep 17 00:00:00 2001 From: romale Date: Tue, 2 Jun 2020 14:44:16 +0300 Subject: [PATCH 339/507] formatting --- config/locales/en.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 02d96f1bd6..5c6493bc9a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2905,7 +2905,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using first: "First" previous: "Previous" last: "Last" - spree: your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" From a0aa42cd5837848d402825b31e5e4feae4d12838 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 13:26:12 +0100 Subject: [PATCH 340/507] Remove resource_scoping from api/variants spec --- spec/controllers/api/variants_controller_spec.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/controllers/api/variants_controller_spec.rb b/spec/controllers/api/variants_controller_spec.rb index a5c81329dd..c91f25f2ec 100644 --- a/spec/controllers/api/variants_controller_spec.rb +++ b/spec/controllers/api/variants_controller_spec.rb @@ -113,7 +113,6 @@ describe Api::VariantsController, type: :controller do let(:product) { create(:product) } let(:variant) { product.master } - let(:resource_scoping) { { product_id: variant.product.to_param } } context "deleted variants" do before do @@ -121,7 +120,7 @@ describe Api::VariantsController, type: :controller do end it "are visible by admin" do - api_get :index, show_deleted: 1 + api_get :index, show_deleted: 1, product_id: variant.product.to_param expect(json_response.count).to eq(2) end @@ -129,7 +128,7 @@ describe Api::VariantsController, type: :controller do it "can create a new variant" do original_number_of_variants = variant.product.variants.count - api_post :create, variant: { sku: "12345", unit_value: "weight", unit_description: "L" } + api_post :create, variant: { sku: "12345", unit_value: "weight", unit_description: "L" }, product_id: variant.product.to_param expect(attributes.all?{ |attr| json_response.include? attr.to_s }).to eq(true) expect(response.status).to eq(201) From 092e047b44c7076f8aabfd16b03d7300494ef9e5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 13:35:48 +0100 Subject: [PATCH 341/507] Remove resource_scoping from api/shipments_controller spec --- spec/controllers/api/shipments_controller_spec.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/spec/controllers/api/shipments_controller_spec.rb b/spec/controllers/api/shipments_controller_spec.rb index d79eaf0c08..2f66d0b158 100644 --- a/spec/controllers/api/shipments_controller_spec.rb +++ b/spec/controllers/api/shipments_controller_spec.rb @@ -5,7 +5,6 @@ describe Api::ShipmentsController, type: :controller do let!(:shipment) { create(:shipment) } let!(:attributes) { [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id] } - let!(:resource_scoping) { { order_id: shipment.order.to_param, id: shipment.to_param } } let(:current_api_user) { build(:user) } before do @@ -14,12 +13,12 @@ describe Api::ShipmentsController, type: :controller do context "as a non-admin" do it "cannot make a shipment ready" do - api_put :ready + api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param assert_unauthorized! end it "cannot make a shipment shipped" do - api_put :ship + api_put :ship, order_id: shipment.order.to_param, id: shipment.to_param assert_unauthorized! end end @@ -92,7 +91,7 @@ describe Api::ShipmentsController, type: :controller do it "can make a shipment ready" do allow_any_instance_of(Spree::Order).to receive_messages(paid?: true, complete?: true) - api_put :ready + api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param expect(attributes.all?{ |attr| json_response.key? attr.to_s }).to be_truthy expect(json_response["state"]).to eq("ready") @@ -101,7 +100,7 @@ describe Api::ShipmentsController, type: :controller do it "cannot make a shipment ready if the order is unpaid" do allow_any_instance_of(Spree::Order).to receive_messages(paid?: false) - api_put :ready + api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param expect(json_response["error"]).to eq("Cannot ready shipment.") expect(response.status).to eq(422) @@ -109,10 +108,9 @@ describe Api::ShipmentsController, type: :controller do context 'for completed shipments' do let(:order) { create :completed_order_with_totals } - let!(:resource_scoping) { { order_id: order.to_param, id: order.shipments.first.to_param } } it 'adds a variant to a shipment' do - api_put :add, variant_id: variant.to_param, quantity: 2 + api_put :add, variant_id: variant.to_param, quantity: 2, order_id: order.to_param, id: order.shipments.first.to_param expect(response.status).to eq(200) expect(order.shipment.reload.inventory_units.select { |h| h['variant_id'] == variant.id }.size).to eq 2 @@ -120,7 +118,7 @@ describe Api::ShipmentsController, type: :controller do it 'removes a variant from a shipment' do order.contents.add(variant, 2) - api_put :remove, variant_id: variant.to_param, quantity: 1 + api_put :remove, variant_id: variant.to_param, quantity: 1, order_id: order.to_param, id: order.shipments.first.to_param expect(response.status).to eq(200) expect(order.shipment.reload.inventory_units.select { |h| h['variant_id'] == variant.id }.size).to eq(1) From 2c2263ab78d35b9a9fdc3641f9e85b3652101fa4 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 13:41:46 +0100 Subject: [PATCH 342/507] Fix rubocop issues in shipments_controller_spec --- .rubocop_manual_todo.yml | 1 - .../api/shipments_controller_spec.rb | 22 ++++++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index e55124201f..ace78ed248 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -142,7 +142,6 @@ Layout/LineLength: - spec/controllers/api/product_images_controller_spec.rb - spec/controllers/api/products_controller_spec.rb - spec/controllers/api/promo_images_controller_spec.rb - - spec/controllers/api/shipments_controller_spec.rb - spec/controllers/api/variants_controller_spec.rb - spec/controllers/cart_controller_spec.rb - spec/controllers/checkout_controller_spec.rb diff --git a/spec/controllers/api/shipments_controller_spec.rb b/spec/controllers/api/shipments_controller_spec.rb index 2f66d0b158..3643f0a58d 100644 --- a/spec/controllers/api/shipments_controller_spec.rb +++ b/spec/controllers/api/shipments_controller_spec.rb @@ -4,7 +4,9 @@ describe Api::ShipmentsController, type: :controller do render_views let!(:shipment) { create(:shipment) } - let!(:attributes) { [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id] } + let!(:attributes) do + [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id] + end let(:current_api_user) { build(:user) } before do @@ -110,18 +112,24 @@ describe Api::ShipmentsController, type: :controller do let(:order) { create :completed_order_with_totals } it 'adds a variant to a shipment' do - api_put :add, variant_id: variant.to_param, quantity: 2, order_id: order.to_param, id: order.shipments.first.to_param + api_put :add, variant_id: variant.to_param, + quantity: 2, + order_id: order.to_param, + id: order.shipments.first.to_param expect(response.status).to eq(200) - expect(order.shipment.reload.inventory_units.select { |h| h['variant_id'] == variant.id }.size).to eq 2 + expect(inventory_units_for(variant).size).to eq 2 end it 'removes a variant from a shipment' do order.contents.add(variant, 2) - api_put :remove, variant_id: variant.to_param, quantity: 1, order_id: order.to_param, id: order.shipments.first.to_param + api_put :remove, variant_id: variant.to_param, + quantity: 1, + order_id: order.to_param, + id: order.shipments.first.to_param expect(response.status).to eq(200) - expect(order.shipment.reload.inventory_units.select { |h| h['variant_id'] == variant.id }.size).to eq(1) + expect(inventory_units_for(variant).size).to eq(1) end end @@ -138,7 +146,9 @@ describe Api::ShipmentsController, type: :controller do it "can transition a shipment from ready to ship" do shipment.reload - api_put :ship, order_id: shipment.order.to_param, id: shipment.to_param, shipment: { tracking: "123123" } + api_put :ship, order_id: shipment.order.to_param, + id: shipment.to_param, + shipment: { tracking: "123123" } expect(attributes.all?{ |attr| json_response.key? attr.to_s }).to be_truthy expect(json_response["state"]).to eq("shipped") From cd3bc54c3758c9db91143cd1c2ac9ef7e4855272 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 13:43:33 +0100 Subject: [PATCH 343/507] Remove resource_scoping to make things more simple --- spec/support/controller_hacks.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/support/controller_hacks.rb b/spec/support/controller_hacks.rb index 7645e87372..978710068b 100644 --- a/spec/support/controller_hacks.rb +++ b/spec/support/controller_hacks.rb @@ -18,10 +18,8 @@ module ControllerHacks end def api_process(action, params = {}, session = nil, flash = nil, method = "get") - scoping = respond_to?(:resource_scoping) ? resource_scoping : {} process(action, params. - merge(scoping). reverse_merge!(use_route: :spree, format: :json), session, flash, From 5d0856e5a3235cef90944fed61af4f1e8b01f0f3 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 13:47:59 +0100 Subject: [PATCH 344/507] Rename ControllerHacks to ControllerRequestsHelper and move it's configuration to spec_helper --- spec/spec_helper.rb | 3 ++- .../{controller_hacks.rb => controller_requests_helper.rb} | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) rename spec/support/{controller_hacks.rb => controller_requests_helper.rb} (88%) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e145fa7909..2ff99b5f11 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -148,8 +148,9 @@ RSpec.configure do |config| config.include Spree::UrlHelpers config.include Spree::CheckoutHelpers config.include Spree::MoneyHelper - config.include Spree::TestingSupport::ControllerRequests, type: :controller config.include Spree::TestingSupport::Preferences + config.include Spree::TestingSupport::ControllerRequests, type: :controller + config.include ControllerRequestsHelper, type: :controller config.include Devise::TestHelpers, type: :controller config.extend Spree::Api::TestingSupport::Setup, type: :controller config.include OpenFoodNetwork::ApiHelper, type: :controller diff --git a/spec/support/controller_hacks.rb b/spec/support/controller_requests_helper.rb similarity index 88% rename from spec/support/controller_hacks.rb rename to spec/support/controller_requests_helper.rb index 978710068b..73afb2c1f3 100644 --- a/spec/support/controller_hacks.rb +++ b/spec/support/controller_requests_helper.rb @@ -1,6 +1,6 @@ require 'active_support/all' -module ControllerHacks +module ControllerRequestsHelper def api_get(action, params = {}, session = nil, flash = nil) api_process(action, params, session, flash, "GET") end @@ -26,7 +26,3 @@ module ControllerHacks method) end end - -RSpec.configure do |config| - config.include ControllerHacks, type: :controller -end From 2f76e0b15baf240de6c050a177acc61d330dbb31 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 13:54:33 +0100 Subject: [PATCH 345/507] Bring methods from Spree::TestingSupport::ControllerRequests to our ControllerRequestsHelper so we can merge them later --- spec/spec_helper.rb | 2 -- spec/support/controller_requests_helper.rb | 28 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2ff99b5f11..edc9519e94 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -36,7 +36,6 @@ WebMock.disable_net_connect!( # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } -require 'spree/testing_support/controller_requests' require 'spree/testing_support/capybara_ext' require 'spree/api/testing_support/setup' require 'spree/testing_support/authorization_helpers' @@ -149,7 +148,6 @@ RSpec.configure do |config| config.include Spree::CheckoutHelpers config.include Spree::MoneyHelper config.include Spree::TestingSupport::Preferences - config.include Spree::TestingSupport::ControllerRequests, type: :controller config.include ControllerRequestsHelper, type: :controller config.include Devise::TestHelpers, type: :controller config.extend Spree::Api::TestingSupport::Setup, type: :controller diff --git a/spec/support/controller_requests_helper.rb b/spec/support/controller_requests_helper.rb index 73afb2c1f3..42575f7eaf 100644 --- a/spec/support/controller_requests_helper.rb +++ b/spec/support/controller_requests_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'active_support/all' module ControllerRequestsHelper @@ -17,6 +19,27 @@ module ControllerRequestsHelper api_process(action, params, session, flash, "DELETE") end + def spree_get(action, parameters = nil, session = nil, flash = nil) + process_spree_action(action, parameters, session, flash, "GET") + end + + # Executes a request simulating POST HTTP method and set/volley the response + def spree_post(action, parameters = nil, session = nil, flash = nil) + process_spree_action(action, parameters, session, flash, "POST") + end + + # Executes a request simulating PUT HTTP method and set/volley the response + def spree_put(action, parameters = nil, session = nil, flash = nil) + process_spree_action(action, parameters, session, flash, "PUT") + end + + # Executes a request simulating DELETE HTTP method and set/volley the response + def spree_delete(action, parameters = nil, session = nil, flash = nil) + process_spree_action(action, parameters, session, flash, "DELETE") + end + + private + def api_process(action, params = {}, session = nil, flash = nil, method = "get") process(action, params. @@ -25,4 +48,9 @@ module ControllerRequestsHelper flash, method) end + + def process_spree_action(action, parameters = nil, session = nil, flash = nil, method = "GET") + parameters ||= {} + process(action, parameters.merge!(use_route: :spree), session, flash, method) + end end From 9d56c180b271d41911d9a2055c8229952b19d707 Mon Sep 17 00:00:00 2001 From: romale Date: Tue, 2 Jun 2020 15:56:59 +0300 Subject: [PATCH 346/507] formatting --- config/locales/en.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5c6493bc9a..02d96f1bd6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2905,6 +2905,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using first: "First" previous: "Previous" last: "Last" + spree: your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" From 3136aa5a8bbfe28c6c0826bb712fb1bead8ee9ef Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 14:00:24 +0100 Subject: [PATCH 347/507] Make api_process use process_spree_action --- spec/support/controller_requests_helper.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/spec/support/controller_requests_helper.rb b/spec/support/controller_requests_helper.rb index 42575f7eaf..93f1853cb2 100644 --- a/spec/support/controller_requests_helper.rb +++ b/spec/support/controller_requests_helper.rb @@ -41,16 +41,18 @@ module ControllerRequestsHelper private def api_process(action, params = {}, session = nil, flash = nil, method = "get") + process_spree_action(action, + params.reverse_merge!(format: :json), + session, + flash, + method) + end + + def process_spree_action(action, parameters = {}, session = nil, flash = nil, method = "GET") process(action, - params. - reverse_merge!(use_route: :spree, format: :json), + parameters.merge!(use_route: :spree), session, flash, method) end - - def process_spree_action(action, parameters = nil, session = nil, flash = nil, method = "GET") - parameters ||= {} - process(action, parameters.merge!(use_route: :spree), session, flash, method) - end end From 13836a62bb66c5139d65d6bea16252bedcfb3036 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 14:36:06 +0100 Subject: [PATCH 348/507] Rename parameters to params and change default from nil to {} --- spec/support/controller_requests_helper.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/support/controller_requests_helper.rb b/spec/support/controller_requests_helper.rb index 93f1853cb2..4aa4c8535b 100644 --- a/spec/support/controller_requests_helper.rb +++ b/spec/support/controller_requests_helper.rb @@ -19,23 +19,23 @@ module ControllerRequestsHelper api_process(action, params, session, flash, "DELETE") end - def spree_get(action, parameters = nil, session = nil, flash = nil) - process_spree_action(action, parameters, session, flash, "GET") + def spree_get(action, params = {}, session = nil, flash = nil) + process_spree_action(action, params, session, flash, "GET") end # Executes a request simulating POST HTTP method and set/volley the response - def spree_post(action, parameters = nil, session = nil, flash = nil) - process_spree_action(action, parameters, session, flash, "POST") + def spree_post(action, params = {}, session = nil, flash = nil) + process_spree_action(action, params, session, flash, "POST") end # Executes a request simulating PUT HTTP method and set/volley the response - def spree_put(action, parameters = nil, session = nil, flash = nil) - process_spree_action(action, parameters, session, flash, "PUT") + def spree_put(action, params = {}, session = nil, flash = nil) + process_spree_action(action, params, session, flash, "PUT") end # Executes a request simulating DELETE HTTP method and set/volley the response - def spree_delete(action, parameters = nil, session = nil, flash = nil) - process_spree_action(action, parameters, session, flash, "DELETE") + def spree_delete(action, params = {}, session = nil, flash = nil) + process_spree_action(action, params, session, flash, "DELETE") end private @@ -48,9 +48,9 @@ module ControllerRequestsHelper method) end - def process_spree_action(action, parameters = {}, session = nil, flash = nil, method = "GET") + def process_spree_action(action, params = {}, session = nil, flash = nil, method = "GET") process(action, - parameters.merge!(use_route: :spree), + params.merge!(use_route: :spree), session, flash, method) From 7b89f4d6c5f8bb67eb54782ef3b45f34bf29197c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 15:00:57 +0100 Subject: [PATCH 349/507] Switch controller helper calls routes from spree to main_app, this will include all routes all the time --- spec/controllers/api/shops_controller_spec.rb | 2 +- spec/support/controller_requests_helper.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/api/shops_controller_spec.rb b/spec/controllers/api/shops_controller_spec.rb index 33343e8d84..91f88abc0a 100644 --- a/spec/controllers/api/shops_controller_spec.rb +++ b/spec/controllers/api/shops_controller_spec.rb @@ -34,7 +34,7 @@ module Api describe "#closed_shops" do it "returns data for all closed shops" do - spree_get :closed_shops, nil + spree_get :closed_shops, {} expect(json_response).not_to match hub.name diff --git a/spec/support/controller_requests_helper.rb b/spec/support/controller_requests_helper.rb index 4aa4c8535b..3ac1103014 100644 --- a/spec/support/controller_requests_helper.rb +++ b/spec/support/controller_requests_helper.rb @@ -50,7 +50,7 @@ module ControllerRequestsHelper def process_spree_action(action, params = {}, session = nil, flash = nil, method = "GET") process(action, - params.merge!(use_route: :spree), + params.merge!(use_route: :main_app), session, flash, method) From beb1b3f3bc803716ae6b0ae21796b908b9d04d99 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 16:11:03 +0100 Subject: [PATCH 350/507] Replay 02d46b7c518c799ad4091521652e95b3298dea93 lost in the last merge from master --- spec/features/admin/order_cycles/list_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/features/admin/order_cycles/list_spec.rb b/spec/features/admin/order_cycles/list_spec.rb index 6021a83f12..ba5f2d4048 100644 --- a/spec/features/admin/order_cycles/list_spec.rb +++ b/spec/features/admin/order_cycles/list_spec.rb @@ -117,10 +117,10 @@ feature ' end describe 'listing order cycles with other locales' do - let!(:oc_de) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } + let!(:oc_pt) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } around(:each) do |spec| - I18n.locale = :de + I18n.locale = :pt spec.run I18n.locale = :en end @@ -130,7 +130,7 @@ feature ' quick_login_as_admin visit admin_order_cycles_path - within("tr.order-cycle-#{oc_de.id}") do + within("tr.order-cycle-#{oc_pt.id}") do expect(find('input.datetimepicker', match: :first).value).to start_with '2012-01-01 00:00' find('img.ui-datepicker-trigger', match: :first).click end @@ -142,7 +142,7 @@ feature ' find('button.ui-datepicker-close', match: :first).click end - within("tr.order-cycle-#{oc_de.id}") do + within("tr.order-cycle-#{oc_pt.id}") do expect(find('input.datetimepicker', match: :first).value).to eq '2012-01-30 00:00' end end From 53a80de503436c1dbce458f01063160d0e23d803 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 17:32:09 +0100 Subject: [PATCH 351/507] Improve method names and set use_route with reverse_merge so it can be overridden --- spec/support/controller_requests_helper.rb | 27 ++++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/spec/support/controller_requests_helper.rb b/spec/support/controller_requests_helper.rb index 3ac1103014..7187670f12 100644 --- a/spec/support/controller_requests_helper.rb +++ b/spec/support/controller_requests_helper.rb @@ -4,53 +4,50 @@ require 'active_support/all' module ControllerRequestsHelper def api_get(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "GET") + process_json_action(action, params, session, flash, "GET") end def api_post(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "POST") + process_json_action(action, params, session, flash, "POST") end def api_put(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "PUT") + process_json_action(action, params, session, flash, "PUT") end def api_delete(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "DELETE") + process_json_action(action, params, session, flash, "DELETE") end def spree_get(action, params = {}, session = nil, flash = nil) - process_spree_action(action, params, session, flash, "GET") + process_action_with_route(action, params, session, flash, "GET") end - # Executes a request simulating POST HTTP method and set/volley the response def spree_post(action, params = {}, session = nil, flash = nil) - process_spree_action(action, params, session, flash, "POST") + process_action_with_route(action, params, session, flash, "POST") end - # Executes a request simulating PUT HTTP method and set/volley the response def spree_put(action, params = {}, session = nil, flash = nil) - process_spree_action(action, params, session, flash, "PUT") + process_action_with_route(action, params, session, flash, "PUT") end - # Executes a request simulating DELETE HTTP method and set/volley the response def spree_delete(action, params = {}, session = nil, flash = nil) - process_spree_action(action, params, session, flash, "DELETE") + process_action_with_route(action, params, session, flash, "DELETE") end private - def api_process(action, params = {}, session = nil, flash = nil, method = "get") - process_spree_action(action, + def process_json_action(action, params = {}, session = nil, flash = nil, method = "get") + process_action_with_route(action, params.reverse_merge!(format: :json), session, flash, method) end - def process_spree_action(action, params = {}, session = nil, flash = nil, method = "GET") + def process_action_with_route(action, params = {}, session = nil, flash = nil, method = "GET") process(action, - params.merge!(use_route: :main_app), + params.reverse_merge!(use_route: :main_app), session, flash, method) From c68459f212a7aefb69863f896de7174da25f70fc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 16:16:07 +0100 Subject: [PATCH 352/507] Make enterprises_controller_spec use api_post instead of spree_post --- spec/controllers/api/enterprises_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index 54c5efc3b3..d0e8209f31 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -23,14 +23,14 @@ module Api address1: '123 Abc Street', city: 'Northcote', zipcode: '3070', - state_id: australia.states.first, + state_id: australia.states.first.id, country_id: australia.id } } end it "creates as sells=any when it is not a producer" do - spree_post :create, { enterprise: new_enterprise_params } + api_post :create, { enterprise: new_enterprise_params } expect(response).to be_success enterprise = Enterprise.last From ff0c93a76bc34edb7d91fb03d9fce65726ae0594 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 18:22:30 +0100 Subject: [PATCH 353/507] Join module and describe declaration so that rspec picks up correct controller under Api namespace and not the controller with the same name in the base namespace --- .../api/enterprises_controller_spec.rb | 142 +++++++++--------- 1 file changed, 70 insertions(+), 72 deletions(-) diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index d0e8209f31..c407a2b918 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -1,95 +1,93 @@ require 'spec_helper' -module Api - describe EnterprisesController, type: :controller do - include AuthenticationWorkflow - render_views +describe Api::EnterprisesController, type: :controller do + include AuthenticationWorkflow + render_views - let(:enterprise) { create(:distributor_enterprise) } + let(:enterprise) { create(:distributor_enterprise) } - context "as an enterprise owner" do - let(:enterprise_owner) { create_enterprise_user enterprise_limit: 10 } - let!(:enterprise) { create(:distributor_enterprise, owner: enterprise_owner) } + context "as an enterprise owner" do + let(:enterprise_owner) { create_enterprise_user enterprise_limit: 10 } + let!(:enterprise) { create(:distributor_enterprise, owner: enterprise_owner) } - before do - allow(controller).to receive(:spree_current_user) { enterprise_owner } - end - - describe "creating an enterprise" do - let(:australia) { Spree::Country.find_by(name: 'Australia') } - let(:new_enterprise_params) do - { - name: 'name', contact_name: 'Sheila', address_attributes: { - address1: '123 Abc Street', - city: 'Northcote', - zipcode: '3070', - state_id: australia.states.first.id, - country_id: australia.id - } - } - end - - it "creates as sells=any when it is not a producer" do - api_post :create, { enterprise: new_enterprise_params } - expect(response).to be_success - - enterprise = Enterprise.last - expect(enterprise.sells).to eq('any') - end - - it "saves all user ids submitted" do - manager1 = create(:user) - manager2 = create(:user) - spree_post :create, { - enterprise: new_enterprise_params. - merge({ user_ids: [enterprise_owner.id, manager1.id, manager2.id] }) - } - expect(response).to be_success - - enterprise = Enterprise.last - expect(enterprise.user_ids).to match_array([enterprise_owner.id, manager1.id, manager2.id]) - end - end + before do + allow(controller).to receive(:spree_current_user) { enterprise_owner } end - context "as an enterprise manager" do - let(:enterprise_manager) { create_enterprise_user } - - before do - enterprise_manager.enterprise_roles.build(enterprise: enterprise).save - allow(controller).to receive(:spree_current_user) { enterprise_manager } + describe "creating an enterprise" do + let(:australia) { Spree::Country.find_by(name: 'Australia') } + let(:new_enterprise_params) do + { + name: 'name', contact_name: 'Sheila', address_attributes: { + address1: '123 Abc Street', + city: 'Northcote', + zipcode: '3070', + state_id: australia.states.first.id, + country_id: australia.id + } + } end - describe "submitting a valid image" do - before do - allow(Enterprise) - .to receive(:find_by).with({ permalink: enterprise.id.to_s }) { enterprise } - allow(enterprise).to receive(:update_attributes).and_return(true) - end + it "creates as sells=any when it is not a producer" do + api_post :create, { enterprise: new_enterprise_params } + expect(response).to be_success - it "I can update enterprise image" do - spree_post :update_image, logo: 'a logo', id: enterprise.id - expect(response).to be_success - end + enterprise = Enterprise.last + expect(enterprise.sells).to eq('any') + end + + it "saves all user ids submitted" do + manager1 = create(:user) + manager2 = create(:user) + spree_post :create, { + enterprise: new_enterprise_params. + merge({ user_ids: [enterprise_owner.id, manager1.id, manager2.id] }) + } + expect(response).to be_success + + enterprise = Enterprise.last + expect(enterprise.user_ids).to match_array([enterprise_owner.id, manager1.id, manager2.id]) end end + end - context "as an non-managing user" do - let(:non_managing_user) { create_enterprise_user } + context "as an enterprise manager" do + let(:enterprise_manager) { create_enterprise_user } + before do + enterprise_manager.enterprise_roles.build(enterprise: enterprise).save + allow(controller).to receive(:spree_current_user) { enterprise_manager } + end + + describe "submitting a valid image" do before do allow(Enterprise) .to receive(:find_by).with({ permalink: enterprise.id.to_s }) { enterprise } - allow(controller).to receive(:spree_current_user) { non_managing_user } + allow(enterprise).to receive(:update_attributes).and_return(true) end - describe "submitting a valid image" do - before { allow(enterprise).to receive(:update_attributes).and_return(true) } + it "I can update enterprise image" do + spree_post :update_image, logo: 'a logo', id: enterprise.id + expect(response).to be_success + end + end + end - it "I can't update enterprise image" do - spree_post :update_image, logo: 'a logo', id: enterprise.id - assert_unauthorized! - end + context "as an non-managing user" do + let(:non_managing_user) { create_enterprise_user } + + before do + allow(Enterprise) + .to receive(:find_by).with({ permalink: enterprise.id.to_s }) { enterprise } + allow(controller).to receive(:spree_current_user) { non_managing_user } + end + + describe "submitting a valid image" do + before { allow(enterprise).to receive(:update_attributes).and_return(true) } + + it "I can't update enterprise image" do + spree_post :update_image, logo: 'a logo', id: enterprise.id + assert_unauthorized! end end end From 251c04f2d91ed06abb1e5b2770bbafa9e25de6e6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 19:08:13 +0100 Subject: [PATCH 354/507] Make all tests in enterprises_controller_spec use api_post instead of spree_post --- spec/controllers/api/enterprises_controller_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index c407a2b918..1b3382274e 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -39,7 +39,7 @@ describe Api::EnterprisesController, type: :controller do it "saves all user ids submitted" do manager1 = create(:user) manager2 = create(:user) - spree_post :create, { + api_post :create, { enterprise: new_enterprise_params. merge({ user_ids: [enterprise_owner.id, manager1.id, manager2.id] }) } @@ -67,7 +67,7 @@ describe Api::EnterprisesController, type: :controller do end it "I can update enterprise image" do - spree_post :update_image, logo: 'a logo', id: enterprise.id + api_post :update_image, logo: 'a logo', id: enterprise.id expect(response).to be_success end end @@ -86,7 +86,7 @@ describe Api::EnterprisesController, type: :controller do before { allow(enterprise).to receive(:update_attributes).and_return(true) } it "I can't update enterprise image" do - spree_post :update_image, logo: 'a logo', id: enterprise.id + api_post :update_image, logo: 'a logo', id: enterprise.id assert_unauthorized! end end From f9d86eb7edce9e32b3547fe0e243796bbd11d927 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 20:17:46 +0100 Subject: [PATCH 355/507] Join module and describe declaration so that rspec picks up correct controller under Api namespace and not the controller with the same name in the base namespace --- spec/controllers/api/shops_controller_spec.rb | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/spec/controllers/api/shops_controller_spec.rb b/spec/controllers/api/shops_controller_spec.rb index 33343e8d84..127dd83848 100644 --- a/spec/controllers/api/shops_controller_spec.rb +++ b/spec/controllers/api/shops_controller_spec.rb @@ -2,45 +2,43 @@ require 'spec_helper' -module Api - describe ShopsController, type: :controller do - include AuthenticationWorkflow - render_views +describe Api::ShopsController, type: :controller do + include AuthenticationWorkflow + render_views - context "as a non-authenticated user" do - let!(:hub) { - create(:distributor_enterprise, with_payment_and_shipping: true, name: 'Shopfront Test Hub') - } - let!(:producer) { create(:supplier_enterprise, name: 'Shopfront Test Producer') } - let!(:category) { create(:taxon, name: 'Fruit') } - let!(:product) { create(:product, supplier: producer, primary_taxon: category ) } - let!(:relationship) { create(:enterprise_relationship, parent: hub, child: producer) } - let!(:closed_hub1) { create(:distributor_enterprise) } - let!(:closed_hub2) { create(:distributor_enterprise) } + context "as a non-authenticated user" do + let!(:hub) { + create(:distributor_enterprise, with_payment_and_shipping: true, name: 'Shopfront Test Hub') + } + let!(:producer) { create(:supplier_enterprise, name: 'Shopfront Test Producer') } + let!(:category) { create(:taxon, name: 'Fruit') } + let!(:product) { create(:product, supplier: producer, primary_taxon: category ) } + let!(:relationship) { create(:enterprise_relationship, parent: hub, child: producer) } + let!(:closed_hub1) { create(:distributor_enterprise) } + let!(:closed_hub2) { create(:distributor_enterprise) } - before do - allow(controller).to receive(:spree_current_user) { nil } + before do + allow(controller).to receive(:spree_current_user) { nil } + end + + describe "#show" do + it "returns shopfront data for an enterprise" do + spree_get :show, id: producer.id + + expect(json_response['name']).to eq 'Shopfront Test Producer' + expect(json_response['hubs'][0]['name']).to eq 'Shopfront Test Hub' + expect(json_response['supplied_taxons'][0]['name']).to eq 'Fruit' end + end - describe "#show" do - it "returns shopfront data for an enterprise" do - spree_get :show, id: producer.id + describe "#closed_shops" do + it "returns data for all closed shops" do + spree_get :closed_shops, nil - expect(json_response['name']).to eq 'Shopfront Test Producer' - expect(json_response['hubs'][0]['name']).to eq 'Shopfront Test Hub' - expect(json_response['supplied_taxons'][0]['name']).to eq 'Fruit' - end - end + expect(json_response).not_to match hub.name - describe "#closed_shops" do - it "returns data for all closed shops" do - spree_get :closed_shops, nil - - expect(json_response).not_to match hub.name - - response_ids = json_response.map { |shop| shop['id'] } - expect(response_ids).to contain_exactly(closed_hub1.id, closed_hub2.id) - end + response_ids = json_response.map { |shop| shop['id'] } + expect(response_ids).to contain_exactly(closed_hub1.id, closed_hub2.id) end end end From 325cbbf3c7d6783a581a1e869c2e5df50192eccc Mon Sep 17 00:00:00 2001 From: romale Date: Tue, 2 Jun 2020 23:40:57 +0300 Subject: [PATCH 356/507] formatting --- config/locales/en.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 02d96f1bd6..725aa6f678 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2880,7 +2880,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using adjustments: "Adjustments" payments: "Payments" return_authorizations: "Return Authorizations" - + payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" @@ -2905,7 +2905,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using first: "First" previous: "Previous" last: "Last" - + spree: your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" From 4e497d93b77bf366b6d929353b5d45addeb402b4 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Wed, 3 Jun 2020 10:31:14 +1000 Subject: [PATCH 357/507] Updating translations for config/locales/en_CA.yml --- config/locales/en_CA.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 754329f66f..ab800f4021 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -664,8 +664,8 @@ en_CA: name: Name name_placeholder: eg. Professor Plum's Biodynamic Truffles groups: Groups - groups_tip: Select any groups or regions that you are a member of. This will help customers find your enterprise. - groups_placeholder: Start typing to search available groups... + groups_tip: Select any markets or groups that you are a member of. This will help customers find your enterprise. + groups_placeholder: Start typing to search available markets or groups... primary_producer: Primary Producer? primary_producer_tip: Select 'Producer' if you are a primary producer, grower, maker or designer producer: Producer @@ -1213,7 +1213,7 @@ en_CA: menu_2_url: "/map" menu_3_title: "Producers" menu_3_url: "/producers" - menu_4_title: "Groups" + menu_4_title: "Markets" menu_4_url: "/groups" menu_5_title: "About" menu_5_url: "https://about.openfoodnetwork.ca" @@ -1573,7 +1573,7 @@ en_CA: groups_search: "Search name or keyword" groups_no_groups: "No groups found" groups_about: "About Us" - groups_producers: "Our producers" + groups_producers: "Our vendors" groups_hubs: "Our hubs" groups_contact_web: Contact groups_contact_social: Follow @@ -3268,9 +3268,14 @@ en_CA: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" + customer_greeting: "Dear %{name}," + instructions_html: "Your order with 1%{distributor}1 has been CANCELED. Please retain this cancellation information for your records." + dont_cancel: "If you have changed your mind or don't wish to cancel this order please contact %{email} " + order_summary_canceled_html: "Order Summary #%{number} [CANCELED]" + details: "Here are the details of what you ordered:" + unpaid_order: "Your order was unpaid so no refund has been made" + paid_order: "Your order was paid so %{distributor} has refunded the full amount" + credit_order: "Your order was paid so your account has been credited" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" From 61d85eda6197e39ff2c1bb163ac6247dcf76e9fa Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Wed, 3 Jun 2020 17:40:19 +1000 Subject: [PATCH 358/507] Updating translations for config/locales/ca.yml --- config/locales/ca.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 3336807d9e..461d8d377e 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -3275,9 +3275,14 @@ ca: invalid: invàlid order_mailer: cancel_email: - customer_greeting: "Hola %{name}!" - instructions: "La teva comanda ha estat anul·lada. Conserva aquesta informació de cancel·lació per als teus registres." - order_summary_canceled: "Resum de comanda [CANCEL·LADA]" + customer_greeting: "Benvolgut/da,%{name}" + instructions_html: "La teva comanda %{distributor} ha estat CANCEL·LADA" + dont_cancel: "Si heu canviat d'opinió o no voleu cancel·lar aquesta comanda, poseu-vos en contacte amb %{email}" + order_summary_canceled_html: "Resum de comanda # %{number} [CANCELAT]" + details: "Aquí teniu els detalls del que vau demanar:" + unpaid_order: "La vostra comanda no s'havia pagat, per la qual cosa no s'ha realitzat cap reemborsament" + paid_order: "La teva comanda s'havia pagat per la qual cosa %{distributor} ha reemborsat l'import complet" + credit_order: "S'ha pagat la comanda i s'ha abonat l'import al vostre compte" subject: "Cancel·lació de la comanda" confirm_email: subject: "Confirmació de la comanda" From bbf381d13038c1a1a01e395e783fd27f02641f34 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Wed, 3 Jun 2020 18:32:57 +1000 Subject: [PATCH 359/507] Updating translations for config/locales/es.yml --- config/locales/es.yml | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index b04da91a62..a4452acd43 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -323,6 +323,7 @@ es: show_n_more: Mostrar %{num} más choose: "Escoger..." please_select: Por favor selecciona ... + column_save_as_default: Guardar por defecto columns: Columnas actions: Acciones viewing: "Viendo: %{current_view_name}" @@ -686,6 +687,7 @@ es: ofn_uid_tip: La identificación única utilizada para identificar la organización en Open Food Network. shipping_methods: name: "Nombre" + applies: "¿Activo?" manage: "Gestionar métodos de envío" create_button: "Crear nuevo método de envío" create_one_button: "Crear una ahora" @@ -865,6 +867,7 @@ es: incoming: "Entrante" supplier: "Proveedora" products: "Productos" + receival_details: "Detalles de la recepción" fees: "Comisiones" save: "Guardar" save_and_next: "Salvar y continuar" @@ -1174,7 +1177,11 @@ es: signup: "Regístrate" contact: "contactar" require_customer_login: "Sólo las consumidoras aprobadas pueden acceder a esta tienda." + require_login_html: "Si ya eres un cliente aprovado, %{login} o %{signup} para continuar" + require_login_2_html: "¿Quieres comprar en esta tienda? %{contact}%{enterprise}y solicita tu admisión." require_customer_html: "Si desea comenzar a comprar aquí, por favor %{contact} %{enterprise} para preguntar acerca de incorporación." + select_oc: + select_oc_html: "Por favor debes elegir cuando quieres tu pedido, para poder ver qué productos hay disponibles." card_could_not_be_updated: La tarjeta no se pudo actualizar card_could_not_be_saved: la tarjeta no se pudo guardar spree_gateway_error_flash_for_checkout: "Hubo un problema con tu información de pago: %{error}" @@ -1534,12 +1541,17 @@ es: orders_changeable_orders_alert_html: Este pedido ha sido confirmado, pero puede realizar cambios hasta %{oc_close}. products_clear: Limpiar products_showing: "Mostrando:" + products_results_for: "Resultados para" products_or: "o" products_and: "y" + products_filters_in: "en" products_with: con + products_search: "Buscar…" products_filter_by: "Fitrar por" products_filter_selected: "seleccionado" + products_filter_heading: "Filtros" products_filter_clear: "Limpiar" + products_filter_done: "Hecho" products_loading: "Cargando productos..." products_updating_cart: "Actualizando su carrito..." products_cart_empty: "Carrito vacío" @@ -1550,6 +1562,8 @@ es: products_update_error_msg: "No se ha podido guardar." products_update_error_data: "Error al guardar datos no válidos:" products_changes_saved: "Cambios guardados." + products_no_results_html: "Lo sentimos, no se han encontrado resultados para %{query}" + products_clear_search: "Limpiar la búsqueda" search_no_results_html: "Lo sentimos, no hay resultados para %{query}. ¿Intentar otra búsqueda?" components_profiles_popover: "Los perfiles no tienen una tienda en Open Food Network, pero pueden tener su propia tienda física o en línea en otro lugar" components_profiles_show: "Mostrar perfiles" @@ -1905,6 +1919,7 @@ es: admin_enterprise_relationships_permits: "Permite" admin_enterprise_relationships_seach_placeholder: "Buscar" admin_enterprise_relationships_button_create: "Crear" + admin_enterprise_relationships_to: "para" admin_enterprise_groups: "Redes de organizaciones" admin_enterprise_groups_name: "Nombre" admin_enterprise_groups_owner: "Propietaria" @@ -2310,6 +2325,10 @@ es: resolve_errors: Resuelve los siguientes errores more_items: "+ %{count} Más" default_card_updated: Tarjeta predeterminada actualizada + cart: + add_to_cart_failed: > + Ha habido un problema al añadir este producto en el carrito. Puede que haya + dejado de estar disponible o que la tinda haya cerrado. admin: enterprise_limit_reached: "Has alcanzado el límite estándar de organizaciones por cuenta. Escriba a %{contact_email} si necesita aumentarlo." modals: @@ -3053,6 +3072,8 @@ es: zone: "Zona" calculator: "Calculadora" display: "Mostrar" + both: "Tanto en Hacer pedido como en Administración" + back_end: "Solo en Administración" no_shipping_methods_found: "No se encontraron métodos de envío" new: new_shipping_method: "Nuevo método de envío" @@ -3064,6 +3085,9 @@ es: form: categories: "Categorías" zones: "Zonas" + both: "Tanto en Hacer pedido como en Administración" + back_end: "Solo en Administración" + deactivation_warning: "Desactivar un método de envío puede hacer que el método de envío desaparezca de tu lista. Como alternativa, puedes ocultar el método de envío de la página \"Hacer pedidos\" configurándolo con la opción \"Solo en Administración\" " payment_methods: new: new_payment_method: "Nuevo método de pago" @@ -3183,6 +3207,8 @@ es: price: "Precio" display_as: "Mostrar como" display_name: "Nombre para mostrar" + display_as_placeholder: 'p. ej. 2 Kg' + display_name_placeholder: 'p. ej. Tomates' autocomplete: producer_name: "Productora" unit: "Unidad" @@ -3221,6 +3247,7 @@ es: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "Un artículo de tu carrito ahora no está disponible. Por favor actualiza las cantidades seleccionadas" edit: login_to_view_order: "Por favor inicie sesión para ver su pedido." bought: @@ -3248,9 +3275,14 @@ es: invalid: inválido order_mailer: cancel_email: - customer_greeting: "Hola %{name}!" - instructions: "Su pedido ha sido CANCELADO. Por favor, conserve esta información de cancelación para sus registros." - order_summary_canceled: "Resumen del pedido [CANCELADO]" + customer_greeting: "Hola %{name}" + instructions_html: "Tu pedido con %{distributor} ha sido CANCELADO. Por favor guarda esta información de la cancelación por si es necesaria en el futuro. " + dont_cancel: "Si has cambiado de opinión o no deseas cancelar este pedido, por favor contacta con %{email}" + order_summary_canceled_html: "Resumen del pedido [CANCELADO] %{number} " + details: "Estos son los detalles de su pedido:" + unpaid_order: "Como su pedido no se había pagado, no se ha hecho ninguna devolución." + paid_order: "Su pedido estaba pagado por lo que %{distributor}ha devuelto el importe completo." + credit_order: "Su pedido estaba pagado por lo que se ha abonado en su cuenta." subject: "Cancelación del pedido" confirm_email: subject: "Confirmación del pedido" From 7900cf9438dfa90003f1ad2dd0adf485caa35cf8 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Wed, 3 Jun 2020 11:13:03 +0200 Subject: [PATCH 360/507] Style spinner SVG by inlining it This way we can tweak the `fill` property of the SVG and style it with CSS as the documented in the author's repo (https://github.com/SamHerbert/SVG-Loaders) > An icon's color can be manipulated by changing the fill attribute in the SVG file. --- .../admin/components/progress.scss | 5 +++-- app/views/spree/layouts/_admin_body.html.haml | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/admin/components/progress.scss b/app/assets/stylesheets/admin/components/progress.scss index f595b54072..c3ea8c69b3 100644 --- a/app/assets/stylesheets/admin/components/progress.scss +++ b/app/assets/stylesheets/admin/components/progress.scss @@ -20,10 +20,11 @@ text-align: center; text-transform: uppercase; - img { + .spinner { position: absolute; - height: 30px; left: 50%; + width: 30px; + height: 30px; top: -5px; margin-left: -15px; } diff --git a/app/views/spree/layouts/_admin_body.html.haml b/app/views/spree/layouts/_admin_body.html.haml index d4d8058c7a..0bf05450ed 100644 --- a/app/views/spree/layouts/_admin_body.html.haml +++ b/app/views/spree/layouts/_admin_body.html.haml @@ -10,7 +10,27 @@ .flash.success= flash[:success] #progress - %img.spinner{ src: "/assets/spinning-circles.svg" } + / By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL + %svg{:class => "spinner", :viewbox => "0 0 58 58", :xmlns => "http://www.w3.org/2000/svg"} + %g{:fill => "none", "fill-rule" => "evenodd"} + %g{:stroke => "currentColor", "stroke-width" => "1.5", :transform => "translate(2 1)"} + %circle{:cx => "42.601", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "1", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "1;0;0;0;0;0;0;0"} + %circle{:cx => "49.063", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;1;0;0;0;0;0;0"} + %circle{:cx => "42.601", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;1;0;0;0;0;0"} + %circle{:cx => "27", :cy => "49.125", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;1;0;0;0;0"} + %circle{:cx => "11.399", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;1;0;0;0"} + %circle{:cx => "4.938", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;1;0;0"} + %circle{:cx => "11.399", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;1;0"} + %circle{:cx => "27", :cy => "5", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;0;1"} + = Spree.t(:loading) \... From bfe17f54d7d5fed5b0552e2c634c6cb029492a83 Mon Sep 17 00:00:00 2001 From: Lucas Hiago Date: Fri, 22 May 2020 20:37:28 -0300 Subject: [PATCH 361/507] Change minimal amount in price sack calculator to float --- .../spree/calculator/price_sack_decorator.rb | 2 +- .../spree/calculator/price_sack_spec.rb | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/models/spree/calculator/price_sack_decorator.rb b/app/models/spree/calculator/price_sack_decorator.rb index b474f77861..389649f916 100644 --- a/app/models/spree/calculator/price_sack_decorator.rb +++ b/app/models/spree/calculator/price_sack_decorator.rb @@ -13,7 +13,7 @@ module Spree end def compute(object) - min = preferred_minimal_amount.to_i + min = preferred_minimal_amount.to_f order_amount = line_items_for(object).map { |x| x.price * x.quantity }.sum if order_amount < min diff --git a/spec/models/spree/calculator/price_sack_spec.rb b/spec/models/spree/calculator/price_sack_spec.rb index 921b657f88..05c7a8cb8a 100644 --- a/spec/models/spree/calculator/price_sack_spec.rb +++ b/spec/models/spree/calculator/price_sack_spec.rb @@ -49,6 +49,32 @@ describe Spree::Calculator::PriceSack do end end + context "minimal amount is float" do + before do + calculator.preferred_minimal_amount = 16.5 + calculator.preferred_normal_amount = 5 + calculator.preferred_discount_amount = 1 + line_item.quantity = 2 + end + + context "with price bellow minimal amount" do + let(:price) { 8 } + + it "returns the correct value of cost" do + expect(calculator.compute(line_item)).to eq(5) + end + end + + context "with price above minimal amount" do + let(:price) { 8.5 } + + it "returns the correct value of cost" do + expect(calculator.compute(line_item)).to eq(1) + end + end + + end + context "extends LocalizedNumber" do it_behaves_like "a model using the LocalizedNumber module", [:preferred_minimal_amount, :preferred_normal_amount, :preferred_discount_amount] end From 0b76a2594183eccf40f5691722af3237e92f1eda Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 19 May 2020 00:44:09 +0100 Subject: [PATCH 362/507] Add spree_core dependencies to OFN so we can upgrade them This will enable us to upgrade these dependencies independently --- Gemfile | 18 ++++++++++++++++-- Gemfile.lock | 16 ++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 9f842b68fd..9d2e680a20 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,20 @@ gem 'pg', '~> 0.21.0' # for details. gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-1-0-stable' +### Dependencies brought from spree core +gem 'acts_as_list', '= 0.2.0' +gem 'awesome_nested_set', '~> 3.0.0.rc.1' +gem 'cancan', '~> 1.6.10' +gem 'ffaker', '~> 1.16' +gem 'highline', '= 1.6.18' # Necessary for the install generator +gem 'httparty', '~> 0.11' # For checking alerts. +gem 'json', '>= 1.7.7' +gem 'money', '5.1.1' +gem 'paranoia', '~> 2.0' +gem 'ransack', '1.0.0' +gem 'state_machine', '1.2.0' +gem 'stringex', '~> 1.5.1' + gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable' # Our branch contains two changes @@ -50,14 +64,14 @@ gem 'kaminari', '~> 0.14.1' gem 'andand' gem 'angularjs-rails', '1.5.5' -gem 'aws-sdk' +gem 'aws-sdk', '1.11.1' # temporarily locked down due to https://github.com/aws/aws-sdk-ruby/issues/273 gem 'bugsnag' gem 'db2fog' gem 'haml' gem 'redcarpet' gem 'sass' gem 'sass-rails' -gem 'truncate_html' +gem 'truncate_html', '0.9.2' gem 'unicorn' gem 'actionpack-action_caching' diff --git a/Gemfile.lock b/Gemfile.lock index 863d90a098..3d841a7705 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -696,16 +696,19 @@ DEPENDENCIES activerecord-postgresql-adapter activerecord-session_store acts-as-taggable-on (~> 3.4) + acts_as_list (= 0.2.0) andand angular-rails-templates (~> 0.3.0) angularjs-file-upload-rails (~> 2.4.1) angularjs-rails (= 1.5.5) atomic + awesome_nested_set (~> 3.0.0.rc.1) awesome_print - aws-sdk + aws-sdk (= 1.11.1) blockenspiel bugsnag byebug (~> 11.0) + cancan (~> 1.6.10) capybara (>= 2.18.0) catalog! coffee-rails (~> 4.0.0) @@ -726,6 +729,7 @@ DEPENDENCIES diffy eventmachine (>= 1.2.3) factory_bot_rails (= 4.10.0) + ffaker (~> 1.16) figaro foreigner foundation-icons-sass-rails @@ -734,12 +738,15 @@ DEPENDENCIES geocoder gmaps4rails haml + highline (= 1.6.18) + httparty (~> 0.11) i18n (~> 0.6.11) i18n-js (~> 3.6.0) immigrant jquery-migrate-rails jquery-rails (= 3.1.5) jquery-ui-rails (~> 4.2) + json (>= 1.7.7) json_spec (~> 1.1.4) jwt (~> 2.2) kaminari (~> 0.14.1) @@ -747,6 +754,7 @@ DEPENDENCIES letter_opener (>= 1.4.1) mini_racer (= 0.2.14) momentjs-rails + money (= 5.1.1) newrelic_rpm (~> 3.0) oauth2 (~> 1.4.4) ofn-qz! @@ -754,6 +762,7 @@ DEPENDENCIES order_management! paper_trail (~> 5.2.3) paperclip (~> 3.4.1) + paranoia (~> 2.0) pg (~> 0.21.0) pry (~> 0.12.0) pry-byebug (~> 3.7) @@ -763,6 +772,7 @@ DEPENDENCIES rails (~> 4.0.13) rails-i18n (~> 4.0) rails_safe_tasks (~> 1.0) + ransack (= 1.0.0) redcarpet roadie-rails (~> 1.3.0) roo (~> 2.8.3) @@ -782,10 +792,12 @@ DEPENDENCIES spree_paypal_express! spring spring-commands-rspec + state_machine (= 1.2.0) + stringex (~> 1.5.1) stripe test-unit (~> 3.3) timecop - truncate_html + truncate_html (= 0.9.2) uglifier (>= 1.0.3) unicorn unicorn-rails From 095d0f4ca8f905e85e0e2ca8ec8cbc355e3438ad Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 4 Jun 2020 15:58:22 +1000 Subject: [PATCH 363/507] Updating translations for config/locales/fr.yml --- config/locales/fr.yml | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 9289365e81..7ef0e26b8b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -2785,7 +2785,7 @@ fr: new: "Nouveau" start: "Début" end: "Fin" - stop: "Arrêter" + stop: "Fin" first: "Début" previous: "Précédent" last: "Fin" @@ -2900,8 +2900,6 @@ fr: abbreviation: "Code" new_state: "Nouveau département" payment_methods: "Méthodes de paiement" - new_payment_method: "Nouvelle méthode de paiement" - provider: "Fournisseur" taxonomies: "Taxonomies" new_taxonomy: "Nouvelle taxonomie" back_to_taxonomies_list: "Retour à la liste des taxonomies" @@ -3113,10 +3111,26 @@ fr: back_end: "Visible pour l'administration uniquement" deactivation_warning: "Désactiver une méthode de livraison peut engendre sa disparition de la liste ici. Si vous souhaitez uniquement ne plus l'afficher pour l'acheteur, modifiez-là et utilisez l'option d'affichage \"visible pour l'administrateur uniquement\"." payment_methods: + index: + payment_methods: "Méthodes de paiement" + new_payment_method: "Nouvelle méthode de paiement" + name: "Produit/Variante" + products_distributor: "Distributeur" + provider: "Fournisseur" + environment: "Environnement" + display: "Afficher" + active: "Actif" + both: "Les deux" + front_end: "Visible par l'acheteur uniquement" + back_end: "Visible pour l'administration uniquement" + active_yes: "Oui" + active_no: "Non" + no_payment_methods_found: "Aucune méthode de paiement n'a été trouvée" new: new_payment_method: "Nouvelle méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" edit: + new: "Nouveau" editing_payment_method: "Modification de la méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" stripe_connect: @@ -3132,6 +3146,21 @@ fr: account_id: Identifiant Compte business_name: Nom de l'entreprise charges_enabled: Frais activés + form: + name: "Produit/Variante" + description: "Description" + environment: "Environnement" + display: "Afficher" + active: "Actif" + active_yes: "Oui" + active_no: "Non" + both: "Visible par l'acheteur sur la boutique" + front_end: "Visible par l'acheteur uniquement" + back_end: "Visible pour l'administration uniquement" + tags: "Tags" + deactivation_warning: "Désactiver une méthode de paiement peut faire disparaitre cette méthode de votre liste. Si vous souhaitez uniquement la rendre invisible par l'acheteur, modifiez la méthode et utilisez l'affichage pour l'administrateur uniquement." + providers: + provider: "Fournisseur" payments: source_forms: stripe: From 52323887b60eaa600f8c200e9010f90a228b6007 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 4 Jun 2020 15:58:45 +1000 Subject: [PATCH 364/507] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 49 ++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 0701634c52..47745f5784 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -2870,8 +2870,6 @@ en_FR: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3083,10 +3081,26 @@ en_FR: back_end: "Back office only" deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + front_end: "Checkout only" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" + no_payment_methods_found: "No payment methods found" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3102,6 +3116,21 @@ en_FR: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + front_end: "Checkout only" + back_end: "Back office only" + tags: "Tags" + deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3269,14 +3298,14 @@ en_FR: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Bonjour %{name}," - instructions_html: "Votre commande avec%{distributor} a été annulée. Merci de conserver cet email." - dont_cancel: "Si vous avez changé d'avis ou vous ne souhaitez pas annuler cette commande, merci de contacter %{email}." - order_summary_canceled_html: "[ANNULATION] Commande #%{number}" - details: "Voici les produits que vous aviez commandé:" - unpaid_order: "Votre commande n'avait pas été réglée donc aucun remboursement n'a été effectué." - paid_order: "Votre commande avait été réglée, ainsi %{distributor} a remboursé la totalité de votre commande." - credit_order: "Votre commande avait été payée, votre compte a donc été crédité" + customer_greeting: "Dear %{name}," + instructions_html: "Your order with%{distributor} has been CANCELED. Please retain this cancellation information for your records" + dont_cancel: "If you have changed your mind or don't wish to cancel this order please contact %{email}" + order_summary_canceled_html: "Order Summary #%{number}[CANCELED]" + details: "Here are the details of what you ordered:" + unpaid_order: "Your order was unpaid so no refund has been made" + paid_order: "Your order was paid so %{distributor} has refunded the full amount" + credit_order: "Your order was paid so your account has been credited" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" From d5d6fbc01d1103d7390db31ad2d2a5c5b920cf11 Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Fri, 22 May 2020 12:15:54 +1000 Subject: [PATCH 365/507] created partial for order page title to resolve French translation of new order --- app/views/spree/admin/adjustments/edit.html.haml | 3 ++- app/views/spree/admin/adjustments/index.html.haml | 3 ++- app/views/spree/admin/adjustments/new.html.haml | 3 ++- .../spree/admin/orders/customer_details/edit.html.haml | 3 ++- app/views/spree/admin/orders/edit.html.haml | 3 ++- app/views/spree/admin/orders/new.html.haml | 4 +++- app/views/spree/admin/orders/set_distribution.html.haml | 8 +++++--- app/views/spree/admin/payments/index.html.haml | 1 + app/views/spree/admin/payments/new.html.haml | 1 + app/views/spree/admin/payments/show.html.haml | 1 + .../spree/admin/return_authorizations/edit.html.haml | 1 + .../spree/admin/return_authorizations/index.html.haml | 1 + app/views/spree/admin/return_authorizations/new.html.haml | 1 + app/views/spree/admin/shared/_order_page_title.html.haml | 4 ++++ app/views/spree/admin/shared/_order_tabs.html.haml | 5 ----- 15 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 app/views/spree/admin/shared/_order_page_title.html.haml diff --git a/app/views/spree/admin/adjustments/edit.html.haml b/app/views/spree/admin/adjustments/edit.html.haml index c31dfb145e..756288c4f4 100644 --- a/app/views/spree/admin/adjustments/edit.html.haml +++ b/app/views/spree/admin/adjustments/edit.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' } += render :partial => 'spree/admin/shared/order_page_title' += render :partial => 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' } - content_for :page_title do %i.icon-arrow-right diff --git a/app/views/spree/admin/adjustments/index.html.haml b/app/views/spree/admin/adjustments/index.html.haml index 7268441e1e..02433a6e5c 100644 --- a/app/views/spree/admin/adjustments/index.html.haml +++ b/app/views/spree/admin/adjustments/index.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' } += render partial: 'spree/admin/shared/order_page_title' += render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' } - content_for :page_title do %i.icon-arrow-right diff --git a/app/views/spree/admin/adjustments/new.html.haml b/app/views/spree/admin/adjustments/new.html.haml index 3eb6f5c58e..2af33aae54 100644 --- a/app/views/spree/admin/adjustments/new.html.haml +++ b/app/views/spree/admin/adjustments/new.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' } += render partial: 'spree/admin/shared/order_page_title' += render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' } - content_for :page_title do %i.icon-arrow-right diff --git a/app/views/spree/admin/orders/customer_details/edit.html.haml b/app/views/spree/admin/orders/customer_details/edit.html.haml index e4fa93ffbb..7c6118cac6 100644 --- a/app/views/spree/admin/orders/customer_details/edit.html.haml +++ b/app/views/spree/admin/orders/customer_details/edit.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Customer Details' } += render partial: 'spree/admin/shared/order_page_title' += render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Customer Details' } = csrf_meta_tags diff --git a/app/views/spree/admin/orders/edit.html.haml b/app/views/spree/admin/orders/edit.html.haml index 69abbe8f38..d2047e6bf4 100644 --- a/app/views/spree/admin/orders/edit.html.haml +++ b/app/views/spree/admin/orders/edit.html.haml @@ -8,7 +8,8 @@ - if can?(:admin, Spree::Order) %li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Order Details' } += render partial: "spree/admin/shared/order_page_title" += render partial: "spree/admin/shared/order_tabs", locals: { current: 'Order Details' } %div{"data-hook" => "admin_order_edit_header"} -# Suppress errors when manually creating a new order - needs to proceed to edit page diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml index 9ec198b2d7..556e464cd4 100644 --- a/app/views/spree/admin/orders/new.html.haml +++ b/app/views/spree/admin/orders/new.html.haml @@ -1,5 +1,7 @@ - content_for :page_title do - = t(:new) + = t(:new_order) + \# + = @order.number - content_for :page_actions do %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' diff --git a/app/views/spree/admin/orders/set_distribution.html.haml b/app/views/spree/admin/orders/set_distribution.html.haml index f5e259321e..3579619185 100644 --- a/app/views/spree/admin/orders/set_distribution.html.haml +++ b/app/views/spree/admin/orders/set_distribution.html.haml @@ -1,12 +1,14 @@ -- content_for :page_title do - = t(:new) - - content_for :page_actions do %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' = admin_inject_shops(module: 'admin.orders') = admin_inject_order_cycles +- content_for :page_title do + = t(:new_order) + \# + = @order.number + = render 'spree/admin/shared/order_tabs', :current => 'Order Details' = csrf_meta_tags diff --git a/app/views/spree/admin/payments/index.html.haml b/app/views/spree/admin/payments/index.html.haml index 3c62b54843..7fbe76429f 100644 --- a/app/views/spree/admin/payments/index.html.haml +++ b/app/views/spree/admin/payments/index.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' } - content_for :page_actions do diff --git a/app/views/spree/admin/payments/new.html.haml b/app/views/spree/admin/payments/new.html.haml index 7c825051ad..710456cc2d 100644 --- a/app/views/spree/admin/payments/new.html.haml +++ b/app/views/spree/admin/payments/new.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' } - content_for :page_title do diff --git a/app/views/spree/admin/payments/show.html.haml b/app/views/spree/admin/payments/show.html.haml index 97850cb19a..acbc2d8aaf 100644 --- a/app/views/spree/admin/payments/show.html.haml +++ b/app/views/spree/admin/payments/show.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' } - content_for :page_title do diff --git a/app/views/spree/admin/return_authorizations/edit.html.haml b/app/views/spree/admin/return_authorizations/edit.html.haml index 2847c10965..9f5429640d 100644 --- a/app/views/spree/admin/return_authorizations/edit.html.haml +++ b/app/views/spree/admin/return_authorizations/edit.html.haml @@ -6,6 +6,7 @@ - if @return_authorization.can_cancel? = button_link_to t('actions.cancel'), fire_admin_order_return_authorization_url(@order, @return_authorization, e: 'cancel'), method: :put, data: { confirm: t('.are_you_sure') }, icon: 'icon-remove' += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' } - content_for :page_title do diff --git a/app/views/spree/admin/return_authorizations/index.html.haml b/app/views/spree/admin/return_authorizations/index.html.haml index acf016b50d..bc8ed9dd80 100644 --- a/app/views/spree/admin/return_authorizations/index.html.haml +++ b/app/views/spree/admin/return_authorizations/index.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' } - content_for :page_actions do diff --git a/app/views/spree/admin/return_authorizations/new.html.haml b/app/views/spree/admin/return_authorizations/new.html.haml index 54573f7392..5594288cf3 100644 --- a/app/views/spree/admin/return_authorizations/new.html.haml +++ b/app/views/spree/admin/return_authorizations/new.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' } - content_for :page_title do diff --git a/app/views/spree/admin/shared/_order_page_title.html.haml b/app/views/spree/admin/shared/_order_page_title.html.haml new file mode 100644 index 0000000000..927062d4f7 --- /dev/null +++ b/app/views/spree/admin/shared/_order_page_title.html.haml @@ -0,0 +1,4 @@ +- content_for :page_title do + = t(:order) + \# + = @order.number diff --git a/app/views/spree/admin/shared/_order_tabs.html.haml b/app/views/spree/admin/shared/_order_tabs.html.haml index 89d7299fdc..f96a5dd140 100644 --- a/app/views/spree/admin/shared/_order_tabs.html.haml +++ b/app/views/spree/admin/shared/_order_tabs.html.haml @@ -1,8 +1,3 @@ -- content_for :page_title do - = t(:order) - \# - = @order.number - - if @order.bill_address.present? = @order.bill_address.firstname = @order.bill_address.lastname From 78fc6b71388a019e5445317b8142eb604bd30319 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 31 May 2020 18:22:32 +0200 Subject: [PATCH 366/507] Rename "Geo" service to "GmapsGeo" for clarity. This service directly calls methods in the google maps javascript included in the darkswarm layout. If we're moving away from it, we should clarify where it's used. --- .../darkswarm/services/enterprises.js.coffee | 10 +++++----- .../{geo.js.erb.coffee => gmaps_geo.js.erb.coffee} | 4 ++-- .../unit/darkswarm/services/enterprise_spec.js.coffee | 8 ++++---- .../unit/darkswarm/services/map_spec.js.coffee | 4 ++-- .../unit/darkswarm/services/products_spec.js.coffee | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) rename app/assets/javascripts/darkswarm/services/{geo.js.erb.coffee => gmaps_geo.js.erb.coffee} (93%) diff --git a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee index 46e50cb574..843749c2e6 100644 --- a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons, Dereferencer, Matcher, Geo, $rootScope) -> +Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons, Dereferencer, Matcher, GmapsGeo, $rootScope) -> new class Enterprises enterprises: [] enterprises_by_id: {} @@ -59,7 +59,7 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons false calculateDistance: (query, firstMatching) -> - if query?.length > 0 and Geo.OK + if query?.length > 0 and GmapsGeo.OK if firstMatching? @setDistanceFrom firstMatching else @@ -68,9 +68,9 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons @resetDistance() calculateDistanceGeo: (query) -> - Geo.geocode query, (results, status) => + GmapsGeo.geocode query, (results, status) => $rootScope.$apply => - if status == Geo.OK + if status == GmapsGeo.OK #console.log "Geocoded #{query} -> #{results[0].geometry.location}." @setDistanceFrom results[0].geometry.location else @@ -79,7 +79,7 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons setDistanceFrom: (locatable) -> for enterprise in @enterprises - enterprise.distance = Geo.distanceBetween enterprise, locatable + enterprise.distance = GmapsGeo.distanceBetween enterprise, locatable $rootScope.$broadcast 'enterprisesChanged' resetDistance: -> diff --git a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee b/app/assets/javascripts/darkswarm/services/gmaps_geo.js.erb.coffee similarity index 93% rename from app/assets/javascripts/darkswarm/services/geo.js.erb.coffee rename to app/assets/javascripts/darkswarm/services/gmaps_geo.js.erb.coffee index 866dc2f742..d532574d0d 100644 --- a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee +++ b/app/assets/javascripts/darkswarm/services/gmaps_geo.js.erb.coffee @@ -1,5 +1,5 @@ -Darkswarm.service "Geo", -> - new class Geo +Darkswarm.service "GmapsGeo", -> + new class GmapsGeo OK: google?.maps?.GeocoderStatus?.OK # Usage: diff --git a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee index 82c26397ca..c95fbdf81b 100644 --- a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee @@ -1,7 +1,7 @@ describe "Enterprises service", -> Enterprises = $rootScope = null CurrentHubMock = {} - Geo = + GmapsGeo = OK: 'ok' succeed: true geocode: (query, callback) -> @@ -31,7 +31,7 @@ describe "Enterprises service", -> module 'Darkswarm' module ($provide)-> $provide.value "CurrentHub", CurrentHubMock - $provide.value "Geo", Geo + $provide.value "GmapsGeo", GmapsGeo null angular.module('Darkswarm').value('enterprises', enterprises) angular.module('Darkswarm').value('taxons', taxons) @@ -118,12 +118,12 @@ describe "Enterprises service", -> spyOn(Enterprises, "setDistanceFrom") it "calculates distance for all enterprises when geocoding succeeds", -> - Geo.succeed = true + GmapsGeo.succeed = true Enterprises.calculateDistanceGeo('query') expect(Enterprises.setDistanceFrom).toHaveBeenCalledWith("location") it "resets distance when geocoding fails", -> - Geo.succeed = false + GmapsGeo.succeed = false spyOn(Enterprises, "resetDistance") Enterprises.calculateDistanceGeo('query') expect(Enterprises.setDistanceFrom).not.toHaveBeenCalled() diff --git a/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee index fb4def8342..eed215dbe1 100644 --- a/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee @@ -1,7 +1,7 @@ describe "Hubs service", -> OfnMap = null CurrentHubMock = {} - Geo = {} + GmapsGeo = {} enterprises = [ { id: 2 @@ -54,7 +54,7 @@ describe "Hubs service", -> angular.module('Darkswarm').value('enterprises', enterprises) module ($provide)-> $provide.value "CurrentHub", CurrentHubMock - $provide.value "Geo", Geo + $provide.value "GmapsGeo", GmapsGeo null inject ($injector)-> OfnMap = $injector.get("OfnMap") diff --git a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee index 62c8c0a071..88ff585f00 100644 --- a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee @@ -12,7 +12,7 @@ describe 'Products service', -> productWithImage = null properties = null taxons = null - Geo = {} + GmapsGeo = {} endpoint = "/api/order_cycles/1/products?distributor=1" beforeEach -> @@ -53,7 +53,7 @@ describe 'Products service', -> $provide.value "currentOrder", currentOrder $provide.value "taxons", taxons $provide.value "properties", properties - $provide.value "Geo", Geo + $provide.value "GmapsGeo", GmapsGeo $provide.value "OrderCycle", OrderCycle $provide.value "railsFlash", null null From 76aded5fb5c8dc3a97a686a92427da5cfc8beb11 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 5 Jun 2020 17:51:06 +1000 Subject: [PATCH 367/507] Updating translations for config/locales/fr.yml --- config/locales/fr.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 7ef0e26b8b..88e0e981c1 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -403,6 +403,7 @@ fr: footer_and_external_links: Pied de page et Liens Externes your_content: Votre contenu user_guide: Guide utilisateur + map: Carte enterprise_fees: index: title: "Marges et Commissions" @@ -2836,6 +2837,14 @@ fr: new_payment: "Nouveau paiement" capture: "Payée" void: "Annulé" + login: "Se connecter" + password: "Mot de passe" + signature: "Signature" + solution: "Solution" + landing_page: "Page d'accueil (landing page)" + server: "Serveur" + test_mode: "Mode test" + logourl: "URL du logo" configurations: "Configurations" general_settings: "Configurations générales" site_name: "Nom du site" From c317ae7bf3cfc3b3cb374c36c6e352ddcb7b14f8 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 5 Jun 2020 17:51:47 +1000 Subject: [PATCH 368/507] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 47745f5784..37dc60af05 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -403,6 +403,7 @@ en_FR: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2806,6 +2807,14 @@ en_FR: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" + signature: "Signature" + solution: "Solution" + landing_page: "Landing Page" + server: "Server" + test_mode: "Test Mode" + logourl: "Logourl" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" From e2e3ae68b72483323bb8c86668e7cb990c465911 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 5 Jun 2020 11:36:27 +0100 Subject: [PATCH 369/507] Update all locales with the latest Transifex translations --- config/locales/ar.yml | 32 ++++++++++++++--- config/locales/ca.yml | 36 ++++++++++++++++--- config/locales/de_DE.yml | 21 ++++++++--- config/locales/en_AU.yml | 32 ++++++++++++++--- config/locales/en_BE.yml | 32 ++++++++++++++--- config/locales/en_CA.yml | 32 +++++++++++++++-- config/locales/en_DE.yml | 32 ++++++++++++++--- config/locales/en_GB.yml | 35 +++++++++++++++--- config/locales/en_IE.yml | 32 ++++++++++++++--- config/locales/en_NZ.yml | 35 +++++++++++++++--- config/locales/en_PH.yml | 32 ++++++++++++++--- config/locales/en_US.yml | 32 ++++++++++++++--- config/locales/en_ZA.yml | 32 ++++++++++++++--- config/locales/es.yml | 32 +++++++++++++++-- config/locales/es_CR.yml | 32 ++++++++++++++--- config/locales/fil_PH.yml | 32 ++++++++++++++--- config/locales/fr_BE.yml | 32 ++++++++++++++--- config/locales/fr_CA.yml | 32 ++++++++++++++--- config/locales/it.yml | 32 ++++++++++++++--- config/locales/nb.yml | 32 ++++++++++++++--- config/locales/nl_BE.yml | 32 ++++++++++++++--- config/locales/pt.yml | 31 +++++++++++++--- config/locales/pt_BR.yml | 32 +++++++++++++---- config/locales/sv.yml | 16 +++++++++ config/locales/tr.yml | 75 ++++++++++++++++++++++++++------------- 25 files changed, 692 insertions(+), 133 deletions(-) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 537091cb62..f4c0dbbcf7 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -398,6 +398,7 @@ ar: footer_and_external_links: تذييل والروابط الخارجية your_content: المحتوى الخاص بك user_guide: دليل المستخدم + map: خريطة enterprise_fees: index: title: "رسوم الشركة" @@ -2752,6 +2753,8 @@ ar: new_payment: "دفعة جديد" capture: "إلتقاط" void: "فارغ" + login: "تسجيل الدخول" + password: "كلمه السر" configurations: "تهيئة" general_settings: "الاعدادات العامة" site_name: "اسم الموقع" @@ -2816,8 +2819,6 @@ ar: abbreviation: "الاختصار" new_state: "محافظة جديدة" payment_methods: "طرق الدفع" - new_payment_method: "طريقة الدفع الجديدة" - provider: "مزود" taxonomies: "التصنيفات" new_taxonomy: "تصنيف جديد" back_to_taxonomies_list: "العودة إلى قائمة التصنيفات" @@ -3024,10 +3025,23 @@ ar: categories: "التصنيفات" zones: "مناطق" payment_methods: + index: + payment_methods: "طريقة الدفع" + new_payment_method: "طريقة الدفع الجديدة" + name: "الاسم" + products_distributor: "الموزع" + provider: "مزود" + environment: "بيئة" + display: "عرض" + active: "نشط" + both: "على حد سواء" + active_yes: "نعم" + active_no: "لا" new: new_payment_method: "طريقة الدفع الجديدة" back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع" edit: + new: "جديد" editing_payment_method: "تحرير طريقة الدفع" back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع" stripe_connect: @@ -3043,6 +3057,17 @@ ar: account_id: معرف الحساب business_name: الاسم التجاري charges_enabled: تم تمكين الدفع + form: + name: "الاسم" + description: "وصف" + environment: "بيئة" + display: "عرض" + active: "نشط" + active_yes: "نعم" + active_no: "لا" + tags: "الاوسمة" + providers: + provider: "مزود" payments: source_forms: stripe: @@ -3207,9 +3232,6 @@ ar: invalid: غير صالحة order_mailer: cancel_email: - customer_greeting: "مرحبًا %{name}!" - instructions: "تم إلغاء طلبك. يرجى الاحتفاظ بمعلومات الإلغاء هذه بسجلاتك." - order_summary_canceled: "ملخص الطلب [ملغى]" subject: "إلغاء الطلب" confirm_email: subject: "تأكيد الطلب" diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 461d8d377e..4ee031cc78 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -403,6 +403,7 @@ ca: footer_and_external_links: Peu de pàgina i enllaços externs your_content: El vostre contingut user_guide: Guia de l'usuari + map: Mapa enterprise_fees: index: title: "Comissions de l'organització" @@ -2812,6 +2813,8 @@ ca: new_payment: "Nou pagament" capture: "Captura" void: "Buit" + login: "Inicia sessió" + password: "Contrasenya" configurations: "Configuracions" general_settings: "Configuració general" site_name: "Nom del lloc" @@ -2876,8 +2879,6 @@ ca: abbreviation: "Abreviatura" new_state: "Nou estat" payment_methods: "Mètodes de Pagament" - new_payment_method: "Nou mètode de pagament" - provider: "Proveïdor" taxonomies: "Taxonomies" new_taxonomy: "Nova taxonomia" back_to_taxonomies_list: "Torna a la llista de taxonomies" @@ -3089,10 +3090,24 @@ ca: back_end: "Només pàgina administració (back office) " deactivation_warning: "Desactivar un mètode d'enviament pot fer que desaparegui de la teva llista. Pots ocultar-lo de la pàgina de validació de comanda configurant l'opció \"Mostrar\" a \"només a la pàgina d'administració\" (back end)." payment_methods: + index: + payment_methods: "Mètodes de Pagament" + new_payment_method: "Nou mètode de pagament" + name: "Nom" + products_distributor: "Distribuïdora" + provider: "Proveïdor" + environment: "Ambient" + display: "Mostra" + active: "Actiu" + both: "Ambdós" + back_end: "Només pàgina administració (back office) " + active_yes: "Sí" + active_no: "No" new: new_payment_method: "Nou mètode de pagament" back_to_payment_methods_list: "Tornar a la llista de mètodes de pagament" edit: + new: "Nou" editing_payment_method: "Edició del mètode de pagament" back_to_payment_methods_list: "Tornar a la llista de mètodes de pagament" stripe_connect: @@ -3108,6 +3123,19 @@ ca: account_id: Identificador del compte business_name: Nom de l'empresa charges_enabled: Càrrecs habilitats + form: + name: "Nom" + description: "Descripció" + environment: "Ambient" + display: "Mostra" + active: "Actiu" + active_yes: "Sí" + active_no: "No" + both: "Ambdues, validació de comanda i administració" + back_end: "Només pàgina administració (back office) " + tags: "Etiquetes" + providers: + provider: "Proveïdor" payments: source_forms: stripe: @@ -3281,8 +3309,8 @@ ca: order_summary_canceled_html: "Resum de comanda # %{number} [CANCELAT]" details: "Aquí teniu els detalls del que vau demanar:" unpaid_order: "La vostra comanda no s'havia pagat, per la qual cosa no s'ha realitzat cap reemborsament" - paid_order: "La teva comanda s'havia pagat per la qual cosa %{distributor} ha reemborsat l'import complet" - credit_order: "S'ha pagat la comanda i s'ha abonat l'import al vostre compte" + paid_order: "La vostra comanda s'havia pagat per la qual cosa %{distributor} ha reemborsat l'import complet" + credit_order: "La vostra comanda s'havia pagat i per tant, s'ha abonat l'import al vostre compte" subject: "Cancel·lació de la comanda" confirm_email: subject: "Confirmació de la comanda" diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index 5ddcdc89a3..ea894331c1 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -402,6 +402,7 @@ de_DE: footer_and_external_links: Fußzeile und externe Links your_content: Ihr Inhalt user_guide: Benutzerhandbuch + map: Karte enterprise_fees: index: title: "Unternehmensgebühren" @@ -2785,6 +2786,8 @@ de_DE: new_payment: "Neue Zahlung" capture: "Erfassung" void: "Leere" + login: "Anmeldung" + password: "Passwort" configurations: "Konfigurationen" general_settings: "Allgemeine Einstellungen" site_name: "Site-Name" @@ -2849,8 +2852,6 @@ de_DE: abbreviation: "Abkürzung" new_state: "Neuer Staat" payment_methods: "Zahlungsarten" - new_payment_method: "Neue Zahlungsart" - provider: "Anbieter" taxonomies: "Taxonomien" new_taxonomy: "Neue Taxonomie" back_to_taxonomies_list: "Zurück zur Taxonomieliste" @@ -3057,6 +3058,13 @@ de_DE: categories: "Kategorien" zones: "Zonen" payment_methods: + index: + payment_methods: "Zahlungsarten" + name: "Name" + products_distributor: "Verteiler" + both: "Beide" + active_yes: "Ja" + active_no: "Nein" new: new_payment_method: "Neue Zahlungsart" back_to_payment_methods_list: "Zurück zur Liste der Zahlungsmethoden" @@ -3076,6 +3084,12 @@ de_DE: account_id: Konto-ID business_name: Geschäftsname charges_enabled: Gebühren aktiviert + form: + name: "Name" + description: "Beschreibung" + active_yes: "Ja" + active_no: "Nein" + tags: "Stichwörter" payments: source_forms: stripe: @@ -3236,9 +3250,6 @@ de_DE: invalid: ungültig order_mailer: cancel_email: - customer_greeting: "Hallo %{name}!" - instructions: "Ihre Bestellung wurde storniert. Bitte bewahren Sie diese Stornierungsinformationen für Ihre Unterlagen auf." - order_summary_canceled: "Bestellübersicht [STORNIERT]" subject: "Stornierung der Bestellung" confirm_email: subject: "Bestellbestätigung" diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index fb801884fe..87dd14b521 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -394,6 +394,7 @@ en_AU: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2703,6 +2704,8 @@ en_AU: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2767,8 +2770,6 @@ en_AU: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2970,10 +2971,23 @@ en_AU: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2989,6 +3003,17 @@ en_AU: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3153,9 +3178,6 @@ en_AU: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index 963ef29366..ad108f1377 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -389,6 +389,7 @@ en_BE: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2658,6 +2659,8 @@ en_BE: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2722,8 +2725,6 @@ en_BE: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2888,10 +2889,23 @@ en_BE: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2907,6 +2921,17 @@ en_BE: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3060,9 +3085,6 @@ en_BE: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi%{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index ab800f4021..2d06220419 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -403,6 +403,7 @@ en_CA: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2805,6 +2806,8 @@ en_CA: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2869,8 +2872,6 @@ en_CA: abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3082,10 +3083,24 @@ en_CA: back_end: "Back office only" deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3101,6 +3116,19 @@ en_CA: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + back_end: "Back office only" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index a847a5bf98..f3effeead7 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -394,6 +394,7 @@ en_DE: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2670,6 +2671,8 @@ en_DE: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2734,8 +2737,6 @@ en_DE: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2904,10 +2905,23 @@ en_DE: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2923,6 +2937,17 @@ en_DE: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3076,9 +3101,6 @@ en_DE: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index c20656fd5d..f18c25b4dd 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -403,6 +403,7 @@ en_GB: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2812,6 +2813,8 @@ en_GB: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2876,8 +2879,6 @@ en_GB: abbreviation: "Abbreviation" new_state: "New County" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3089,10 +3090,24 @@ en_GB: back_end: "Back office only" deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3108,6 +3123,19 @@ en_GB: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + back_end: "Back office only" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3275,9 +3303,6 @@ en_GB: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_IE.yml b/config/locales/en_IE.yml index 6970317b5b..0f838aff2e 100644 --- a/config/locales/en_IE.yml +++ b/config/locales/en_IE.yml @@ -403,6 +403,7 @@ en_IE: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2811,6 +2812,8 @@ en_IE: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2875,8 +2878,6 @@ en_IE: abbreviation: "Abbreviation" new_state: "New County" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3083,10 +3084,23 @@ en_IE: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3102,6 +3116,17 @@ en_IE: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3268,9 +3293,6 @@ en_IE: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index edd74cbdb3..22a9902b96 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -403,6 +403,7 @@ en_NZ: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2805,6 +2806,8 @@ en_NZ: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2869,8 +2872,6 @@ en_NZ: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3081,10 +3082,24 @@ en_NZ: both: "Both Checkout and Back office" back_end: "Back office only" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3100,6 +3115,19 @@ en_NZ: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + back_end: "Back office only" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3266,9 +3294,6 @@ en_NZ: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index 884b680f84..154bb93df0 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -402,6 +402,7 @@ en_PH: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2787,6 +2788,8 @@ en_PH: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2851,8 +2854,6 @@ en_PH: abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Category" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3059,10 +3060,23 @@ en_PH: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3078,6 +3092,17 @@ en_PH: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3242,9 +3267,6 @@ en_PH: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index e3c8f3950d..e1deb0373b 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -398,6 +398,7 @@ en_US: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2780,6 +2781,8 @@ en_US: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2844,8 +2847,6 @@ en_US: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3052,10 +3053,23 @@ en_US: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3071,6 +3085,17 @@ en_US: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3234,9 +3259,6 @@ en_US: invalid: Invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 225939fb6f..06cd4ee1c4 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -403,6 +403,7 @@ en_ZA: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2732,6 +2733,8 @@ en_ZA: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2796,8 +2799,6 @@ en_ZA: abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2963,10 +2964,23 @@ en_ZA: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2982,6 +2996,17 @@ en_ZA: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3136,9 +3161,6 @@ en_ZA: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/es.yml b/config/locales/es.yml index a4452acd43..0fc3a89fe4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -403,6 +403,7 @@ es: footer_and_external_links: Pie de página y enlaces externos your_content: Tu contenido user_guide: Manual de Usuario + map: Mapa enterprise_fees: index: title: "Comisiones de la Organización" @@ -2812,6 +2813,8 @@ es: new_payment: "Nuevo pago" capture: "Captura" void: "Vacío" + login: "Iniciar sesión" + password: "Contraseña" configurations: "Configuraciones" general_settings: "Configuración general" site_name: "Nombre del sitio" @@ -2876,8 +2879,6 @@ es: abbreviation: "Abreviatura" new_state: "Nuevo estado" payment_methods: "Métodos de Pago" - new_payment_method: "Nuevo método de pago" - provider: "Proveedor" taxonomies: "Taxonomias" new_taxonomy: "Nueva taxonomía" back_to_taxonomies_list: "Volver a la Lista de Taxonomías" @@ -3089,10 +3090,24 @@ es: back_end: "Solo en Administración" deactivation_warning: "Desactivar un método de envío puede hacer que el método de envío desaparezca de tu lista. Como alternativa, puedes ocultar el método de envío de la página \"Hacer pedidos\" configurándolo con la opción \"Solo en Administración\" " payment_methods: + index: + payment_methods: "Métodos de Pago" + new_payment_method: "Nuevo método de pago" + name: "Nombre" + products_distributor: "Distribuidora" + provider: "Proveedor" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + both: "Ambos" + back_end: "Solo en Administración" + active_yes: "Sí" + active_no: "No" new: new_payment_method: "Nuevo método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" edit: + new: "Nuevo" editing_payment_method: "Edición del método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" stripe_connect: @@ -3108,6 +3123,19 @@ es: account_id: Account ID business_name: Nombre de la Organización charges_enabled: Cargos habilitados + form: + name: "Nombre" + description: "Descripción" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + active_yes: "Sí" + active_no: "No" + both: "Tanto en Hacer pedido como en Administración" + back_end: "Solo en Administración" + tags: "Tags" + providers: + provider: "Proveedor" payments: source_forms: stripe: diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index 660a0744c1..bd8f7c51e6 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -403,6 +403,7 @@ es_CR: footer_and_external_links: Pie de página y enlaces externos your_content: Tu contenido user_guide: Manual de usuario + map: Mapa enterprise_fees: index: title: "Comisiones de la organización" @@ -2795,6 +2796,8 @@ es_CR: new_payment: "Nuevo pago" capture: "Captura" void: "Vacío" + login: "Iniciar sesión" + password: "Contraseña" configurations: "Configuraciones" general_settings: "Configuración general" site_name: "Nombre del sitio" @@ -2859,8 +2862,6 @@ es_CR: abbreviation: "Abreviatura" new_state: "Nueva provincia" payment_methods: "Métodos de pago" - new_payment_method: "Nuevo método de pago" - provider: "Proveedor" taxonomies: "Taxonomías" new_taxonomy: "Nueva taxonomía" back_to_taxonomies_list: "Volver a la lista de taxonomías" @@ -3067,10 +3068,23 @@ es_CR: categories: "Categorías" zones: "Zonas" payment_methods: + index: + payment_methods: "Métodos de pago" + new_payment_method: "Nuevo método de pago" + name: "Nombre" + products_distributor: "Distribuidor" + provider: "Proveedor" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + both: "Ambos" + active_yes: "Sí" + active_no: "No" new: new_payment_method: "Nuevo método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" edit: + new: "Nuevo" editing_payment_method: "Edición del método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" stripe_connect: @@ -3086,6 +3100,17 @@ es_CR: account_id: ID de cuenta business_name: Nombre de la organización charges_enabled: Cargos habilitados + form: + name: "Nombre" + description: "Descripción" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + active_yes: "Sí" + active_no: "No" + tags: "Etiquetas" + providers: + provider: "Proveedor" payments: source_forms: stripe: @@ -3250,9 +3275,6 @@ es_CR: invalid: inválido order_mailer: cancel_email: - customer_greeting: "Hola %{name}!" - instructions: "Su pedido ha sido CANCELADO. Por favor, conserve esta información de cancelación para sus registros." - order_summary_canceled: "Resumen del pedido [CANCELADO]" subject: "Cancelación del pedido" confirm_email: subject: "Confirmación del pedido" diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index 5a0a66e6df..1b4b545419 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -403,6 +403,7 @@ fil_PH: footer_and_external_links: Footer at panlabas na mga link your_content: ang iyong nilalaman user_guide: gabay sa gumagamit + map: Mapa enterprise_fees: index: title: "fees para sa Enterprise" @@ -2801,6 +2802,8 @@ fil_PH: new_payment: "Bagong Pagbabayad" capture: "kunan" void: "walang bisa" + login: "Login" + password: "Password" configurations: "mga pagsasaayos" general_settings: "Pangkalahatang Setting" site_name: "Pangalan ng site" @@ -2865,8 +2868,6 @@ fil_PH: abbreviation: "Pinaikli" new_state: "Bagong Status" payment_methods: "Mga Paraan ng Pagbabayad" - new_payment_method: "Bagong Paraan ng pagbabayad" - provider: "tagapagbigay ng serbisyo" taxonomies: "taxonomies" new_taxonomy: "bagong taxonomy" back_to_taxonomies_list: "bumalik sa listahan ng mga taxonomy" @@ -3073,10 +3074,23 @@ fil_PH: categories: "mga kategorya" zones: "mga sona" payment_methods: + index: + payment_methods: "Mga Paraan ng Pagbabayad" + new_payment_method: "Bagong Paraan ng pagbabayad" + name: "Pangalan" + products_distributor: "Distributor" + provider: "tagapagbigay ng serbisyo" + environment: "kapaligiran" + display: "Ipakita" + active: "aktibo" + both: "pareho" + active_yes: "Oo" + active_no: "Hindi" new: new_payment_method: "Bagong Paraan ng pagbabayad" back_to_payment_methods_list: "bumalik sa listahan ng mga paraan ng pagbabayad" edit: + new: "Bago" editing_payment_method: "iayos ang paraan ng pagbabayad" back_to_payment_methods_list: "bumalik sa listahan ng mga paraan ng pagbabayad" stripe_connect: @@ -3092,6 +3106,17 @@ fil_PH: account_id: Account ID business_name: pangalan ng negosyo charges_enabled: pinagana ang paniningil + form: + name: "Pangalan" + description: "paglalarawan" + environment: "kapaligiran" + display: "Ipakita" + active: "aktibo" + active_yes: "Oo" + active_no: "Hindi" + tags: "tags" + providers: + provider: "tagapagbigay ng serbisyo" payments: source_forms: stripe: @@ -3256,9 +3281,6 @@ fil_PH: invalid: invalid order_mailer: cancel_email: - customer_greeting: "hi %{name}!" - instructions: "ang iyong order ay NAKANSELA. Panatilihin ang impormasyon na ito ng kanselasyon para sa inyong talaan." - order_summary_canceled: "Buod ng order [KANSELADO]" subject: "Pagkansela ng order" confirm_email: subject: "Kumpirmasyon ng order" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index ab4a5e02d3..5405e9484d 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -402,6 +402,7 @@ fr_BE: footer_and_external_links: Pied de page et Liens Externes your_content: Votre contenu user_guide: Guide d'utilisation + map: Carte enterprise_fees: index: title: "Marges et Commissions" @@ -2738,6 +2739,8 @@ fr_BE: new_payment: "Nouveau paiement" capture: "Payée" void: "Vide" + login: "Se connecter" + password: "Mot de passe" configurations: "Configurations" general_settings: "Réglages Généraux" site_name: "Nom du site" @@ -2802,8 +2805,6 @@ fr_BE: abbreviation: "Abréviation" new_state: "Nouvelle Province" payment_methods: "Méthodes de paiement" - new_payment_method: "Nouvelle méthode de paiement" - provider: "Fournisseur" taxonomies: "Taxonomies " new_taxonomy: "Nouvelle taxonomie" back_to_taxonomies_list: "Retour à la liste des taxonomies" @@ -3010,10 +3011,23 @@ fr_BE: categories: "Les catégories" zones: "Zones" payment_methods: + index: + payment_methods: "Méthodes de paiement" + new_payment_method: "Nouvelle méthode de paiement" + name: "Nom" + products_distributor: "Distributeur·trice" + provider: "Fournisseur" + environment: "Environnement" + display: "Ecran" + active: "Actif" + both: "Tou·te·s les deux" + active_yes: "Oui" + active_no: "Non" new: new_payment_method: "Nouvelle méthode de paiement" back_to_payment_methods_list: "Retour à la liste des paiements" edit: + new: "Nouveau" editing_payment_method: "Modification des méthodes de paiement en cours" back_to_payment_methods_list: "Retour à la liste des paiements" stripe_connect: @@ -3029,6 +3043,17 @@ fr_BE: account_id: Identifiant Compte business_name: Nom de l'entreprise charges_enabled: Frais activés + form: + name: "Nom" + description: "Description" + environment: "Environnement" + display: "Ecran" + active: "Actif" + active_yes: "Oui" + active_no: "Non" + tags: "Tags" + providers: + provider: "Fournisseur" payments: source_forms: stripe: @@ -3193,9 +3218,6 @@ fr_BE: invalid: invalide order_mailer: cancel_email: - customer_greeting: "Bonjour%{name}! " - instructions: "Votre commande a été ANNULÉE. Veuillez conserver ces informations d'annulation pour vos dossiers." - order_summary_canceled: "Résumé de la commande [ANNULÉE]" subject: "Annulation de Commande" confirm_email: subject: "Confirmation de commande" diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index a9cbb2d1e6..fba999a5cd 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -398,6 +398,7 @@ fr_CA: footer_and_external_links: Pied de page et Liens Externes your_content: Votre contenu user_guide: Guide utilisateur + map: Carte enterprise_fees: index: title: "Marges et Commissions" @@ -2792,6 +2793,8 @@ fr_CA: new_payment: "Nouveau paiement" capture: "Payée" void: "Annulé" + login: "Se connecter" + password: "Mot de passe" configurations: "Configurations" general_settings: "Configurations générales" site_name: "Nom du site" @@ -2856,8 +2859,6 @@ fr_CA: abbreviation: "Code" new_state: "Nouveau Région:" payment_methods: "Méthodes de paiement" - new_payment_method: "Nouvelle méthode de paiement" - provider: "Fournisseur" taxonomies: "Taxonomies" new_taxonomy: "Nouvelle taxonomie" back_to_taxonomies_list: "Retour à la liste des taxonomies" @@ -3062,10 +3063,23 @@ fr_CA: categories: "Conditions de transport" zones: "Zones" payment_methods: + index: + payment_methods: "Méthodes de paiement" + new_payment_method: "Nouvelle méthode de paiement" + name: "Nom" + products_distributor: "Hub-distributeur" + provider: "Fournisseur" + environment: "Environnement" + display: "Afficher" + active: "Actif" + both: "Les deux" + active_yes: "Oui" + active_no: "Non" new: new_payment_method: "Nouvelle méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" edit: + new: "Nouveau" editing_payment_method: "Modification de la méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" stripe_connect: @@ -3081,6 +3095,17 @@ fr_CA: account_id: Identifiant Compte business_name: Nom de l'entreprise charges_enabled: Frais activés + form: + name: "Nom" + description: "Description" + environment: "Environnement" + display: "Afficher" + active: "Actif" + active_yes: "Oui" + active_no: "Non" + tags: "Tags" + providers: + provider: "Fournisseur" payments: source_forms: stripe: @@ -3245,9 +3270,6 @@ fr_CA: invalid: invalide order_mailer: cancel_email: - customer_greeting: "Bonjour %{name}!" - instructions: "Votre commande a été ANNULÉE. Vous trouverez ci-dessous les informations concernant cette commande. " - order_summary_canceled: "Résumé de la commande [ANNULEE]" subject: "Annulation de Commande" confirm_email: subject: "Confirmation de commande" diff --git a/config/locales/it.yml b/config/locales/it.yml index 70c28a0515..89e40ea4c4 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -398,6 +398,7 @@ it: footer_and_external_links: Footer e link esterni your_content: I tuoi contenuti user_guide: Guida per gli utenti + map: Mappa enterprise_fees: index: title: "Tariffe azienda" @@ -2786,6 +2787,8 @@ it: new_payment: "Nuovo pagamento" capture: "Cattura" void: "vuoto" + login: "Login" + password: "Password" configurations: "Configurazioni" general_settings: "Impostazioni generali" site_name: "Nome del sito" @@ -2850,8 +2853,6 @@ it: abbreviation: "Abbreviazione" new_state: "Nuovo stato" payment_methods: "Metodi di pagamento" - new_payment_method: "Nuovo metodo di pagamento" - provider: "Provider" taxonomies: "Tassonomie" new_taxonomy: "Nuova tassonomia" back_to_taxonomies_list: "Torna all'elenco delle tassonomie" @@ -3057,10 +3058,23 @@ it: categories: "categorie" zones: "Zone" payment_methods: + index: + payment_methods: "Metodi di pagamento" + new_payment_method: "Nuovo metodo di pagamento" + name: "Nome" + products_distributor: "Distributore" + provider: "Provider" + environment: "Ambiente" + display: "Visualizza" + active: "Attivo" + both: "Entrambi" + active_yes: "Sì" + active_no: "No" new: new_payment_method: "Nuovo metodo di pagamento" back_to_payment_methods_list: "Torna all'elenco dei metodi di pagamento" edit: + new: "Nuovo" editing_payment_method: "Modifica metodo di pagamento" back_to_payment_methods_list: "Torna all'elenco dei metodi di pagamento" stripe_connect: @@ -3076,6 +3090,17 @@ it: account_id: Account ID business_name: Ragione sociale charges_enabled: Cambi Consentiti + form: + name: "Nome" + description: "Descrizione" + environment: "Ambiente" + display: "Visualizza" + active: "Attivo" + active_yes: "Sì" + active_no: "No" + tags: "Tag" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3240,9 +3265,6 @@ it: invalid: invalido order_mailer: cancel_email: - customer_greeting: "Ciao %{name}!" - instructions: "Il tuo ordine è stato ANNULLATO. Per favore conserva queste informazioni di cancellazione per i tuoi record." - order_summary_canceled: "Riepilogo dell'ordine [CANCELLATO]" subject: "Cancellazione dell'ordine" confirm_email: subject: "Conferma dell'ordine" diff --git a/config/locales/nb.yml b/config/locales/nb.yml index f8a72d5423..073ed2c232 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -403,6 +403,7 @@ nb: footer_and_external_links: Footer og eksterne lenker your_content: Ditt innhold user_guide: Brukermanual + map: Kart enterprise_fees: index: title: "Bedriftsavgifter" @@ -2788,6 +2789,8 @@ nb: new_payment: "Ny betaling" capture: "Fang" void: "Ugyldig" + login: "Logg inn" + password: "Passord" configurations: "Konfigurasjoner" general_settings: "Generelle innstillinger" site_name: "Sidenavn" @@ -2852,8 +2855,6 @@ nb: abbreviation: "Forkortelse" new_state: "Ny Region" payment_methods: "Betalingsmetoder" - new_payment_method: "Ny Betalingsmetode" - provider: "Tilbyder" taxonomies: "Taksonomier" new_taxonomy: "Ny Taksonomi" back_to_taxonomies_list: "Tilbake til Taksonomiliste" @@ -3060,10 +3061,23 @@ nb: categories: "Kategorier" zones: "Soner" payment_methods: + index: + payment_methods: "Betalingsmetoder" + new_payment_method: "Ny Betalingsmetode" + name: "Navn" + products_distributor: "Distributør" + provider: "Tilbyder" + environment: "Miljø" + display: "Visning" + active: "Aktiv" + both: "Begge" + active_yes: "Ja" + active_no: "Nei" new: new_payment_method: "Ny Betalingsmetode" back_to_payment_methods_list: "Tilbake til listen over betalingsmetoder" edit: + new: "Ny" editing_payment_method: "Redigerer betalingsmetode" back_to_payment_methods_list: "Tilbake til listen over betalingsmetoder" stripe_connect: @@ -3079,6 +3093,17 @@ nb: account_id: Konto-ID business_name: Bedriftsnavn charges_enabled: Avgifter Aktivert + form: + name: "Navn" + description: "Beskrivelse" + environment: "Miljø" + display: "Visning" + active: "Aktiv" + active_yes: "Ja" + active_no: "Nei" + tags: "Merkelapper" + providers: + provider: "Tilbyder" payments: source_forms: stripe: @@ -3245,9 +3270,6 @@ nb: invalid: ugyldig order_mailer: cancel_email: - customer_greeting: "Hei %{name}!" - instructions: "Din bestilling har blitt avbrutt. Vennligst behold denne avbestillingsinformasjonen som referanse." - order_summary_canceled: "Bestillingssammendrag [KANSELLERT]" subject: "Kansellering av bestilling" confirm_email: subject: "Ordrebekreftelse" diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index d17754b707..d2aa82ed37 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -389,6 +389,7 @@ nl_BE: footer_and_external_links: Voettekst en externe links your_content: Uw inhoud user_guide: Gebruikershandleiding + map: Kaart enterprise_fees: index: title: "Ondernemingsvergoedingen" @@ -2667,6 +2668,8 @@ nl_BE: new_payment: "Nieuwe betaling" capture: "Capture" void: "leegte" + login: "Log in" + password: "Wachtwoord" configurations: "configuraties " general_settings: "Algemene instellingen" site_name: "Website Naam" @@ -2731,8 +2734,6 @@ nl_BE: abbreviation: "Afkortingen " new_state: "Nieuw Provincie" payment_methods: "Betalingsmethode" - new_payment_method: "Nieuwe betalingswijze" - provider: "Leverancier" taxonomies: "Taxonomies " new_taxonomy: "Nieuwe taxonomie " back_to_taxonomies_list: "Terug naar de lijst Taxonomies" @@ -2897,10 +2898,23 @@ nl_BE: categories: "Categorieën" zones: "Zones " payment_methods: + index: + payment_methods: "Betalingsmethode" + new_payment_method: "Nieuwe betalingswijze" + name: "Naam" + products_distributor: "Distributeur" + provider: "Leverancier" + environment: "Omgeving" + display: "Display" + active: "Aktief" + both: "Beide" + active_yes: "Ya" + active_no: "Néé" new: new_payment_method: "Nieuwe betalingswijze" back_to_payment_methods_list: "Terug naar de lijst van de betalingswijzes" edit: + new: "Nieuw" editing_payment_method: "Wijziging van de betalingswijze" back_to_payment_methods_list: "Terug naar de lijst van de betalingswijzes" stripe_connect: @@ -2916,6 +2930,17 @@ nl_BE: account_id: Account ID business_name: Bedrijfsnaam charges_enabled: Kosten ingeschakeld + form: + name: "Naam" + description: "Beschrijving" + environment: "Omgeving" + display: "Display" + active: "Aktief" + active_yes: "Ya" + active_no: "Néé" + tags: "Tags" + providers: + provider: "Leverancier" payments: source_forms: stripe: @@ -3069,9 +3094,6 @@ nl_BE: invalid: fout order_mailer: cancel_email: - customer_greeting: "Hello%{name}!" - instructions: "Uw bestelling is GEANNULEERD. Bewaar deze annuleringsinformatie voor uw administratie." - order_summary_canceled: "Overzicht van de bestelling [KANNELD]" subject: "Annulering van de bestelling" confirm_email: subject: "Bestellingsinformatie" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 2b46b8d146..d7328b6e33 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -382,6 +382,7 @@ pt: footer_and_external_links: Rodapé e Ligações Externas your_content: O seu conteúdo user_guide: Manual do Utilizador + map: Mapa enterprise_fees: index: title: "Taxas de Organização" @@ -2623,6 +2624,8 @@ pt: fill_in_customer_info: "Por favor preencha informação do/a consumidor/a" new_payment: "Novo Pagamento" capture: "Capturar" + login: "Entrar" + password: "Palavra-passe" configurations: "Configurações" general_settings: "Configurações Gerais" site_name: "Nome do Site" @@ -2687,8 +2690,6 @@ pt: abbreviation: "Abreviatura" new_state: "Nova Região" payment_methods: "Métodos de pagamento" - new_payment_method: "Novo Método de Pagamento" - provider: "Fornecedor" taxonomies: "Taxonomias" new_taxonomy: "Nova Taxonomia" back_to_taxonomies_list: "Voltar à Lista de Taxonomias" @@ -2837,10 +2838,22 @@ pt: form: zones: "Zonas" payment_methods: + index: + payment_methods: "Métodos de pagamento" + new_payment_method: "Novo Método de Pagamento" + name: "Nome" + products_distributor: "Distribuidor" + provider: "Fornecedor" + environment: "Ambiente" + display: "Mostrar" + active: "Ativo" + active_yes: "Sim" + active_no: "Não" new: new_payment_method: "Novo Método de Pagamento" back_to_payment_methods_list: "Voltar à Lista de Métodos de Pagamento" edit: + new: "Novo" editing_payment_method: "Editar Método de Pagamento" back_to_payment_methods_list: "Voltar à Lista de Métodos de Pagamento" stripe_connect: @@ -2856,6 +2869,17 @@ pt: account_id: ID de Conta business_name: Nome do Negócio charges_enabled: Taxas activas + form: + name: "Nome" + description: "Descrição" + environment: "Ambiente" + display: "Mostrar" + active: "Ativo" + active_yes: "Sim" + active_no: "Não" + tags: "Etiquetas" + providers: + provider: "Fornecedor" payments: source_forms: stripe: @@ -3007,9 +3031,6 @@ pt: invalid: inválido order_mailer: cancel_email: - customer_greeting: "Olá %{name}!" - instructions: "A sua encomenda foi cancelada. Para seu registo, por favor guarde esta informação de cancelamento." - order_summary_canceled: "Sumário de Encomenda [CANCELADA]" subject: "Cancelamento de Encomenda" confirm_email: subject: "Confimação de Encomenda" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 0fad5eb3a9..daab978405 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -403,6 +403,7 @@ pt_BR: footer_and_external_links: Rodapé e links externos your_content: Seu conteúdo user_guide: Guia do Usuário + map: Mapa enterprise_fees: index: title: "Taxas da iniciativa" @@ -697,7 +698,7 @@ pt_BR: shopfront_requires_login_false: "Publico" shopfront_requires_login_true: "Disponível somente para clientes registrados" recommend_require_login: "Recomendamos pedir login dos usuários quando permitido que pedidos possam ser alterados." - allow_guest_orders: "Pedidos dos convidados" + allow_guest_orders: "Pedidos de convidados" allow_guest_orders_tip: "Permitir o checkout como convidado, ou requisitar um usuário registrado. " allow_guest_orders_false: "Requisitar o login para fazer pedidos" allow_guest_orders_true: "Permitir checkout de convidados" @@ -2809,6 +2810,8 @@ pt_BR: new_payment: "Novo Pagamento" capture: "Capturar" void: "Vazio" + login: "Login" + password: "Senha" configurations: "Configurações" general_settings: "Configurações Gerais" site_name: "Nome do site" @@ -2873,8 +2876,6 @@ pt_BR: abbreviation: "Abreviação" new_state: "Estado novo" payment_methods: "Métodos de pagamento" - new_payment_method: "Novo método de pagamento" - provider: "Fornecedor" taxonomies: "Taxonomias" new_taxonomy: "Nova taxonomia" back_to_taxonomies_list: "Voltar à lista de taxonomias" @@ -3086,10 +3087,22 @@ pt_BR: back_end: "Somente Área Administrativa" deactivation_warning: "Desativar um método de envio pode fazer com que ele desapareça da sua lista. Como alternativa, você pode esconder um método de envio da página de checkout s" payment_methods: + index: + payment_methods: "Métodos de pagamento" + new_payment_method: "Novo método de pagamento" + name: "Nome" + products_distributor: "Distribuidor" + environment: "Ambiente" + display: "Exibição" + both: "Ambos" + back_end: "Somente Área Administrativa" + active_yes: "Sim" + active_no: "Não" new: new_payment_method: "Novo método de pagamento" back_to_payment_methods_list: "Voltar à lista de formas de pagamento" edit: + new: "Novo" editing_payment_method: "Editando método de pagamento" back_to_payment_methods_list: "Voltar à lista de formas de pagamento" stripe_connect: @@ -3105,6 +3118,16 @@ pt_BR: account_id: ID da conta business_name: Nome da iniciativa/negócio charges_enabled: Taxas habilitadas + form: + name: "Nome" + description: "Descrição" + environment: "Ambiente" + display: "Exibição" + active_yes: "Sim" + active_no: "Não" + both: "Tanto Checkout quanto Área Administrativa" + back_end: "Somente Área Administrativa" + tags: "Tags" payments: source_forms: stripe: @@ -3272,9 +3295,6 @@ pt_BR: invalid: inváliod order_mailer: cancel_email: - customer_greeting: "Oi %{name}!" - instructions: "Seu pedido foi CANCELADO. Guarde essas informações de cancelamento para seus registros." - order_summary_canceled: "Resumo do pedido [CANCELADO]" subject: "Cancelamento do Pedido" confirm_email: subject: "Confimação de Pedido" diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 8bb42e8411..600a91ef7f 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -194,6 +194,7 @@ sv: footer_and_external_links: Sidfot och externa länkar your_content: Ditt innehåll user_guide: Användarinstruktion + map: Karta enterprise_fees: index: title: "Företagsavgifter" @@ -1905,6 +1906,8 @@ sv: update: "Uppdatera" continue: "Fortsätt" capture: "Fånga" + login: "Logga in" + password: "Lösenord" tax rate: "Skattesatser" tax_category: "Skattekategori" tax_settings: "Skatteskalor" @@ -1996,6 +1999,19 @@ sv: name: "Namn" products_distributor: "Distributör" calculator: "Beräkning" + payment_methods: + index: + payment_methods: "Betalningssätt" + name: "Namn" + products_distributor: "Distributör" + active_yes: "Ja" + active_no: "Nej" + form: + name: "Namn" + description: "Beskrivning" + active_yes: "Ja" + active_no: "Nej" + tags: "Taggar" products: new: supplier: "Leverantör" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 01e6b5b3bf..09160deaa4 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -182,7 +182,7 @@ tr: title: Açık Gıda Ağı welcome_to: 'Hoşgeldiniz' site_meta_description: "Açık Gıda Ağı, bağımsız, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Kar amacı gütmez, toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." - search_by_name: İsim veya konuma göre arama yapın... + search_by_name: Üretici adına veya konuma göre arama yapın... producers_join: Temiz gıda üreticileri! Açık Gıda Ağı sizler için kullanıma açıldı. charges_sales_tax: KDV Uyguluyor mu? print_invoice: "Faturayı yazdır" @@ -387,7 +387,7 @@ tr: edit: 'Düzenle' update_address: 'Adresi Güncelle' confirm_delete: 'Silmek istediğinizden emin misiniz?' - search_by_email: "E-posta / kod ile arama ..." + search_by_email: "E-posta/kod ile arama ..." guest_label: 'Misafir Ödemesi' destroy: has_associated_orders: 'Silme başarısız oldu: müşterinin bağlantılı siparişleri var' @@ -403,6 +403,7 @@ tr: footer_and_external_links: Altbilgi ve Dış Bağlantılar your_content: İçeriğiniz user_guide: Kullanici Kılavuzu + map: HARİTA enterprise_fees: index: title: "İşletme Ücretleri" @@ -612,7 +613,7 @@ tr: about_us: desc_short: Kısa Açıklama desc_short_placeholder: Bir veya iki cümleyle bize işletmenizden bahsedin - desc_long: Hakkımızda + desc_long: HAKKIMIZDA desc_long_placeholder: Müşterilerinize kendinizden bahsedin. Bu bilgiler profilinizde görünür. business_details: abn: VKN/TCKN @@ -795,7 +796,7 @@ tr: producer_shop_description_text: Açık Gıda Ağı üzerinden açtığınız bireysel mağazanız ile ürünlerinizi doğrudan müşterilere ulaştırabilirsiniz. producer_shop_description_text2: Üretici Tezgahı sadece sizin ürünleriniz içindir. Üretiminiz haricindeki ürünleri satabilmek için lütfen 'Üretici Pazarı' seçeneğini seçin. producer_hub: ÜRETİCİ PAZARI - producer_hub_text: Kendi ürünleriniz ile beraber başkalarından ürünlerini de satın + producer_hub_text: Kendi ürünleriniz ile beraber başkalarının ürünlerini de satın producer_hub_description_text: İşletmeniz, yerel gıda sisteminizin bel kemiğidir. Açık Gıda Ağı'ndaki mağazanız aracılığıyla kendi ürünlerinizi ve çevrenizdeki diğer üreticilerin ürünlerini beraber satabilirsiniz. profile: Yalnızca Profil get_listing: Görünür ol @@ -1148,7 +1149,7 @@ tr: checkout: "Alışverişi Tamamla" already_ordered_products: "Bu sipariş dönemi içinde zaten sipariş verildi" register_call: - selling_on_ofn: "Açık Gıda Ağı'na katılmak ister misiniz?" + selling_on_ofn: "Açık Gıda Ağı üzerinden satış yapmak ister misiniz?" register: "Buradan kaydolun" footer: footer_secure: "Güvenli ve güvenilir." @@ -1157,7 +1158,7 @@ tr: footer_contact_email: "Bize e-posta gönderin" footer_nav_headline: "Gezin" footer_join_headline: "Bize katılın" - footer_join_body: "Açık Gıda Ağı üzerinden aracısız, adil ve temiz gıdaya ulaşma yollarını keşfedin." + footer_join_body: "Açık Gıda Ağı üzerinden ürünlerinizi sergileyin, çevirimiçi mağazanızı oluşturun veya grubunuzu listeleyin." footer_join_cta: "Daha fazlasını anlat!" footer_legal_call: "Okuyun" footer_legal_tos: "Şartlar ve koşullar" @@ -1170,7 +1171,7 @@ tr: shop: messages: customer_required: - login: "Oturum Aç" + login: "Oturum Aç / Kaydol" signup: "Kaydol" contact: "İLETİŞİM" require_customer_login: "Yalnızca onaylı müşteriler buradan alışveriş yapabilir." @@ -1214,7 +1215,7 @@ tr: menu_3_url: "/producers" menu_4_title: "Gruplar" menu_4_url: "/groups" - menu_5_title: "hakkında" + menu_5_title: "HAKKIMIZDA" menu_5_url: "https://hakkimizda.acikgida.com" menu_6_title: "Bağlan" menu_6_url: "https://acikgida.com/connect" @@ -1234,7 +1235,7 @@ tr: footer_pinterest_url: "Pinterest URL" footer_email: "E-posta" footer_links_md: "Bağlantılar" - footer_about_url: "URL hakkında" + footer_about_url: "HAKKIMIZDA URL" user_guide_link: "Kullanıcı Kılavuzu Linki" name: İSİM first_name: Ad @@ -1359,11 +1360,11 @@ tr: brandstory_part6: "Hepimiz gıdamızı seviyoruz. Artık gıda sistemimizi de sevmeye başlayabiliriz." learn_body: "Adil ve temiz gıda işletmenizi veya topluluğunuzu geliştirmenize yardımcı olacak modelleri, hikayeleri ve kaynakları keşfedin. Dostlardan öğrenmek için eğitim, etkinlikler ve diğer fırsatlara göz atın." learn_cta: "İlham Alın" - connect_body: "Yakınınızdaki adil ve temiz gıda tüccarlarını bulmak için üreticilerin, pazarların ve topluluklarının tümünü gözden geçirin. İşletmenizi veya topluluğunuzu Açık Gıda Ağı üzerinden listeleyin, böylece alıcılar sizi bulabilir. Ortak hareket etmek için diğer hesaplar ile iletişime geçmekten çekinmeyin, birlikte daha güçlüsünüz. Tavsiye almak ve sorunları birlikte çözmek için topluluğa katılın." + connect_body: "Yakınınızdaki adil ve temiz gıda noktalarını bulmak için üreticilerin, pazarların ve topluluklarının tümünü gözden geçirin. İşletmenizi veya topluluğunuzu Açık Gıda Ağı üzerinden listeleyin, böylece alıcılar sizi bulabilir. Ortak hareket etmek için diğer hesaplar ile iletişime geçmekten çekinmeyin, birlikte daha güçlüsünüz. Tavsiye almak ve sorunları birlikte çözmek için topluluğa katılın." connect_cta: "Keşfedin" system_headline: "Nasıl çalışıyor ?" system_step1: "1. Ara" - system_step1_text: "Yerel, adil, temiz ve mevsimsel gıda için, bağımsız ve cesur üreticilerimizin pazarlarından alışveriş yapın. Uzaklığa göre, ürün kategorisine veya teslimat tercihlerine göre arama yapabilirsiniz. " + system_step1_text: "Yerel, adil, temiz ve mevsimsel gıda için, bağımsız ve cesur üreticilerimizin mağazalarından alışveriş yapın. Konuma, ürün kategorisine, üretici özelliklerine veya teslimat tercihlerine göre arama yapabilirsiniz. " system_step2: "2. Alışveriş Yap" system_step2_text: "Gıdanızı yerel üretici tezgahlarından, üretici ve türetici pazarlarından temin edin. Yaşanabilir bir dünya için alışkanlıklarınızı şimdi değiştirin. Gıdanızın ve onu size getiren insanların hikayelerini öğrenin!" system_step3: "3. Teslimat " @@ -1383,7 +1384,7 @@ tr: checkout_headline: "Tamam, ödeme yapmaya hazır mısın?" checkout_as_guest: "Misafir olarak ödeme yap" checkout_details: "Bilgilerin" - checkout_billing: "fatura bilgisi" + checkout_billing: "Fatura Bilgisi" checkout_default_bill_address: "Varsayılan fatura adresi olarak kaydet" checkout_shipping: Teslimat bilgileri checkout_default_ship_address: "Varsayılan teslimat adresi olarak kaydet" @@ -1638,7 +1639,7 @@ tr: sell_hubs_detail: "AGA üzerinden gıda işletmeniz veya topluluğunuz için bir profil oluşturun. İstediğiniz zaman profilinizi çok üreticili bir pazara yükseltebilirsiniz." sell_groups_detail: "Bölgenizdeki veya ağınızdaki işletmelerin (üreticilerin, pazarların veya diğer grupların) detaylı rehber listesini oluşturun." sell_user_guide: "Kullanım kılavuzumuzdan daha fazla bilgi edinin." - sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Platform üzerinden satış yapan işletmeler için işlem başına uygulanan ücretlendirme %5'tir. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkımızda bağlantısını kullanarak Fiyatlandırma bölümünü ziyaret edin." + sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Platform üzerinden satış yapan işletmeler için işlem başına uygulanan ücretlendirme KDV dahil %5'tir. Kar amacı gütmeyen topluluklar, kooperatifler ve ekoloji/gıda temelli dernekler ile çalışan üreticiler karşılıklı dayanışma ve özel fiyatlandırma için iletişime geçebilirler. Fiyatlandırma hakkında bilgi almak için, üst menüdeki Hakkımızda bağlantısını kullanarak Fiyatlandırma bölümünü ziyaret edin." sell_embed: "Kendi e-ticaret siteniz olsa bile Açık Gıda Ağı size hikayenizi anlatmanız ve ürünlerinizi satmanız için yeni ve farklı bir seçenek sunuyor. Siz de bu ailenin bir parçası olun, hep beraber büyüyelim!" sell_ask_services: "Detaylar için bizimle iletişime geçin." shops_title: Mağazalar @@ -1713,7 +1714,7 @@ tr: filter_by: "Filtrele" hide_filters: "Filtreleri gizle" one_filter_applied: "1 filtre uygulandı" - x_filters_applied: "filtreler uygulandı" + x_filters_applied: "filtre uygulandı" submitting_order: "Siparişiniz gönderiliyor: lütfen bekleyin" confirm_hub_change: "Emin misiniz? Seçtiğiniz pazar değiştirilecek ve alışveriş sepetinizdeki tüm ürünler kaldırılacak." confirm_oc_change: "Emin misiniz? Seçtiğiniz sipariş dönemi değiştirilecek ve alışveriş sepetinizdeki tüm ürünler kaldırılacak." @@ -1753,14 +1754,14 @@ tr: steps: introduction: registration_greeting: "Merhaba!" - registration_intro: "Şimdi AGA üzerinden bir Üretici veya Türetici profili oluşturabilirsiniz" + registration_intro: "Şimdi AGA üzerinden Üretici veya Türetici profilleri oluşturabilirsiniz" registration_checklist: "Neye ihtiyacım var?" registration_time: "5-10 dakika" registration_enterprise_address: "İşletme adresi" registration_contact_details: "Birincil iletişim bilgileri" registration_logo: "Logo resminiz" registration_promo_image: "Profiliniz için duvar resmi" - registration_about_us: "'Hakkımızda' metni" + registration_about_us: "'Hakkımızda' metni - Hikayeniz" registration_outcome_headline: "Ne kazanacağım?" registration_outcome1_html: "Profiliniz, insanların Açık Gıda Ağı üzerinde sizi bulmasına ve sizinle iletişim kurmasına yardımcı olur." registration_outcome2: "Bu alanı kendinizin, çiftliğinizin ve işletmenizin hikayesini anlatmak, yeni işbirlikleri, yeni bağlantılar kurmak için kullanın. " @@ -1808,7 +1809,7 @@ tr: no_producer_help: "Üretici değilseniz muhtemelen gıdaya ulaşım sağlayan, dağıtım veya satış yapan bir grup ya da işletmesiniz. Bir dükkan, kooperatif, gıda topluluğu, restaurant veya toptancı bile olabilirsiniz. " create_profile: "Profil oluştur" about: - title: "Hakkında" + title: "HAKKIMIZDA" headline: "Güzel!" message: "Şimdi ayrıntıları açıklayalım" success: "Sonunda! %{enterprise} Açık Gıda Ağı'na eklendi" @@ -2233,7 +2234,7 @@ tr: user_invited: "%{email} bu işletmeyi yönetmeye davet edildi" add_manager: "Mevcut bir kullanıcıyı ekle" users: "Kullanıcılar" - about: "Hakkında" + about: "HAKKIMIZDA" images: "Görseller" web: "Web" primary_details: "Temel Bilgiler" @@ -2261,7 +2262,7 @@ tr: content_configuration_pricing_table: "(YAPILACAKLAR: Fiyatlandırma tablosu)" content_configuration_case_studies: "(TODO: Vaka çalışmaları)" content_configuration_detail: "(YAPILACAKLAR: Detay)" - enterprise_name_error: "çoktan alındı. İşletme size aitse ve sahiplik talebinde bulunmak istiyorsanız veya bu işletmeyle ticaret yapmak istiyorsanız lütfen %{email} numaralı telefondan bu profilin şu anki yöneticisiyle iletişime geçin." + enterprise_name_error: "çoktan alındı. İşletme size aitse ve sahiplik talebinde bulunmak istiyorsanız veya bu işletmeyle ticaret yapmak istiyorsanız lütfen %{email} üzerinden bu profilin şu anki yöneticisiyle iletişime geçin." enterprise_owner_error: "^ %{email}‘ın daha fazla işletmeye sahip olmasına izin verilmiyor (limit %{enterprise_limit})." enterprise_role_uniqueness_error: "^ Bu rol zaten var." inventory_item_visibility_error: doğru veya yanlış olmalı @@ -2354,7 +2355,7 @@ tr: saved: KAYDEDİLDİ saving: KAYDEDİYOR enterprise_package: - hub_profile: Türetici Pazarı Profili + hub_profile: Pazar Profili hub_profile_cost: "MALİYET: HER ZAMAN ÜCRETSİZ" hub_profile_text1: > İnsanlar Açık Gıda Ağı üzerinden size ulaşabilir. Haritada görünür ve @@ -2369,8 +2370,7 @@ tr: alıcılara ulaştırabilirsiniz. hub_shop_text2: > Pazarlar gerçek anlamı dışında da bir çok şekil alabilir: Gıda kooperatifleri, - gıda toplulukları, haftalık gıda kolisi üyelikleri, alım grupları, dükkanlar - vs. + gıda toplulukları, haftalık gıda kolisi üyelikleri, alım grupları vs. hub_shop_text3: > Kendi ürünlerinizi de satmak isterseniz, işletme bilginizi üretici olarak güncellemelisiniz. @@ -2808,6 +2808,8 @@ tr: new_payment: "Yeni Ödeme" capture: "Tahsilat" void: "Geçersiz" + login: "Oturum aç" + password: "Parola" configurations: "yapılandırmalar" general_settings: "Genel Ayarlar" site_name: "Site adı" @@ -2872,8 +2874,6 @@ tr: abbreviation: "Kısaltma" new_state: "Yeni Şehir" payment_methods: "Ödeme yöntemleri" - new_payment_method: "Yeni Ödeme Yöntemi" - provider: "Sağlayıcı" taxonomies: "cinsler" new_taxonomy: "Yeni Cins" back_to_taxonomies_list: "Cinsler Listesine Geri Dön" @@ -3085,10 +3085,24 @@ tr: back_end: "Sadece panel" deactivation_warning: "Bir teslimat yöntemini etkisiz hale getirmek listenizden kaldırılmasına sebep olabilir. Alternatif olarak, ayarlarınızı 'Göster' yerine 'sadece panel' olarak değiştirerek teslimat yöntemini ödeme sayfasında gizleyebilirsiniz." payment_methods: + index: + payment_methods: "ÖDEME YÖNTEMLERİ" + new_payment_method: "Yeni Ödeme Yöntemi" + name: "İSİM" + products_distributor: "Dağıtımcı" + provider: "Sağlayıcı" + environment: "çevre" + display: "Görüntüle" + active: "Aktif" + both: "Her ikisi de" + back_end: "Sadece panel" + active_yes: "Evet" + active_no: "Hayır" new: new_payment_method: "Yeni Ödeme Yöntemi" back_to_payment_methods_list: "Ödeme Yöntemleri Listesine Geri Dön" edit: + new: "Yeni" editing_payment_method: "Ödeme Yöntemi Düzenleniyor" back_to_payment_methods_list: "Ödeme Yöntemleri Listesine Geri Dön" stripe_connect: @@ -3104,6 +3118,19 @@ tr: account_id: Hesap Kimliği business_name: işletme adı charges_enabled: Masraflar Etkin + form: + name: "İSİM" + description: "Açıklama" + environment: "çevre" + display: "Görüntüle" + active: "Aktif" + active_yes: "Evet" + active_no: "Hayır" + both: "Ödeme Sayfası ve Panel" + back_end: "Sadece panel" + tags: "Etiketler" + providers: + provider: "Sağlayıcı" payments: source_forms: stripe: From 9e278d5b2f0e3574c57feda05c148e09f0785e86 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 4 Jun 2020 12:02:11 +0200 Subject: [PATCH 370/507] Improve performance in various reports --- .../spree/admin/reports_controller.rb | 6 ++-- app/models/spree/product_decorator.rb | 6 ++++ spec/models/spree/product_spec.rb | 31 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index 54f2868610..3ada1fbbcd 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -247,8 +247,10 @@ module Spree end def suppliers_of_products_distributed_by(distributors) - distributors.map { |d| Spree::Product.in_distributor(d).includes(:supplier).all }. - flatten.map(&:supplier).uniq + supplier_ids = Spree::Product.in_distributors(distributors). + select('spree_products.supplier_id') + + Enterprise.where(id: supplier_ids) end # Load order cycles the current user has access to diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index fe20fe5194..cd427376a8 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -84,6 +84,12 @@ Spree::Product.class_eval do select('distinct spree_products.*') } + scope :in_distributors, lambda { |distributors| + with_order_cycles_outer. + where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id IN (?))', false, distributors). + uniq + } + # Products supplied by a given enterprise or distributed via that enterprise through an OC scope :in_supplier_or_distributor, lambda { |enterprise| enterprise = enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index a8c6368a70..d3d47b21ca 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -257,6 +257,37 @@ module Spree end end + describe "in_distributors" do + let!(:distributor1) { create(:distributor_enterprise) } + let!(:distributor2) { create(:distributor_enterprise) } + let!(:product1) { create(:product) } + let!(:product2) { create(:product) } + let!(:product3) { create(:product) } + let!(:product4) { create(:product) } + let!(:order_cycle1) { + create(:order_cycle, distributors: [distributor1], + variants: [product1.variants.first, product2.variants.first]) + } + let!(:order_cycle2) { + create(:order_cycle, distributors: [distributor2], + variants: [product3.variants.first]) + } + + it "returns distributed products for a given Enterprise AR relation" do + distributors_relation = Enterprise.where(id: [distributor1.id, distributor2.id]) + + expect(Product.in_distributors(distributors_relation)).to include product1, product2, product3 + expect(Product.in_distributors(distributors_relation)).to_not include product4 + end + + it "returns distributed products for a given array of enterprise ids" do + distributors_ids = [distributor1.id, distributor2.id] + + expect(Product.in_distributors(distributors_ids)).to include product1, product2, product3 + expect(Product.in_distributors(distributors_ids)).to_not include product4 + end + end + describe "in_supplier_or_distributor" do it "shows products in supplier" do s1 = create(:supplier_enterprise) From a287f370b54d67042c22cafbd5e19a1ae2552b51 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Wed, 3 Jun 2020 14:00:01 +0200 Subject: [PATCH 371/507] Remove unused home photos --- app/assets/images/home/groups-bg.svg | 1051 ----------------- app/assets/images/home/home-apples.jpg | Bin 140856 -> 0 bytes app/assets/images/home/home-oranges.jpg | Bin 107368 -> 0 bytes app/assets/images/home/home-strawberries.jpg | Bin 583172 -> 0 bytes app/assets/images/home/home1.jpg | Bin 211404 -> 0 bytes app/assets/images/home/home2.jpg | Bin 249850 -> 0 bytes app/assets/images/home/home3.jpg | Bin 199656 -> 0 bytes app/assets/images/home/macbook.png | Bin 35191 -> 0 bytes app/assets/images/home/maps-bg.svg | 1090 ------------------ app/assets/images/home/producers-bg.svg | 72 -- 10 files changed, 2213 deletions(-) delete mode 100644 app/assets/images/home/groups-bg.svg delete mode 100644 app/assets/images/home/home-apples.jpg delete mode 100644 app/assets/images/home/home-oranges.jpg delete mode 100644 app/assets/images/home/home-strawberries.jpg delete mode 100644 app/assets/images/home/home1.jpg delete mode 100644 app/assets/images/home/home2.jpg delete mode 100644 app/assets/images/home/home3.jpg delete mode 100644 app/assets/images/home/macbook.png delete mode 100644 app/assets/images/home/maps-bg.svg delete mode 100644 app/assets/images/home/producers-bg.svg diff --git a/app/assets/images/home/groups-bg.svg b/app/assets/images/home/groups-bg.svg deleted file mode 100644 index 19d7f926c5..0000000000 --- a/app/assets/images/home/groups-bg.svg +++ /dev/null @@ -1,1051 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/assets/images/home/home-apples.jpg b/app/assets/images/home/home-apples.jpg deleted file mode 100644 index 91bfd4cfa59fe4d1321f64ae99b17eea4b897d93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140856 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∋UNYqra>0RF#`X^vrIDWiSr68PM2biK+qLi)U2$4dMbEX|j^(ci2nA z*>vNPwI>F=(~<)yu9}TBU0G1hn0 zpS4XapG2km5Jg7#h6A%EjSU9^`cuuNKE?Ie^QUs~6S;IgEDV`5vgpPJ@k~d08KsyV zf2W_FqX-K7T21R|qbtP2RZxJa+aT}C8=7+phrK?KSYu^ZO}icrBNu&ugLn29Z_~ z>G2Yo`H-%+YmoHYw2T`64g4@=;Yym;idD+R#n)8EcWV4PFXNT+qmFtvmxgOw%q1$g z-5zcKoPN?AeSH{d^=j}E<~BFq!@`0UN^b4P2l#0C(WdEwsk6p9MQ#omX(gwID6y5= zsz8>-L@ZAz^bT5LGZ$8rkWG!0h~zF^HG5p?kd2?KP+^q9cthDy55kj zh+iE=*CXU`yNp5KSV(;m1TjX1VQvpgD&zHc1NmiM{T(u(#PtTsM%l`fKCYB4Xga%{34t)>$0440V^b9 zj8};9idL%6j^Hb`bfdl7+R@zx)4;yMC*pR&_rfc9 zXU>@%(<^L)>3>?i8Vz%Lg83v!`zJ%)v?QAU#-nnrf1uZg?1{Q*-~$; ztRnpNSa3dDgZg6Lo?vMTm|bX%^r55XdFO6q>r2FCAq{WSZF&1E5& z6d82fHq2fUjxZwK|5S1_ggpH)Wv$7MJM-lO*Su|`pZ2mKRPpb^FYWde`@H)z@3n+D z^cve4IhJaSMPQ$P^T%Bw*W2k15PvWE)4EcWl|RMNUax)f*D$V9n8uZo)#5wDyb-^E z=l3R2tHalg3)NA?4@*DkJ+)`L$$zmaX;1e0hKJBoy&f1B;LEV7G$nFQV%OOVC11HO zPT+EWe>>$G*vgsdeWMxs^i&1tE`%GZchO>{LA4aFB4F{anxw>@WcMMO7jOgg(w)XO;x^ZxP_mpvf*$NG<$JAZVM zuJpEIon$uc{n?Z?SvPU#cU;TGEK&hWJ_>hKlcKgd4A2G{!wJ>_>_y(gs&v}VN$mNjrLP&d8lcAEbOf@>z)(!j@N`$**c z6K|K6OLCa~I(g~1ylrxt{M4QbXeQ%t%s_WFc;2Vzqy(DBh^>wuIdiwt_x+Oe++Z8E zjy3&8+@RC_E^p5D@pFfQwYE1(q$Im#vT^Ru%A>yPGLK%xqoh`E;nTgrVDRGVB$;{) zLuF?wDg1MIiR#|Tbx!hzze*AmYC?*eV0(AU?d|qaFsu5;AkdV$M#AbddJFP(@Qt|W zV7R=)NY>v$F^Qqq_Jgk|{(&OYpNN=cr&kq<7KAcE;rtgDD&MEcAv0&MECuI5KH`_6)81=Z*rTs~6qnvMZtCk}BqNNlul#+_rU6{;NA| z_YK`hD;Ud!;g@c&P2hjLc4)vgOR|(dY&DF}BQY{dOs{lDy+oevBb%J)H1EEI$Ha}X zIK3!zw<`#v9DNB=4uqC?sE%zoDyhDgIn8|xBvlRq<{>I%D=vz9{_bW6Wcb#eP1PZ@{4w4O~L z2{X@mY>k2Bl=R~ZlUrI19E$OP(>Q79H@Y;^%(yx*3B=0x-ryf-Swt6ac$ZC0f()M6 zNK!e+@nq{h`}J}D6YlK>w;K=3HF-v;0qhERwxX862TPscsC;PH1TDm}-yV zz2jaVWnL$l{4gb=RNJEQr*8MUh}Q4)cUBc1+r*XGXHP;FPudb~F1$ki5?hFP+;g|| zaM`DIL%>WHcAD>9e^ z@#I_KER|){n)c%S;+d5}+qT!!^k;25VeJi9w3Un%ea^+J@w7-vb#MZbJq5~8U<`*y z9k-*M2x?pL2W>GiTkd<`E7^~SVp!?x^sa7Ks>~d#GvUPM=R*+tV{u2g0JX(=1?#1m z70%cE|3Espi<$_IR&A;A-XU#)6f|X@sS`1kN@@7ZkpKw0>6Ufcl zWOwIqaKvZpfEV|K@0UW@-*|Z_h1$VlA^vbd9YhpzWS$^w&UphIkS2;hiH9@gDu!oBg; z7GTqMUVzh8_R6X=8h0H=f4bJ2iy#OU#*t_QfZ^m7b*7s2Ea#F(F@2I-(Vdh5ecnH0 z>2VViB2X%VRIkB*vqenjikjHe0Jw10MP7M`CY|mtH}w%)-0ERo6OnTR{9PTgj)et}k_HTEyCd0p!)#B!w&K0H z%JLM~%Y501`M*r{v7Xoqh@^Ke}8tP`dbm0UnJ?jiEnGh0kPZ3I~Q5;;GR-;p*+_nJ+XC*x0f`GGPOQiNT zY7!di8AjkE@7_p`<5k89#hcFw7w!)EHm=os1cqPBokca8$C}2C*V6M5Ds}1 z(SIR zAFvDq{GEjyLatXcT`d9sYYoSQbpE?CnbbfqwHefmt0NE0xP_%5Aj(Vf$LqkP)-~2pb|Ulvl*K*??)OgRdbT>W)Im@zw4fqo19Q zHcc@%AIWiNik0^#qsM+GtG>X#K3URYjC5>9aa` z9ka=3o9Qx=aR_DTP0)Nigg9LaSqQ0w1uspANZUvzApa7*CmPoif*otk9o4}vuYVtE zhVHpufPsUX>8kHARlJ(5bHtN!AzNgCMgaUCjks9cVCqO8Vn(wjgwb6xGn;={T~F3` ztc`#I-1@@u&Bx~mRWc}jQl^__5;&o?0ePMhy$pQ!zmL~1xn9D;_z~^$c(d%Cuv?4M zAuvua{ZNa({|E*E5TSBZI-Hol=XwZid4!^Ku`|#1$Z8??Xapnk4uaT_MZ}jLUVXIp zw;Pegn=P)L$TtHl+2&6=_GV*=GO*pETvz}Kl>X4qZ%99Nzk@B=378l}YCQElT`>S? z;Ze*p97RK)*vUM5{{gY}Y!Vh`XORBFgK%sWVrSd9-cidjsPyE+I=~kD>w!5y_wv>; znXuJRQLZmB|DhDS8dC4(+J6Ei1D4E@V77Qt%g26o$DTtd0T%k@aKsB$fnN&o*qjJh zY&1>B{$h1m!T^|N@Bg0uI|4c@qv^c%Fvu=mr@jz4E&wzD$;E}-7wWg6^nd1t+WtJy zDN%jtijxE?QwchLGslH8SS?P4rppufGqrKfcUY0~^YiR|k~eX#(V9?71CU!n>yX&= z&+#QPfWr*w`_yDLG&CUpfuchgq4fJg7b%XsFa8h|)XHJ;{tx_d=$(+ci0LnH2T?F* zm@_|lveg;D4)}I83IIl}CX>)QATA8l?Esb<0i6())YYia8`4%iCCF+<%u9)cQmVVj zI@}u?9J;E%iarsyZde6|($4)otvr9bh`*%asQSG!1^&OyHt>sKNl(MRZv*^?zCOV?b_NC>4Q!O7OjX2|nh z3R_fN5*N{~y7SyZtyynM0~Xh0*@}&9UQzn4Nw!4@&*KudC;+WQE@4~ z!QpoatreEp9G%6RpNnGv#7L#AV?-<({u70O5_8N4FPjj%(+luB*oaTF2x8V;z9qbhMkLe%Ah&ZUl?9oKrCU&{lh3~R zoAwhnoGuLIIH)d(!8$ukh>KXa+U$h3$$45g7A&>}AGO6KGPh9S(D!w_n7Vv}Zq~iN zK89j>`qh$lM$)Ct+ebLX+iCg0EID`_t%eKwAF+Udw*@JkM_)bhd`Tb4e(4@jSqY_Y zY$Mb^dy_2}Vwn}K4`V`R5mmI{QWLc0enWbCH$>1lZA*f0+J48@KM?*ONaG)<(Dp@; z|5vM+v1-?;>ReF=N_FWs8E z@s$~?z8(WT*kL+fE4gRseXHJQSYP91c%`BvaET8UvvX-{@V*-NC+tI(>SA+8txp=h zEFOj!9KNYyamYbzaSYJ-zA^R(i|A^9o__G792WgyGepFqIV|+@@A2Zv%CGt&3W-0j zttMbTp5^p*hdyB+qAzK!|2&^_!NfZDZe&e}d+KG!#=lCYsCTk%^7&DHgZmb}2tR-6 z*gYgwi=H|a)zAoL+R9){OFv3|d524PzYM}s48CXsR0RiXX|V&>Uw7dquwd* zmi0-7ef2unxw2`J#ksQ&YZ*|Y5y@6dSL9Z=d63xmJ0XxQ542_7&f3_z*|XYj*2IR| z5`Jvf*v*Rg0V$YgClN?GWRxp!?NneYa)vJc0y)$rf?yM zp+)>u;RH8s#e?`pQFB6`J~nB}8?QK$Os^Cq)l)vtuQh(y#%xx~e4oqzEd-s|PuT;V zL&L$ss#60lBiVCUZ|}KJ!iM2~_ju-SMKeCoV}Gn-#H`K-*cPefb9BbW@LNqeDe8uiJVq~qI_{Tj^4Uu0hO$(8r#GcKOg?>oPrg&7+`V&&VmFz)9kJBwdp zdXN+Bevf}W`G9jvK!UR(V2EL#{F~2UZ4*#bvsjO!-FsrUWi4aeFuY%0rhu;xEAXZOFXE<*d6Sd<^ow)5 zOwYI^a|4fQQF#l#Ia6{jX0B(_Kxlm@G@ecDc0mQ&+t(OwTI&eDhSRoKsb{^hk^ogU z7kq;ncZ8ov8BeKuSoEP0m)Iey@^sQ-$GGyUsnf{^cl0&e+Svch{sSqjTCJ`pIKnY~ z4(+Nutism=G8z?U5QDsY&CR&?(&qj89u$N^%OJO$Q=jDlZCr6OO!w?yRVM2n$cmdI zKAADLGgxNxDPD3e{h9XLTW&c=D?f(xyr&kYHiLn6gt{i`!t)F0`%$yc+745y(+*ZR z7Oz?UP-=>UI^iV0@~>;S$-unZF`}3!lM;Ptnf<) z*=Ec85^Mc0c3!xtifZI#?N8fk05d_$?`l)Lsy?Vv!ndQAKd^VZKW{w~R~^m_Wj{PV zN^(YL-!9a%oxvHkq!QPDwbiC&p-jtcT(kD4nBJyLr%bcyIdcY4{{!WZG)mw8@oU)v zojSW{(=oXM$bh#wQFm_Ht@i`SxpNM2$S$$2=ZhRc`8joa%<&882lTt2o?+KL#jNGJ z!xHcOk(A4Mgs*DEFP^L1tUGki!0jWjl3hpD_rwp{G%ki#*0b%RB)xI1s{`@84CPMF zJDmOwacQ`Wd zE_FpRM)05ymYfuc4J`|c$1St_y^ALwD~r{X4t$&jf^gnGwnOaNC~5SQ@!46Qsg@8Y zf^}=0ONISY1ZE&-I-9FP#(YRw2ePXpDs3X?e!S9JecrTCC9}3)9inT0_XB6A;fSrl z!ODP3iaC;f_QhYX-}S!bUGSNmWEdOn`FPXY0`Aj*d%(zmvNG~Vb9-$UH9i_#5cIT@rJ6);A8EPHnG0)7}p4XIYPfjNo>>#lrr>#6)@Zu;DrfU{Bb?R z$|_`G_Bwe6@yut8Stwgk|=x}D< z+3W3ZQ|(^f7hj1sl^pALhnJ%bXoO{r5+HGHa=3UZN?qN%b4NI*Dlu)&9-f_$>`h;Q z?}sc^+qQWDN?F^EO^4NJ1v3P?ndv4ysz`|wt(G6zpyyCPR^@8NfvwQUn=~4FAF=5itj*Drp3>B-N(DCt&!+TR+gs#t%Kfm4cDL2A zXC-Yj&A*?HzII9D*p|a)OmWgybv!@a5gIRlvei-7JH)ow|G)Jj4?zYF&L5zmU*6o9 zP%4Q_!wK8?)brNW5qg7Hj(RKCkWD>AJSbb#3P=W6HWj*NYYyo{dN;Mo5M)L8YJ&lP zSDE9yFyhs9^UmyOcYXH3ZDD*439=3a*~oN=Z0#(>84Y!Q_5zI^tH3)_`_?2so-_>?ES20OsmRW zgPjmFJT5F0=Vcoo>^}dWfUsz+2FUYhbE$6XaRK;RN(jDM%s|`gX~a|o3T=CzdeXYF z*`d_q;pN>~k5EW6>?a=}e5w^efR{)r5{(p9nCyMa_Rs-tF@&%Sai2|~vV^A>tHt5d zBZ&HzlCt~8cqrAwgkk}opwKw))1D&bHE0jOd@*|JcLf($dGdScY(L z#8J*vN69SNJlfeOlP04|eSd17L&)@6W`G6SVf{g?U_0Nt24WWeV71I92sCPp6fkXg zd{`UYpYtx>*+-tBBU>%$^bJS+$T1IDcR6nHuB@!&ulqR=QwkzSTPA(wQHe<|E8_7fQ>c+6e^!IHE?+= z5wPo=(W_PZ@csfYO)$YOteb+?FMIX{q!yFmUUkgt*C&xZ^QW<(w{bIM?k9E?y8Fz1 z3qQWn{z$8GwxilM{vQajTBU27sdIKZicatm>EpAbmuF5+wAp)?SW?njl9|V!FJxM# zUHL@ji+b=Je=89|e%}#YE8-+>1)te6#+Mb4O&Z&7L1 zCoEWl)qCZu=fgd~NV7zak)@}{v!|CRQK+tsPilLGMD!UJ-J@M7nR1P=ZkDng#NnD9 ze!sSYAL2#z;FGN@3QUXnl=n4z5RQ$-fZL&n_!>cKR#c%!qrjXY$`uQ+$-YS4vEtH% zg#{iW+^{Pppt1>*xS8}0HFt({cT2v(JrZ>~|53&dfF{;!Cq3$+qX#|u$*0`>& zuHO1BR@wyJwqc*2gg;oDbVG$H2aQpwM^dwDHM`7;S@g%pCSNmW*nc{ajF=a5Z>Rzc zdB7~xugx-WCG8+dfYRec#VmIqZit9V#g!+9296QdReFfwdY1tgFKy`?aee0e!e%gp zRfd#CfobWjy4Db9VS$USQ2I^b{~oHrApE#nvK0&+_bQM0rb0W>k6292K1dA4U!Dsl zC+j;cl_Ah~_=vVT++Y{XZ@}~Wt{yO;OYi;mo{4~peET?Zzu%A)&ipoYR8}^IcfT4f ziO<%%-`~^7;Ot*5DjNSq#g@y!*?JAJd0!1;=>pRwa*O}e#iNCV9%-&6AZ5DCvA+$k zA;!@o6{rnz7{7uQVr#%!wu{Wur4pw!FXuj$DIO2jAHm+ybNTYX0BwSpT%2aMqCCg% zyzzSraWe!#6_Oqz+J45zzs-fEH(0SZo$fBBKX1XcQ6^-hCOWWcW(`EOY; zZvvB-&8w`e(5`U*DraF(o7U$j`Mr39M21QRBWgn~Y^cXt#bLPlY#?NBZ@i@*^RZYk z8DXoH3XXU7kh)LI#Q?RDoTb97o)8R$V$2~RP{bYnGIiG~#eFaItaG}p{4Fu`N*yi& zObw^NBN_OTvkn1|eFI+DxNaQp{j)x`CVH{`p@nV(YHrrn6g9<>RxE6cEerlcY{+?j zidW4}C`Kd984Y>1+K2r*5n7IS_eM#_i9;eNYFu&gr)f+(VpAVDz4N4aAr4(*JkWnw zYT9BA0Hm~8j>EN@4rS|()Wr~y7-11!$#?EoS%{qHXVbZ?#oIp5G^4E+&x!415tU3^ z^>!j{?ofmw;3dJ8Mj#`CT_L8bQGgWH5rk4yrGgrnXiMBwugv53^VT0-B-+}zUx)D+$? z=lR;&Qszn;9_CW=arRh^qvdd3_Kz*08lXa9#5kVHt;NZw8SPGMI4wKj5rB5H9~7zM^l2GQir!OXVkjZDWwT+Z;l=kG z4}qfb-x_m&T?|qP%k`}$>u7=nOew9LRJg+B5_ZS>Fa8?bNiBYUw)f*hF6?>D3Lii9ikj3zHga7c={3gXjF*3-rgUes`MjN9EjtyW&OYx4F-^PdnLs25 zyZ+B)_KMnBN^#e$bLf;aY=}0*qUYdZ;Sn=U_=45btxsWJ z0mtMO!)e&hz>fV^uQO{gP762R^x-e|1Ztq&;Li`#t%$v0E$XQMymU)eu{i&>9bCn{ z+~prP;ajG}V_rmsPY+1Zb7d%0G_#KJoyG^?e@6uLQ@odTylWR&^FcS@AG^vK3KqB8 zPEtz<_21V5Xt?!s?_$_PHRHhTq9bGf%9*<10Pt{44~=d;Yi~Sg?ucH^Ui>~jRWH;t z{^uFmap1u%uWcgdSI9l+-8c0vS2+z_x+4VP4Ln|G%c3EI5pvv1(4N~2Z8JU^xJ2i= zYw|K3AbwvwYyQ}RZ!^7*rrwwsUixyrWVKM)0Gztms-^dp)B2N&)aiO=hqD{_@xf{8 z#aWuf)F;^BdoBI-0bBDs#ddlvx+|`h1Mp^XcyLi^k>c!BwF}xtS(;-hqzbV*o!a6E zz{~gFfs6^o(+X@ zFy+r@-m9#cOv6+N+sxtQ?Wb#3U?R|TLyHC|8eRopD^VipXC)FeN4K)mEphQQQW?93YTvv&gOerGQ( z-;xWJK^z~iTw&|ILadbEBBCFjvbo#T0UFiBOfgbKHK*bRplTj%PQ6F(5*x_<39Gdg zwTs8H>l-!v52GOURP0A}fW?7E9CBHF>nP8!&K6$8myXCjFxcpl+^9=__6qkrZW}Na zRxc=d*qCk5zn`&RAts5h)o@rn=mA_Az8LEkGeOkzj_JoQekW5r+C2BDFr-!$ z9z~mIhKi3{g$%B9DTtrlE8@tCUCrMK2)G0hy^mIRP_*sb3_q1QDX*tMBb-~3*GCiv}RWkpPN zkZ2#@{B(Kyjz1Jc_L3yOKgFfwcqI8to?8{3D`rwAi~4zp50GbpTwKko|IenI4*AA9 z1DLOWp2@cp_}WIU$U59r=w}%8VbsZ}7Fb9yO_N5uK~qsMa@3)f(!3dztJJ$Ahh~)2xYJCSPx0o{5FM3I}>&aI5#wH+;QYK7=gHc;pbh*k_M-JrPfquR0D0@5W z(;H9c(RS|0OYqp4uGY4;{2_I%u??-)j@77m-X@Wt^5yI2j0^gh!!C(5VRqVJsPF{) zeHX>)5~p;&`3bjt5GjOm3Or6C=u!8c`!>GbN6Mw$Tp0URzjz4V#b*la8u6&XWqF)9 z6C~@7@{|rSuX&(uwWFhU91wcD>0+l&`AvG7uuN|VEEp*u6{(JpzEuWnRBeDd9Q=w> zHa)$nbrT-hsCMn=m*;2FRvTw72e}=j8=tdv5B{^f5r3MEXVEja@>O_F|i%ebwUyGB46!r^daSz(@xO?7qS++wmwFJfaYeGdAM?s5ilX&qRMJf9Zzk2!BIX)_L_~BEAa0?`IIonvs3# zuz%G2(Adp3#$R0`qCUQauB$kbX>4<(bXpU3e_G8_g9L%dD2~_tSn$@yrSXoK-W-vz zRw0zgQ3x-cDk{yIPHXefGgm{UPZsYv0jV$m0X?epV@CWX=F4cSz7juvp**T+_B#R= z+yHfPpem8V>&rM7a>cr0Nb716CSkhlFl}qR4{I$IP9h^n!Dp_EA1?%F!imBGN2KLL z4FmrYLY3~q0ir-+Gx3egl~n{RDd|X-c|RohUS(?-+=~U49s;GZ#Zju8!qnjvh8`lb zE|bQc!ou{QbqCpT`c?2h!$4Ac@JQ$*y(0&uGa(QwDUL%HwVWo4BSkdg*4-|33|wjl zMM6z%HVqSqAE~N8Z(UHmJwg&G^+YWE{B3h$)oWm=GV=+vO}*FC>}KOUiUwAkE4-$o zZm~+H--4>*kyagnNp{qgwAcWJ1I%d!HO0wVpFZOT3bB_G+Pnc-=lmrlF^3nqce+n3 z!+H`zfS^S{-6SO6LAGt5sig1GU*HnZxrgw;#g`}aa)QcmYjcV0mF_VunF>pZs5Q_f}0 zqFyfHn0R5fF4B)X3QegJ30y~P8tUvW_GnuSB+K0z<2n?~Q>4~+re;ag3^q1Gj%n%XX*!{ew-&gLN-tt9_R8WF)mLLZ~I zdX?Cl`Q)q!E>ymAU*mf=0|Fl^|KKE#v;l`Q!^Ka-q>y+F}_sgpkvuJw>q?bMyU>d?e;)>R)KC0 z2u}_F1HC(UpKWp3e*F8TMqwL#gj^$_s__B*%S%A%FBV+IRX84v=#3wu!_zXKE(3-; z=W|~+MPmMF%Es28tWno$ccS*prXgJr9V}6qh+ekSY&3Wj&Y$YGaT%SOqY>i1L|j!z z!`(d0tK|~^fr_hLQe!>dDt(_FaIZ3#PXD|#9&r2Ko>7J%hg5$Y^VgLBMn&7e;%`X7 zr`kO9DRfQvgC{>ZN$3uC*MTz{h0{GB4k`dm*EG1rlDmm+7Q@a$pJGej{C<%8QXL@+ za}Fn~E#Su^5p45-hLQ!C56rf@vDeRS2eq7C6hU7!mltQP2#c4&-`Xhybo-Pc2=ns6 z!!D+}x|9SU8xVMkOV|ybV4Vlku|FopgsDDf&S*;nVye4uy6Wja{j-kwjrpCPv2_~a zz?ErRHZeiz@7fVNJLNDoHsyRC%y%;hiAmplBYAuo24qf3GlED-u3aO$1_F_j0V$OK zrA{)Ef}uPTlGm8-tMM8dkugg-c=M^-zcGHrl7G8)?Eg|Juc?Ce_|s3qMDI$wTPfB& z8R&8AlI?kUa_`_%8|*WVxw#8XD-(BBZ>?6S>LoLY492V!&I?vVpOmL5 zF2=YhslG|9T<@R09o4sW`uGT<+Wp});2%gYyxeYtYH#Ivdu%<2_m7JNuVo*l4>j|x zu_!+UYo-tVaS1QTQd{4h-j!Z`9J${r8uOxE^>bS5S;Lt^`?H!SL+K?lw@pulgf!I4 z_ssTc>7=>j9_D-WN2|Cz7dbQjJaJpfmO>sQnKa@IAs*`z?hXk9UhqAm@iNCEaZM+LH02vH8U9c!{0UR64tnk#``#M%Z{-V4 z#!fShQm-+kv@4cSmJgqPf3M1Qww=Ld{y(bDGmx$JkNfUURBdV$wQDzKQMC35Y6YQ` zh!vyM4CS`>mRLoNP$G7Wwy3H^?5(I#qcv;PF8Z9_&;P~qcoQ#@>s;rY>s;sh{jTr# z^W)=vS6;V;y1_FVqZi{cC1aRIt(>PUApK)7n5(pog2FXyVadtfto~=NFeZti>_x1N z)_?@2vyg#HE8YJ^uwOlVjije$&BR1yZ$6a7p#fAnP-MVID2jM;UK48#Vx8|4CJ&PA zF)5K#{l!xX3%zkovvC4F>Bs#O_OUZ5WLqFOC5Sf8!K2jV_p(DS^CgwlNID&#PSh6 zJ3T#3nxot<37tG+B6hlJ?0!M$S1-m^T{4J?CphyK9#VJhZ zGkmXk`#Hd6nzBcgj-5s7+X@lgvAAbG`g|xRgKPhO#VY}-lR(h%$=SmS`t}TEPOvT4 zZs5M8zR23HQx^#+<&ieP-mnaOdmnUcxHegnGO{@Mnsx4!<#&0BivG@8t&@RVyQcEI z4jq>X&AQaL^Y&@R%Y3;l%DN+7s57!7?Cuy3sr1bT~grm$hEP`;IA_UInOLC*jcs+1(Z{DV;6|ac!Y`G z)c&uR<%$7qN|d3kwl)=5T{r9e9z;4OR~JESXi$za&eSp29}v_zM`pvtbkB6k*G5-@ zO|WcyKJukzcHcHm-G~{A0es~}hR4DiW^+$_>eUwy9ttNi?w&F({;X-wqAF`#+we9U zc{L}lRP%={N~S{9J~-bXp&(Ca{KyuD#Ube_Zm8_Ptzle7^ z670NU)2n-@q5RBep+2jNf#GYCu{esl%xn@jPHN2I>sc>07c|Z-40&28?nd zjIriDDJba{gl6UHu3M_p*7}MBI2k$kKD0lGj?SJ~M16RtBtSIr1-ba+?4(#3=++LT z4GhP29cJ#<6p^I2v{Ei7%G}ooUlVXz$HMDPm8-Xz3|K9Vx$1KdDgzaKeydRCm^Vqf zU-7)ZcF1g`YrEc1FSW~+}tt4&oz4Iq_ z*rCgCYTO9(YtW-n>2Epp3)^c)H4d}PYHpQP9~ez8gira9&KvfnL2rCo9HrGIjYD50 z)u_8T#FFI7E7Z!WX;#cZ8AmY;js#E}HCFQO!cF23Dd|VY>{z~NmX?t` zC-sNOmw1Xo!H{E#uqQbV9b0^*$IeXS_9HHeF6lc_<+9 z!LMI2C}O2J?}{1SM+J6|JZ$%=aR4bI?HzUAoAqEV6%p;S-_fzSVvBb^3s-m(x@Y`6 zrbnn$0~9U!Bm{!Z>a+OGRN{UX8QWV_nn~+>zHD*%cu_YhS1y~N-Qa92+cTD@L|sl^ zS)f~Z-Dm%KxDoa6iV6R-M+p_G6%<&QrmRZVlymO;Lae_~T9d@cm?;y#*fYzbDblRz zZ4t*4?iKyG^ti6c_5wOSo9l3$XP&z@gcG%LG#@6piuVs0vGAw9q1WKeuPfCr%*J2z zJe4l>Oe?k)QES-l3zH*-u_TDt5BB?gjIDS)rz5SvSgMfa=HRn0JFB6;=yJR6Xt6S; zfU;uUUt&w)-P57)Mx69mpGwU7FQapXWkJ;dl^E>w$cC5EBaQ>{;sd{7)N8x!XkUg* z<#JN~_{TAwpgTSa@` zRSRcKE)!2j_hLVN?9EN%HpawFh1F|cQb;N0z|5XsaQkz=gC|!OC5hgyilf&2N^92n zRW%$6a+y6XD$Q0GYx~`N}@)!9!M+-wsbH(&U`00Jt6%gT= zc!L_teRHe62Yk`-XMy0&gN?|cOD&BtVV=6J$Vi__P-hG)in(8EG;1_g&abqckMCV9 zZZw&`(tzo0_P%4B!_dVYDMNu+nmDLuw zyL4r*2=;5f_GJ}^E;2oPN=JuWr%zh_ zGa2jC7|R6SWVt-;c_0w^wWtWITgYTd*+=Z$1Cw%^UAI}ke*Z((S8cGW@Ul|c!9_j! z?cK+K4Tjc?j$e=7{LK7J4lOa7x!=oGAI~h=yZQ1d8WYf%p3-^n zf@^I97D9Z4lA%|byKUosCpUz6ZG?^8qr8kI|G@#w)HzMuaE?|k-r#)lbNtheYxft+ zch5(2>6gKYuB7-<1@gOv>&+*Ie2bOd{)ZES`|n=Fm~d!FpS|bE&W?|J8_zO%O=yKc zrN?!d2zc$^KX-O}9VD24U;Cv?eZ5XkF6szmqON#OwH|G-lGZ&+o4TZ9-r;G)r`YyI|@(FN*1(c0dUU?7vVVF>53rov=qnzjh7GF4Mn97wNJ zI-p}5w%KNz8FRM%d?3$5t%PZg=A9D;XBtzLD1=~}=E`wO_0~zeJdmFsE7nW-A}a~Y zEQh-El^WOR`Q02Rj16)cDQ-_&?fN-bGEUaV7+wYYtFH|vvM2&YEC6qY+G}s+X_)Ww zmLjs5u*ve-AiMn3Ink1py_fs(cUn>fM{SHTN!(x1E<xhVewPEN7*aT@qjrf_ zqL(la13Bj#m%40*@$uCvm>&yoLbM34>x{BUVaNA{kBA4BU-QLUO4kp@!Sxa=p0+pHfeN$C$K z)Y90C@IF)fYHEy zyIo%nH2N`@F*CDHz(lv_t#SOjiBPf7Ez`Ha#WJf=xc7RqFpB3J{lW8ap$wk)^z1L5 zzZwofsc7h>m&%1JF*b+Eln9}P0spko`h2R7PMmE``lRKWaz!+bon1&3 zqHP#9uATap!GOZPEL+Xjerv-cbo08w8f-7;;A+~|y$j5QuC>}$;*nA4$pUEGc( za+T|ygfP~LHWN!uQTm1glA5&H^V*VvVJ}R0Mb^&|fWvsJ?GLWex{Lw) zIavWsIwZkT`8oga8@)Ma{6(1X${dqGdUIdy-F}Ccc^Yj2BM#h1_C-(iEk|(An|`Pz z)%F{2CC+Y>pEY6pv)VH+2s`3mA|iv~NpZl9+8wzPjQT@HV?9Q!PsS^ar_M;K0lvLA zopF1$dPu&(*KU0J*^!`}9(0r=;d2{>4VYfF{=t*ELhhs)U(NOngDI*EJn4S8(Z-kq z4(vbmaU+18&rravG?)_9)0XH{6}OK(Qj6G4uZ}S`GBolx)=!5J3JML+DiwUq8CgKf z&(WH3V|(LqwC^3Z1BBn&tBze|XQxG><3`BUf=rh6W}caeq`wp1#!{KxfBQ;KB+T@= zN0VBE`o6z>@U7?|m~%K9Q%CQp!%flZ_t_gRz_+W*w|x&mrLQ}2=JU?N(#fhKa`~KM zd?h+Z7##3rEMNCpb|lV37+jb4pP#>g*)Fa7CW(f7M z@UYI;Z-tQRWgv2ONpSX*Y|?m|;8jnxeO~qL&IBX#``C-B>O$2c z0f|l|tb{iX7Cgh!Rx*;oR~(?C^L^~&2vl-J&|8UCSG78)O-bRI*(0V99>q6?=PIRS=K z&&8-5PSLD}+WVQ|Pr*=!bBIFZ~;+IHMh+T|^X^OE^c!w}4YGyi= ze`#TuD5T-_tB*WNJq!*ONVIeflU4({t)HY$#;ThLdg=?l z-xYFYDZH|1y03>e9_lnU?x$d=okM@f$5WQnk>Z4~SNM9O_|g_vq6JB;>P5{!#XS;L z9&*?FaSp4h{h|)VVowEwdXaIQ;Kz?>3SQv#>{1U3p3zq38^P6XNGJPb3t(_0mUNFk7R#p8m%WR zoR;h@SyWV%;w|l$>;P0|xCXfLUIml(4_@`1#}kWgL9g#-H#SVqP5vQcD<~DCT>;zlK8@n3-@Ut`L!TP? z+=#kIQ(OH+pT25~5R#Y=>bP+YKt+@1A3M|}IQhA1ibafsBPxFClE;xCuj^- zr8k%FJSFU8umi=Ng&-tKgBdGj_Vv`~ZvG?@qMx%HQt*{#w*< zb{ri~qjL(iI-khnG(E!WXNoGykKXS7KqyG|v%asy>mN6-mJ6LJZ-`+T>^UEJrynY%Ydi?{;~B`|^`LrOaHes;R1L-% zh2f@hgZaT!G$03vfgk;yil?9san=N6z3<}+jAn;FT8n*vAvouYwrSCajCY4Jm}-hH zhNUlguuuiTKA>&p!KH|m=cJ#5)#aBxqQ635tHbQ`Bb;_B~= zFS|mh|%G-lATkM;}jSB4f zLzN`q$*{X?|LklyrX}i^f~JS5kG1a&%`sts|+hi)SKM z>ab;3X;!gqqLcZE)cl#0l+(pC=D)aXUZyrrAlv}04>T+~4G<%eb~2pSf0taNapDO+ z`NB5d;t#buXrlO4CXy_=_^y~j^4eTZ}jG;&LYeMEg6!(YF7DG8JlYFGIVo3{U{?0l zaZn#3b7FF3y0yECq&u|?(7eSx^_}I;!AWoc7XzCW{fc>-^FWc#9?Z8?r7T^lW{kII zVDVs^D!)H4do2G0OGCZtw4e4*hcbWPkYa7*h2$fu&8%Y9uf-!jU$*X~rW29Ge_uzJUDH?W;k>G&uqG{ zOgje)j@QX9U^=-jT+!?F^3~FIcxF4l zNE(vQ>b@a@2W;jLlcssy!9ks#zeI6ZAofm?ep(tg3w^t^BDaVLDEZ6C4Y9N)DOT<$ zSN%>Yj3ZCjzYo>M+n&~s5*zmJ-sa-QN6^Z1(?_c^bf(MkJI4uEHec82639^*Qx3da zL>O{S>*uX_l&`Uc^OiW~#n|wfdEv&tF&UFeJ2UQhD-Qf}o+X795x~hhYIzOUuutx5 z@X(?P2-4cAaSk9PKh?k`_+x5*JJq&&q8}v4mVucRu^Mc<+M2;Ua4PvZ*l1T(Ut_Os zPg&DPy0<)otsT-C!B!W1VgYP7$#q63d$>mkh$RHGCKUp^Sls_F{{z^<`v3VKj~V~l zvjXrSSIF}Is`p-;vj0V32nZ#cmqA6ufWKWH#kFw0S>QiTlBLBfE;krw54dh^E5;Xz zv=ch1OPQW85%m_apuI|~f87xf89^BSYK=la2dB^Rz=c2$F-SdiV0RAFt{qGp$pRQq zwU+8@*G_J~;-x2J5JisLk@N5}OV$@Auw0~WCpx+Y01)adhjZu@WL!r(A;SmCQ z&kv|tMY$#d{lo!r^$bGC;hYI}m(rLZ5}AD!d6rg$&* zrzPNz7J(Ym#_fh6hZ*EPJ;>!AKI-jNi5Dc4wX^gw$2f3P$0}`D;anSUH+j5WHcYx8 z3!wq8FgY(ZDH<{T-HpsD*{7S|nr=iA*~wE#vuE(FL_2`bQC>zL2e1R$ehL8B3JRE# z#VG3N=s6gsa62!JBO!giTvHa+_K}YEW<)o0OoH(Ad%sPZK3Lnf+l-R&d;&9e--me6 z2b8iGBnig@g1O_m1>|JA1wl!oxO>yJ965>KvmmHMr8K-z4ADMLg+l?)L3*oFGrlGW zN+Q<};cdg^X%)L6L=HkkL%fgt{Cw0_Q077Z-Tk2Xqw~7NMl0KC`w6^+>6XkYmb0?% z+=B~BMiaBRme|<(t`RTEs#20ZEf!>{t+seBTM2B#(xT23L$c3TQ-VxZVtODd)klgU z7Jc9*WAcfT(4=e4SyB@aj3j?En=$QY5Rxdv#tppvo0=p3_4O7j>N8p(gJZ`To2!F^%D^~N z;&p@bRa|7M>owgIEuOGEnO{|l4nImnQ)W=EO0>fNP#*#h*?M9~^T;1EaePfg87O5*mFrhSdWe(yThkhJQzd9S;e@_W zYix`&Ruc+}ta^KMgP;;O|A*{{0svx{W~s!$Pd`c)M{V=`OqSO_8~=`ke0-@k@J zqZ92!glR7T&`udJc>)h(#|aB@pZ+fpp!8xtWldLCl@<+r3&u5w3DFLbP_F{!6$%}T zkS+D|ziOVpKj6&1RG&Wtu2pdebTWN4r6;ng#5D3Rpn>I55rsMfxJ9~s1W=eI@GDIK z&G2`c4%)hy&%VstgzCF604E5{w=SY^6-kH@pnz$tb0(+&Ty1zr3L1364__XIKpjvo0qIu$-C!|l(_!gZpK|~scX2ix}=^{M-&4>o!_1a0Q3^#PhqKJ({+b|>x6hR zbTX|%Bmry};7ypWGzkGDku@hQu_+G9wn2{jl>N8edrPC!m8P0<_j)*0Jo;D z)6wPLJbyNSyg60e-9(UF9coxy3%44r0mHcJA;#v_5~p81_rc!X$r=p~B!p375VxdO zJ<#~3;kh<2v3Uli5I*Y=miA7L8iHo_w^4_hC!3~OWj3<0suVYa7Hry(z>qi>-U0Xr zW{Gv#ziA>$wiE3;_yDEd-C&7dpfQLAItP*4D$>*nYD)#KYn-Kp?nm_$b+XAu^PzkM z6b9JCrC@DsN^V+lgzhAK^}ANT(J^&mmViPtA^m{#?_Z+C{|4Utmnz_Bld~{}G~1Gf zVlGdBIx&EN4x4tRgnh2id=_RuCMIRHhTr|~4*osTClMw;-DoL_7@&+AFJ089#iko? z`?MDQ+Y(`8a)j;#%FV&5>Aj4kVC0BU5Dc@Uo=8ft)zbUF2gGt7%L=*_bOg;4xFYD- z@V|Zx74qvY6E8z4>roYA`k)*kbSvUz5hYVQfc*(_;=XlseyqC!54(4;j-nNd#6FR2cGO9-}8b7FFC@ec5 z@7-6rkuxd|yex;^UCEf>5;5r{XrLwzdUAiXI}#=uO1MaG1Lg4l1|*EJk8k_q5dYD* zh6aAU}@O_shS>v{%L#k?p6?+VT8&PZ}|pkvDp9VA}Ls{Gm{HYvi|6&Fd} zO#q<24g8P64`rejUg`A}ZdqNqlLCiW=yzSmZZsOp*>dU|BsVJt&X&F_vEKqrf+zQv zo>(VuyWv(bFK0F_*xg!Pb3rb!-vHJUK*$HoQ3m3|os}{TLQkgWHfF}eJW~V|ClosKWbz<$E}fU5r%c5j zb)@&R3weFB{OC!?KI0}KPy_)PL8lmwTu%h}^|W-crWkLTo>qx;*P*wv<_p+9^8Pe+t)NjJ z#IMOpG9JnOJ|^=Q0A@wyA3Eie!_s@P$wxejU#-)s)x^B-&@-?Hhg`LWn&Gfk=A0rB zCL!1P9R7Zk9v92L$KfyF?w@imoQ|(Y-Vu=EU$bHc+qeZ>y8F5yH_@M_22QD1&o{#_zbnwX10$?kthbz(|VUnyOsrcYtCc5go7VA(5s?xl1 zu5KnP2a*2vv-WL-tD!s=29TegEoEcH-0g|q8{ZSEReyX)hE7XFS;=ou6wUQFK)HcA z<0t6%SAMu+gX6&0y2QzU$*$D;w`~K^?TL7dIy8&Nt)UJ!cX^zt#h8Cop#&YF+8mHO}7DOyLrX|GB^Oi$rX?QsIJr zKsi(Tp#!?M3A`wq_xYcr=ki3H?!~YlA!n-Kl#uLw<7k|XPFv+p5NGqHM{qO7y(f_A zyWPNrvqR&DI*%u4Le(=8t6KM_{ZR9sSF9d?F~|wHYGL z4zGsVl?&v!JrB4HIQK@?q%#C@?1Xd_d9Sw8&^s=9DoZTek1sGJKDTb!gAgU|>|aWM z19URVs||98Nf?Qbou7mU)vE@G%ev-iHZtCQT6cIV)Z0Dk$GGE9w)&&`V*n{scZb#d z@nptO>eQ%A?QQ6AlU354xFnMH-Ckp$D_3ac|4AefyLvj4kIG+v(XkE=5lWF#-LDw- z(dV^&@bV#aAG*H>nFh^Oi(0zm;)k@v#9Z&%eiv(~@ol=bO!+e-O>YtZ!oDv))9c%^ z_rptX`?4$T-cO0hl@jZ~yGh%U=HK%EkR?C?I27*HCUo=)ekyk?MHRwO2zCK@k7QxS zMH1*7>!yC&>FmLMF&7jTQjZ5^hvq?KFAFZ>wCD`fTrxj&1=+NQmRYwqCoo$<8S7G! z&_Nk5Q)$MVLEc%CIU=rbpwxpuC@L!pczm2~$3!jGQ!d_3cHBllHQgiH#TD!cW_J%t z0qht;{hlgq_%iOUO4ms!+hQ~4$+jHYR1ADlcV)g0y)X)}P7Y!H^UZ;bLmBMEKH@-l z_8+pGxUO?CYZmXBZm+TEUH8jZf5>{9Pfk_(%czwVa&>!C%|9}_EbEITF@J880B7%; zYWK-g11sPt#bJHK`YHE*?qtzJ96uCq&JQSxBZse%Dcs|J#=n!1@8R1@SyhyfKwQ2? z@_=}V{j_N{A_8hs|2DZ4p&(X-ah03QmG9z0$)nSW9b;3?cP=%>8}(%s744OHTmj9m zb;}GW5zo1>@OMq>ECbB@00hH% za(aAU)+bnNT91WyC|G{*NqQ63%E@FlweDfdFz(69%200W-hM@TdV{;9T^>h_R*-w! zhGk-79nuDki~I!d3J#4f`x{OJ%US4Om)rPcSsA`$w}q{OAaYF)X*TC>8p$oq!4O1$ zG>{>T6`eay{CwxG>rehN&8enGCp8e`lYPjzmRL@Q&8C~B*Roe8s%c>FOwe~ zRl-$JwE(Xq`1zqPY)Yd-yYjT1*+kqg3PV=bJi{xpn!w+)D_^V z{Qb!NUtemP%Qzsi3buWi%A%NWr6dF*T05QOHU=WGc!1nXG$DLP8c0wW_&xKijrI zqs7FbUKQ9`{;Km-vKqj`3NS@UwhFEjmH$iF7n`Ij<^s&}|sV6_1X#z}!JfJ9_ z{-}6VH;LHoIyuqQhjg!JGL)489Ici;wdfMf`8G5T8ywj3`UeNrIWy@4w26Lub@Hu*Os%YcG^aMJ2A16&P%ZqE=DWYF>@-v{CY z$d~=+?N?b1`E?=q0P8||xT~H84ueHH5wo~{RVyt2vj4=lw6AwIe>DAW8t%11%HrSG z51c}hy?qRvwvP`$?6olg#vIP#L-Q;>o}##=YJm>AIoLRXwKBqaSWT4;o3*UAfcRK#S?90}@LvII*cu736DG1>m5s!NBxnqDRK|4z_x4Nw z_seS4)7NJD4MFtX+i;TGGY=|(9>w`%*7vemG7tB}tjx;u16?_tVHgPHO&smjNJWn8cEjj;-O!6qXjjb%}OgW{!FnrtQ0=2Q&bP<2gVM0X@Vm za8W#Cg0a@oCE8m69wY3-H!gGn0ESEyRznz!Yi*y$vAW{Hw}D7%;2xwXQB>H_rWp?b zp|cWF8yy=vF%k3N$^K9O5~li$Pu6aBQW&QKNX4!)S^QKG8(xzSo+oQ@47N*PazR6- zZiB`t@Xxj)>cy8V)N5ZqSf>L9wn`4XnqI&U^EhsYH$X^zbOH0R#18t$94(@x^lkvrcJQes;IM|5+y1hkhZlg= z0=bZRAg2HTmbOD}5-2O{&cOb-K69};<5I=p^s&b^&=d{nYr5CkyvOV8=dt87u4Nkj z9sff>#SSzK<~T(1V4Zl;)7D8HH3y!X2-v`P`8F&o4!S*&JH~lDudL)1%^JikwzCMh z|Nrmds*k1{+_yB$Lbk~Odd`;tni~&a$)xO7ON(EBxL1x?^ksxZudYa3mml z17sY1nl6!F9pj#tK!j^SFT7q<=!GFn1vi*5B9_z98`UshI)C~i!>`+IaEK&?5!v*9TN6fMZ6#2 za3(@4v7+2zUDnKCxr%6S&^l|$(i@*Az}-XF8ZzPQ?OB#rfLaWTCzFkxzsHSiZL)$E z3=s``j`%W{+?g9WZ}b^L5u6{)DZ0x!vvp6{Q5b9>bhLyO#@-VrBD_DsP0`k>QjV+6 z1$@niO(Ih#ErBe+`llB2oQXyO6{U-Bob_}gj1$#vN<>aU`9p7(>^(-Tu$}%YDQ_;> z3t`0tjv}BmV;bOxE%+sKYTbVlOJcjM9VM279Thl)ze)DBDpXwJKE}8gG_oP*FPg3t zh=DT)Y%9$l)7D~z&%`$UvZ~k6m~~g^udKMW%)AA{(#_?Xq>DE4%ku5wj{Z+xo82|c zA70W~^c`AgVIrJ$4<=aS9h-2hMB?Q@tSZONLIw1u!`>o+-7^UJ-DE}h$%2(pR8v=( zG~&E=nX+mXhWD-V0`zI;Uk=m`hhHHys08mW--RVv-{56cEt0Lvf*T?2#^fM?P}^SI z0gqgMv=zy{J3AJNV9vTz<`Vy*=(OnVKf}&4D>a1*2$9Fwr^1es%TU4BhdqR>|XZ)KKn(zBVrn)+d6rD!ciCVV?S*3AC<=sO-uU+N(1^9hW zLjm?nXv!Wi<#8=N|3fzT4HWtV@U{YE>fHySS8v4nZSP0(tMcKHpSOJb$z^ZQirV z`8>EAeM4u$NvMPp2R*Q{3+xA_%3w{eLMI~{R{xE|sqMiPzVhC|e6<@9ljN%b-&Tb> zqvCrFp5?B%7yy)ikKwf#Et@u+WvUQz_FX5p{KFc3Rfsc0czZ2MB)Wx4Kr&kJ=I*6| zARUCi;#{P=obAI)im1=uI+#z8Y!7}bSE)WYCD(TrXhbWrylUX;ls$J&RD7R?k`1OO z#95|hBXZt*AAOs;5J_E&QJ+DmvunJEnUSlNu6k|TR4~2r#62cPx5TeKGUsqv?lRTH z1&2yTiRez~)lcEJBUG3t_>C5{)-5h-cO1UjD?Nx*o;J)s&!^ki9yNo9kazRLCpslu zBdKV3hEL}&G{T!KpI84&?wkIhO35A#@P(cdh{`3%@lvl}_;^$AAok;Eu0bW;=g-*HPynR|*ZduH&~ zai9-r*YlVhQy)baQNYslrY!8M96y7W|1pC*K2!vTklr2E`U$)zB-Ic4Ag*s|9{;!b zk?C3Ll#HgE4)zv_ioBD@tlDb3Q-^)=m(s5Chl;sI}N2z4qPNgC3wCx zqGjk~HG!h>ZtD0z3(GhpuqVN(kY>7;89|+s+GlB#p^mkh;`X$`de2Gag*Vts1t}kr_AK3!hv3|3WlB)4$v4wltxmer!|j;D3@&o8a^hi%oi0?L{|$x@Ddj&0QMspS9y zSNw9Mf`W4L)+#=?*WAdC^@T80hTtt>(bwvp{&~d$2e%{dNivjklJ-Mg%=(yg4i^ebI$-WN( z7BRx24s1C~CE}dL+a;cv)_w3E6P?(}yDvFfUtcsIQ&I+!8Iur8Btj=A+~t|zMqe>5 z7Wx0uMsg${yV#HM08wr?773jYcO)XAXt;Y%wdIT#1Xutr-wVz#^s*vt5b}fg~LO+osd2#C$yX&LL<@SN@H%y4!hl_2YOP;wRaq^8o z_|`4a!wdoI(^C$!!hXWjw}_G=jwWC^FMl`b!ZV0|V4J>^!ZMb3hITEYJtk-_51c-- z39V3#NMNQRqtN2*+j_oZFR0ZeB-fste9RSXTg*YXwtb&=EoHEIR{n;(!GR{7g{q}{ zPus86m48^ZA5Uq`&&qks)$gqQ``L8@3oy_2N|mVrV5z$#Gp)=DC{sv8+@nq>$U8rE z%Z}W~Pt#cFP8p4sp%%EM_x*yCTPZh-AF+|O?MF78_gO6~mNp6JmeXoIyF&iHO5y80 z=e12geDxgcgmzsTXgyN_NB}5u|H3!8*h!N?Fl?F96Xt=OW^Yp0)*=wzX$~W`{r|=K>3#B5K{2Gt@pa(4%9TD6&~ksfrjomruddg_X?81M(b?SAZ6(}sP2slM z;wIk*SO85Ym%H}@f=tpf@-kBA zY*6t>pIRQu5Yw}NoS~82Bagl=;L0d49AgfKN&c(aJ0<2C&<9b{&>oHCa zbFXzoa(}$eVq0;C485uPl;Pfi`DK-rk-NX0^9~3spQle)u^n5cq(q#*dwzpA3G)@O z?0PVPvimi8Sq*uCE&XxHXI0&9>8-A?hC&&Px48tw4VS0L)>7R`w*vNS7rk8;8194) zducHN6E@+z;EfSr?^EO^?-z@H#wG{n$l%DMn6s0a{^b%Sxsu~3VvQ&10el6S_o<{5 zsouaGd4nK_XFD&0W(KZo;iLHKj^Dw86yMaJ#An_68g2YtR4#40HX zOMs6qo(&X%8b(DDIb#jf8y7g?*>f4vb8vn~gPdqkidps#;Z_BpNY7!Q_Mt}wh+qSY z0hcN?0wsX9g(e(rT9qJ5GeXqaN9S!yX=^EvY)V#sRoKQzW=_ci!-JxezgP+ofTg(d z&y^cj$^Q9ErTFI`K+$)Fj+^%0Rr&{@|F9Hx*BE%cB%iCMg>~-M?fp;S2S6!ycTL-O zIB$Rh<#)Xf@JiXgg99G!yW#L-#L@F6*pS=Bot$KJ@P~s1-M*2eSBG^PuQWr_-^IB= z%ja$lFE5Zf3ybtN8V)j*F+Zznc$S>jULIQRZ+;>g6sANdzk21NoOA0VetEG%2~iY! z_)elK2Wqmu+;iG-_S+#xa{- zmrERdFV61T&N*$>!!Y?t{tRSLzU| z_E2s{fk>ww4fJyz^f|nk8B0<mjzDDILUwl&dP9DZd4jGdMYw zr_)1{1;6pnc@B+QgD*HAJ$hBh5WjIhuYc|?xj(5Z#X)N~p_|T$+9tYVi9~#N7R<%$ z^eS-swTHyH{h(BTt%SDs+-pNO)=0u1$JQme=0iDs3fbWWoP7?7s8|k_ z1CEJ=_jQhq?Q+jsLLSsNQ(t^0FDia=3BJ0R+CV>Y5e2vFw=Kn$9OCye0IR;QQn-Xqkq@qv znZYfXVqoD*n)@Z^rl+jB6EVzU{!&uEQR6{2>EZ=v{Ku@DK>ca`v*-R32)#BkyMKWa z2th%&H76_B`)!9I$%N5T9)fkM;|cw>DPY5&oi>%jC)q#+9;lsodRbms`7+5@r(c#T z?6oylX|DnEhnQheF&Ufr#;t1vEAG{~x^XJ9-XRXeM_Wlx&h=b+*e3RMB&VJgrY* z&I^V|Fz?=htG!^fOC<*UWul;Bus4Xs)Pw4(lP#9vuZaP#8+gDbY)F4cu7ha%9a>wG zHcWdbqN2)l-d>@=2-eTfhJO$kjgWM?qcW*OeqE5`*gFlwc_qTb>G=1t580XS=>i(( zt4yX*orW>*ohrz))}w-~vAP^HejF-DfMJq!wTt=f)>h6>t#x5Cj^RTClZ*nQ~@SU@9sk%w~)aoSTb>ag}LW?5_hTz^$iny=AfIq2eU zbwNUIatH>sJ04%&@f~i+VvY;zP3tUc5qMwo+`xQ^OI16Xq7eRzbl=)mQ1eSle5b;M zk>El2xr6&bpQ5v!cjaz*$##&y3%&${nz-wuON;!F*q>#tb(@h`!@pZHA7?a0`-+dM zb-&$!1qwTh*MeUb4-WN@_P>wU$0{+U0XNd*Iozv>_6KUwAY(PyZ%=(X` zlQ-J4`?_LnQ7TKh&Mbwl0=Ik}QYPxov)s-v-S63!klh^o#aox@H1$e^cF1?5=3R1| zBLu~-`va=pjVX8cItn5XzQ8G-9h~NC;y1yIHdQ|SZL@(wLevsnR~(ohP4TvoEHC`H z7Z4M~^Zip*9HwOvbOR0gN-C=Ck&92Ue)}R2+77s{27bFj1FIMFogFD*#jR?DU((w) zqZoko<5r61e-@1kY8DB19Bwi8@53oCGanrpXM6pSB75JXz2;tz8G<`EP4~;t%hS%v zujr||JgcfOu!19vZThlUg^qt8p1S`J3u zL%F?K%Kf`O+}%D;6TGNaC^>&ibzey#kgD)@!R~|HN#bB(k2QJ7PV$^33_X0@oY5<&J*c zPtm6b3X7ZIhR%+kf5?Bid>$^f`Cd8bS^i~Xk~%n;f$t8N7DSplpOhwSp+2uJ=qX== zW6Tq|3wJA0ueM%U;vo_gfc~j??2(CswrL)riuAn-4Vqy5J|>%fTGmWQMItJXoTfdd zEI%RPvZNH49|bXnTBQ<{613QJiG#(%uRhl34Cy*B_8&J#St}cTEIaGN*X(_CeIxQ# zs>5q6ap0+@tiN)ek8$C=EyXg>1qZS&t0-Ew8zcQxId_3t z^G~MVpEQ&9vtch3v7Dtxt*)BNsz=gKuVTNC{;b;tKmousq;2L6ZcR7( zlbEUf(o3(d2ywN>6xcT4DchvTR_=vbQU>q3txvL6!{qXwbzemlYh>F>=Oowpq)xf< zaDPGm^!?d~r^O4P0XX|JqOA!bYmh%U3^H(IFU+^d-|*vE-m-?K3rt zLGVm3KyI#3+X4XjBR@*duTaii%ko^t*KL4LHC!{*VMpz2vF68l>v8iY(J9CLlzfK- zl{)HZIO9Mr(;ZNI|Az<)&?fc4ahbum^KokN&_ljKoU|b-F1f!X)WMZl|E*@GU&%Dl zX3qeAbZP-nXIk6(X13iXH)wea{Yi1jWmJ%%c9;CubkLtUr>ggLHRE zrQ~E<-vBF{xh!(y13lqDwfpDiD#(A)YPwC!wxF3!=|mUFnrGpD<|%5J5SlhOx5HL(vBm zK*j`ZY|>*RAycy}{-m95M#r9MB5V`qvJ~w0FjJUzPm7f~Wshh+J`F0`Erx$0?u^<$ z6$}~MY^h)wk8EP>d<%&UEl-|gj!BgA1vw%(cqJjU_1Ld4!&p>2iQB>8~74Kxd{tIbdnNocqbT`~LIOkXK#a>$H0bkl5DuGx*?K4$}ID zE}NZ0j6mtt8K+X8!SszPUTB|Zc%x57#&EwU8+DD1S}BK0hL-i-)Nz|T3(OM z@nC?mV}HF?1uwPgs*&sM?SFlkh5Be?UR5bMhXtphgJ&eUo2bJayxz9KfC{ThL@?l} zs-8kNWwh_;=T}1^bvjzSuRe=F%hYcR;~AoEbmnmC+O`aZ z*}!6NfzO2PD9;*CE~QN)Bwr7VP_JnMJf>tCnD2sq&AMZ_T%H;#$A8x2)jo zxk8-GF1D{#xs_m^{I#7jQpMeI#{)p63LCzCnh|&Qd;6!sOUvjmW`1?XMC2(Lt1r!U z!<^>}!T(tG@LojSY?ZAqceBBXSB{x|P6!pIrcxdI9y02VOxdJ5^`*FU=ZtPgQQT=#8znK25zjtfATs~W_Hg;$|zq?|-5l0!eYBpQ zK8~WTr)2lY^OL&M)zsuirnD7kcWHwMRKec8iTNMswZU%EBSmks$kF6gt8wMZg*8)yeLLWyOuabnRAy{)XoJ4Py>| z%@fDjA|);DaMulI{Pd{^@!!V+AC{+j_UnZPAA(Z3k%q5$cRx9tHx|Awb&?yYsd0*6 z%;b;TBUlL+7peV$M)o%muu4d8d&6vXWN-s64i{BzMtXOtQfzWu?c=aisO^Gas6uYV*6Jm*z; z62e@7lG1dbBXs~{f}V6OfjqA_-BD9dPM1r$`asR_hWiJr($xBd&l-bhlBoo4lixm*NMruYuk$EaNSJB zIN_dtZhp|!9XXC|PNj|0LN_^q*6G2pzA5X9x=1{O^Pj|s{FXa>q?x(xQsFISQ$1CE zIfF>F_b5fCSfru_LhUxv)HYcxdPs&dUdNOamwxJj8s&$Wy=x+Ws+3$Y>Axp+2>9CE z@Q}6zH*d-#)SI>>yu!TgOfk?alzdVTV*oerx=em^3Lj1{P0N8_PK~x9ozer+QI2S* z-NJJ3y4Le<)(&Ec_uc=gWB2ocy9MfU!Q@EQv68t&1g$4Zo*s4o2_L2uf3y=--+Br|ocOC`Oz?6%$nM(6 z?_+hgx8iQ>b=XJ!KBj3NhSSdAj^{VT0<6RmYQg%-uT<_!=TBm`YDmub; zq+?J>T;iGh&=>HasJogr-O-NQoGn+V9=%t$9<~F_z5(@Oi)mXvxg(f=uL^}q7NoKJ zR}He3Z*VL6?YNrK*0iF6 z$`O-!ytjAwr+V9!FPC-$*CeT4XSe?<&v+I^YGqqa$_}mWj*QmwAxCGi-WJ@&BVz5C zMd`prvKK*_VV|p1?1RZeGJz8>SW(eXlNeDN;G@%q{3B{kNkLMoEr@ZxBM}s z{1I_zw!8IUXfcgtpbE4ei0i2|(E*=(gBtDUGnEu_drdNRkP{KFM2ul8QH?pceJyui zVeEwQn`R|zxN*_pg}J+Lni3TvRm!8U?U-DqqtEslOpXjlzn?;=_r;luiy90MC9^VY zZ3{BW)s{y7MHR0enuv;PL?3HNQ4zOn26EyNZiQwS(@Uv>{E2fNZ$Kq8NTMl)9E>xpLdFy^v`6MBuS+R?sV^H* zuD_4n79&SAeeTLKkJHzdW0!I?vTtlJ?lN^>^s#c#f>09BK4e^QFZQ3>6C!82GfxAj zFqNlq1JOzC^O;H4o}Ev$?J&Q@Y@?za?c#sHMi$ltJcpPf&`*0LlWagFW=^I-Jp&IV z3zP70Of8`0=6q01Nx_6DKcv4gRG`>zs0m!2T2mf%wSZmZMVhjcbRf+o)E3z^J$gw9 zIe__<3Q}i%X@E+mu~WexTnZ{5m(Z$8j20%KZI)}kO4E<5loj}e7sy2x9J9+Bw|kfD zT^>EiSSGi4l(y4Ln8^ql&Lgma+wu%)rczbuM<4U{>+={w8svT`48{McmC8w(b(Xqmt!{@eVM247mdL4~%rmm0X z`&+Ds-J<&60(o8IJNMO;;+m(CvsV-Y_vOb)CE&!4w0W6kxcms!D~y-zP|JTC%Xt5D zO~KIbdG`_;5$6;u;MrZG0UMa5^&IW)yQ0*XlJyDWU0T7XM;2gvpCJP8oep>vab`Kj z9cIQ!MfqTpe2mOLjPgl(Gl%z#-KPx$cnM0{1^P(c^}4x$A<8IIF)TYuF6hSnG#Tp; z(+NgQbgXNMu8+*O*!5k1A`Yn>(?<2XzcD;Uv7n?gD8 zw6p%Gh&`3~DsE@d2adaI@`)2d?0U&;+HMn{hgVe%$y3DC=3UU){J~tQ&Rs+$BW}kG z5iC_z2O6V3t*!D>Vybm}hl_%t|8?v`E@a(H-oMm(!D%f?*V`~LD~$JOVW!Za{FYMa zN{)`e40W@{oHG4ZWSzZ#(f9AI8LT#R2KPPkb)3$wL=21YIk{P(LuC>G?bCsv@&n@1 z`pNSusFu;e`;G4pA+>(tX9~W!e^{H|G{iW`v0TWu8CNdwoF`{`|N4DwnEy_rPtSI# zGa3E!_c8IUSKjgy?hSqJ98|^a#B(HKBpnH2|8)zHf7{_}XOd8qC4M`Hz=MUD!FJu+ zuX2lXjaBnV|LYfU6Bm@mtWR=#3;D1h0^s*Cy!Je+T`Qps;KNeu9N6elSuIy54koMb zK1ka&owXmLCLm|?J;zSO∨k?a2ewRDwKiJNn`Wnr4$i?u;gebJNe#GZ&OQ{xwUG zgw1cylT_aB@9>8>gydLkDHYeu2Z3+>FBxxxN(hM#Cuw8wDX^#>@pR=KwQtS-{2qm^ z2xbUl@AJ$6jNbNTZRHv1yx^g4@62h3oa&y>HU!nTM_w9RT3}SEgCvpfBQJ_x<2KQQ zCabxML>6x)df8gH3OUZR%hi$PWhZf;M{O(-X#=khV<7I-6BM>n7Ha6D*F_F| zU7lH+vhC_3+%m#R1kj!;&2l|;U~{_Ofw&P8&&B+Eqv5(28D%HssO9P@KXX#9R6xjs z*-6dJI{c8ZxZ>M;&@-p6u{7DTjm-2yCPk+qbr*ht(b#arqX&hC-wP0U8 z#9vOC<+^G_|3%QAGP4Y?c)jhWOpl_n7_7z=Iwco%hY;uJe8TdK0dGvbEAXC3@@-3F z{A3JXuS_YZoTmxrM%~lKIDH`j47On^sXWo*30`6YJ*AtHYo4%`45%3W8ROM7 zZI+uFl?{t%PCCff5p^Zkqje-5?ZZLx=6-I z69c?@`X#<)OxM9-WTCm>+f(0PfJ7g{_1d{|aL3?KnY8Ba&pqs(s1|h! z!`)-mfAgW0$tEgn!FdH^8kcnhnDBGig@zda>}JEDT|w`mpvz*7oOq^8-`YHgmv`~3 hNx)E{^nIz+2RY89Jgp%S&+(k7+Fx_84E}rS{{dSi?N|T+ diff --git a/app/assets/images/home/home-oranges.jpg b/app/assets/images/home/home-oranges.jpg deleted file mode 100644 index 671f02d979eb4436ddb84588df1fc8c444802b4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107368 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 z zF-ZmUk|gCUCzXQgFM~CIZ&tS8$+5uw@vy6xEirZ?c!~s~E9@%uOzOnsO?r%WZ`SJt zlf!ViYU(O(y*T&9-SYkeykk)^zn$RNl$|~z@Y;JUdDlorfZ(hQsi;dM_i6H~QJ7{g z*(Mb-BckZRv>ky2sm4XnTY~O-f!W?)4!!mq?e{BzC{9!yKL{yd+w1njRD0WCH^v=!{jsj#G&aVPA?!^N>?Bh7 zK|W!~gl1hbfLYDxtjN@*h)C7@`bAXhwwCmd#03J0OPt@!)-Y@XZsnRg%;c|%WzxXlpi(40{ghNlf^N0go)*$KMaWNmE(LFZUqMWFa zFI@d2Xqw6fcrzO*Q0Y#DmLz01c#*4L^lzn@fe4#~X&BiMI?^=>(JZqFUashUBb%sN zbKL)GC(uIAzcstfv}MPMXah^3?2~zeGhR^s2Cd7E%huhhWf;QP1MczhSootO8Pc@j zt!NebqN&)EK+assV2zhex>?(g#?Ir?BG*|D24le^)>HR`U~@e7$MzApqd(5EixEwf zJZ4XCmR!pxYDmNBsLv5E-R^4H;lq@PRe2*@O!P!O&0XM`{-d_=B(eh7BpBNo7Xr{VN*8#ag?vI@S4kMzS^@9>$Jx zNvBwrRvN&*UJSCAY=6F0Qk+)PSr(hk%`gs1kkWZAT%X+iwX-t#rebMdew4pj|0W{! zbV?_~%4<}$@+Ye@?=%ZcWgf!YBb{&Frcf-V4 zwR`Ex$v|9_ley6)F^HQ!Ppsd|P8k?b zRbSF@XOee@CuIi9yDlzc){>PMOAR;(yOi~16znSZ(C$rJFiNSwB&B8KhFqPVT?cox z+_u($ny~coC%2bU#be35Tp6VxExSaf-gkVbg004Ef-BbR!TgSj)a9O6Uz-H^h}L$> zem{if|8}09Gm+hwF|4Vw2n@zFRWfNRi)i|IB zv3)9|IJ*$^-uJEi30e47i{$+W0&3%VD4qR^WJdp?-Ns7m^tl6(J;=dUqG78R*+cuW zZz0B47N2EgTu0UayGbN2Pj#7qTZWxlP++xq|IK?LpSiFu)j?tlPN}S-&RlBI=6YK* z<-(~`2-xFu$P*o+z=BYnvw6}|Z?5OSyXIymzCP7hMJ8ud6P*}MH;$>h3@^2Y6#NHxJKkyy|AN(zW6JhJz&znGip|nO zFMD;}sapKc%^B{qGW*hql}820TRwhX!VZ)ZNJbP|&0v4qf5_3d{Ef9o2{;b≪=m zE8FlZrkZD_gHrXi?6j=6ngq1n9o81Ce%n;)#>h}49)J4uZ2k|LGpu-OjMhYS)CQ(+ zj+}RCu5zy`nX%@cLCbFqh(nHM`wVY(hLJ(_{_c>Ts6eNc%$cJ@%rDISZ1${zvlZna zW_@U@muhy=2>W6C&OBhoB-a3Y!*eWVCpK|xpxmgsgDAja9=)NIh}pai%+%ZUK>y*n zfHn?W5q`a7yfYlsNSHjF=BhD&Thb9xO27*)0*Iw$i&Hvr^L@G}9kOQ4AAJhAjNYM2 z6B_#uQ1t_3SXHG;C)a6a>v7_PW^Ok3n$CkVd0wJlIP$oyrJNNZBtC}yF;|w6Z%>-@ zD$@9Z(vCU@`U7<=nx(L|r3MZ~W|RK5#+y6J3Xu2}TIbEAAcB%^}debjs2|j!VyENKG*UKUJsow$mx`HIp%f zE9=mD z_gQ8e_^7F+N<|$?{M(ew5hy{ngHxn#(`nWqXCO%{omSO)h5t11eoMZ{N|@3T4E|?b z^tC1UFs2fXOf3d4s{nB=iK;45gx|D=dkd=h(HDzw?m%CZ*0bFHxu2Pt;7yIa^CPd49dCEGKe$*BrzY&X;WGZ1;WKR)^Kxb~)f2Hj%CYQ1CkS8A2m3@2T4 z$lqM4UUjy^Nd*e2mKL$lKLRa(?ErtH;+cG!=U2D1I7P}@og59-MbxxDpFxwfzFiiz zN;P~ul%9DrwS7EP*Fj5Pe6wjWpeJNW&&R5{;%JkCv&>&8g#ICL0*>Ub;a!asvW>dN ze0RsXzi_gdOQ}3lyk@In_V}Z=fz56C5N+1-S*1DWQ>IoMTkIZPxe%e=8VQFC=^-oB z0KL%@5tRZtEItDQ*N;^Y0JmH-q zy1A7eK_>JoyA2@VXuCfmP`P|e2|b|a%a`kdRc*0+b#$&}lt-Ki=m>`VFAjEUepVg{Pp+BvZW_DWXD zNN8nlwrTe~DE#cEweYWsWjmi`3a-AGQxzxKcE*Z7vyrq7u;uwm1eDG9V6pF}R*yrB z9H|mm0?|Q!o}DkBrI3`~L{gPw@er;eC?Ns@ypO7BTEFFCDIRUW7owy2uJQ#nfmbqb zX8jk*dtW-Qvc;A$v}bO+ah^7M(EYHZyNCZPxg9LS^^D`$32x_!8MddvcH4!{(x3J! z6zY3?#*!I5M^uwC12cb!mqO`H)fZh{a>E zq=`fktRX~&1-R!5iOz#=Ibhl9t& zbOx!jC>(z&d*%6|O%%mH=U||>;xcP0Hf~ZaK*>CBrE9Fw;posWg@zs#&4YXKH<`Uc z_BrYJ`|i0+Vs!|1t1kwSxUD3C(C9r;1!sX4RRt!~bmm01-|K+tpB2Z!ZL4*eSXuiO zi-tzYZ<>OC3RP>f#uuI|)3oIe_sRw|4xE*F=-vFe3eyo?mdTgyK4e1J5N&Dwd~IL; z);EyY30Ob171@;`XrKrKu~TiBNIwKRT`xj+>g|M1b*5Jn%yY$3y(MpbwN!o6UQlU! z+DQ4-E+K5i2RYm~EZ3Kp@%eE}T(*Vwpi;v7YeLTHgCshojo5D6GWhgezDy8au!%QK zor*rs3+an$1Un0*?uN^DJUwY+oPUM+n|i~_)&7|8QYJmt1E~M>xhKlXRAQR zi`84!qO~z|uFTnpZ@F5yFXlBk-{7s?$#cKwoe9D;jwPY5lQ`k(ZtfI6ne;AEG?H*> zv+)QnMKV-@92+)%&9ohliLKqcY;R^N7GL29WnZ!6h+`Z^^jjJfOX>x1gEM{A3%ZC! zTSO%Z{N@j~?;dq>92HvJ&iAJ@imwb^hc;8i-?d9S6kj*YDDxyloW)OrgsN2MZ;uIr zyLVj9rbW57Kg%Z1Y(3ZSpFrqF(~kHemn06|mymT!F8ho6zF#)*j`oQutw_gZQ_v_a z3JlfG(x4v<-Wx@qtt9m-UX@z5qVGTzZGUFJOW9fWZ-Z1^pN}5t8XHwVP`9HI#G<#J z+fyN*Qbr>n>zIyodZb+awxgSG3-H}X+5i4E%XU_}<3R*TiQl>P5qafDSP7sMKOj3fui9`C&OJ`cYdm?F@!za@y(a4vMJ z@xAzl&!^u~uCb0bHrTL^b~&CH{fR#O@xA&w>|#r*x9{O6RAwVbW-CM}I{?I=w9GuH z`m&tu!u}ySQpSE3lVia5a(P;l_9E!4#=1{ObuQo*@SbrzpNMjSv85qa%5J{9@CJb~ z-u>&|&V7GYHU@Sdqt0Dst@G|%bKd4qENdEBd`@;zx8^q7S3E`n?QV%Fvt{~aY60Ei zx?UybH^`(n-W?kVz%*fEQD>ZIQ&fQrcuzY!F1sk5>IbWO>o@9T7Z|l!f_XzSyR(1y zhBJP?K0N+(Jd;4yL7>JIyLF7#c5C4J;Wh+U1tyI$GIRLRMo7AiuBZ0nZ?KPRN=rtU#+Ybgpb7GPzz;nD~o+W z)w|F|EA{SQA|!~QnVgM+CFmVD*G>>BnBW6hOB^^XZhCU*S(rGmFt* ztmLKk6so6!l+t|cSNo!_H|J_IhCYsgr+O1?KR)fTNB1fo^()-*?*!x@BV<;AU`x{U z-MIf>_V7RS;s3CQf2JP*paNRoj0qN!WP5%Bg|aR=PVqOCb)>t$prVE4t&@JkTJzf;_qjr^zE!!xoC4 zy82$sAR}D--o17gRXKmmPRXkfknV5jg*;uzO)SvJ|D**-;{Y7}?x}hyRnegtG$DSk ze2msmKsvxrJhoOgzsqZc7GjfonssYx0r1QpZIAcP&Sws0U$l0s!UPwIZ|c-HpaK5; z3{Q*z(+ATsQIvKiOS2GO?#ag2-KtCrkx#~DHS^=oIg~*GDj!js%g+kdTd3X#gzZ=p zl8lH!VvQ^cYcM47Wr%{Sinr1cV7s|P9LM|yicU+*jm5agw{HuUPk$gatpWZ&Ey<6s zlPNxlpNM=>D2tvfjx-?38f(90?P!`WK9dmKMGd|bjrfRla!X{=bhF4`c&JkyB(JT6 zh4GxFSN;C(p?LcGyL2td0Uh_S+|JW#IqO?V>?x9-rr`30cxyLORu`#^+wOaxAGef3 z>4nKDa2F9TZSm+g*J_4IL~ex+`V)TI33OS2ojaDSAI?S1wNRfaNSIf&F5Y@J7Z}VNn9(uP!B#=((a)>s$nze zE_xyg>RUktW>TKdoTx`=6ok_&(7dKNaO-v|(v(edFeI9g3VyWo2rg7C!rS|f<5|;#Z2k?)CEh=AD-XCaF+%40#I63^I2~-eDt%G$QOlQ`^zh>n z_bxZuld0d2F#;mV_wT0cv?2rZwLe*lW|v}lX*@i%q_e+%U!r*=d5jEg2QX?P(>ZcE~gT^leD$C{i{^DLb63Pi`)^0vm18k5H zTpqX26UCW5wpZ-m>=Y+IS89P@v9XkUbbG9dxQ#ZbqqQaYX1JobVAmaFv-D?|gqcU|B`1k|rv&0{g6w zAul_322CMIC|NSK}bmso@L|0hoYZPEaM)WvmXcC1gVUt8Y*WwV*z~0P> z7)$y4vG9$5z-dC$oDX^-=0#@-DfYr}CyX4}FrrVH%@*fRsM)r%Q(P+%{L;y0wlY5b z*q7Pb!@CeO)0pd1KJFxr4I6R=cd3>Rh3Gy!`XUv=$>>K;{jwN`+-%t<4YP_B^$MPL z05FV+5j~VrTOD-po=@?GHlCBLau#xYUag$Rr=wX}|4gUgvq^@%hRMy7BimTziFbHx z9^m(he0V|-tD<&4Rsy3KKE*5VaA)ntZh~4t>oWOv4d?F40!t z{jYRXXePYTcNRY;HpKnUN~Ymj8KEaPh3J8^hY&OFqVnnPdyat^X??&!sY{s)cm}Xc z#x@4iFrg;*7ga0Bq8M2`xjj4z+!f%$&`giR&|{VWV2_+}H6O=nw+b{m zRnQ#E8FhC#I|E4aGCay={rQclY9iCIY%OKbv$H|)7~-RVNoIfM!z4KgfI1jYp)tuG zXd+?FmiKs$Z9j=iBw_fL0Zwu#Uw6ogqA?kYdAw zV}W)pMtcz}nX1PQ7_XhS)T0E+=e-@0(vN_9f-#5_4As>M|GjrCBmhjz|LN)bzg>M8 zm;fwnQW7$99A*kZ%Kxvg4+9gUTe80KV8WJc`Af@6TN}3czQQv`Y%q5B;O3&7hHGPC z`!uxNn6~)ZF|xVVBrjn>6#_>TQC^Dw)gdAz&1(W~Qm#W5%@WPHdhFJHyyzgc3>P5z z%5aR@=5xZ4Xi<4^%TzrgoFZu1Dn@^$md?QPPEMXx5A<4p)1aIM(;%=vmwR-=Gz`{_ z`FSypjak{n?%fL~E7mXE?^iZKg)3Sa4Ffdn)_UqAt~Xw{oEqVe-wb`w!Wor_)-}?) zYv#P1fHMAiz8ajO_l)>Cq z0mayBk;&dg&ZuCl$PrZeoRg@P_9I3|kia@J2K0K9QriIJY_Bmxf{GJnr~crnbpRKtQ4I)Av;)<>o4XokI$ z8*e54+^JhrV3`7oLL&c^me>^HvSo~>ZZ=$obLZ(PU;`T>6Ys1g;y8!M za4hCPKB^AOQ*Pm@{5L1jn}iM3klqWpWg5Gl&vnV%v{nq_;I=s*$j6teh`euYCL$a) zj^skEn#U7#h`Pi5eyTZF zbKTrX_HwQlWHZ`!nq8OPeS^R7d*JIjGgGq(yBTh<;l6z@pZ*r4z4p&kQ&LCtSVvn6 z@~XVuwAYb)!k0FFg?IIOlP92|4l}9Ga3ZH+I@PqLKIQn@_j7^ZXw@_+v8=4Pe_NJ> z$*=vFV$H5)7d^GWNwW!R-8#az;VR0sZ`MtR9Nw(`f@#5w*xW(vab0=ky$DdV(lcLb zrlZ%F;mIZ>LzZ$j`?j0Bqm>%=2PRx2<8K~lDeeDN&CEDTEM)tiYQUATN%ggrsV6DA zKi+(&s~|CmXv@1et`=v^_|`;w`L_~UnY2Q_!X7w-@5`!eC1h?_icRl~Y}L3Sd%Dy* zRHV^t3WieujpWMJhSP3THR1B28v+6Xe0QCGusa=gDE)I3YXlG4x?Csu!$PJdL_$$g&l6L%jQGv?ic66Ef&3nB+DeUL$f((U zwGKu$5YzUja}1N2PKNyYfq5(6;0b+*v)p0=b1w0w-FiOX3$2`j=i_57gJzW@U3Nm= z6p660a&$ubHz`&PVtyngAH{ebtz!R>F~Yaz({+Oy?+2`Bak2TV`(h0slXhmFx>P7*Ns!c049kx@;M>>0g~ z&YroA)AY2Np>&%7 zBbv1xmES5O$X3zye=H0{^Ovjh@pNYVLv;_D#Wc$Z(Sm=P%>bgLEs0^C@^*eGnR4Ya zjxBSYsed;^!=wf#87uPpo>=nKq5o?xZmi}k_wkXQC`A>Z@Vbm}3%?dO@7}hx2B%8T z(u88^d&n=a8EA3bKNL$iW9aoi37F9|03^wh!0vAn-8<##XLgMoL8AwmjPMNm3D0n6 zqq_+HnAxn7^PE^v)!qPARhwsO{zxk@ga8|6gixx{7H_k%u5Fx;uYD*}$(oaE?F;}( zD5V}ZT;`VgS_Xsns+j%-X3KPV%*mexhe^2dbA-OqTQ)9h zt&4U%z1H_U9HoPs9ml)DdS~w9Bekt=n|c+T$c2PEt0csh(b*K{G|7*;Z#*6QQqM@Y z8FS79vj1fe1YX|mBCX6WefOMK?%_XxIE{K#hW3L9u-q*4j2Hf(*gvz}>s|G3JFanR zAa2$!r}TiL>FckVIcMp-!~?s~e*I z>1dj+t4Na`@>H33FRwg;KDZ0>l*l?9tWAo4X>MiO9;rEdg^S=v9k>|^DyR}o{mqI3 zgBugkh*tYmbvP5wz&`6@eJdMXGd1?U3?wW}&?nHl>F+(NIttd{Uz-H&-2z+Zrqr#$}#Ot71PzgMpz|ublsObvErFy zlQHPO9xdb?x?wvl6)ui~V%3ur ze-0)#QDk9YGvs4t;^JU|_FEpoTYUcj;5eqeJ8g0XP_}oSZxq)`tRJ)Z-wYbPkhPlh zPSTdggfAGD_r7_WNKnZLf-SlrghWiNe%_(Uq*Axz*)Ft3Tb)wPeZl4$jjb z=h~zgX1D5G6>Jy!mL636{CcUn+{}##+=vv71PS717_C5KlWV^J02rC$IV{Y?berDy zES-VTT9UkLa6WA^!;;7Hf(T(Tjf0{r$28=B*1PMbRVrp4UTz}>0togFah`0#I`x_r z1<{(V(a{1GAo01lVf`7E&u#$)K83j~ap=ZOtUBp>!43r^{TnVY^3d?6QDw|w;b+H7 zXVA)t8}K5Q00F_6x8mR1BKxdAlRMJbX2X{W{MiVs5jTsK-kvUN-}6}1F^W}cFp3$z zdRUA+@v2bZ%v`MeBuiHp8zbiR*HabdxF!-ZD_39S{!1lq^HHjB(3AdKhGfkSb~!CE z4mE&hR^rMQckEiIc+}`B82o%tu=`3;`&*1<980LhRm#J%Z2~JBFK`ye3@<9mHTV+-pT&pv!u9YUy zk7*p3l~eK45u-xAdRd8tv8A;-n0eVdKZ14vjWxhCsf#OgvYec&F{RE<&lM978{e&V z`+97trRwR|6C&GUsZcdEu(sfXgj`^P;dDQ$ajwE@kkylOF#K3xN~e%Sp)xAtUeL3f_AT@Zvjqe{D9~j3i31`^jb+L^d ziXL~lz6m6kv`c9tl$x+CSkZD#>tom=RcMu&P|C+*W|A=LuFH3+oo-T|Y79|{fs>5@ zE1(F}Esv0y7GG-~H^nPabC5J(u(rel#j)$byAuwdEZXX)$&b&loUS*@ajUF+hPSek zP&CC$C18nlblq+IFvQ8oq*HzG3TZg#VH9IiOeLkJ7$D*11>~_{S|OjZVqL9YiKMLS!i3k?g7$} zgtd^v#^nfk|N785v&l4Yl~{Ls5rSf z)jhM#;zAl8F!AFTbdDLg95iO5DT^^A&Hgq?Yb@g#0KHrACtWFX#>}oiB2iMVMSK!? zS-tPLs=O^j!Gt?Crzg4MxNR-fS=$;JeR~WUU(q75YY96%)pzuag@#*gNOIFJCedof z$3^scz3dP*kBxl>x2>SCGemkaFU9%vgA5|t;ryG%>jxd30s39n*m}L=ztCUhIK4+j`X9byJC`Vc^5TmsP2_ z4;_`@VUq4=oD#WIRC?|N?~+zk65!q}wo&9^l-U`*3@haH;Q-8>!5t zaub5K*D7}58!%ml2UE_zeOxp$#&8EaC8dFF7k1wFH?qvm!+!BLOZ3y6rRLG}+DpHACQuV7oM}0$WRRN<9 z2ZIj=7~q4#!x+S!SVf3zbSQ4(hQ1;i8m_%mZKBdCrk>YYG8XHe$)t9>zV;(qh%ziN zCN3>tOp8jrK!pkHESlp+FtH_W>Wy1E;Y$8`07G!n$jxC9crfs0V<9r|gj_H6@9NA- z*W&HnEvC-o%#w^DQ^;=6sahV}G!mL6c-~D%lT&3vHPqWiC=+CucrgAR)1l2&)TTu%@O6-OJA3lZUkJKu6&oh3$2qCrLrupSP$c6fin57zI`}F@iw!jD5I%fpoX%rsBF7) zabrcWhEPoJ+Pm@dx_At44CwVW7^zua35Fl=GTEphn~gX5$Fi$(8I09#ZFcS3d+aT- z)x>zA1+YzY*HpzdwVjVU-pL6m7vU;4OW)hK36u`_V98yUDx4c;R(atQ6BL`X8LXDD zfc`TWK@7N#4<>r{N<-Twbs$6erp>(Cs#Nv7Xb)|erQ)5LSrXn6ix$Uv<6{2+0mJ@wsEu>7 zX~_QM$g>%+n;vUSsOs}wSzT#nU!MN}Ln0D`6CKU@1*ym^_JX|aMni$J%zp^3eAIR< zZ6~imQl}uot69eJYCn|$0Kq#XS_2{`H5iqrUb)mT!64CVmsbSue3)YrSSUOJqg|Es z=tn6P>>#72O_>bFY7REUMTJ%@vKUFTbW>JG{UpkbmHnU43Hdi*kYF8BmXv3vM%)zX z2q7*9WRT0c-zxqvc+C0*v|`z@DsEkx7$<&p5)spT6Rx$_r$9REQ?P#for|#P#cv4( zP7P{~$lCff=S)X3yG4#|Vt3BWC5&2|6!4-D+-cCRqC*-E7!S^-$d$Ea(Pgn~{%a_z zx+uu4ag<$>>?{#0#JG>6j?{H6TUe7CdbK)0!>?aG3xVB{3yp{+YkpkT%-G_tcYU#r z_!C-!EOzTUiLL;!wl#CH8j5$@mvrFHt9v$;epO7?+Lzz;Z~9o)k?I+4Yn}JK^Q$AW z94hQgwfq{L6cEb7JQXunU881iitAd63}#;-hzluNy!&2oYO%%E<+fHlrh@iYO(fTs zm1PN<_;90Cak1;LrPhVDk*nigW}{~MAjqg=^#aMXHyu#z~y5%qGe-+ z$q9WL>djSo69#`N$FjXm&4vkL@+FgMv`~u0@-hbsX0a_Tz3+R1JE5`mCLT?hHrM2} zd8&2uddwk_mgTO?acXN`ngiX8Drrbs!?9TKktwX#TiI`;H8x~qwUHAVx^Mna=F@#m zmZ}TlDWREEV!c+SO4j%!^E0dklml9vie;46Z4_fFH69iuS_^M^EV0^I&W8jn?!vi^ zljBYH+Op51aw5J?94}@;EjP_|$5S>Jrk1=MWLvT_uBPj8Z!>-i9qa>ytE-hHALqgAIwpL)huLv(HalDxpYNuw%wZ#oVz8Od}F0oP@(G`bh zATbe)z{C)8MUX@bhmA$Ak}+f88L#HVRd=fFa{}{Siqh2H_r24SnGb_rC>bp-yit_7MAqurZh*y(=FZDw z!4PS`7`E3#t+dcy-*?WSR}!Ncne2CN9IUa^G4s7$nIL}UK9x1*S(2_VrN5-AJ()iB z-~E^7i&Q&97P(cUfd>Q`UP{<=B9fodqi+MeK39Z0ehYebB;4!v|{ z#876mE9s4rU{(x!?zvrBXzc97^6FPaN-v$AD_<_ybmikLq#+WlZ{*0v?68*}Rs@8q zl5D12JB9~ySql(=BG|7>J*@to-pz1~ISP2C<%r0&zAaMrzvbKWtEHN}w7>dA&i?Ch zwXd7Ut=O5A{e!A>6{a;mIt0QEOr%%!PA4bRgpTH5@ zb&Q38<6fa=)xlG+Wk{7&o%5Sa2w1UYb1KmnChUOKn-_hjtYtG@Ysapvi#8Y#E5ymh z3y+Y2L(k?#jBIyeVTK+nRxMVwE2*&m0G6kL-o7lUyONE!J9nNUfG~+JXXrV zmnCy6&Hm5rQVlIay0x~QFw!qk3p%{sr3mWj8;YI5S}ISP*!H!IA(X9nwb%4m%sfjj z#mUJOq%y{KZ^4I(?D5H@Td`kW0rq(6XMIq&(XiF6bpiW&?8PujExk=-N{O2@Mq%aT zWI;C5YXwAd8KH_DraO$h45VgNKquQtq4^W56Ep-xY-Pp%Y1@09y?w;4woE&1wAv8X z@I(ZNOBVrp^{tDNK@1hqrBe#q>B}4dgB{l@=~h0k6j@}fMlNkXgAXBwP1Q^wX35;& zXQx%QZui|~G@^h8fGB?iYW#K>tkL6fP#hi@5SH@X0<3GYu?m4?(V8SrTzm2I)irit z$oh7U59L)A>*`twU5jB>g#PNPsxPcq`8dg4Sru3S5b%+Kq}Eoto)ZBfgDyCDP99R9 zrmiJbg|5pWvWQ`f38wh+(#q3(n0aHp)HTzmMpHWrZpmzb(+dyDYfOJDkf&mQBxKW5 z_c6w*f)T-+AaTBGZriq)z%HRWj(1$c`WI(5ZQoAhA{en$!7H<6obu*Za@c=5*0JI? zOUACND$K~rV+1o{sa~e9<*-W8>3F2j!ns(u?+)*#YQuaNK9;>!$^u=#`OjW8dvfyE zE!;nD+vfL6HCy`(h6+m9tjyC=s_Vx%{{YRVCOZ+%_rnaTwyaTwM}yBs6I?eYBZulh zB=44C7FlN0RWCfG*@~a^SO4=^Ps+=<&tZJ-tYgkVp{ur`~kWEpIPAlNpZofoz>F0q` z7-4G(EeZT@dov+tRBI7PJJB3ytkgWzOa+`n!R0II4V)}gb|;RHD_*roWx2iFJZ*BD4`5pYmCP&ofIXi;T5cCOl*6+yYpYiqvIY^lbVy%z82_ zujbK;Wv^wdOd|~uFGDSaE;y;16>=l7fcDZ>D*3okjg0LKuG>R?%(2u6AeGmTj|nBq z7FVIMtg4knQW=eqmTmHR+$Lm>D=erh#&uHMc87prHw6YuMEy|vJc>op0di? zE!LNF#^5CH^L#wkxET4avbaHn1}E?<5v}eRFtX$ma6x_9ZAuGmi&^{#)v7e@+l5_C z3A)-dD|a@z;p_4Y)2cO@0F+@jjB)a;w&(l>GuoT7$un40EX=mTPPH+Xit6ISV>5mX zU{&2;VS##Ho|>O3z6oOIDC1elm_`$5u{&>bd*2)UUeNJ_T@`&asDo?_k=Kv_QFVjz z4)xco#jRDk%Zfi6xl2|lh5;RUud4D4p6J6o06 z*ab#FxUF6Iwi#))whs6(#u);oA|o|+D=TsG(}#@C*->BdOGYm&Q_lYYN0MwJ9zH68 z^&CyIZ5ldFKrCbV6UTB%0`Nw*#6vo*c`OS*sCllP4Qw^82MFcfFxOSb zRP5x5j0H_xWv;uC7RM)ib*_PmxS4cpu9hAIp)kuEn!~;CdxwjW2#j}*_NDc-6AObb zK9)9AGZM~TQDYXCM?3wKHer$bXMO-@CR+G4HLJZ4I5 zsPSAzuOgH5B{kZ!dON)e)|)uNF^#-5v=|$FH2K*EIeBmA zdzt?k)MP|8Ot?95LDMQ-86rS}w7G4R%xTUDWg zyAlft6B6I4WE|q2&KT?z%Czr$-){K1X_72#i++Xq79C;bT^o;+VT|m=#||NjVJ1AP zL0nT`LrngT(ueHq?B9o3L&FJii+^it<6>`n+-9=PYNFIVHRM-f()4wj+B)0T zb;kLaxp_C^R&vg1&CSRhbb=~_94YG5Bm};|JXQ!0kRS{S>tCIS!+_Y;io-wh|23#rXDY|=FF8dVs_s6Ynh+|0Ils|DbaZC_@cv8qurHqP()0A{tVb?dE72xg+v*ya1oC0X<*N+2wbojy%5 zj#aGRgB~P$(xjx;C|ZEgPc}9)T&>xlohzZ&8yd)x%B74+ZC7But;44x+pVtpa&P0N zv|)xiExWqWFiW!%eZ76XTQTGo#}wi{J7rsyIHrFU2vXSz#kpD=FgGA!TV&Z$+a z*kpe|$V-PC+s7`kV6VgM>&9SgYs0C5piDzRb%z26l=*Wo$l$xYs!k zH3Tcr4M3&g9HJ>;dDPbk%x#)kQC2oRrI=!i)C>~Md)WJ%;L1f+<^W2H{Pj)7#<$g- zr%M7vK7Lmmd%N1zSMz7oU6QW33{(nUqgH|5`3I6-(OS4#qY_z*ae_hmIUPI=eqyFD zSB>#%`Ceuc;`~df98oC7qZ^E>?F`(Is-@XMRUaQnIc!Yc_ql^dmU&JT?@d`?`!Gd9q+-_ORhDZ*k`M~AEw_Y5 z;~Jcs)#keO>o+@g?c289sK-KzpC>2gV&G={qhDH9?5Bly0I{Y%7B&tul+0h9y>mbuQ|{t`sb4uEnmaDTI?Z z`0JwL_0C!I-m{S^rz0~eg0)65*{n-LvBaX9IB4bDu`o?#;-tV>@0pr;>Xa>J5!c8r zwb!p##(ETikId;%W02RCO0oGjIOG%bCpIDyX9pX%29yS^!#h{ zs3=-3`ORA_csMg38HCV6!VUokL~DRW-r8ml-??eqwi@H)HXTS(+-8qr&@50O;eD|m~Trads|tr09kHt(4Q8bNwnK6tk+m!U12oIk25V5*N(K3 z<&Qf500mm%L5F=UkNg(n(~Q_SAu;ZxLpp_+m>HPRH;Dv(wWOiw=vP<+_^@foTUx7b zs-vXE!Nv=hQ_(b3hKm*vjcHq{FwN63=2a+}PxIwxB8t^o)I_!NDoUNP0aZ=Xi!-wr zb)Z*|eKrc~Q*C}(Z;23O(T|B+-YCQ?W*6|)jxoXdS1sxl-tBAWQ^AhR*YL8C!qHqO zB&BNxA%<LnMo^g%56%|!&P5pOe zE>*V+%&c3NjhHiXGTQEd5c5JITz}@qmsx4=QuL**xpK0yFeXCNm64JeZ#VTc0x*DV z+*g>>>HQiTs#cX(FQ+D*BO7eaw)(BND+S5(cf&xMvST@Z)~%J^*4sBypy7+Nv)V0d z6`9t1N%W`u5Dpqa-#pwd7qg?BidJ_xYmQ+vnX(A{F2{ zy=7?Yk3%K)6YbiJW|!MrEmxqru;a~fo~A~x6j3v7l;U4UooosP8BAs_P1&oHW<@CU zv8nOw`c5<6%GG7f>}7O;=~jIiiusY+IcAmE=Nk0_yo%_Ln_g#IpZtoK_)aT=ZXP_AM!jhTS>-h#X_M;tI3!NztuShJbgyXWmoHNHMCeZ zBAQ>VVn2APC zc2EFg1s2eLbvOo#!3-7f^D=JY+YAF210X5KyZbNt7G#-+2hz^UqR6x^68yKov3+ol z1lq-!wm93``OTYVX=4HTxvd^ElftfuBmEpOjO)X=0Dg53I?_#%-u%0AnV^BO(JQjb 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­ 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�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%0Au0Sggj;|7ezdu-x^0&b? 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

    Z^4m))-2iKG#x0me;nBk8GrKQW(= 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

    |=;PtvB;_y@F`ULFV)36nV*00BTXZ$$R}$Q# zu+2ZT!!&HdS1A)zDJVyeKkZU4%ba|vzX21F9u$TcXH)^9Q+uFUGQ;E`75ij;BJxNeahjjckgUw|sMs@*fV~F5nie zphU90N!=v@K=OY4xjTPR^<8sdosrqR*7(K}l+y6Z{eJ6zWK!3&8jG^U^-hBhvIs%S zcr=N4Ir&Ai-EDnv?0L*A9;*45`X%Wb`(>AjHiR^KY-jA1Y26A@vqS>-JLW3>F2&0G zya|0-_@!)YkMASg=Dfdm;*_mjw`^2lsVk2dXK!!Dc-Hdl32L+%L1ch8J-yqReb`>YSXJH zoZUR5-SCOT)!0+(b$zRF2h9p4x-2w-u7|;vqSfy6kr6K&Sf@h&BkNPufxeXbrR!=f zy+c-l`OBl6+1C?EaY!MkQ4N*7&E*pRK9z}gUY3zzo(u~}@^0LFg14KtWi683(Rf}N zf|&grR3?cj2d-u|Xt69pqxEC6Y2Z> zDv?5;jwB4XJ0SppUfc@$)oO84PolgGlrA%OxLHs{9%GT{UK;3iV*=4*31u|J2l7`k zwAlR&NbdQMtb`dwxRhoh_~y4o8sS488rf) zo8~VNjpL{VL1fVVS4qfS^x^aNrXBn z#zwkfUJ#-0g+5qk*!E|syflcJ2i_atmpw+<#@Mw|9cSD#$RBAxt}7)8@QfRN(ya!2 zHLhuF_6vfIIj&;Y*dD?bDNzT<1stXK3Nk@YWKNO~Oy;@b+pukH}8&I0$H~4}@kSs|WK8-XaR@>oVV1NV68z02@>4 zzf>-|qx>04k;}+ueZU>*vmwdZ`{hbkf~d()hi6AVjK09!*_Fq3cSWyq)x$j8teDZe z2_eX}d93oBPJNpN@|78%xX;m96er)ut$vhDxs_wwS=zP*>Oy_K%l89tKvVFC+H?QR zYw;0xvqd?GmzmRYj*1{~vH9nsmpC{3g>zX`6;;5(V{8Tuw?aXva*qR335>}@eTi(~ zxJI7^alF8dZat-ywQKp6_s%ktgi<-fHQAWrv+d_1-8X!sa9F}X!%G89n?o>8tebB! z!+Q6mYw3WgmA3Sn^}giuN*iLV)s$+XG>>E1+U5tvK19{4O6-aXSaCXyw3t4-s7?>Z zH2y0G%LA8MGP$Xy6nyxfwmO-p^iK~;;vt21JV)H@E1mH~hjL4_mc)#+bj8_r$xtM) z!R?jHfu&W}hJ9EJtKaN-Ce6qO&6`NZ3PISY6|qyu3uPj^9)7~DSDC4Y&w|>M7S4=t z1Vg8rdZJnD+gcU!=$^`lf!Svj9J>P#O#Rk8Dp_12p+bN{4|}cJT{ixuI1pnBjb~ z9R#6MW#U8OP@kJ;)|$U;>wz|GGjO%cI^f-;faH!PrVuUwUYksV?LDmef>{+f%VEF> z>s`65f!&?x8FqbCi2La@1Dcor+~@Yy`dV-Nt%mCX_;<+fpz8P2pz9&>F1fg~-uSi! z=KY1vT*K>$T%e?GQSTMHZscX%Rvfp${Pw7XPS%>%?+7T zL%9&sLx#{AcsZ=it74p?X~t_ppL*%HU`eF+La5mp`_wbxFPI1c8vHY@4js7*vKp?C zi-3I+$e_SRw;g#;c0zq?_s`=SAjB`Rn>oMCB@qs*DTa~HXS9T0h-}abQ!sC3l!42k zn$oSMbatE%ZC*5*YcHoKw5KaFcAR8LDvRvU;mJ4>>cg^VX6%x=jX}5DY{ya?w(pLS zb)){AqVrC_wehHAGILmw%uk0A6hll<&B2HK~9aLo{yTy>xoiDfVG6 z;2*bMQEhop%{+GJ0u(gkQ}Ji;s|WW%CYZ6)Xelw5q+(k+jLm)?vm*9p`Vx#()>w#% z)2}hc_aXUj0=wpaCHw-9?++IRd||g>Het>RCS!Sy>i^PsK^{ zKCJ87r$r-4?b8L^j?vMmcbXT=@=F&4TJTq zonSSqp>8u(PyB5=gR|*q>7SPhYTH$i&p*~@j+6hw2(xpg35S*q1*O43pNysa7Y!*; zc9F>HK$^35aH#I%xC}S>9v**wigvphKV>&QSK%gb+{I z(N+$#XDEfSdwP5sCfrM#^{yt&`jbnPWlPp4c^!B@f~MAV@twXSd6ZwSArIh;Dhni` z8^+~ggnNJ7FthA$!C`Us?L0-8Fa&70wm#z(TH`SgI;|L6Um+t$8v5u+ey{9S1uj)L zQz=yy2>OMf*SR#Fz1@Ogo^um3hHkANl<@9s?~c4r;q=SN?yC z?&ioB9Je_%Qd=AYzk{D!OEb=q4Im{#~aYr z8eqfab8KHfBkeKUG`MWi4GO5`U2Fml+yd80f)&!WNh2P)MNfnh{y}n_Q=IC4gLm|C z60)C^?onz0!85}(yRg3cXeGG*phLn$w>8_l#J-5G+m|>Q(wKKXAvQAD*}t>nAQh#? zq^M0I&yg2THlIMPf-+wv;;o&cC?mOC!UxRgKy9p;Hpk_1VjYk)q9FXT^rIh~Q)gkU zo*0vu;6l^lAWmD!ss_rdQyR_8Clv=;tTyFCPb-KhuWFZdwUR%2m_)!Z`ur!qg!b>e zfp<+ejN4hQn!e}~hSlzk8d6%0hXhKl23*PLk#Gqiq%#O7BToNPmU;)vYh~o{^7ba! z2f5tNlO^5~0;Mgd0wf1Y9fMBbyagpd_J_{BMxEuc48cr$tflMEL}=WVcq}z`~q=Xx-`*Bmb!ZvDn@`Ix!yl9lQ(Pbucl&g%g;eJWsqskm>R<65=oIQagH`>4AtJ}dB zPW8Mn4#QjfKwBC%?=(`;u+~N{!_#0+YYcy%R<+evkxAT!X;Ey`S+oAxeCInGOic&M7rVzt1n6x|7^Is8f~22I}drHr6cXWtS0quOC$3K znn%YeVOBWAVO@%BvSHQJn;B*mp12_4I8gPBVkLR!vRwx~ z@(Y}6?v82`^~=&%zpYC{cmjo0M$DUE=X%vlh_}1YAfM(2;<=4JtDkc@QiH1M_upm6 zu>Q7Bqw{sG)Vep)JQ5SMj`-9KWrm>VCY!lz42Hvq5uN{$p?#~|&hFG9054r0XU*sa z$^$3&CXd*>LQuF!gm$)bpJ{cQUC*!0PL1Cx)L${peAEE%m%ENLK8%O>=2Z%pAB^7x zw8Ivg*JH8!9<>7CX}SV8#BMvG#VPfEK!>Bkcm<}Aq(phCe*j{UquHM&9q68yxgeq- zby-+w5R+1{gP_}(sfeRGwlwO_@B(+#o!4$J7JQZ1|H8~?&$p^d-kJ*HbtWaNE;g6l z|4^r0JCrM&Lv*vOW5%w+IQ5vrD2#J^r=vf$*>OA4;DYx@Oype2Y4j&PsF(z3qO6pF z1^vmt$s6kB9WhHAj(;jeF@ zWM}oxMMi2F~}GN-%d0Zdk1YTRa3!kfZVjOuMkcq;O%0 zPrVPIa3JP2W}0vDP4=91pgx2bSP3!SR~=9kpcB8`h_1R^8%fDIN%Oiv(O}QI*lE9k zM)(}@$w@d<338-m7jPh#=4{lbtMn5c=IW^4yF_qo*%t5}vO=?OKF0IC6D%ERp)nJ) zaNF}n)fiICG=*pq9pxRHH&Szi&CCx3V3zU&+^(&6w5C6LFYxjIySJt}3 z%+aQe7dsRaC=p@Uv46K$jaB+JkmpfZqNZe<+)_i0iq%r-`?m?=^31hA3(qbcM`JCObDXu;g5`w9@Aw*J7R!#E zY$+V^DB_D)P)WrhO0xv$EzZ$yf4f@6ak50%PqWKCtUg8%r^>pcJSax$c(HgDOAR2& zT*RWg?vx(TzX05fz$`0aLMwfkkkM$~v*8Ga6xhCd5V#A8djUwT7u5}CtWZ>I9-IbW zuhw|92BfW|oQu4c)vVz%S3!YLjO){j;n8?i>2_asyX++2=7 zI|sC}-u_qVE*t84#4lmTr8Ka3=dVM2CVM!?=|cGh%YJ}YY})e}YK`z>e+IaP(%k2^qprWh2_`%3(NH%Gm+H2Yw8d!Hk?$rYpAOuKw zGg3RW59fE=e%PQinkb;u8&SWW(;7Cehdj@d=o#!3Pvaw4H(#!ZwRF8}^^u?AAv+S$ z?!Lnd=9kNp05x%ur#l-y*D*8PrBVCA^G;vR*Ii4T;iXY$WDm?yVC+_Q=4Fs)mQ5qX zedmo+2)IDC=k@PwE8p8S@_VurD>+q-20ugE?2=1-RCnyS5~=k(irW*J4eUkS0UpPp#lzNK_iaQ@f|RlfJo*hzNakGKuu(vG8)h_T&M2Earme)z`qv>`(He?ggz<(E`IHo3zALL ze?M)9IAxrFNHVpHc8+lbGS**(%fvriBO@)5E)Y7>&;3w%CHdaPx%kA~z|Y&0whJ1h z?j)DI%){XiJ9Zb`Is89Ct{Ey8npP>?qvxkfI_L=>$!O^q9Uqjp=_{{fK2L0C?o=iZ z`!UMyVe3Iae+F}zyAPVLkQaIB6t?!4hku_`>u2&sXB4mOR#^MZr;%p*p>9b>=kFcm zLu!Dn=3FSNn3>hv;*L@zmg)K~(3TrRVA^iYv1Ep5R($^vr%Pi8`Aa%$ZXaba>tz_% zCy5*r&*$5GPJcW96JGX_AI%zoW$ZGj)iok*0{qwS!MR6zZNa#ZMDE*V{Gwz!`||A? zUqkb1B93roT$4qW!_T4jrKXO1X)h=R zKE3On68P?(Y%e+j(_M9_|LfMHyVSArL#e;x6T+PH96dmiXhm>4I(+25zK7Id-hcQh zLL?DC`krIv@G;M?yQj5eTUnPjBvfApRNCwQP3Q2_I9=pNTSH0Qsr;Z#e5FbL;R~dX zVqu0k2E91VvaFfIiSnqs1SX`g>FMtEO>M5gi_C-QcuUA_!_}Mv=WkX|tmxf2uCvLC z6H``FPUJxBxh$Gj^?3oYX7*5%36IMYQJb!x_u2f z2Zdj?zJ&&AXLXsaW*FX#J%`V&X8{qTHWS#>Rtk}x9mho5Ikj|;4-Cjzh3~=6m0z-` z)`eWBKoPHOyi-uyrB{n(FQ=GcCib}g-&QvZL31Ob#x7QL2GlQ?U2o8z0TS{dxW+juoIcli7}TPl<# zFehp!JcJr+Hey%k-=%Pc%Cj_SE!j3dW;N5HWu~;dR%bSot70=rxm^GYsWBQ6Y`N5n zMO1P~hOcd#6YO_vv>QFC%mod|K0$%xLS2J;r4|$1E{R~xI0_Q%Cti_*kH&(%qfKL) zm{+mxU(-j?vrVYp@A}t(YVzn-NT*35D_AQCmIz9BBFiq7UV*qbPJ7RzKLuNH5$&c! z4ErxFZ?+DU-4L$FGAFqn+Qt#N-)IR^%>60|GpJOq{je{fAaKe^aOJ;^EmZE(qPoQG zUj%9of~7Gzv9X_TK~0BLd$GTtL+8o||LzCg;HwJJ=!>^zC6v=yhMQM11>)IsrbIVX znkxLXbit0p{gBGorMm2Ps<9xvW(~LfBza9asWBJAqLE%mIO?wi&mb3p@LsU=AZ`=} zd`Ga0WGhe`Ozl;ePcztNJC%~FIs<>I&S4klZ9@on| zn(Z3lkoq98n0w_FTCu=zD|eTO$PI~l{v{WtF6^Q#8Ia||cK5FuueC(G2a%6y2O__*LFAX<&Mi}~M^a;jnmlF`%cQ!o0FIMhSf$wPCVN7} zRyw~Q*-5fKr}W=={b5I!$22OACW`1)?DJWFug+O3iHsqacx%S?_C&`^7nq1^)=wAd z(@|!wUv80^STq{L)_v|0x$MEU4hriYgD|kkWa`H`INZ~WcjnEwN9*sutcCc~F01YW z#BbrZNVt>~8wgSj9P=Q#Uy*Gs^G7q8*yqFS(`8 zP)YOkb5;9Wf7>;-+D6#OqeKi$@X))fu;@|Dp<}wKYf}Zii*zFA$2x%YZZVds>33wq zr2}JwdLFE*b7^1kP3I&96{o?4RfJ6PC!sGF5;0;txcI1|u9`to&?Mp!I&pMJI zRZw?kt*+kVKCkyImG+f6Bui#yP0^EG5+q=mn#F=Dgac8PS~WFs-=y zj~^LYvFCFxRC%oejJL{BQ2UG~wIfFVd9kN=`US=Org1?ljz?NM@}Kl%Ip`Ofy{1=* zWy1thYh}2cv@Cx_6{RVK{Z5{&oILuoDCnOJZ!YP2B26LnlfUJ0pfgn$&GCp8^ynCV%tZ1BJ4jW?zK$5l*Z zXdG(oolIeS+3Vp2n7yjo3{9?O_a%?uy4EcqOtZ==w?;rRT$Lt!!%Dg2Psx8|;@{zT zQu3sWdhjQ3a$h;q?r|$+MkG({D+lxb?X6o3HI^K;1d5Lv)XLsrZ0FOt^^v2ys^i=^ zSsL;UtsjM>*qo@6@rGmJ2Mkv3#n(7sgK0BMQCe`tF(#E)KNM+EMei(R5XO;KnTUUi z4)!aKS*{1hn3ihD{nW$I8FdxqbQL};)bG>NY^c6D3{=iDMK=c(IWd{XeU4rz3&9=L zS^I4|A-q!Pv^dA?U7H+D`94mK{sHI$n$B ztQgHOKOS!iACJbhJXgB8$uPa4H5z3l*F_&ba~>ibqHO*jnRm;gt@3;~FDy1rpga3s z(cGgX;l`M=@eXmZc0I&yhJ~9^f7sgK0xPh;*X2pu{G**$R&BtbOd ziQ+JmTm5dg;sDLtN-OSnumm5Gji1$FxQ>W#dod=^6{akv<2@RBOP&f%l+2?^5XJb2 zT+%WmGwC)r2DqxHO?6hO{uH(CGMP$)89zffTRD+Kq6EvOED1iK`7QYMm}cZSUZad# zg}Zo&H@Yu7cahuf@9jPQsAqN=^Wz4Q^7M*)xw5ymF-nH-a$O*k~+3N=H0&=f>zp6bvNCMkxwo2tLx%9V3()J&;ylB8-Qrpdg|G65ro` z|G{~k&+D9XpXs`_vbpLc{$wCt82e+ADZPLV!KE)GHP3r?woaq}+?m^+FwY4EH zO}ddjZ;pvw_q?$iHwPq6$!M~wbsHC}PZg%J{MuW2H=5m&Ja}W->ZE%!dC{_Sa;Uhq z7=zB)xYh}@tAe`UOd*-pkBO5xb>eew`E&FIYsb9i_jC}q9h!6!^s0X0arf!@Afk(A z@31CN7ad<{TW|3#>W}^?UG%$`bHOg9d&T zZzXE@&Hx@Jnr6mXcY#VfU((oqw<;PS4Q9Vsln;Pk3&WR*qb%3G zfpk-XLzm|mVxSTmsm3Wl4bfyh5?(@MvWx-s$Fg@Qfma?;hdhM!@M~lC~{|XY~O#NzGIi>vew}{p?!rd&Hb0Msn-2?=A1s7%`7m z@RDImc#0R2aSdD(J#pyj%CxD_Wqxgd}-y{16qjxj+4qFMi<#Uf%;cjaZKTlX^k(2uhsikt7YfxGZx6 znDuLil)hrdTrGJws_s}eI6i1u5XZB+%$5t(HZT7*RD8O$D8BYLyDykgCF~l)syFXA zv6rY`R5KYN2+Me1lr%i=eE%VNPxTk3c~EjkN-(K5S!$Hr=G4LU+-`6V_EJ>OV3G0b zRUyO9G9D+Y)Ky$|m&OJnnULp5E3NcOkh5Ra^(CoJBg$=mIv*GE2t9hOTD{0rxp<+3 zb^C3J;Av6Qd0@nb{b0HLEr*5D%ToGp2Nl);v*vKLP1bQkwF=uLrQeh-Q1MJCEyRt) z`7AUJsD$`24X?| zhf`BIcj61;pT4H{lZ&4j$daVRWu9pMwVkj`+VmVU;A#%AQ0adMS_CFmsWsPxdj+$Uw99$C+%Bi7o2#))0a<^mbjFg{ zY*gdWL|xVJhLg16=n-ZO$cl`Mp+~Sn2-%`jENn^@hV<5!`iRb%qXDQai4$tbqkUx! z%)M8*d-^D*E-jD2*z?Gx9cE;diYmW5I7K$rod}oskY&EH&A+;P?cf9O~TrdyFIHJv%hIcfbu{*ox#Lvi^_Z!v}%HPWR~nNZJsa z5=$w}(8=Hb7GT+*nOr%H%Nl5K_;{18>O!%|A!cS`SYvM#T*pxw^CziJEX^v5+MDsG zj?kp=o$CR2-T2@m-@xVVj<^Fr#HI*)Pg1Twab##QS6pB28&XIQ$@&ain%Xj=N}ARE zlf{lc$=LQs>#E>V9~~uEg=TY3>ZiYg-){S^3ZOEAp=3U8V8-7QJemfOV(SZiDx`ll znjP#C{n1L?LiyD<=2=7bESDGztd|@n*2%Lvh`4(EMDYna7_xr^U-O17K;>d7r1%sj z{ICBp+-k^xc*!bvUq1))L%^U!?e2*KD6Z3Yinw4;_P_cyF@yEH%RO=dNq?v!qb-M~^@PD^2A zjZuh9bZq+&vj`*AZZ6-I|8jdn!~sCffFIwbKgN|8S+DrrdV_&_r41LI+PCRV_+^$d z>FPw83QTjh+1WXp3Z?Z;QndF~7WnOQZk1=X%nCJkxp(JA*gSkZky8~r>*I|3x2(bU zygrrUU7Qoh7VT{LEayV z*9g!fl}SZqnqQmtK2x12@`C~S&hNB+z2c!gTw%l8xebjGN3}x+m0?wLLdN^Zx=W1z zqQ!z4VV?2$uhrYVSvHeb-}<_+_2}mrCCwYC_mKx$G2E5BUzBD)kqu#FVFGr0u~O4~ zT^uB-vcqWf{D>Hn;N?#FP!A7T%I}ehL+YcueJ2_1%k+dt*V&y` zJj!a|j8DC3;`s%uw#m@mYd}xV6N0BbsZ!N$q5ntT8ySs*`tz!CQLgtS*7V#dv!xbu)EuC6BL*gYBcWJ*T!1|5x1n#D7v zJ1m^qqB?I&@oR15ZL>R6Dwnf-mgcl=XKGPnacOci%h0|b=%_6gGzl+{q65tJZz%Cs z*)Bxyi~B46W^DaP?urbq3gPUg*QM|9ZoU+Oz4Ub(xsa`Myg=e!B32LW@XXau{06yt zn-eur6;j5sq1gYLE>WDh>x0Kvl!D!B+jHVH`P*BSG23)T-OAI}9UIYighDF>yH8%v zF2f%~)-DOpr`pJ8XcFHYt+Is}VJYLCtPY}l0?MaDjWM*$8D=hyiz{Sf)&koMo4ny9 zYCA@WEapLXA~(f42)*z7{yZTm3;&NH@`P^wRibuO?UKbkDA7#@g|3ccgv+;r#Dc_q9Ltg!ps1$oB zN!iHAk3G)ed_2Cof*+lCy4pmTP)V_M3#~g&DNpc?wR%)Gs%bMjgO=iFi2x>lY-z|e z35|BaM=O5ljL+satLT&dp}DoM2Ic^GDApUleHG{GX{4c%*Xg!B3|S{oYMc7X{1z!6 zy>WF@!XdYrsz*%Z?C_B-qmDEO`zP(}TY^g5C&j}uLE&z)vW{7*UxgVf4xn1y7_;EA zh7gj~c2m2H8ey`Hg9V(hY0@T;js<&_b`$`I9R})~e~A_%?S}SAI)Pag@-a{klOAG2 zT?ajIiTx>_Xf-Fv`)t9{)@ur_WgzfDw6xRt&iO#Yp?dF#6_l5cA0{b{=9u&&%eADZ zZRbfh&n5cot}}^ye4#SLnL%OO3G$^LCwW&9J!otFyzM^nl=>k@>;D+Wf6zoI(;<<< z-=QvnDEjK06l|}hF7RF{+^)y~n2}`p24ccWA?M$d;=WHA^Mgzeiq@OddsLLZx%obB z>UQ-ns=O^#eDua_%HP+Z$!55Oy>MfIbJ4+-+SFJJNsRY>?gujovR=Ut9-7&u4L~Cc zPstJ$P`*X&lWZfB@YHd}9thOq0YDQM;98^*09RAzVp=hP@rWdY+iv*y1|G1C2?~XH&4PMrd`GvEs4lN>bvnwIcpAV;tzC9Q zq^f=PHm?oxM{#KbUYc#}ZB~^wxhRJ4x0xU3{AL=>s`PeH-l^h7vw2iGfpusds02 z4EBuR9aKCi9%#+w;Z-3~V+gP7>;Gp5;-)bfSe;{WV^+C0t8yb_&0oO?G7zr(7OFdK zac8)qZz^1Ml&`Q1hy44n`8uk2&tII};#kW88B}Y~WC^lRH}X&0Ckw6Bd(kin3iJFPi{~JyyZ6O+hFlwSItcAqDl~k--tLN)Hx>Deo*Zpb1Wqw)u{06 z0d=rY`8!dpJH%9W3w2O}{Ccp1eW4GK$4kM;TJZ{rs2Un&<%dJPUI)WAUw+6FUu<)> zENLP2#x!YiLM9J|Ibo7%x$WxM4=B(#bI{H1{zVdVqz(I34RhK2-V4)rfvk5-nASTy+MqX_{{~gM-i1h6{;|dR~7OSq2%MPI+5CU1%EBP;BUrM7Q+KXCW$;IfMwNtX)+L&2}36ns8`guyl^k047ozX zz+e$j!Gi;>sYB3%bEBXK1--#`U$MWd!_VdX8>Jb?*6kfJ!o)l_xqWV>S{@{}1VxDI zUxcehqC%?aYyqD0vhe7H|CEeHPtsl2Xduo-Fq{CmZ4bSj8-6xqiR8~DF-#G^WvBL& zRbt0TpkF5`*3C2O2U_>?%Ih7SBZq2PSJwor9D?89$`W`*xYCVREIiK8Eg*bu8W||9 zH_3}U;0sL%;70n`R0(yo4+ID@t_#~g4lE=AM9&PB)7}>v_aH=N2sR&$oNuGlSq82s za{Ia6lpHW&G<@d|;J1iZ^!yw>1t3^)TL6iQLd2SK{)x8VfW*&-kcd~f3L0-{x7mvt zWIuMXO8ysKx^*Nrsj;G^j;Kg>9b}$tbX{Q-rt18cayuU5woeY!+Q_yJ=G^zM3g0f7 zWQbwE>;f+AJ;sJAo~wxjan_vS9kx9L8I{X z0YLSHutb1lX$9PgL!Ka*cOGp!VCd(x+tH8NITYU~Socp=Z!o6?Buc0SI+ zG<_qN8hlVjo|z6-LFPvxHI9T)Yykc?_9k~ z%1V7}syKz^lSXHfcYHSKYi-%0b^`h;hjZ8~ZKgTS#d39eLoE9U+ICFXVwm}?x|hQ} z`gz!8GOSN&nuxODu^dxS2Dd4fMjdE`Xv{q6GyWnyJ2k^${E*-JP-1H0DCdpcONhS( z7t!uO<(t*_kOGn$Jtk-c+y!KMA1r( zCAyERdG!xfEQSxH>0uIn`{+G~mUY?s8F`Oaf5M!xdpWWmt*w34N5S%&l!=XPV_A6sHU5V2G8 zJ@yXGHJHfsk>Y6Dlh@e%4jvjJ6DTG_g4{(Mlh|sG2;f%A$nwwUd~qV-2|xBLTvWM5 z;#&?GIxBtZ(DL)!ioOYG*9+w2F6eE-!GzwS(B%W32sj-zX%lgoG_|nFsXqw%Q`}&A ziJl&={8i|apfs7R?EO23KoRR+&4{LQrUQ0Mhxx!n z)j-?>c!Qi6KN(st1LvxdDX=H_WopZ(g&cq{8)H8@N31(aEIM#RI^~~W+N&2j#Unzw zg6M)uga0isO09&W1|zp#+6x1wfRvh6&Fi=YGPWVwei16F^IQx zH=r+X6MWOuPgRD=;g!`A^l4M!?Uxgbm;eg!2^afvnmJc2^Bpb;1=>{J;R}i*Vy22l zs>PND2kWv-2FOM{=an1C1{=#c)LkREWex@10F5{xsx#^X{%ft%F--$z%gtd*8H@o31qU$56uu zG8kkNy#Rb;Qe(EAZRAlXbE&0^4a+}}FV6Awk^>wv#ka~T%8!+7`I^HZinQ+^F>eOe zdNETOXWb=ayMvZ1t38i%>>0l^i44ISee`=3jlHpKtS(MSH`feIP81D&5By&g&@j6c z>iXURrW$H84AM~dQ~gd;nZ8hRCd}{6^GxE|j@TT^*H6hax|-hJ8f|)~m0EMjSK)W| z55Vc?$wiOt^@)~~S1O-+URc6};-4qXEAIe!2zIX zjz|iIR*BNJ%_v=wP*2PCZ*74IP1#^Mlhl z9DPFrz4!*R=0Z)nnA}3OO-raU^BmCw`{h$^UB09cCp%XRH;Itjk9w;RsCT7Rg8?y6g~zZJOjNb0%yfnPn${ZjZ+u|2Y9n zDr!CEX4aeM~=&vMd#bzanI^x;xomvSqma-B%494wQko@wASN{ z0$}7w@zoUQrx)q*fwIuntQnUFc|3wZ#`SOxY*x@io}$UQ zIk_}2@j}u4*5-LGOVgwc^9j~vh_yp>_y#hi+BjUGS^RnlDXxIRqRJ~EQP_Hebt5m$ zA2y}_Oiw+uT2ipOOu>we#0+>s=)C(!te(=bRMsa^Ab)g7ccP5=-(u<+374%hy~Fu} z@27TnWv#FK?t$v-=xujreJc`(R?->n+CD{nZJS}%JbH8X@vz^oFU0jBK za>v>M@ZC-ZH}3Wx77OPBewIMZ~E&e z*2aJxZ4?-QLO+iP8Or&UUk^A{h+8#u_h70EoBw5%WL6xbx!sjkv}oPgB&1%3Uucn; z`3R!3Pp)HrOo)wA(@LoF45f2_4jJB#3KSHqbD4qdFHFI|nJAM&H-q{N#b8F!q66L< zgQl+p5(93a@7aLrbAOG|Lb!UcklsgIt++e9|NcBD$}4G01|L9JC!XzJf+ghs%=3#N zG1w5l+-{`)CV}v`iuhY?g0Y?T{E`xh=fhI2@cKtW=Vc6frwAW$rPLB=i`3J0$oqA0 zFh+^~d#FehZs;d#Nw&arj8>%v^aa6?H2W?BuvW0Ni`*84#5ifcCP6aDvixk_>1prQ zMR@(EDDrL>vyb@MmVps)jroLN=kzG+xqY*$f0V9aDrd+enzvb2Vj)Y;>u9$XNTkR~ z-W{JpJ2KF=09LmT5BIsMePcX&)o@q3Ci5%rX_W#b)95zW^{SyduiX$xc70*4A#tQ*x#9ljj!}Ytat}`UrXL5*c>i@Su<61_`W>5%+;e z>@#&Pg@Tt;FDD#mLUWG$%E(s3%6*S3&H<#=mRt2o0(Np`nCj}ua zGmgD4WZsJ~wXjh7-D*tgWY-C+$9c1#N#VNHCV{D{W%fZYa3zj|C7=XFBNuwGRH^4!J2TyGED~(S6fikxJ2b4;i@yrzga+F-HW5^e4}sIRjBWOes;~@p zj~-lPJqskrKpX0gGwdBB?`Y&dD;Mj%HbuK(Dlgk<<>`z3&9MHO|8E{w@0qz4vg`__ z_wrfdV9j11sg~?`&%|n#o+-(28nhy`OQduJkV-@?)w_2w){=!F+Dg0`tm!^hZaP+*5tb$ zNG};3GC6I12cLl%;^aSiE?$a9rw#a;ZGwwr6`!1{LMEiv;P|arvPsk59IktJNf+Uf z1z3Fr3m$9lin7AG!ZcTr`|*YwZ3o~jShr6A$8%D>I=Ac0MBuY6EdPD9nJgDaflHBN zz%V0Me2PWpU7sBO5t4A^L$ll7ccv#lE0vmy%Ic{8FfY;?zS1yIewJ$$a3}?!f$1{p zL$@t_EMFJy?)87**?ebD6rUx{5nM2%eI}UrM3^lfXIZ2SrEcj^V1yGd7SKP$7zr5iyltKJFe_vBA z6c+~k(9GfHUr<+2E+Xalx0oFqmg$gWTZ?;^Jt^wTC4uqpP+kmFAdBm&fvN{|pY#b6 z!buK7*yP6_zNi%NSoFi{d@b&oYF_zE?oLh<%$;U2!XW+M?{nc<`4+$E4fMyFhz?m5L@( z!xMwJj~47)|KNqL=I744a8WM}aaY2BTu3)fZ!wx%xG6H&o6x0wjB^V@ zg4Sq$X4Jf%B)#`!j~pe(tLYBkaGsQsd~e+Q1Vy?8Xv^vYdn|zSKuB&KsAxG;#XD)i zR%Z2+wG_h|(<)KdD6UL3p`KwjYcaz$=`WvF74Nz}@B`56n9GZ1y1{vo(2hBfu{K zs#x2?uGxN+oU!K_jBSU~XQJlU`vP5Rw~5#Tl?d)&CD;3-<%!#nfLrg32tsmdT}%Z+ ztwq?0Qvy8mKtmX*q?e~hvxj^d21&O*+qdht1gXOH?piFn)VSw0FLvjinKxIwExdK* zbTFvyhQG~9Mca2Zr2n-+mY!<^j9+2!zkgMCBf&dn=M$)?nOAG<{LHS3Xwe%A@_Zb| zI?Try!A>|mO=zd%$TH-K_!0J_An;qBE>PQ;6UxNCr9pE~6g1Ij(p7V%40Z8__dPTc z3M()jFp~caXl58$lWrTQuwPl{gKux^k~(ZtP}B?<;Mh{2h9`ewm~tLEZ>2%rGM~OFceEok?e~tmqudX zB%5gFbAy`1Hv`!wC@u2Rg!JIEYmAf-RhF9=Vb}_cS0+%Yag560Mj|^Yc4TI?6q+3$ zCyE)w{Nv3J%!5C{vUt1~@l`#%s)y^8cd|6lAQzKXb93&`)Mn6XOHKuRJ~-2KVhEt@ z=Q>mnN3rt>=Pj2x`Z*cchIBd+##SHmDsGuPis7oBfcp`LD&|F>81qB%@A}wkq>L<^ zo8a~W*m@n!``xB>1m62ehT#TVF@P%V@K-qFIG`kr3nMG_cFsY9SXXcIR@1Jn?g+D8 z7^Bt}Lflyb#tOL7_}4wFRBpawQTfVJKIC)=oz($E*^C{7U<1v9&UEuXUoK@NZMm|0oA=uVMR z5EOrCDdAqMOB{5|=M+CsE0@vx&yD|o46;L;3bw<22qO+h1Lo_-4%+x-Mf6-$#;;U+>BW^us?s+XmqUiYC$jQ$98x3n@C}cpalvp@M{3EQT~HWVu!84(~&QVfV@3H>Oa)){L5Z ze%wn73w33qp0g=I-Kd&jO&vwc4v1K_qH?0|7@fI|;oARyZKIji0Tdb@*kkmpBpc{5 zxY5)CBHB%s9}8@C@2g8XMD-1#Byh_ZRD;<>_x`I(%wF=mO}Kv>`^?(nGBP}BhT-{9 zz54w@FHIs8Cx5*obK2jKmni19=#-v3m38tL)Kj9f2h_&`hBY7`Mt8-KzFYqhhz_#l zCQZUk{7%qogXnzh2#D7@VSYq-<{`o>+0h&JDG;45P<=DFOeD&w2xT{X#F|0qSeA)B zWK61gs)RCpt$AHwO@`p6*>pc+?%k@*&gnq&+#kFoke~?(*A|z}x3_pl;Ev0FeIRX~ zYUE)EK47VEo;&1UmzVR4qTXq?=4B80{GF-9v^?*DY)#gniT+7q*JD2>RqpDY6f&pG zZUL9U&J8G3<10l7u4PMvh@V@WB-Pci&#wS`jY8DM_jK^%y2(4NKaBLuD}@USQ-_5| zxp%hHxDhi30vl8hL-ITMJ)KFa2kcYfGZ$q_#itwSx{N33g^ng9#wm;M>WD=k^-5;; z_rF-XPJXY6`!NC|YO>HOGir+wwGn zpmc40E}S+@23edI_%4c!7e7m(GMgq)IoTih5G_)+s+C30bwGdT)9G&EjS%~UfbgC}o&6SSf^7 zcS`;{|KH`mlbvtKJ#-W5U-SujvfAVu0n$9qiWI=hNz9L(FJ`8ClQGdby0SyV(p@#Y#(bBQaE3?Z)-Z$Yt5D6F^(;_Qeme zM^?6v|Kqe<5%)A~_XVuU2nr$9@}s+DU26}RB~4qBjFn-ofNbFRxbC~J7F*=7T+A$r zy0FoH&6GUPX1VyY0iDXM!6}y5hoqdZ4n3ss-of_jfmlR#t!p}b@%_3@2RU5fBGLON@8aMG$*`lww=>*<5%r|6oGYD^KA=f2$ovDuND%p8)`GUi zu~9;0%)3YVAs6yK$}jKPI+ucMD5k1>Q({-gg2;?<=qc01Qfpm)&RZ;1vVc9P8R2br zvV~>*xuQ-K3p3sgFSmxqiuiBZ){mwI z3pXBcO_-3O1pk*)cCAxQH2}PYxaHG4N1$MQK-7s`x@)un$<5#o!#<&^mPz&kiR#ES zEALts6>TAePDrK^lOfs~A(sh2ILzarMIaTVvFKGB?Lchz;41}5OhE2fme&@OWqYyz zCFd4|^A#r7>hQir`HgO!4V$iSEP;+w(RncnoktQtBqF-0G(?hM8Kh%b)&EGQK9;WSp75=VugQE5!Ey)ak;S`TLkhV0m{o za=0yI7hC5Xc){1M8HUa43i;Q6DjY}cGopieKmmo(wsyt+)t1>KElZk9 zOt6-ZaJklPU1=C+x@I{!^R&?;*JLX6bNhh1z{XgYZZx&h7^M9tW4jQ^c}vIZgRrFs zms~&0XhLO8J?WWWi(g>4a?9V0X(Z$Q2c{Ll`c5_@9_G)?&0mvPLtz7}zI=bS-jIHvbqCtP|=SkRWnhz=Cxr%fH@|L!7O zXoRdYz5QIX$Y{0t)Z`hDiS_$7|v<%KmE_(1CM_0RVRN zgaz2NVY>+jMsMCCg=NTHFRIh^^W1B~Z|<*0?U1Bc#3#da{}c*3s|Zuncv_xnsz2z5 z&Hh*Hd$s>t{Wbo7+whZk#lD*vFEoX(ac{>meDw}os^k8452i<%4(;bR8_~oL)~Sx2 za;^@UeIzCvcrg)%UepyZ-+pt7XxRjV!!U(mc}^`^2dryR8gu+k)u$uQ1U7w~^W*9i zv2JsoVGYXUJ|8LmS$;C^6)2Lzt!cV;M3A;iT36PgPc%(6G`Hu}Xyu*cZFW#Nm`is>GIACYYB1Av%n62}M4~D-*{?6G}3BD+WydpXV z4NI{dN+6JWk#)y-M3fjLxj0-FkVnKlEcpTMS=%HUWl zH!rnDVrHe<7EjfqYoi#As#(BBj38`>ajIR`9*j{r_BE+bHF~Ul^u^g2sBet7meJkv zEnT!Kt(hXJ0wD%=lheYHx(V9-w!ueY*Bfrqd(jVe|J^Xg2L+8yIdx7P4B4D=<3{SxP?y;gv%emxbz&PTuidF0y5+>^FzGoAXo1HB5S_s0I-=IV^Jl6G;VolC5G(W!{QzmK^`p{ebZc|$Y?>skOPr6!O{rwwE+Y)6Mc~y z=jFp`QLV2Y<$URq2V4qmLY1Fr3c?LB@Yd0|d{!Trc%?Erz3Zz46i|=$CI9Oou$-F; z!9`6!Q+bL`2kOO9FPALWo>N_3wOe{xRdzw2Qru_6j9&fmc6Nj@kR6=vk1T7PZ+wdA zTg0Hb_3#7RNyB0}&vW72PDT;>1w5m9UYklSQc2x$SB5-4*qiTNDebPDlN8Yl$F0Z& zMfP3D(xG0_-vDHKVc?2ldrc7vFXewt-z9aJ(;}(yht8J+L30~6V-b_arPC}N`BNDD zH$kzAu_HCeKjL;s2wuR`=5&}Biu@cU-8`1)Z|iVw1h&;vGmoi=c<|FpOn1G z7nt}Pi^ZQ=9mcQ+BCc<4-+4=#WQ!^Qd}=3#zLj5{q6X|mGD2WMFCT4W@!B2xagt*~ zE|Y>A=h^Gz-q*w5oRPw35mk!44?Kd`PRV8dtgN}C9|v99t}f7AvYoNu-Ln^zlGRO2 z!&6lfTbY{E-^ysH7@`NO`1$*l&tyl;#oTjycpG-$kR6ml+nAU6!$}}dnE-|ODjY`> z<_Yu8EB~yzeW^A(5|^lPVA{&9sH5x_ zZD<3rQ`xcpQI!??Bz0OW!&!u>dx6F&c$Uw!?dIU>dOkQ+5oVec&QZv^&2-gLCzyXh zkWB>SFVES)gP1+msA~32 zY@vy+r#4cq4X!VcI`XR3_JzXGj9a`?*eSf~?r- z0@bS+5Ys@kNr^nlJ&8>|Xha=rSoV&zvq~SyZiQ$}Ozp!}?8g1eI3veUg=u$`WKlE? zo%qb~z{2Yr+d^Gs^0X}i)r$x51IBwKspMK4&QWwm5ky~XP~Y2M)+MA_y17&FWhtn+`EG4(;gk%U67lb?4;Q^7wC`Wb1ZrTGx|R9rED7kl{<7 z#5*!`50Rk@%lsk-F>alktctfYB{4@O3bk7>-#^Ko*3roDujL98=;;D3i&qGRB~CbU zDx90nO>wvxhBlFyuOy2I3^oyz@9`(o5d;-dlO^0Ol5VUZ8%{?S?$3e%QL(eZVpW5n zf0S+wbVOgk9$3t}D%Lo}{g<3>r@v0m7!S!Cj-T)8z7= zG6T&-#dhMdMYzj4s6qNS6m+d!E?>nuZYY8EP6uMEzr2SDizXx1E)*)vVU8m3z{JY$ zPaG(oWiE8N+uzzm8;P+rc6WM21po~AgAe{8mlJk4p0o#wSgL@R6sK1PX)FPkv6ai7 zRNtV;V_W_%y}7`1vtwo?$i$N)+xO-EoBSXk1XYdp(s>bML2hc=d>oGj!i6pWnb z;SWs-h2)aQ`{I)ECOj`shurc?^iD}V6I6*esghwjEF~j|x_0oQt?$JU7qri^Ib6U? zwsP-vk7;$J+138OHb0Vvx~(dN-^}WKV{d226>&D@cc2{BDNppVaiH5R2&`_nfQoX< z50V!?%MmusB0Os@r;{QTs^Ut#oGyRjlfs{eM;xk+e|*?1s996MpHw`Y7d=(?{QEEW zH|w%oP(oJ&uybQTo=7l#vY5}C>x$eCa;Ec@pF=*;0PM=FpZZ1x*0hDcOzB(j)AS)R zj0-aS<*W}axm*bMYW%sM22vR_2%A(E)kwqFuxU-rg+mBk9Z=&oEDsgetS(g^gt;Bs z4rxnCKu$8?`r-)z3fQMc{iJeM7iYdcZF@^`{~bGx^Aef@1He*6(_Xe87hHVi<2M!ffKo{N7u68fGsEjuH=S;|hNzMIrbrIH4~IF?zC*PV5gdEZc1fn6zTq3z zD`(i_Tr%F%_zW&#QdH*6-N-KIA!l$j{JO>w_`~N{}^2t#9ZkB9>jyTxK_B zJqgJ=5=Z!O4aakmbv}3ODK>2?Png8>0l`XXQ~E~tmE9BJBDFhSp#FJCs)r3G#upys zQeC*;wJ+-0LUv&AWZ9ArpVlRdZv;3JvU4H+VOt-uQtzNftoq@9yY6dXcAu__fhGr5m$)8z~C&oFk;c+WrTr z9~9w5>~&?@Y3D;f8xsy0iciM?hcwBTRu+rZkF$90B-YUsFw}k%{~Y;CJUyl!g(uj< z!X!N7h2z$)}WfPROnyH|%~h>Js(2 z9Dk@h89>q!zh;TgVvc>qBA|I(&@&B5C#V{we;4Yyb6&|f&pRU@gv zax>Ab7ekCR*#(BM2)qNT)<`?*)*?ewB}=P=!TMcPyQ4>CMe&K;PMWMHIwrEaHi^0r z{bak5EOeTlL=8q?DWvvaptEy~R6^yD$FzMU;UN0dH@i|gK+xW+UP)@_E!v`qgs|t{ z64>`saKL1er34v=jOjV9XPIzyl*H{2{oqm~50mov1} z{-i1qIhE&@w*3@x=pjQHRokdVlU41(j6j3C`V^MeCGWK^u7C!BCcZom;w|$I7rcz+W0xov#*`50bY90O(vaXUEXNJyq&nwd-0vT?B zRq(7mS@gWsDuWyeZsr}x!*?ovHpKO~JC!SMrCno}TNJ;@GdtP$sSrWw`EZh>HFs37 zg=ZD7V(eT&r^>bhx^z{rHL*`{-t@jGr}3tL7F%v^UKa#qPp-CFF5?Fpe3F-O15Jx_ zFOYmLnK4v_s|YWHZ$7+*4nd^gw=Q}~pcy+GXrov21UDN2;yD6T(NW56!lBc>W zML>fRr076pUP_c4C}{u_$Rq;3AU=8y#bO*>$U5J$6EiX?M#+7~N<|neeYzr$&*M2D z^UeCcb=Z3vyR{izSx#(jws#c580+TTVw`Sn?#3zKlXS927v;TLDS~GtOTXeDERYEr zE|Ugw-Od9sdU#G}dsDgm3F}}3dXSmBH5)P|(4FTMeVi=K2g82MZRUBd?PVK5kc?4n ztFV2Opb++EL|BI-WxdK`IdFrlstUTe`6n{2AZZ>VS4cLnd7B2bTWbj42B(C>V1{c+6>s0Hg>g3T2 zc|V!t)dj`3j*Q{_oUBqtVfu(J3iGvyfUSf}b5dsgD?#6sfZ@7;i;_Hv z#B1FJ`H~+$(E?%$$XEOAvv(MR!aXxP85yXo%#U#n!`LUc7%1ovf~l?Zl~Y8VLJOLO zXdFFMU=WXIv1?K}P=-2eXTyBrQyEs28#lQK%w^(ZmzDw_TAISeRdv;_3uNYY8jzre z(djN{=JnxVPuK)W@hD1-HDM0Fd}bw2RcytEO9{$gdkj7#K6YUAckz`X_gq7aoL8!@ zD6`N2rK~G8kMG!{tpYdlBl5CUPO*+4ubFGmiiIG}(hqXMko7z1pa0h{#>k^Am^c%ST@!_PY z{sE{(P#&-AaF6Qm{GD|o^HpCfbKF9#Em%|l z2n(RH6XaQaRbC|3ZcK3#Ppuw3q6!p`;FSm9{bbdTaD!Ul6@=UOQ?n{4qjTif9mKv~ zYU_s?dq!PcLwx3oNwZgkQ?<0tQQ(~$=vxhlD&(vdW|7AIGCsSMJU)ZE?Rlp=dz{^gv+nFsnTH&*_dJ{}BcX4}?(EVzcc|>W=aI4w;WVrwNhcQyNhuk> z-~ILZ_w&c+^LVe<>-n+_4-_AblZmXqgJKO)Rq|B%g=Ooag?hoQZ+Opj)|QL2)MU@> z+OkaEPC~D!L=qkksmlotsh3oNfeRC0aXB|<5ivr47~K7Lxq7L>qlq}WUP#3s+H6SbN$%()_qUYOrp4D!A7pm|inaGu zSJRb8Am|NfKIh}K0)lcK;pPCxXcNMr8_e2+;6@jTu(hqY>YAg~k)HK~7u1TPpl^&8 z)gC>iRPR_hb^pPR0RmMEz>GT3z=0Dpg?lB~rbGwjY2%V4sn#z3ER4lnIk^MwLu{7K zx;_!Oc%1$09a(@BLdq1ZjF_QCcwcLX>O2EY=p^?F&lJhxgZv4sy;=3NK$CkyDz{N} zYAa4IL_g6XzE~HUIB;e_@%#9jGbHk1XCKYuGBSq@xWEUG74pB(1*ka5RBy_&gXeA2>s@8`bKW-)6SK7W;PsI)4sH>fG>1iAk{hiBVr4OY`I}X zE1eS~<#asjH;QvIg)DwOk;_tB!UY?&kPPqmvSR2$d|V|7idYyvSDX9}iu@k~airf- zVWFJ;e02O!KI5G5yx^z%C^BVRW#hN%W4VV<38`YIBSkL9B~EPcHc-tdXg9U%h@$OQmD+TeUHCTDb!U`mO}11~T}KaBW;n|xW3RyW4Ug7MeY3P~ zscHc3tlZyX3Zz_SBryFZIDWxDrMy?!xSb~UL1{iJIF4D_m`-%!34E7LQY`D77m`Q7 z6p4imcz4|8A>Q(OE+MQM>?PPgXhp^orj(YdjL~~_RVqHD$gH#ttR2=sUa)N(LiGKc zxQYKa9=K}ROT!2d+8=x$d=aP|&B8`j^=U|trd{bEw5*%&#;OqgmDGcRO?Di^H?r*i zC1T}KP&rwliUZh_H(kwV)LXdK$u(!~dQr9Pn7fn+7fpH5 zD%`A@j4J7cP0@P_`O$3_eM7b3w%^k%#f!&MSKd(=U|j+^1dQZQ5jPeRhsG_e3R-5+ zq#qpNLet>(v~m9{E8m?WlChkr#!rcLdhs%|)n4q(*l|-rIK4ATYN-$CNRCveqAANGZ{loV+a_Q?+Qyqq;*K(GSsb;V1KLrnb)uo_usGfb%C*oh1kvIA z%(?eP7sema7|p(|*I=e_2+r&(#r&HEV7ZW;z~R{6t=g{0zCvMRcr zgh|O>#JJ_0SzYUt?fnGTj2Dx>m*t+1VWsn6n=7hwJ?>4J+?9DO#H#jXrd_vq zVN~3TYoVSBY;04HS8yk^fwD6fm~#64wjn7_fL9mBEwi^JGh$QzVLuX1%ml`$P9yNl zMj5ubTK5A0vp-Ay`~NYBcyy~JW=z=rtnnd_dUh__p3KN6;BEvAI9I7t{HrvI>(Oc8 z4|5nHLfyS1sZhmCDx@^U+#ta|y8_oDMO`f%gy!KgT(HW_Lux-{8N;n{*jQV0*UPWY z%R>n1l~88W_H_h91Is6lKH&75^*mq&NA_h)M`7p!I}PrstY9~0il^T_u#UAc`o1>s z*q*ZjR;PPX%(HQ7u;3TK4Z`r=snc zu7u+vO}PD@N2HtIowH3(LYvw*S=-1HQ!X1c0B~p0%8Q)aCf49`k39OSE8^e?|3+J6 zuyC3ta(i{SY4!H!;%Or@Yr`A*M?@<#Y;8?P!wr@(wGJ2l?_`t6^=x2;SF7%mA>MBE z`|RyMnPtz8isWKhxuDWhs-^a`I%ze+sk)VXcTgP_oT}GITI&50a?!r@q2d7(fn&pd zxQlDDdE}q4^5q#~FgBsS--M3|gpC$7w@?2v39C?Ls0S~?wthv1mD zsdQSZVdU9_7jVzk)$dTu{?V*+7kH!t|t8Y!cL7D2lt+G?pBue<5+)*(ChN zqd!0g28Fht8oyJgw+g(^=XTo;mFh1dc}M>!W=p>l^Rv_cL~P>u_`-fq_iklG_Wja7 zSZ`G_1OD1Qu+`L5+blRSR%2kb99}}? zkgZfjDh%qT<95ihnal%t;Rzqjl*Cr17QlVcJBl{12N~>l{2!C6Dt!j&mhU|gJvrv{ zg@)&&Oo4JDKtiU2g9ynu;~ewYfRELCQ_S}^<$>diSL?uGU@XAM)$;wUF=mO})Wr1r zX%?!Y5cc0AnGVIidMEi8{^kl%Oq)|S6#^wg!L-99XwA)|Vw>d>d5?Ekf~ut29#-kM zc2G>ZlVk$6X%#AY#9giaI5GJORn8eCKsE}0xLjLV5*aP*+2l|?UfB0HQ=+r>n*E^7 zBLu@19y3L^on36CT*->sMktZ(_@!t&N>&oKT$C&N8J{T%-h3bu(X!)Ds=OQBGB|#m z?7=(0A;dA}Ifx^w?4j*x;KEPcpADjU*Xr!ZqMo-$H6JN?QAR7biWIA7%y(41p=IiV z#l0A-oUGe>PX{$z&Qik!*fZq=DZYclwCd>>C?qQvFtUeD2NZ;q_R z6BOrlwPK^Eg!vpi6N{*CvZnJHwGo{C(cDV9W1(iRp!*HTdDcdcSPD6;hA2kAN1e<> ze3s2(wavX0MzZWTImEI zXeMJ9nJko*Q>DZeoUhriYIn$YkL)gQx}tr-3B@U$EA^x(9u z8yMO`V)6cr`8T{SPKj$w&7-WZa=Yo3p$IRDF$!E0h+0>sSyN_$b*h|Gg7jz2jK&m| zN}!HxbexXpC4Wg~0rB!o%Bl4$No;*Cccfo!kfvC0z4Fbwm71(h%ZRVMpHcscD{`Gz z(9U&6N@51F_v>%1Lm8Z(ue)!Wu)d>Qtwu7NZfmQ(1})C9Kd2Q_k_@(;z(lBj!B3#} z!MDMi!o~F_hS5>CN>3*l03$qq#A)w2sILcSVAwa|l-2F*SitDwDLm}HWU#0zNW8Ts z4{aw7&bHym2UcSy?LYC30V7$OpmAO&Ml6tywaOAb{Cjo9{2+11x^RRIU`joXCcKpN zv#MiPlT@l?x!B&lhZn*o@Za4O$gcKhPyv%-)3QeH#9nJfZ_^tKlm4_N;AD)6=MEuS8rjvXv&BRGq{suW% z-D+Pl*rKu$`uHKL+4!B^_l2ex9apUGu+!R}qZizOu}Y{}&`oC%vVnrOa?ScXmY^xF6H~ zkxwAZ+wWE=@lN-v)2`-fRp5&sY@uzGsSb)EJ8xd&BXUJ0cG?mj=x1LC8t=XN^$-IJtEGJ5m}=7G#2^FF>RO@$j4F?QZ?RvVlN*UN6Y zHIt3HI!_!v)PiSv*|F%1RH zA~=SpxYSaYD-J=ISJ636G`IY7KYP(Db-t2WL&&sR4&i};b!=XpRfSvY7O9@#6fmv|N9IF^9Ij3$rf&&6nt<`l>0VZkan!vj z`RGE|mWHU}ROJ&HU{s3R^}$zCpi&FJIfX_}^Xwr+M!Lkx)li7-mGb;39xf% z4{&(_Ps%etcFAA1TKu-=A7&7o%x&rAWU68pOrtU2C)u14k$@LJ8zsilrvX+BBkW!L zzV#k;E1G`w##R=5OfXP*CKtUN4o<5IH2NEnsgztGC?`#q=u!J`@w}TFgR<5_7Yr z6>s+kH%c?n^nArTRGf0BQg`6${do|IqFp23l|f|XE8iYhe7`9Xs?v6fD<`C9MvCbb zk|Wu|09utUoFwPko2A4x)!CUsyzy%`4zBCig{|Y%6u)+lL#DA<6!vxlTKV2L$+32t zxT=yh#8})DM6Mrne1^H|=U9|Kh0;42XLfi_Qt9_~SG9*YZ(8T1$$umcY0H1|3BmvV zlfi$W?picw$1>h*7|Whxyxd$SL=d+W~3ga~nE z96rK{^~xj12t?V%Bb?g0S(X{vNyjA{(ZID$>VmnaL?F*QPE(8;AuGVJhfFOG<{cKl zqt0DW^U|^>f`Q4AyBgoT%HzNUj*nN$5MmHX$smZ{(YA2v7|HtqlHELPBDyiN9Kt8VpY-U5KGCx13Ju*lzvhm~gIfBpMSd)n@Al4LP zdz8m3j|hM0Uc+=gn3{qf?9_Vtbb{Zi-VLbLz~|&IU)t%RQS939y_hcX(#aV+1NfY3 zt0QalKZf8FdE>PDtxm|j03AzEuSMLRln;X4OsGG-!!tP|2OOk@=dc@upbNgwr%M6O%)>U2yqNN~n!&=PAkiQI+N>EIPx0To{b> zv-A1JpkAN2eKO2N1#luiZD*ub&eVsLxezR0F)?~=DxBH1$JttVTDDWU5N(4IL*HN1 zFZ{qgKnUTw>O#v=0#@R|TekDL<3ML$_}c@<{B$wr8qcBcf!yl;eQTU!NlpH>70?G9KVS7q`HD(zVsd_Y2%DcZHts*KE+YopO(UVn3(LltC6!;Y$q zH&!%yRz))lvJ3^EZ)SYSCBP$fWp1nq6x%jth3j>~6$U{j!fJ%UJ7%LljkMkoCU(v? z`qA-E7w#x9z?A-)CeO^=09RPgusuPGyAjvF;1@MIe3o>p9Rs^R9^-J)D(O>?NIq6~ zCNkJKipmT^QlG9eYUHJM@XNOK3`?kjraY+j(3;+o?3Rc$42YfgAABOfuha-qDh#dF zshtRc!&@RRTjTa(AP@5PSVc09?sZJ>|7N^?BK~h|bacwm*zYGMwCxzct4l9*($<W4V$R>F`VO3dky0;1@)}`OgZ>OTVpTK5t0qOus5KtuPU(Lv;rH1? zqrp`D_T!7fM;SWr$jFb89$n;$8-E|Bc#W?PKb*Dny}`nfo6|MLRHx>e0IhL7&Q|5H zko7mf`Lebp%wD-{xOhqRZ{3Ugw)I(3SrjuJE&Z% z>n4_ihD^TL``E2$LAzqI+$znx5x+df&@hk}WVdT0(oOE`PimDJbCYTXP75Sl9to$} z2gUM6!`>FG`G5DX547~f*EQ9o#~U^jielA?Hq~ z5QMO8(jWfJb=aET0Nx*RPZLrslZDHKTvtD{PN@)oaY+H&I}ezO z=XCSU*9qkcis_g|QgAWkDvM9uU8YNDR?Jq3ljZZIpBevS@KiXxq+ZZ%xLzs07O!-R z#_kT)IYa&j&FwboUKydCOWW5tS|V31I{Gb|;hdu^PZuE{$3xbS?lWlG!XC+9U%06+ zU7C=NW50cdcRO=f*^Dlyn#jr=5`m-6+c((B>8ph`r4)<}G4Z)&7 zHUxO0N&*`L$^!bs+SE!72!S>hGQWzZgD58HqNMcj@sR;9_}grY-jcxTlHSlbtN%a> z99#V)ykBZ*yyheR@Fu^sZsVaH<&}qxuV4xZ6t&+4vUb68HPoG(E2m~Hp20XzD~P%B z6d1A>GWZlMQkR606Q&D}d+Jdx`)0aEx+PNj3Fg;)KY{tBv)9KuVy;SY z2V3^hjS?!K-m=;dYGeIiy7yvg=ARDonc%%BAvXi#5Er7P?jK2sZ;rX+%?h85JBDtJ z_EQ>2hOn85?B1D(oD!I8qpS$oP2CrCoDdxOoeN5{V(`Thk&UTy zdkm_o>i!Jb+t>^ob)PITkP>W%&w%5x*0yIfN+ zax29{6ZA9Fu~w=;HzD~}1@MZrJ!_YW?VXv3A{3-xu=6&h(9#rYcu#Fp^|un2`kyQm zqd#Y7sGYn4?*sXs{0rbut{a|wt2N9gd=j0X=T*NvSU zy2+L^EZ{72wOVCvZGafrDNXPF0Y^FA-^j0xvz`B&r-sq*&c0L)AfezGkK(98)?vtc z5geX~30u#+87MbGZy3Gcyhj}^ql`DZ9?S^yVC{LJd0B&Q;y}L)7@aBEsoNQ#K=LPe`E$&)wg`Tsjiwo& zZDc9RQKe`^3txKwFHRXlktf2v9!NwY0j94a zH{P&tMvltP+v9s@T0)AHkW1%p2k=A>mn7lLc4WlN0iz9qL1hTeH#;iVrJ&9#17ubZ zNH<(L_qUyeX+ETR>Q-m`N4b$maqv2;5-@m~40zYQ9{l&dW3zNUPCRH=lpZy(Co5Z| zCRPj?cNU4Y@t5^ieQQctJF6t9(6fe=3kbz}Qa-g#lj?fe*k8!|-5(Nh0Xvsh3`38G z<7(j=lXej}=&07gADq~y6yGhj!LLziai%Sde~X{AOIj9%Ze>~Zr{1Ck+3(n^sJ_p}_c8P_ zGh7FM4|Q9Ccewy?=g$j-UzCRRxT(a{6q`Y1@2UOO zJ}Meq+ZF{}z>3ZsPn#n^vTi2D#E?Y{|CpfdXk5=xQGNrKKa=I-XnDWf*ijKT*#x;@ zE0G(%L2ro9YupA+6$eM2tuluuaeQTy1T_-NGKI+OnpB`V z!QL}nZ4!F7v9myeWy5rtgDr5$7A~`bjkTIy2!1kSJhE3QzZzvGg;mnvX_xf3Sh zcR{T8VvQ6cv4O?dK$MFprPUEkHdO#V<4WPFemRCU+Z6P!vHtaV=XC55AH&Ba=$#c* ze*7Wta(%bcs)+;KX2%7Rgy!xXwc$;jc;f5UGkHIt12!RPO}1@1K#b1aX%7p!`lcWM z8a~`IGg2KbSV0sJYd{cRukklyV6!9boKKH@KWEqHc;p1diY@&0Z%xF{v$FWRld3}7 z$ZA+o^#j< z{+d)Vv6Z?QlksdwCzgxM9 zgIREzuxic1DvRA!5nq^S947J+hQIR3+l}X6^=pdLt{~yqg32)}en77znU6pTe+5rC z>JHh6?#zs)F@@^uNi!@w8@Tt9MV6g~%MHPyvn5lSaY9B6&Q3g#a&Qq%fRDs-R-bM3 z)ltIJe#62{?M+2}DV0?;h5d6Yj=*I5wu1{6DHSG6zm>{OYE0i%&)L85WAb}h-9zs_ zfmJa@!H1lF*U8UO3&T592XLEXeamV!`yd~u%RalAZ{B+xlqeM@=nIQGP)zuQg=RZO zLpm55>j@K;{@0Rofu1N|QRvnf_qJ7&SZWhS&4ZMpH^!@8n7T+`j7IOW+vW zr}0@EY2Qs8ci^6gTOnP?2=u2oxm)r_;Gqk5EGk139ypvfm@HLp!%>TE!Q`P0RnzL!I`_N-F=b4h^-w~@2MG(gB9baM2^Dmqdq@2* z;UJ#*>#nj>_kUHW=Z}JZ8{UfraV0Z;E)}T1Pqb987sS}_b@3D2kCU5L41Gr{GF$$p z3r4zqM>aOMZ-!QeGz5uevI)pXlP&B@iGSkgSKw}A1(G8-b^%}t!!CwO^G+wp_PNRe zeP}Wdxx9l~@2+pY+XV{|{4)>_9X1hZlG*5H0z9_yh=CvP9=wW=lRX1|ha-e}_Ag z6O%<@XO-^1|75*s!^l)<`KaA@^DD29(&}KnmE}HN0dBgk_5h3w`z>L6I`Z_gp?ZQW zx38a?bW9$AQe5bN|3q~m=?7W;fcJ(U=Xghe_o@H;tbs!P36w|sbSv!B9lI)R_WaWZx&gQF9TH4})l|nXh(+|_i z{}4pScweFwH8AY1wK>*P1!Q4arbdQ|FGZkG-KGDAUzVqDePD71jIbQs+dLmX*KAIKwogj|(cbw6O$#0u*FH=$gyoyia`Q{;{=*W}f~)v++LOUPu< zVV_?Wf{nvD;BplM&=Bk!!+LC-C12GpTV>ZFY?-Nrs-s<>V(s~oSuDzttmNl)w+bM7 z26VeT&~7b0l%B{J zZ(qO&peoRW3*0Q#ArAZ9bRAPg30`T9a5L`R5X_`9TFT^yQ<%miFm|`ol~&of`Nnw` zFm4IoE?W_Nh}k|TQOUx|ivD1+)ryeUgKQt(k!86LLa7XM#l60vU6r*#d7wm9 zY0cq~A^Ym(+tMNnsD7|kcD$5$JAZ#0HUfQWxXc~!K8%G?Z!Fu@>nTB47sUncnggRU zBI_ZPv-J#1>LWa>LZu6g9!OEUv9DoRa_xIz>%uK{0-Mh&spjblezTstjDk2Xzl|Wh zJBc0>A#v|=u#}ryWVlBtO%?i$?l{GQMybK_Ca_59TgmF!z4)YeEL7KI+g?v&*P0Q3 zSO^Tg%|t5?UL04-VQ<#rzDq^!vFIb-hWy3NGv1HNwpu67Ut?2=<@do}4D>-Xau2E7 z*ZNv!W<||>qH*|<1YU9IFXI%h6+=ul(^Q*``G1^_UAbQAl>=uhO_z^mX~1}?qjZ6e ze2c_Uxf7``6@10JO!F3xA&*c6-C}+4X>z6DA0`}~N32ntL5`x&jLaUc0@j>#K*vCw z;6H2adhb}#ISk;-4uYp+JsI7h261JrbnQvO1MGPMdD8W@?pEoBikuGH((I#S zChZj}lHPO#{RY1BO;`w>sEU~+=7>E$&cCiMfpBQib0yMH7{RE_=-Q-Cy1e%;#wwPl zj6x{d{xuwNHNz7dpoA8huBFaj{AnFc9P%k255>xoE-^Z`4PC>B zD4Km0PCG21P`~or7f>;5;`pkqU+p&+PjmVJ$dJDLKL)s5EC_wWtr&j)`dRiW2Dr~# zSD}h1pj2Ut!i1%|$ATX8Dcm)8vRHG`jpcmsz%G zg~(&#@Xs&xTw&>R%_dQ*DYsCrDK=1~ZdTY=nzB=~e-%YLry(BkCX5!?6zvcccW$Bx z0nhi5KiIi?x=T`ek4w-2tIKo3*NC^h@7SoP(d30o)J%*!3x{tJmuIMQ-|k`g?NWne z&xL=S@7V7Qz0YUgWBqDC93jyan9D!pxc|q{fZEmr9l(Bhj+?6k#<#At`ubRC`2hr? z^OY@8l36_`QZj_+YHSy_w%$vF-K?K?KN)dt1xux7GRtc1c%i*CdL;IvYx7RbZ&DxzKhYw- z5xasPyq~-kunCL@KS0i{`=<(mD-1gyv943ReDh7zQZ_R~>Zk5l#f)1j+7}zEgim5M#W}y#y}DXW3wgH{kuQDp z81m}C$J_LuA+eS>HQQmNWzkX@kEz1tq~UW0mw zkX{s2HY@UF5!x;s>!}4$Vsu5Vo27>C7(s2in(7+rc;lzV<-$Ys9=L6*yyN}qPTb5P zwof2bgNUOgvlD@sOYz`EkRGNyie?v)>Gi;6>Bf^gHqUrB=G+0JEEQ#mvKLB=Vm*pz`-e@#eWJPGyxx`^ zs84dBGK_BzPTqOwWo0b{_s!5-05-*(#$AYqi$zMSi?C4IR2HMHz&Q>e6}iUN3l>GO z(ePN6KEcjnWr>G?IvOJQzQA9cR_9rs57z2IV@7QV3yRtPD2!ayY=EfoB#f{5rNkx4 zjK#A_KUMqSXHN@H^GoP|Totc@s=x4KoX3X{A;rJVMO@yuD;K&nrr5Zn%ZhyWQTdjM zec7~Y;QN))f1|6ipW7CgA4Rbp7txLEHnnnA2XJ&iNs?TtbX$4YV<(G38b`F2#JPs@{(){}bFB0;Uq9OhC zTG+JXZhi{rI*7fwsb9zcdy&MWYYaKB9==@`dr+m7CMKkFI{l-c^Wg)`#x<;-kpP7( zW!YI^-LM7oB6Y&8HJmfuFsEm7qZe|Mpv_ZiufMD|Y|{%g5&!vr4423`1>3B|SqhP= zYZG3H{*7BC{3!n{F1buV5Pn7~cZg#VG1e5Ww-P_BM0xE_$Z=2JgArPUwwi=Oq)}azqjQ zS$N;r_UEZ#)5qznPo&*0$g)f#;yFEjCU<(alD}URcqRS3SE`4!_TQgOrf?jQZc0_@ zo^hyEVf$5yD3t0^e0C-~t5d2#+0_BHg;9_nx`g@YV{~Z26U7yX;d`#*CnTij%;2{4SGvKVC95 z`001HsTY#jxOIwi{l^U<$gPI7M=_%hyIkxkp4LMPN{CP*18yKAg7}UvB$J@*yH)9A zBh$k32C48jr@PYi4?)Y=b`?gD_Jo$GGu8AT@ODt3RX~svXY@jE+nVi$?Ua@A8wa5q z{|JoOeEL=LHz3(}?fL=R_H&fylCbJCO3%u$*Ukmbw}jiT@?|EQe+%gmGeu^v8|lk< zMP6ard~lVZpu2h|9Dl70O_S&QTlYqW~;p+6@t_<=>(PNKS@lhTUgl&DsomjeZ7Em*f>Z(!&lxJC3eano)x8HBHkO zZzmA=9aMNL1;i`&*pJM6&XL^>1rxS(kvwlX7gvfu5L4@EK&p0r4a#;#S0NWnIgfEc zF$J6pDjU)NvbB?s@`Q)SzuC1LXsP6c_+yTX2{URQ4Ia+mRmU6rlR!%Iyo*SErz~^V z(_nr_Tjk*FMr!z)jFPr}hRZ2Y2+ks+yoT;=%6L?euI1j3N0Baw7RPx*^R%NibdItH zbn{iy`IbBfj9YExhCnyK&K({1E>`iMj`hgu%pRw7ojTT&)ml&!w#oP8zg|8;)}4;V zi@uV^%2N-#fM*-U=@bJ~+3%68j3@b)><;@Hl|0m^4^JoI>(!)(ah`o#eh(zUfpYIPUd|H2-Mr^bo>H zu5;!pngPW`OKxnq7y&@i#im=Fcp~Y+Ok?@kLzwdw!P^-6bqMc|N9d9stM~(RKO6s#VR7QT;fMeC z^@#Cf;{O-~6vJ%BX4>cC08WFRTS;@PfA8;0MujhDmSVdUrtcJ} zqsU!_v|}oLfA^hv>E>sx*aJP+1AR^7g6oLM>Q2Q-7xS}B^bbS7#K!>sfQ1H6OCTLt zRt#v5?l*qe-;A7Tjjm+lnQ&!J1o0TJ@?Y*C0`;v zE~$cIf0S+3$~R>s56Y0}0x-X`0aNmXrkvv= zkvX>rBmkp&K(v1N&E+_YE=)n>3sxAH`yR4OT#|7}vg6qZf*|uIfwLrsKD&-A%bhS_ z>AP481!jk?#YZESoY$)OH$Up=kyWxx?QP6h($YvPjbXFH7!^MJ+pyzgw0xvxWXlXLez@ zZ3OoxcRUFUZ(oCPR4yKh^`smy2x9b{32`vzxerIVc9a_QA{Xox?i3Z!pX9epZWKzR zhWIyhL_9E_I34+ZN}feKXI`^EIDi2I%Tk*tQ+cDDgUFIt7HfYRmuhfoj}KvUpg-Zf zR^XD|gb&HQ>X6kd5>u_EH1zt-82<;#G)DbkF?;N?5Dq^zv81Azaz*_A8Q7(;p8 zW1N;Gshg?nDp`^LkYNtFSAtCPA7ff;3Axb%}2L2I0%w2Jbzl)Hue4Irvt# z@9PTxe1?nF7QW`B7UnIxYGqxds9;5)n2k0%E}pH=$Lq21PvNv6!)OD%lEB>m7^Z>* zBlriN6= z2H(ChZt43gf?HW(D$gr_tN+Opx+%#!Y9pmGCvS-On=Bu?{sLeF=DqcJ*(U+qJR3%& zj8(fPCJRh)Gd{$15f*a7!xtaemq=N8x_>~FM63O?8o1Q2|9vn2*0}Y3Ny8}K=NnrZ z-%Ac-8(=qcSJ9hYWM;!viP0E_imo~|+wj}@CRODwkX zB9g^sz;Ch9S)I|6mBZY-dbZB8_Y4B`Jixien7eH6!)i z9^Z?=ZWy-7v8E`PtG-R7ejKL#Rc%b=jN1C;Ch5S=`~7jQ$k?C!hB>`U;4!yAw~%{; zw~MR*&z?6{F$<0VrrXKzp&f1JW~A@H0n?Lqbr+@nes7NyQGBeDpS1B@MG5iEDmTEz z>LsMZKW4O#mx-|iN2ITvU;L~QBEr@Q+DBMD8@l&n?#0`HH`Lm`3*bpHB;%>fvUoz~ zgo98ckKROs;qO#D*u`{((+Gc&b_sxDC7g^`Euj}0>3h;Qvx)h?3tb1uVP=))ZhuQI zBQs;XIo-knUgK{H*tviDX-j915`Gx!;hU}s@efz16`fY4j~p$Ggt#c&hz^4;jOt{5 zMZDbHmyhUMaVvR8Ho7k%$3MJ}aspcZm{f z)ckN{*^#>I+Z!*E^e`V#^)%J_n){W6Qm0s<^wANv-N0M(9WHTcPG{b|rVyhHLR z*eglO&FNoqBXv_`0Ppd~A%EjZ-@dZSo*-3ft|I(mqmP^Amomz$aTjc4Deff=mcxhm zL@25hyJ51;xCj{oflp1FG1R6(1h=Q*bqhv(BTr41ad0Y8Q?ayKRgv}M{;s0g3p7{y zi$km~K+GkcIfugR*L(B$K2y?3<8#e~vpk3dqvQT1m6Dx=IfTURfBF9ICq z;Kij~Kyq%HUD{j-x@5OczwSq*-&1w=CHt@ZcSY}YHXNZX;&fvjf0>STKy+2NN>MZY zD{+o~S;Xnq z`P{-Jo9_RsX0mwUh|z+D^dFx zlBP=!{z#Q;y2!P(>7R&Y5c8$~cq1_TT@i!_u`||#XgXIjXu7Z&zcXFwh*Pkxj(r8)Y;e&VK^3cS&!wSj|!CITZ6I6a~j0Z zqyE1FaQQa@jgjd4i8Xup7jG0o>c=4Cf-suQUe!(NS*4D0rMyt@*IQpm`MB2MR+ zJZl-I+X!BoaED{Dc!{R!t6;>EmJoM;UZ63?ysJV6YOA8Db8Sc2d6qF7Jh;gC^Ma6@?W_cy}xeleFYetmX zkvQ%a#~oq`A-o>DR5>Gj%}x6_v*e5tV-)z@QcvF3`95OYiaEteESBIu&|q}`p3)Zs zM5b%bBfG+(Z)#{;V69Rg&wbFx@mk~89E&ceW?g6I3`3MD3uGz?K?YS)mg5->hzS*^ zYTM5jZhbVY+~fI9;^ItsKEwTP?Q+w$?iRlF;(XXX_yPZS;zN=gck-vt9Fbe8vD2dL z23UU4v^>J^rqnhxLsvtNPk@#BX9ydb^Niw{Ji-vFG&H3U?%DgA=5%X8w4!bo9DlF0 z!13EYz%o?d|I93Ab;xsqDS+bR9_kWJIn=(H9$Ev8WNIPIwbD$g8}q+jw)#?bRC5Ad z&h-pdk%o*{oL78Nv18a=fZp{eZfZ>a8ZA?37P`agq;3k&-2Baj7>nt5u@&8sv{6jm z;E%YHudGXy;7y5x`-5(&9tg`ha+W5h2C3;4BS_g2(9axB-Zj^r^f2sb?J^e)H|ON& zpZm+{++XIo#b)eQ7YoqdXB^`Q6uVnVTM5+Gj5e>vc)fW0b0WAmkvP2rQn_}slR^Gjvc#XR+`Qf`yp%lJae1Tl(>%FEdXH9|b&L zC^d?Tj8(mPiY%oAuRQpocD!wGP?f#>_Z7G~E!>JJA#O8TZ}#Gx;VNWGO%Z|BX^3Jn z=MZEj^<27V{crk0G~C1=NQ-kC=O$%X&^Lq*PP1w1GUX;22{{#`!`6=Q8q@94K;K0Xc|K4 zwekWQmwFC-Tu6ZNcTiZhX^d&!elG5~XU`58bZF24a)+Z0G;o4bkO^FR5ya+d$U4TU zE!q%wzyU3W;QBqtOaqoV5vtv+nNQUYl#bDjrw+30Z_7(L;vwsAG!YD zszP!#5zqLV=pYzkH;IvMJ>wiTE>&s+oBT>*;sC?~&MsuS-^w7^@8$*3aXDdA7@L?& z^YjIntbh0TCgT?h_J~Ij%nd-K(BLAZunADY=Ef*G$_&c} zu?vh;!z@8U)x^#mzzpy00v0gF4Pb=~=gbEEAOf9`wg-Oj&9`#s>2O;uVFH)726GiD za2uzX=!GaI$3A76++*HgOE#Btbu903*cWgP$!QoJU&IO_3wPoor}!e@2jUnoRjYYj z4a=PI8kWP@*UY`sa~wdcF&>p((9Gf)UjG0xm%U5f^oi4Q?aL^{$4|roqx^)eaWqzm zi)^p7DRor?cfXl%zNM(FL7+?1nR!N1BSIb_i&}xJa_wH9F&DHJ3&b8djyOV1UM3NV zjnNwk88JZ{Za>+36%U*IF)%qkBHOGhQ@;=r@o;&_!5y(JL4+6_8L4vXC>dPDYNd`Z z@fy&pj9GOlR^u3&_k``tP~{C}0BS9!a=KgtD9Dluvdi|N2BiF4D`DI&j{L$F7jqo* z@eM0fEdrv^DPU9`m`s+cGiKoG+|)vYsiA*~o=r-Uzr=f1=7Fd$Jxds6hY{_c#HqQ= zfE9BQHzx_Wc$PoVo^%WaDRv>>iLyHwU<&jn5U$>HE)=b zo{@uy7v>D5EI2diKN98KVh zls+_5ofY_n*t;x6&q-FHbb6^*82my3`a~42GRXL{zPbE$N`E{adZxdKVV)m}kA%pf z6^B_viG8v~8wd?ve(`)6Bc#;7QVGLS)mwq3AE=ma=3B$W<~e{IpJ>!C5KJ!&U)^FB z4Y5$_n7Jv5rAEg80PMpf1Xvrm!dvwVm4(Z2q6NzlS4_o>TtUvD)^isJKY3)KxpQno zXoXPr66R;FuQNcnDwlAaE(Z_!H0o8T`UOdtj+udwn%1DMIkw@tT&C0})lhP%orK3O zd_XO+DdGxs`-D1Fw`-JoV%fy7QtQ})miHT4Ux*sAz2(KqCRZ>OhQ9L_c$9GDBC*5* zS%`*<@hz@Woh8JJ%vm={l-?O9D{w?Rg$Bt>wDBz~QBHGlZ8XZSI+)`_?Jn7Mac?)` z21hekk*TMclz)W8NSfDQiC((A#;dV>N4Ul`MU@7oSW27$eq)}Hg}LyV?MvekUr9zE zRo|@Yd12Y6rkK`pVY!c!c_}dVqiO$6sSfSM%^zF;w>lQ z8(F!9ZtLb)njWxX*tnM5wQAwT)%loXq`QyymaHF`y?5+KyZ9m%>=Z?Zm+XMzZQFl{ zG62lS=03pAypwBgXA-?r0${Ctq)O`X0=CrT4_(Dmcg59uT4p#1O4B72odz z6rZR@w+T!@4xeTQ%}hif>pPYPf8=hIG4_Trn|Mk>{-og+wa2maiW>g_ptv^m{Q!X5 zW1%N0OcsUsnUpqT5qCj4nU6GS$|*^cl=g|eRT}j$Xb-0gK4Kc^r>u`)LuMIwsn%S> z^Z_%8NotgO9%i2&Ce}q!FUQcaM@Z*dmNCSw5q%coJCw2XCJbg|5l+8|Ic8@VjTp=i z@Mj@KAIwI*H}uP8!IlU8`V*yz>M83f)U_4HAYSQ^eGz~8QA04^zwCF5j!$J!C@Wt9LP&MLhk*>_L5s@|K7y>?Jx%hJq30qZCw^NiQm>7`0pFp&t{1!kBu~Z<=@`a$! zQAJI_wEqAmkiuNeqhMhQw-?_tW5lOqt-8YDUx-`Yp5|qL}v&KSf{;dpyNx5LFgaMIp@3#H@|StU&?AK((S`D8F~{J$WnE z+~$coLHO1eL8HbGLbDzM$Z*1+SMs5RJ1;v zX9foi7p8Rnii4WVj4A1&Y^|#_|Cj+qct~vIY;|R<+zvt4bBqOwh!gQ=XL&Qz#EO~xq;g7@*RYtsG zKFHzpln4EmlOT#=OjA(gzlqkw=4*^Ycyk+JDbI=OzcWWjaUooP$R5N&oJUb`9mJ!7 zWFp2AjXIbZ4gQQ2Gnd2`^SFpYh(gQ}2KvAqRN|;KsY3eAH)MA01h8eI-QUd9Jot)p zQ7j@I#KLAd-x9g5p;j6u65<0?#6x(2MVN@4e$s;{@8}3`b>ePY^D$xHv@^KO-9@_k z5>PvXye?SMEwcWfBAl?~7Xc>yH|8$AJixIiZl(5Gsc~$-Y!>RGbEH9OF>2seUzjDe zULkfsQ5?%;f6T3xS}zb6XS6X%kF>hvLA627pqPZjJv1`*lub!EArA!DzxtIN*hVcG zz-5;O(-}HMDHv=}zq~}Oyv79(*=8RTEaCgdqk$@RedV|m9@RJkTD7S5DRG?Ipyh7o zLEHml{ty*+`+{qAGJq|uMu)G&&eb+g%($jM>r(kFjYfqI4MwS3Cqmg5lo8e5bgHx`4K?k{vy!9j4;inlxW`V|gnB~ic1 zVy#qEEQalW5ld)ZT9?`t>!>^WO-5r49|lx!@8HROZj{wGLLOi5eK zL+vx7&HMbzdj9}LE^d_YSBO(7V+@^R z#LkXobyqWw`#NfKGf}!~IEhE$j5W{M7V@$PrK{Q%t^zI0;&}OvlP|m=Tr6f4ILkM! zeqj|@uYx)-36~5RyM}bcJ5CWHZ%7b3OFax08Ck4L+jjus(YcSxXHlW~fHHspyOeTZ zZ_*NaM{|3ZX9>d|zP+RQDiLQ=!p5p2*A2r2WT7l$Xl8hse2pyOlzLe4h|skqFUx# zf%}HGweL_4G9m>gV~&rRaEX>uvk=@if+y6TA{h~7y!nNQM>Al{bGSBxckcqOQmz=) z%H>T?q9wI8;(o>u`}s11huTvS=AoDveXz=E_lyQ&GKHYkd&=2i;7Y*&WfZ`VYl??M zXxA>i;X~;RmlA{aj3ItzO{7`|UL`is3$OV<5J^rIP*qx(F82de#8?gcM0A$|!&Cmh zEi5-12mZli%g&S(8l_pdU_8v4l+tqqCaI}vI{B8{Hz)_~6Pqz)tCWD;zyA45F5uX* z{K~etEYvF0bi^$ItCYH|5~d4IE*7JhEYYb!2ajlsyh@`sk!`!0UFG+U8Fw$p$v0p7 z0?ZgCm(9R9!#PaCYI7d!+swByc1j&I(FtaWa)w?a(u-g>d?zaYvKPpxF(W7^C9|TZ zRb1RoEcyT%nT%sKIT-ppYQ!-C90pFJW+g~t%jwnLNz3;-n4QvfElp3kn{V~T1RJ{4 z>!;|ESCuxVr5-otRK_dBp=nUaQQ;1uQ2vmL(7AF6lYg>u?eq%)x(vfyt0AiC;sC~G zqg;R2InRV{94!e@#1=i0hzk+usCx<2uZhn$^c=!=oMBPH`5>CUBZ9_wnH?puLmb6! zd5aL}jyk0nO=!QA%M7A3QjDiU6x`^{-DADxrI==*vpKl#8Dg2Ja>_|?o6-m=qGSV4 zwAfoE)UV93ah2%+QmJ?Ya)X3-2rinIP^d5y{!Vwlyt5aWfq7USCQRjHM($YJ#n2?8 ztB;5lTt>FDeqsw@9Y~oR#h_{N5Ep?1dp|Lk4ctTN<^Z+aV;|%ZeP!z7?+LG?g9;|A z{v~Wx_?*d#o*}(|iNR-xS-r`^r`30%vhmU4*qJ(kO9qvV!7Fj6LJR8=Vz(2b^v=iK-!5X7sXA z3!)b13{v_**Jy)vNgY5aj>(o%FATipUeUC=o|wki8;jF&(RTu9r1J?c_fQ=okK!wd zSR1%%wNR>1F2CwAYpB=`;%^_Cn z#J*u(W^GkK8-5oa9P);RRYX=lQCD#E;rNISz92Zv8|e+*)y6f2&Y&fLOQ4%Y)T6C? zO(L!-cesNYie&x8TTR1@2-%dDAMl9DB?dR~E{0$$+4q&oWU<6l*5GcO z%_IA`?3gaDF&qyBRilWahNX=>!t+6##Yzf(nCV+2{KVi;po$4W_JVbF0* zU;YQV6D*U|$*jb_6ozm^uI}Oj{VtfxXHJg_buHrTf zzS4ywq^Ml8Y&0o%IYc2*OYI7duQRnllvQ86)ruf$t^sJr!x?U&X3DR6lrsLJawWsn zP*T<<)fI8gTvQd%-OC;`8Ld$c4N4feyHFf)2B3>!qzPKTl4mlMW&komaZpTZQQi2I z-Ay0)I;)j;8(x#YNFq|)AG%P>2$Uu~mwsZ4ScERvV+6FYff>ZTK@pAL;vw|&8mzQ% zI6yOTo4>?RR*$s5$L$Lt!xy?GgkcU8I(O!w4LN*91=LKx9Rh@iV1LGAta|h@ocx01(_00))GkB`OGCFL_BT)kaISP+tgq zsRIz?*Sy|w8!IcsC6=q=Ce7j8>Sxc~cwVIpW4HeRsZwgAdtrBpRP!lTrWMTn45ixm zIGTQAdf`wjIDo(LDlYB=ih!toqKUfkP^%5V#^nZ`OI|9X_(~K*e)&WQeO#uA!l2&F z{{R6JsH!r;)lODt75J6(5aqdS4kdk*0~4Zo-dD!H)b`@n(9 ze3M||_hK#$>WHOZ40FLA!EeOkJApxU^E&4KVrs(@wvf}jR<#B*5dlNm;aFdJrVzqH z@d^Qo4Aevg!4C`wXxgE-#G|fyre)%OgqXBK^Ukas2_2~V2QMj*aVtn>t+AzZKMrg( z@9)x$ZLiP(9BK3-;W_$00dvk9;Vqzl@Pwwg@F527Ljq1FuOCht5P6j}%?lHH1Tp^r zkLW-QYpL`qw6gO8-ouz9)87fnB0bVc?SRUJK}5mGLQP#CiMg~tk1&!0ib8f~fJGs< zGm9l534(vv=Ll}(v2JFPR72P40}OB^FQ`-7=!@$T$?57T!}*(TZ-&)Fo|pTs4bSUa?r-8=2%z$%PPn(Wv~sHUwM_z62-d` z_lBVxFEGe<$4(*ZXaTIeKmp1{b#W;a5%2q$wr!U0AAs+^- z+Ew?M7uU?aRaC!3y{VzaL=?ijOWI;vL$7&e6JL=7V;JUb;#44HMSP42Tikjq*gs@TM&Ce(O^~C< z^9|dG*)#2aAb>_2I{8Fsh(yhQucn0vMkU0oGhY)S2ZdDN+mD=UhO63Rc1LAlIQ1xG zyv1hjrCpgo{6xl;u>H-zh3Ua9U(%_Tw-TY0#T3I4vfD(}t;(4*s)dZV8ljR~@iiJx z&LI+|ui-0us1UJ?Y7d&0p>TLBhMWcAq!wKzsJAdo%Uc!nP&Kczbr~tmuM*jqs0P=c zyg@f)wYsR9;V-jrG%OJSqa?vQMTJ(NsfdGmPcb~IWu*N|P#Jtqftaiu+`3+_P-{0b zXxj~RGa%{v!iqn$E6WxEX1*Z&hr=ud%Ppx*HJ&1KTo@^J1VL3e;-@iv2^paCy3|7i zeFQt3d0Rm?_^ETcb14NdzMUQe^kWQHiRo%<#BoxOdxt02&~%q)RJ8g6Kj4)5IAVFx z!eq@ROwRoeh5rB%TO^_T3B?zfwmI`Hqcsr7wg(DRm}N0GlFF?N zuD2cddMbmxV>-<8qhHfD25vKOtC@ossdv1#O=ZkztOl)My?E{98F8GJKT)JWv$<#8+IhE0)E=<_*F{gq7imH{NRbC+_ zg~K+p;$$!70ZdBo6hSk&cZd)*nO!28wWyj0Pz%+3#5s}54xk!@<=5nkx+ap;^dE_$ z{{XNQ=?yq;=AoFJK*ljL;NQJO+;-ver2U-fLJaap}Cl~ z^BGN;nJbbI9k7aR4U1Bya{Z>c<}=mH6?XhUR{3gcTuYaP6#oF$U8^mb%p(gR zxwOhu4(jd)Lw+X#SF~EMuXtszaNIRA%~ZfEQp9h>r7ihjR3->x5=0g+>`ZDRhY!r# zf0VkZe&o1g_?2+4%pk-UV&*{7euR>YwZN#FR#1so=1?zRFh;TYi7C^>BL-z03csR@ zZx<;a>VxDHXuL>nBlhH(Ykw0#YAm~yl>p=QDRmOAI9N-HVxZfcD>V6=S^1Uc2=F0g z9#9pVm{AV#h-Y2R6Y!1*6&IJ8N9DmG0=tWd1NAa@agRb<{*oZB%K=RhP)AV-YTq?C zmX-sdQ)MnCiZ(#i*5#aCM)z*wvz+*4I_VL@)AohcYG>4YN`lrX)J*fmle7ATpAiwrNa-F3=01MK9@4A6O9DvI{GAl!um)$Xik-* ztgdkP)1yda?YtcvM(>%T(qzZcTsR*=Mdr5)bBS*OOb0`2Dscqj1xF2#jKk{_k7F>_ zXYuhbyK~`yIiPo#T!cBoA7A-9@#0X#b8S08I-B!3oJH@)I+rLb%-ouVQ(5>QQodhw z$S$WrKsmwknE|QFA3yp?PsF`UbcM?*5UaTLxjDFF1TUt)Xjh%v%ZoD}6Zshn}C>n77GAjU2b@Y`p^{dEP#d^kn50>_SdJeumeye? z7RwGywAM)7BwxHLA&wBMC8RN8{7lTc_KE}@6rrJckF|Z^`9Cm@ze#~PmbY)(0j2y# z8ov`I6uFUAsba3~WVL^!Ll;uACGUU9Zdesa$o80hzSEY8ga}`uIimc*1*D~tU;V-v z75Ra?bsD7C#MP#ds6Xw2ff<9-HvnfB;&dFur3VTNsad;$gvB=YfYdH+OSmY7)C!rM z8~ZYxK~klJUEknLd#QTvrpf-w_x>fuRrZN|X$JNb^#saSUiBRCCMn-wjZK85dpy9y z2#OEJI*$BIkvL{Rv9w;l+z_WIf8h`{73|GoifIl|mZz_TKx-ahjdK&(0cgY;US%S2 z0O5tO8GOR;b><CHK9?}jQ04uhy;AC|{(?*Q#Irsp{PCNa8CX+Hu2&8Ld6ryy zd5ithDs%q;XI2g&3r7>CWxkgyd#3}4cj8ufO!=hH=H~Aohy|rw5Z(;mStmgrWtJO+ zthB;M_>{7mj2ea;exi;p5H(W5#mNcR>K)qJN-X4@wBxlYA!w$uSy^enFx5B&&JTWO zV%V*hQiGd_r5S|*!{P%*_uy^k(WmPWKDx<+e5FxEXS+ot+KtWjw zsQdlEwq^}7!eGCWC$tdm06iknP->i9BRQCdKM^UdPihM&dpLj>aL=SF*U*)nx9=IG zyYnq8{30mQU?0w<$td`XX$dWvN)}3JFqxOcoq6K9f zvHOB~{6}?6!qS&r{J?CGI28b0%9a|Jz7ocomB+7`+iE2nfKjwtq9r572$>b+;eKF&J`8U z@`YfA;M6sRK*p%u%Yn5uE3e*z;>Adt7@K8&B`$`g=iWLTKq|L#wlf8(j>=%J+0DE8 zi$xh=fU2dwu!jf%ZPY^LhqPK!qbzhl6l_#|;<0g4DjtwQ!R7&;AQfO{wFcpJCD(~) zDw@}yp&yLYe|;IJIm~Cm8HA`lTUaPwBFxt^GDQq73^UW{Z!a3xeM){z9ehABpcDLiPwR zJY0T`xlh@S7bebMi0c0Ud8LxLujYOlB>w=GlQ78^=KH6psjw8%*)Ngw;|}3e&#(7N zO8pDaAQKQHO9fng9?R*|Os5)}aTU|~oh?K5MP@S;F+39uMMM_&@ij60;4qbPr$6>q z<1?R$tNKg?M&U3Fe}O&7hC%Zy=PzmFfzEQDvq+(#+9?MP!ENhz+$F(}`ZL{NUbE>~-cQnz^RE`$RHt+7M?K1=bSHS5l=_K+sfFt5X`IC`KYW zZXcSsBMGq_L- zxTp-&%r0V;E?Ds}g73r)B}GB0ZbU8PpEB zsG4XTTtUx?KrXHbH;>G%8M$uV9#J59VQ#rzKSgA^s%1f=w_jcoo;@f z#4|RS`hhp>OJg-0+UXor%q)EuBlA2MPS_#quh3vEmigjSNC% zpUk^FT%hX~ra=cIA4IFXWnVBK+nevwR?HJaFEas0(IXLHj)#b2MiQ3tMqOASyg;_1 z92fSK73a*yw{n$N?gFs|i=xUWMC1eB3OSgzn@9(U-pmH`iHEEk8a`prOnk+Seu&uK zyg(Li0wL61j-ycGYYo6tdVsQpXxyRx#13|&o5ELR)O-b80oJEITq&(0mdo=1L@9&= zhcb>?vs<3w5N___uBuTm)lH19225YHER06*t;QttF5P|zJ;XM+c$v0DIByYM)Ik1N zqrc3+(-YSb6`NS=km@!@36v%;P=e5#2jUoEwfBr@#9VGTr}~+AfP;cv#KdxkFl#|A zX6_c$Npom~(&dzF5O8kgk|~O>d0~vrsHpdtK&y(qvlFX?v(!LUFvB?er(21EcKDeX ztR?qgYZ~^QR|1Pm%&lHXTt~=+aVD5*9JrGg{!BQu76vlkyypm9YN6=VO|u%XsAVSb zRCe<74y9KN@A8=gcLu|+d5z%~)*@^r5J_(0Cxd- zA(N#_dcCJh7X}HarWx-uwYcIsCU{lKk+w{+@KA36NTC3uv(E-E^|L!$>ht4#u@Z#+%>Wc8Uu3UePrj)aCqeJpiuVV*or zPAlk(_XW?X4}v3ax5{8yxqD_+yC^$Ad8}QK=Vrcx1`w?@jP?A&>X37k){bZ#R;1or zoy?V-^EQEO%?OC@o!W$qMP9J3;coF>Qru@pnS1$Dp~TQ*@i#x=DH>%Y3XbtEz+i?f zmZ=C?k28o_Ir@7r21}Qjs0z+Vz@{I0RCHjDAL=`@xCWg5CIIF8OyS!ARk+Hz1l@*N zNdnV|5GlHfu69C7xL}v05{MjX1q8a3gS&})pg*-OZf_m=gEbUAA$%D7%5u!ab%fJ? zB}IQQSC?L84hG{|C4Vy*R;33eM^@$*6$<9uu)nDFQdLQdEIt<#nUsHUJJL`FqZ%xN z(<{pov_Ir#19vQr*g1j--I5L2E2dZC6?0WGrl6{zg4r%nM?Wy~KT@|!g~-f+cQQEq z!MIvQF9N^ zwOzq#VN1#baG5kE_XX_0K}U&^Vlv)*$~6#MYNG`$8oT{Mx>wzY1qH#D>TVN59Z`hN zSq;K^<>DrKh;o0(DTDVMY;`bkkHoO5)D4k_?jAN#+l8*`rZoUJUx;=^7jttXYU41I z6aA(+6wnt6vq@Z~VQS{C4wO1X_(pa$@c^cvJ?af+35u9*;FL8iO{KHIOvZVrIkWbF zZEMLA*7Jl!#JbA-#r$}c&>)Ik`_w$@Ay)+u0){sWxnWx)-Mp~|P0Ue*8=7En_?E!i z9gkk|K(FZrv|6bzj=Yat{Yun8{{TjVxG?MHS9(Adlx-uIJ1@|k#&`O47dn`! z)5PCpOe9UjJ$+0#;&3x9=)BJ}tBIXs=_^`4lVDO2QmnGd7wq?4wEq3J!@sGlZhd`ueA4RA~0y0Z}R!WA=5r2`(2 zluV!fpwmgxWCF2*{{ZrL@^q0prl+E~nT5(K?SDy}5I``&*5w-dH{6a`h216(NY%z= zXZteq=>xGd4E|+HqEiKKa>y*;pyE(gz90bBC6JJ+{Y2eMW`mRF7Nx{$*h-jX=+~H7 zb|%znt{X!a8_5w1EIE!Cb1-w3HC4=8Yxa$1UKU!)H%Z7~t5x}f^`N<^tHDsWmNjgD zunM}mm0D^p#A^Zo#cmdD-^?92MH37gi`+`-znN2tm7RRVt-?{Nzlleq%t4X+m$fwv z3@Tz6fv~tHG2lV2-gi1N#adZF@$$gp)BZ#$LN-~!Sl<@<#@6568 zN^SY3@rd0;zj*CbX zbLIlweqg&*Ux{`F!Qm$Ip~zP(H3F{6mM*t5gK(=|MF4&x-QSqZzuYrUs$|zN7j*-n zP?`v9Y7cmLg0q*Ho2tGD+A$T=`AmtI7W*dlTmb46V8pS57^UCZ7gzHUsDo*YeAHdU zMvhqPA($X_K4J@Kpr#&Ydof5D0nwB&R1mx3Ro@c1w^4w)lvQ|!0B6KXOktW4TB8!c zV`Gqf!`Vfs?q{zkr=kr51Q$R=wbz(hnvAwVtvUP8P$i9%X^5oCGo;k7pa+>>(}|&% zInJiTGv>oYDT(4ZWm9briWv#S&BvjdIcNn;7>2nMLz&8?_u2BM${k5xL*qLJiHTD3 z@DHK~UjO!5XnRA^W8KwE3Bg76+eMgyn`Cmmjzwt7Sr~O2l zg%Ge0pp(d$W1&x(Ze!Y@(FGX+TOWvAxs|>lw;ZcXT(_#Dy-?0-Gjle~=0Y_wYLu48 z(nT|k+MH!U>`Gv^qP^mwgBk zlptF50?Vqob9$FLM%&^Y2=v7bSCEdxW#LeF*5Y<=@h@4HI@A&4aE?_{i{7G_)?plY znNxCzOSZ06h?mmbM+W}UDT}zlULR?hxncO#;6#UMH9(cj7GK#ck3fYuroRwH%UVMVq02 zGU-C$DQyjVl8rz1JA&iY7+sK7vWYF)VT%4{Z&cw+hJrj$@c<(J@x+UUqY#5DW&Z#Z z{KB2OX3xr2bE7L+OKpGTJnc(R=gfO5T46?9M%fKQ(bzHK2(iD!uc;xu~jPN)X=bvoj-h~-AcIMi0sr2 zhG1;8Chs!eS8&bAA*!m4$ZAlx_L$Bh0JOeR#Mkc?rD%g{G$A`nYSRj-iE1`@m@6`% z?plQrY+Xuj^8!^h0NMMB8)1{tg)$I1Gxm+uQrkua<5DQtK`E0d>JKr3ZGomo%mq^r z7*N5B-{NRQHP!n<(-SP|nSh(9V44|jxyh8}VtS??tjc=?^gPDA%w3aHpZ*XeP{%4{ zhaOYkWqFCZisuX;Dc_lU6u8T%vj7vv5wp6V{4oYam%7VdAD^T`x$p(Eq&$EoVaW9p zCQRZ>`XvitBRGd0e>0$?aXA)eV7YEv>q3LOUqK?c$8DykBzG!Z*@)_>Gyb>GKrI~9 zQ->3#t`DdKVieXcUC8<&I7VZ?NUF?_pw#b!rVP`2+?~_jxl`6;=RcpJg`cuk&f%u! zI`m4%q{ph~8~#HNqT!oG8^_`$b;L7hDlZ4x1QQh#4L&8Jq1sil{xL-+W!N9t8Fz<~ zlz`0YuA(q++um1p0RucDKzGZsL_levRDu&V7I+tmxi$j}_L%0(;sDXUT zw#=SkLdX!+o@aD2xp|ASqGoFS;h^RTy`iCZ<_X?@U>gL)Q!#r61~WtAUzaDm3WoSk z(zLv?J*8{@BTXaBKiwH>R`%DE^1W(p%1=8q@?X{ib`gHrS;ClmV|X&Kr%P{{SXk6Oz9%xKak;Z4T9Wgm8rxY9&Qn zZijU?S37JJJ zWVO}Tmp%pF5A5N1L=gi23kO=J& zjEUbWH##M>rHoeZubEJncj6*3s%40EXid7RAY>1TpId_MfK?Drl3$9y#B9~wK$+$+ zMaom<7Jt_=jB!qAwn%u9#bFj~mD~-+@G63<0s+O4Z3y3Zmnx-@$lgPdfNd)k$vk3M zhm=`ELom_%O!Q~sJ*xizBL+Ahh~`s&i05)P*25M503j9S78pM0iHEajE%c$HZ+eF3~Vh>fs9+khufF9^29ni=y7gOZ00N6J)o@Tl8m zz#)OzyZ4yZA`G=M15y5!!5XMkKpMpZVkqNDhp5zoZG(x3FI$;JzrWC*%S=$%{{STz zT8&oB?k4Wc1-O=DOX=wKQO6Qe)8O{mx}linSmeNh}RVggUq0%yNu6R zkwbqGfq{Th3oT(a7@G{-;6W>~uc!eL>X1fp6Ubj)ZMlX49diYOv-z{WyDt;p+-V);Wq;LL;?iAQh^nh;GK9&qF*RF zDGrGKtQC%DQ0U9!^7ZEgKKLmb? zIGn}k48SNr`<@}k0j$jo&#?OM8DTMt6QjhhSNu)HE4+P8b}IFP&sl>o<;T%=IEQ;1 z#?h^O%pp+O!|f<3n}fFOF%(@~eC}mSv~vS1LboUrF&YJp*D>c-IL;ypS6*OZ6wcx| zH5a(|twjW@{Kx7TQ1bYQ1;G|r!#YMI9fEHIh(%WJDwaSXRzz~Bk2H*`&xy+)h+(z) zrefRoV;F`lciaa;V%Yvu7dOP`zr+^fp6Qcn?OZp%DjAES<$H+@RTttVpYsE#MGbw? ziE?NdrV(NwxaHZP&ap8UVh%8}UB+##5 ze-ZYXH`Cwj=9sODd&8=&1F5A!H>COy<$xFd{y zBSluFOlcV{i*TM|z95Z-+@Yq^o}-X8Dl??MLvqecRI6!5%=v+Bb#Qf59Afb263E=@ z_PJ7)9wxfqnAYCCpx!kWtR=Qs6jG;RA9o7bi0BAPHSQtGzu7>fjQ5nD#B)lb@B5+M zf5dk1sJ0^W{-ZEKZt7y|>0Ve#T1Xl4kK7$idkiVJ21ECRX6m6qRNfc^8&bWlD8fM7COZvt zlX!^26*dMxh>*^Yh{hWqqDRtc;9&Ye1xUu-SC|V@b;Jy>UgYtNSxs1}Q>-uRc%JAN zXKtU!RB+=EhJVsxulmbjL(B&V_CGN{K_&DtI7%b$(d~n}KgmPr$)YA|ty5R@&9q`Y zT7hgoGWLiEHk}Z7`a%ByBPT3GCRG`l6$ z8JVl3rB#CK79k+nDr%21^>BqKt0!;^mkd%mxs=qz86mi0<_V1NF!ZPaBNqyyhsrp~ zKFc^)?S&7F5sMSq9cn>&511>@gB|ukCF4dQFJdwbLR=zHHiBIHiJHOg5e?_%42TO3 z2)8Nrt_H@}yuu;fNbEjUiInTnFrUDKx8@{QVv&>l6R96)_5T36I2;KuJO2R33aaW>p%5F>{W3F9=9 zscQ(PQz>TEFU|^@+%BACHt`CLd^&S}|}OrP|pMT@g7< zeE^G^ri&7fNkvA8ZDRTy6FakxsE(dL_|=4_yvD`l{Xf|(Pt{QDC+Gvr5o4)1LS5lH z*ndP>_V&iH+yU^uTM+f@jHqXc4+la66-+#Nf{Y z!1`AYdbnl3?7{v5Jb3%1jQF{j@XivLqJ{jv$?$|k2SMgs8|;Hw=2Or{q+G|O^Yko* z$;bS`n8szD^E;t5gqJA4l&2wZ(dKdqGyKf}x!m6qJT7B5=6jVd^devKPMWyP^F2Eb zBvd$n`B#Z2nRa~+zhAD8XapGDyFcuv_!FeF6;bssx`^Tw~j)4)P>o15`cQIG; zA{~}j++6wr9GfEVMe`6KKLj0-HIqv77N?S>h-2(W6-xGytbqfPdkOxCC0Bkz!0Yyc zQSZnzHnsSMn|17g!^R8N&w^4=Pn-h`BmiH2rGiBOD{bt|6aHhI+Wpo$Uy;H80ANeG zH}b=wpTRK(NXHfUfpPDm;32xb$$$;NFa?&dZE8J?Y7Yq+vcBt&Aoxl&{P?Et;FXIn zhG(Ud-ZW}_%8UT_Wz|2HAk_P17obi`2clMq7=rw%N~?f5EF=ZikPL}%4r@3YKh4= z9pfl3FS|T6KU3(L0SsuKgfA-TnC=#^k{{`#7OOiFV=o0M^=q15kNYfAuHkr;ZRTC9 zrxw@C79`fWObcTD?rbw&(cBU5OlW( zo(R}~%wD1MH-p77i9d2P2;a*uFmkDT!?3TIXBJ-)J`i+?i8%m{njJ@FQk30X;^sC< zckKXK;uw5I3SeI{!Ny&4GYQ@RFrXA)5VCMZAcsj+EI6?Ef@mDVqdI&-nQb7p5~#Rg zT7W8mg3?)uh8o)=LmvbUc#e?sPFPl?)yIlU>BfeMT=QNKyEX1mM53=s67MM8<4@dxTx< zi;}r?{yfI*`GX*SAV0!qp`}a2`)9&;NJr@9kMWZEOo+~S`fU4vWXJ^1e&=|P^`?$! zxQCslJ%h}A>?%$L9)5-l5(6WzkC+pq^hd;hnVJcP-}VUgsNGIep2#!D~cB$t_CEwJQZtstI7u2y@9iLJH!e z)5N@4iA^u@1l~R+&=dkFQS$__nUqvfX(_m>g%%i=#UUieXJ{OyhOot z6uMWz6~iwuz1OJ)%FnwL;yx+m@1<|Z64K9sQJ?l9v-2XgAL%HTN;1u_#3Kavl+pGG zJ}SLeGZ7dF{M4*)AlUxYYfJJX7K8w1hoA@*s{SGq_XN&<3kP*PBLc$+D7WB^`VWYu z6@2E*XSFM^K_H{u2h4p5qFH)Lm?|Esf;%603|xGX%E>KJ%01Ds7q$+493ZaxFo5uEk+yvtK8!L)m(yS`Wx}`7_DIy&)*vE#TtlJj ze=+o3Ok=l+!>Ypb9WOC$U^Ok%7?^sYNH06Om3fa<+edHm8!V%!Rp`1D;0(t zNr8qJq4JEWxQ6PgAK?=PJPHLUmy_aU@>VD3L^7pL7e0;^>&l%wG*i%jL8(KRES>lW zYPS4NHu6U~4}@3pbnKL&i&Qsj=o;x2ct<@1ytWAIZf8W0OuuM0F>;2m>||-ZOMU2! z=}lZhiYO(iXaqqJ?7}y<400MwaYwNc#t5TYP)I|`nVCMsW82&yfGEqy%v4rU_E>_! zlq9$8Wy;CoAYaHzNK?s!mBgXte8$3dq=SO!@hwaP%t3sCfZ-Znhr5yXmv4d+4~Bd% zh`~*GL256=GAP=60WGWe`akcd46ZSLZ?}C`BM&f zgBiuoQwkxTu>Aw+_OnRnLzT^pY}y?XnN`tVXHOE>Pp5@&6N${>O7Rv_c_mdm&~7zE zDXIu1dr-I_4vj(C9Q#)s;kYTKP89>FO$83Td?2XOpeQQ-5eZn|iEwIv(&Aaf`=&4= zg>_+;@E}G10K^)b{!u22>`Tw(j@R(7tAL0JY2+|}=!lkqJ>!o1g-sfRhwmv(Rq&KY zvczZiL4+-by2Q=b*kI0u`w@}$Gl);gHcfo6iD~VEV9VJM`7)&yJ_0I7+J-qs-$aLO z*WnDu%vgvxLYg+<`>iPSnu7x4ZfJWrjN zG4(?ate_0XE|@fXTO{_GQ!M5njzg2(k3bIT{=~>)bZYg#F_qEMn&A&4u_NYTxH6pL zp3qq^{$5sa*R`B#5wzl}&X5sXd&^Tw^oAOl(&V7af^{*Y(k-iORoae*3gXrdUQt1eM@nKB!v_?y{ie&*uysz5E%kh$+eL%b2{jz? z01j6XyTSV<`TI2(h&V<9m(z($5~KSy$;7QR;Bg*HhF$zZ%#c!N(3ArT?FuHtsp|qm zE7mkibJuY&+)YM3PGXlQSR`7n5QjNl@}w6eDAl-NHooYe7)8AV!$%V9@;&Y-=%G+Z z#u!q9ti5$%<`q?OLmYXCe~imTVgmA&x<$R2l~pO1Q8DurCf^WUf%H^EbBSZA9kP?m zRuT*V%QpN&j}syW6Nz8^38W7-J2w>;i-aZ>Z_E(oDxv<8r(h+gd=m7FyPRXvtD)v& z5}?}QLv&Ejq)VJYHV+VupNWkbzcc<2Pha_uGdC7$@JrXQtkfM56{(r(B~hwK0&^Tz zN5p^ZQe$#TFH(F$7axLKPb(mdqrXb5<{JwTwyObOC7h+GNgU+pT$* z9p6Cz04Y#Y`w+rvGjjQ6;jCikSBX|xo&22z^iCL?2NA`GnLq^>Xb+SzlDDu50+;MT zhYABj7QygtQT?R4bs;z_@7D@A zVMO*yuE)bElFtM>KP@QaJ-~sj&uMoDxi5G=2w$HNfGPNL1j-(w7%v{kuz>7T!&P6s zMW;^aCVKKQdA(pTQgQ7iX2Q!VnfJp$7pVjn54kE^{46bBh!J=6$g<&M@}6di64MT# zAOs6JMM`toL=q7^4Y97o;pe=%0~}ai)IJqkQ3xzR-jf zEDkzOSdg;uf^Ah3ey~wqjJ!W+c>sDxIB-E#s(Qp7SolZS|WNE(t-t zrYm1CwpO}vE`hM24kFwohfKz!7lO_oX+a*qk3xr}cGe5)sFBD9Bab;EHR3w9-^k7+4$qP|_BMny^OBUgV;5LJY<^}HVP?*ab_+enHUuIi{ zw}@np{Cmnf*Gs2H<`;Uk^{7W20ez+TZ&q3nPFh}gc!^!!fM=EVK0=Aby>|^Av%|Kc$J`i+{ zC8lf4t!c6q?M|%nOsf!RMM~e;m>{^npqRN5>F4ML2V$UxHL)-Oe)P_#l3~@0<&VVb z>4TMCVpT&I{z7i^aJobcMZY&QeSTwbz(WHyefHz?zl0A~I11Ru7sQh}XxZr$BMI_i z87g0h!M(!`e-;2jgW)d|2*9JnOS@l9OQ6vL50n^3-KJBlD$+$@mS18Yd*Kq|*XC)~ zZ(n#K`e=MZ=feWR0q9(=7YdUm3dJ5H6)b)ufWb^_2JA<*z_nnJ{g7*G3{|({C>ZM* zi4o4&f)3#`GvYLILLXVg+NJbb<5n{`La9)kwO&}gEAbJ>{F%hboXawp?=rw<=cknQ zOW^rh<$W{>0yt}GxAkoY^F*3svgZg7Jf^<~KC2T5YCOP^fZq6yD`YS*; zDPAH)qu!{GUW8MiOX2ac^V1V_f%te0y zMr_gAK#jiCR4CXP)*i({8}yPhfOZ(3s(XnoG6%STwP)NQLMO==#K0A2_b}=)>|iN@ z>>)va+=NPlX5lOcSW;+nf@3V5zY>i%dvWg+fNSckM9DWMLID9Duoi+k^DSPU#8Qko zwX-w_R9W~AmF)_kE*oEXuOi0@Q^4n~hs@7A!0DQn9$tS4$sO`zZ~*#Tsi+PI7Cj#k zj9S@O(#ny4j7H9$>(5DL44gmRqD!i{M>c#)43+U0Ak-=V1FRD7B%pRDkD8a z=h{3+JHplUAO%i?H7Git5K0;m!>{Z?u8QDH=%MZJ7Z+GP;Pxee{v(M+?o_9QgD@VD zPH>4BADNdwgx<*dc2_Gw7zVargyvRZSB7Fs9|U_KklG~%4~8}x_<=#h6hap%s*Oke zPsZSgErwR%e?s5E=g&ejA>Sw-%i4~BT>c5c(L?BD@;E4}b3&L}a^tTgyOQQnX~X{j z5^jf{S~vNhNs0F#>CA+Cq_d<-(f*xHWcG=Nj6LM6KX0d%_@a>96C|AsLM%&zO$Xux zLLh4pXi7YzT0i!36>x-J7#Lrd(EtiAQ+gC&4TKdn?GP0Ssotbiu`kL9nd|w5%(LSM zeu86}EZkd)5U@&tmzng0XJq@K<@-!&vGWBgsBKt$49Op51XQ||R$2K*<9MjnGjfXR zHlz*MlxWrF7aO3Thzp=#p>RxKjd0WEY}Ug-$_&G~%F+(FG8iXDkyolnOZ>`MQS$^d zxRf_?rlxGvu|^<MD*mpROIrG|O&Gn++) zaMWFo5Nk6CQHX79%ODZ_xtAs{E+yKR4SM`a^{>n*>-0G;M&Q7=(CM&6NC>~(0Orgi zB7f64N0_g~Tmp~@@L?%X{1`U*Jyi@LAp6tUs6w~h63YGPbS?z&_v%|S%)^_2urui6 zl_>PgnX~DL?tS9x{V~Foe4r?1(f8uQF!Wqi;6;}~@R=5`rk}SIcq{UXbW!aEN?y8+ zrb^U=4YDtNh?b>zAt+l6LCty<7^ohGWCO`ADE?C94C=?l1628tdT-l+)*qxHlSS+Z zQK{%7oeq@3#q$9#;(3CwNvO1TB4h&hNBe3ew!`S0ZF)%y?qteVBi%9FKH|iN92&+o zFOOjGjNCn&VY}&@dqAK1Acd54a}o;<y-t)gC79UWy!*e2D;<`m*u0x$9 z=Yyu@G1k5cz4b3*p78)u`^IgndP?*DOpF%zh0ab$9`gRvBpFuOT<#*Hj%CRZ<>p~) zc!~gX(}}YK=3E!7;v~o%KC;~aH0u_XnF_A^mtgOt#1(bb%(Y3&5Ns|pK+6E5+{-XP z<`t+F!*dxH0Mp(M0}cpk2ZQY>anz2$PEEadmZ$NWL+L08NyTnLKOR+mc8g4B4hX~l z01xYflxvnEfu13j1#=2peZz^3s__9ZP!lfE3i$*QyfYDs@j@WHp79h6fo^jYFdYE% z0S-uEYE}VnnNt>J6=Cv(H;+XTwWK8%LR~eKtykB>1;F-YE*Pqyv+Wkzk75%l^JPu3 zg3su~DTmY}ny~$e@dnjF)Q5?GkcEM$EG1)KzIvW^0$~%)H&foegfVG<36EOhZpXMm z%<0`$fdScG%>E=8!F|ODUBHa_&%@(#IYtk`?YvFpOL7u!aZ0hY6wP z2&e~oOM_}yULi5?r5O?mibZI%(+@UZ5KG6(fI5AZ^Z*~DCE-o%#!tR6*9Sra?yVqYE&2KZvjG19vvUT-%Z?=(XY&isGd^)}E9i%e*D(HpgOOXYHj?*SG&pJ>qZ zN3U3KaUDJ35mF6wLA_<$Ka9=!j8J`CLJEVfZYB%p>oc^CaK9BARU74i>MC4P1W}c# zVP&tJeITJa$1>-ahzc*WiBdAWbeC6`i0Gl~quL6!UlQMWV}~4dh`@m|89wo19;uVi zVwg7h=_^#*&oaz%@=GLdpUkiqcQB~3haF%l0`iQlSuZfJnAMTiT1W7JR29P+SoP^C z9ENe;2|=qKtC#_FH5FlG1fj%cyUn2AFp#6v)V{X(k9M38nW6>3m=+HH=+j__1Dgz}>+2_t30iGpf{I@Op6S zS@wv?dy5MFpupNgC+HZEppzK2!4ru9~l6Lj8!@h6j_}-$N5z^l)n@G@FA@) zseLOZl6>+eENjqDfCN5b>%S<*>n^bb&p-r*3tuv_`~`0KO(rA6CIM}R6!1<_WRa=j zG&={}CJz4qGvG637pX*xR+!|v z_LiwG2IeYDjkHH3Mm0C;o5lIc`OWBt3SVRrqyaPBwr zQ-deGv|;lbGCpbr$@zdGQ{z4ukYQS&hk?H6MK)QH0YW^>_@{(E;leJB_|IYJtUO*9 z(ymfvk?aI#!Zl+a(JFsM$T8JKk(i%(kDQ>!hL3a|@cWTt%Ov?6nElX14R?5j6WPI> z;pht!xes^NTeQ94CI@zJtgVa4W5g@~j?46!DW0H@V}+Ncb!CCqPLKkJTtHoV%DvMD z9cQ@!MGp(MR#DXu`dlBm2!T~JbNz5>Ol)!eQi#LhoJ1+X-DVy(7!6_jjRK|vj>0P9 z80fF7jC zfZ&#yn|S4x5Hs2f0`((WEqEf17r!yWX$J08ON=+>7SF;|0=hcD3a+`7TJywdvQH7` zHuL$GmFM0$pQ;?I@`1Num{@Z**?gf=63+)zEoD0hciaRP{gpV46wfm=&P9kTJzYLf zLILfsc~Ppk>jKz1AvP*H*1GLNrs&RRPR=Ht?F+bu2a>Yf_NJcQSjKm6-J`>)g5Y(c| zSup+JH?m5x&$9L4IZO!j~7!ful&t=}~J>4>VYu>&%;TJ;l$o z1qnhx4;t0K?EW0Yr}CplGx(2Ht|w71-Xqhu(6XahoD8*nkFTR<+a+3H{(WOO;L|E8Dh{%UWLjkq7w4^#ugi@u~w9F~E39&ES zA1Tte0xmIoAuWQ$MX$ans{G0{aG$Hq8AnI{yHv z!bgiT?N=_gpyFb12%%#rwf_JRbqGrir(Y8F+|*cC)}<+R4$|O`N4z(Z#aev82MO5S0AjO9stKJPpac( z<#50?rTdV%d!B{G) zQ_^lL3?-`H#I9TE?JYDv>@JXm>s(GHQ#6~D`y9^TpqTBp0H9aOCao3rnSdVJiDo6q zS7}Zdg_ak*YHvI`N4F`~XYCLLhcPP)>XmyCs(qt1XRynAyXxXgW0DZ2{BS@x1(Ax( zC^hO*e8P4;ympv+zRYgkuZBC&Cmm&^FWf*1&3uxEFGWmD8d2pcPvl08TkyoHh1l{U z1#qa^#EtnSz-ke@k9K>?A#&B1S1vCD;wb7o%0SS|W%)Azq5e=Mc@9Cl>{?e>bYp(?T+ak zcl>^>vnH9ZT_|w5Tc_|d25H3fgyL-|W1X+Wv!H==LYhV=av@R|A7NOCR*%qf#vd6% z#I`|BuejU+3(~hUXXcq$8R)DML^j8Q5518%PN@QX#pwHeFh71HH zKF|YhJWCH6vAq52#zYUy4otrB!yt)AP(X3>D^_YRavBY>2T-^HcTbdU;euCau)%ry zCA-xn#{${nQmY>fu6bjsBR#R=RiQ|r;ZwmJSW|RL*d4?n{^H-TOAqEi<-{13BIqiA z4yJ?t!eyDs)dKJ*P!OxGrneIoGx>!6Vp8t$ENA}8o9KKjUyq`)^gPc>OUT|haYqx8 z7f3d99-&hDgu!8O0ir#%{K06sMT#ZdEzqSES2Gt3G=b3Z0Y$x1s66{h((YK+t^*j^ zNDJKv-z?5DP)vA^80XBrq-%y{oJ-X4FD2A4wSS3*N~kVK?HL3Z1CChtjcOn8H62K+&by(d2J6s+h#Q~6C@{RWjx+5aOG(E+sr|gl^D-{? zx*|@~oGUpvfl}Pea?q|>MJ4o=+Y6Uy4=}K?d@)I#F)a^d&ygCThg{}w=*#HHe0Xwfwi`DK30FU5ec{L6NbI$U;)EORVAVii>y#M{g( z{Rlj$A28@NzcS)zV`F}@;%fcKt$EB4!_jcUh81Lv0sTvzGbtaT4yl70BKx6ZC}x`T za>mwENt_B3Bgqb3E;<6ffYOMVg>u8e1`84Y02HO4ed==*ZuR^paFlN!nb`^G6ayjo zm_}|6?26@^m}}^T1t0B=9;r-P9%V1oJn2gp+D?IlnYdWG*gc3#RG!hu3aCc4HiOYY z_R*lq4ADs308285x_*gpg)D#W=Vxn8j^-~Fg>{=H&PNMwH5QGeJJ2f_(MrAN( zm}-3;quxC{%N^b(9K)M9`Ue>w%n5@NrKLFj(b!t2%9*xd29LTAclsR%WT#`4=4o+a zoxSCz4b0TJFCP9e*p&LbLf~8#p|~zg*O(i!1z1CYHSI1?{Y53p3)D%OYbN|c8K{ig z#D4S4!C?*X@lzC)GX<(QTLjYO1G!S`rF{r4#Gr!`<(#oP517$l3n^fPH}XqNWep0# z0c$>B<26%+8If3&u1L9VI5luEcKMBZ)5NR$`HAE)gKVDjGk41j+99w)P8gJQfkv^n zEz9)H%!Gr;`%iH)6uqGo^9Z~cm0;gkwG=x+U{uV@c!j_a(8TXiYNzP1p_$1M^+OG{ z7r;e?<`vwa-*sx% zGZ1C#))bvF8{U4>kwqf)X%+j&8>xzDUS<4}kBiA&Vz?BNkSXeM8!J#~0S>a5Jy0W2 zPVzk^tblZ;3kZ^cRvj2XTqS%QyhIU0q@p8yY8+hjkXBUVP|6R%#AFCu@!X!utfQ5E z2)%Ep#6!o9v!p13ja3HmvEY;nRLmIV)=~ox4qqvVuXlccRsjz4kzf!7t&Fr01CqBRztQuiw*g6rdO)v+vkPL5wOA&H5A_qf9# zcz~6~Wslr4ed(C4JCpoiMHdJNSdgOy?Ki>d$iCgcZ~((9_9NN9d`u8Fqx>dG*WwT# z=t2XL6qUz<3h4k#k`)z0;x)hGHK#dXX$r!cU?Z<*n5HpvXrGDqqKWO8CS($)yPgS+ zv*=y|{=`omc!aT;!NipHRD0XR-e%*-#YHYQi+EyMPu{2MI;+CDiQWjzGU5js3L*KN zSy4%s!5vD|BcR0!4SQTMf7*-cUBl!aV}&_DxJLY<`&1Q6g$Dls5v>|B@VgI^EGT;9 zk7lW{Y3}ik@a!Yjm#K@`90Y1WdgN$rK;8%yF-8Ocwqc7_DP)RKNsv zC&uB~9`pj}JjXyU%%Cohw6tu&GeDLb{HiUSqkvjQ^AdcJf{egb-4BUE8AAptf)+j~ zl#+at3M0%2S!50+cdLrvsMM@`N-?mTKf+~(d`!8*fw>roVU_GFDK(pU;hA6KjxPdu<^G5YN0ouHy?x}wxionDk9=qph_V@ zgHq>ICXW0-Eg`IKpbJi+kYJ4tD2L^VJf8vyflON!mNBZE!h_o48W^0-jB3@))-GD! z1O|q`GL4!&rg|1Hg7{2XN|)VgSz-d|L1KGEpbuhlapF?xFoe-6IYYT>Tz2aKA&0y^ zIp~$Zm4OrwNdO97)tG7*F~C58$%MF*w3> z&S4F`526PYA7fCi1^b;Pa^m&ql%fRsXZ0-x4Gecj;D=Tb(jw@$<_3|j@VN#1MHG?5 z0+^G8e>WQl*z#1W3LF`(@U%hZTuOk~pXOjB!^d2}zL3nM8(w0p<}(GJkyw^L--wlN z^^b&RM6=v%nU=IVr86gnugH=IkzN7 z&H`h^>mIJ;wuTOxi?IAl!n3Lm#yylaSbCVfOE`G%F0$FrSdqhh*hg2AReR38k%f!9 zC~BO3W#ef>X+V^hnPeOMPLU8y;pj5V9684t0Ce4Oczkk3$emHhaWjl%|mQ zN6iRHh>c3T!aWEI81F9J&ARQfkw;NnU3&5)g(2TAg@e98p8yi zWfGROfzi07WLW#N1fqrf#Cfo#$rC%gG4)hDOm{w#W4C@&2HWnzg@uW=cV8sKb`Q*K z&A)LIt{)8Zzp4#E_fa0eh7OvPrje0A`HLoNEmSBxL29^uV}`AW2r3Ry_8ER@>|z2_ z-7(}611za+pS-Rict5lWD+Cvk%SK5MwoBBRJ?B^$)>oDS6d|f7>Ul7g#iCRNhEcm< z>W~8v_%KR$citxGUH<^cs6@zIeqkr~?rj7%5%`$ssr)#BJqb@$_?i7B9bDuH#_zC#Y|*h;&zEdY2qFOaJRqAv7FbmP4QyZR9ajsp_V$!PyJ4q zi-(VBZr5{Qg^|B7sBP^TmV8tyD{u^P4AP+DxMq-|W}(Dt$xz7_ZuAyR40KE|x`(>L zDDCqRS#pG3DEmt)nJu`M-!W}@^E&IfaX|e_TEEoJI6zy`KxyEPZ=?)zhRs54s9lir z4bw#!Qa3u6)!j=4pSUHI`a`oh`HxE2_)AI^3UNfTgishsy973+#td+*I8UM6u(qO8h=bKGU40<5FDAQxt=*=S1Cm?Z@DIY@)NuWOAb-Umgzr@F!F(+ z8ZzAQjUQAH%}OQM80f}O4*g|-)gEB7gi!LmF)vlFX2a~_2a;Gcp}VA;Xw$BR->rp45Mm}$6tAD+DIk1p#aq{ zL}!VOc3So-e}WY#AIOY>OzdO|X~LRUQ>3mAn0a4HP73CjS06^S3!c1ORIeF*(F{lv zZZ_t3W5mo?;$;Fv=p}A5F=F*K;rW-MP* z#Du*=FT}N+W3ZZjC6oBBC;>tl6=U8my}U|^e;oUb2nLhjC%Z`?4)_Z`(IPj#;)ymM zqEqoB8vwu?@{*J#04GgB7ut^>fcIJgNm4%vtPG)x@`zlk_HjbSjiL}8I);|!8%nVnVm|9Zv($qmL zGl=Ff5;Mn{kYZSN!T7i0QTh>)<^_N*>m5Z?uzqFR#JwQFwCe}N&guD=P`n@u?2O8l zHwcuPFY6FBoPHx*E@`Wb(GhaYcXv5P08qsgcO8JO;T73#p(yI5phYSwyvxh@5}l(S ziIG(b5A#uivy3-}#0rgRCnxypt-Mdi~}KAKZF2bcZJ| z;%jpJ`b5D;ZX+0v@9_$P-~EIswQZr!D)bMbyYnjowg#W$2n4qSTz;j6i{qwecj#iX zn6d{VZT>JF4s%+>Ee%)w;4Vkrfs-ZHQp{s?ly>G)v?5)OxRf~OnT(?SWPj@I!z0$Z_Iqyi)cOXF5HS05+^BV?Q-wAPMV75mBS& zaa$%9ebWU6uY|Ofh7`CYKoUvs5F&k)!Y5tzT&mT_B|+9hsjtK*h54OF6mr}}yX8u* z%}oxA?qbkF(flGX7(l@}7NX6H6=aIKPNEQ(`BPzUp%r%_*ps$YMj!SKOkDXBuuCwY z>%GTXLhvA{8--INT+UYO)o}I!87dyv7>h@|N{m6^ziD9m2@WR;b}jo&RR_c&1KiF! zp6Qq0u)rr-ch%rn;8T|1x+EcM)Tptm*pbuspq?iQ80$#a#CC|R3w=2B0MUjVdjkb+ z0?oq008#Tb2uVyO5DYyDalh>QFmzYQg$=&UKXwp}x9=>P<(MM-%K)C@S+oVkYFJEQ z&)b8#RG5$rAYimPJVg+v#0{%9o;*j!SBc85B?og5b1qS`TrpQG-DQBfC5W{s2QzjY z13N{=Gnv*?`-_JsFm3}Hd`*>%z(To<&oB>9%)zI0ma~|XE_%YQ5l$n_hte%EkFs`) zmcai2n2;#4hN|;2ih$j$uQjh|^qWStbb^gj%u#mv!r8A7X=T7zH|nWkX1qlx@!|!Q z0i!cIR1smQ*BPA>AwY>hUBs7Pn8q7LH0Ez6pz2~@eWhCFCNR`g(}?D? zf-BPyfl25ec=>vpQzyeI5}3Rk%2?l-l-c{rW{0#jOH%1Mmfy6z8h~)zBddGM(r3)T zQr=kh8Lpd^6~u~Y;u4JhVH}>b?=zox!nIF`*3Ni&hHe-YJ%)9Q#l$&$``v!hj2+Hy z8N45U44xgEt^~0$27^$g^7wFq+Ha?bZI2^07*wu+Js_00ww!105G;}JJIB{OB@&g= z5V3mbm%&AGoXzs@s^D7wNEtlDtrhdbGp(iIQx%0?^BKd$qC;~wf?q8YoqI-)*g|dO zGw%&;T^vM5uFys$kJx&mUPH;$rpL~JZQ^^#jYLMh5-pIwFlJ4@-`brx_?eRQ8M#mJ z(qfT4h=)uBDSGl^7OMJU;5^dA8|;L-;LV?9EY*9(0Z;=ixKk1C6SXUff_y#% zU=S$CI}*?@xlqPXqK8}z3qCPEK*^q|0aOVX_C>yq3ZNfVQ6jnbs47yAh)15bVbY*0 zJ#}zpHybfw_aYv!Gg^6{AtH!Yq46;!08wWKGQqc)2-uawPmD+GdZKEu`Gua?wkU<8 zOfw9yP+tA+Crl4$o5#dU7U3J~?<|_K0Sa0xTR{agaENQN1-2W)5VK5j=6U*R(kajs zw|?e3S`26Qn@O~v!OV1vZhz$Mn%rEkqF84)JP>i7!w}CAQ#rY64M{LD1jq!ekLGDH z5H?Z>UqrQ)7*E+V@6vBo+!c-^oEH|Q)LP1g!JF|DK)G-cQ59V!3d@`0387U@p_Z<$ zra*$&Hxk%~P^m>^qgN1LDQ*o^R81;lYT=m6#RNc&KNB7u`H6zl32@(6i(`7)AZfej!K7(F3r=a>PK>Mv*na1O;o3l9(%w2i~a)8mg`+u zxC%I6`GOldxgljymjbApMcWvK**zy&_Ur8u8zkPQgd;qH zAl0(@>k1WMd5jU5HL1QjM4_T|->i40gAhQq&fpMI;v0p^(FCY=-xB4zIc=9I0viw7 z3bGn5qoU;~C|^vg8G8ARML_n8BtK#~6@*9STkPv?5KH^C*0qx9$EGBmRiDu0olw1w3h6&3{b4sAxs*%gZC}FsOV>NPRONl}BPGZC{z3 z`=pl^zEgW3Us&@wnhyN;240uAIItb7{HHLJHrPx~Xs4FVZSwNmH3tLKJ4A ze*F^-Q5(QKOFUzZ>M<+}mz_AO3;BgPfU?Vtt}d-Flw1{<2{3=*U{zHiRu8fOzp%ji zED*4T@b)dk!1N0q^gvvwE}t=FFT)Je6kK^j8xm3oh@?ZBC7ge$FgS`u{~63>nVog>Iqd@ z`bIhk25&S>v9wtT%^)*R6MutA}CO9g5#oWch7~h!t+`CkdDh|7T;-+aMp{2$wHP1*5F*5TL(TS%H z()Lw)?kEG;N*zAN8-Y4vB)5ptWy#him42vLE04S@@NDs$#?%+;4C6AbIS+n5(OZX) z%20`He*G)nUBQeoT_w!r_-Y;oa%kv^(FXBowq$d7%+u_ay&<)AZMw!K)vJ?NnCy>{ z+AWy&BVc-?p29pq*em3OPn?Z5bTDEb&h|m6$$5lj0nB-N{lP_{>kg$l^Ax<-!S}dA zXooCOOY}7c1`wXziE9a10$lOa=@WLKX!nAFb42Y>9j{dSONV<lUV5I+er`@hLPv5Zn{3=lbFYd?Nv+^NG^&F=bIW=`7Y>1j%Br z2N0!3I_@|-__$K+4HyPN+{dv)X^V^u3GsU{RqiP-D-d{PFI{Q55}43{-QoydWqHf& zOtbtV1xL6dTC1;y4U7a_hUO0{0VGddWC2YdxEZdiERVK0@L}AEe~p#lV8L& zqRc8SUue$$2*n_&%D&+ME{w2^2h1eS-(B0T#rcF%s$Z)b+<9L->2S(o!C{RBUCZA*rT8i9y=!O(RP^a1=xn5wK{v^Q&AUMBjnGc!;r^pNi zPaRc8fSpK7VZgr@dMY?!^9(cWy+QlFvdaPJVH|_v99{U1BLn3Dejh0FtKA{Q`>2Bf z4RXiCs2u&{mtSEGdch1l{t^L_wapd_u?SO_#OVr*WtRwxwl#%`tUmG}!^+ES`_674 ztxP^p;Fbt#Xf*wx-$mvU;~;J?n87K9`hmMHy^#U>w-9}0Sk3h+btOx(f=-}<3brS9zcE)# zbm=pJh*1E(HuE}iRsbak`ARxe<~#8eCcSYS{{Rr36@DVxL5-jGT*~2@XYl}GDMJ3@ zJ2NP3PCiiZwf0J>3Rk$L!LN8*I+>Q!Fgum9^(t9cE^e-KnPS+#FuMnFUMeRgziEgt zwJChW11IKCC}shMke#jt4AQY5J)+Axmp0&nWz4!HUZH@MFLr(+Zi*qFfgdTj*JX&J z#I!11h3%RkP5FG>xRffbzi1SV{2`D~ekKE0-)6i^Yjg28O|QykidGd0AA$@u^+eTr zb&YA3P!6Ko^I9TwDS@vXKonCwVjZ&(IB&GfV<^gz&BinSq5?HIcR`uxrRNgC1G1Q6 z-f@78ty>*&1!|*bCZXqFQ(nGe8Vp1SBx>Fn`@<7U(JmDBPCs&jrTP##V*17+Ma0Vr z;LJ{}+_gU;G4MPwmma+(e$IqU0AC!+u~W<|fz{F}kgm~96UsK8#KLDW%wY*h#JZ@T zbT{I4n!2Ilz2f^p-G%{%0A9oyIbx2N0cz}}nG?|8jLH4`<$CAR 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 `*4b5ZV}XdGtnd(M0HfDQ}= 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

    8)=z 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�gvMLgGE_L(ud-$qF1Z($IQ*h)s>WV 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 bqFJ%{kI2ycjXSjPUPg&_f>EpP`#=BL)3yRX diff --git a/app/assets/images/home/home1.jpg b/app/assets/images/home/home1.jpg deleted file mode 100644 index 015b203bcf0cc1e032658eb19473080786167c9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 211404 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 z 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�h0ZDivUP~$jGpv*5-CrRS0M?p@RIqXL= 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%0Aq9(v#$P%AGkXk$Jz9 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%0DS>*s%?s5 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 z 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 diff --git a/app/assets/images/home/maps-bg.svg b/app/assets/images/home/maps-bg.svg deleted file mode 100644 index 48153cc191..0000000000 --- a/app/assets/images/home/maps-bg.svg +++ /dev/null @@ -1,1090 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/assets/images/home/producers-bg.svg b/app/assets/images/home/producers-bg.svg deleted file mode 100644 index 2a47eed65a..0000000000 --- a/app/assets/images/home/producers-bg.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From e8f59ca80f9a9ad251568b6ee85a718524440568 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Sat, 6 Jun 2020 20:02:55 +1000 Subject: [PATCH 372/507] Updating translations for config/locales/tr.yml --- config/locales/tr.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 09160deaa4..81e7552502 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -2810,6 +2810,12 @@ tr: void: "Geçersiz" login: "Oturum aç" password: "Parola" + signature: "İmza" + solution: "Çözüm" + landing_page: "Ana Sayfa" + server: "Server" + test_mode: "Test Modu" + logourl: "Logourl" configurations: "yapılandırmalar" general_settings: "Genel Ayarlar" site_name: "Site adı" @@ -3095,9 +3101,11 @@ tr: display: "Görüntüle" active: "Aktif" both: "Her ikisi de" + front_end: "Sadece Ödeme" back_end: "Sadece panel" active_yes: "Evet" active_no: "Hayır" + no_payment_methods_found: "Ödeme yöntemi bulunamadı" new: new_payment_method: "Yeni Ödeme Yöntemi" back_to_payment_methods_list: "Ödeme Yöntemleri Listesine Geri Dön" @@ -3127,8 +3135,10 @@ tr: active_yes: "Evet" active_no: "Hayır" both: "Ödeme Sayfası ve Panel" + front_end: "Sadece Ödeme" back_end: "Sadece panel" tags: "Etiketler" + deactivation_warning: "Bir ödeme yöntemini kaldırmak listenizden silinmesine sebep olabilir. Alternatif olarak, ödeme yöntemini 'Göster' yerine 'Yalnızca " providers: provider: "Sağlayıcı" payments: From 6c564dc7b27d1d23a04a09d699f6c28d2d2e1f17 Mon Sep 17 00:00:00 2001 From: Dany Marcoux Date: Sun, 7 Jun 2020 23:29:12 +0200 Subject: [PATCH 373/507] Shallow clone specific release for rbenv and ruby-build We don't need the whole git history, so doing a shallow clone is favourable. Cloning a specific release (the latest at the time of writing this) allows us to have reproducible results since we're not cloning whatever is on master at the time of building the Docker image. --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 202bbeccf7..49f0fa4838 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,8 +13,8 @@ WORKDIR /usr/src/app COPY .ruby-version . # Install Rbenv & Ruby -RUN git clone https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \ - git clone https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \ +RUN git clone --depth 1 --branch v1.1.2 https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \ + git clone --depth 1 --branch v20200520 https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \ ${RBENV_ROOT}/plugins/ruby-build/install.sh && \ echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh && \ rbenv install $(cat .ruby-version) && \ From a751d24562fb532148a8f7c007e43fded4e85b3e Mon Sep 17 00:00:00 2001 From: Dany Marcoux Date: Sun, 7 Jun 2020 23:32:46 +0200 Subject: [PATCH 374/507] Run bundler install in parallel with the amount of available CPUs --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 49f0fa4838..c30df2f92f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,4 +43,5 @@ RUN wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.z # Copy code and install app dependencies COPY . /usr/src/app/ -RUN bundle install +# Run bundler install in parallel with the amount of available CPUs +RUN bundle install --jobs="$(nproc)" From 9b8a97aadd0132003c1d8b7dff32cf7e6708c138 Mon Sep 17 00:00:00 2001 From: Gaetan Riou Date: Mon, 8 Jun 2020 15:39:28 +1000 Subject: [PATCH 375/507] Add handling of CSV::MalformedCSVError for product_importer --- app/models/product_import/product_importer.rb | 9 ++ config/locales/en.yml | 1 + spec/features/admin/product_import_spec.rb | 18 +++ spec/models/product_importer_spec.rb | 105 ++++++++++-------- 4 files changed, 89 insertions(+), 44 deletions(-) diff --git a/app/models/product_import/product_importer.rb b/app/models/product_import/product_importer.rb index 80a9744493..f83f2102a2 100644 --- a/app/models/product_import/product_importer.rb +++ b/app/models/product_import/product_importer.rb @@ -237,6 +237,15 @@ module ProductImport error_message: e.message)) end [] + rescue CSV::MalformedCSVError => e + # NOTE the init_product_importer method calls build_entries and + # buils_all_entries resulting in the error being raised twice + unless errors.added?(:importer, I18n.t('admin.product_import.model.malformed_csv', + error_message: e.message)) + errors.add(:importer, I18n.t('admin.product_import.model.malformed_csv', + error_message: e.message)) + end + [] end def build_entries_in_range diff --git a/config/locales/en.yml b/config/locales/en.yml index e2a70ff412..b30cc24c02 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -528,6 +528,7 @@ en: line_number: "Line %{number}:" encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding" unexpected_error: "Product Import encountered an unexpected error whilst opening the file: %{error_message}" + malformed_csv: "Product Import encountered a malformed CSV: %{error_message}" index: notice: "Notice" beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support." diff --git a/spec/features/admin/product_import_spec.rb b/spec/features/admin/product_import_spec.rb index b14122ce5d..fc1624980d 100644 --- a/spec/features/admin/product_import_spec.rb +++ b/spec/features/admin/product_import_spec.rb @@ -377,6 +377,24 @@ feature "Product Import", js: true do expect(page).to have_no_selector 'input[type=submit][value="Save"]' File.delete('/tmp/test.csv') end + + it "handles cases where files contains malformed data" do + csv_data = "name,producer,category,on_hand,price,units,unit_type,shipping_category\n" + csv_data += "Malformed \rBrocolli,#{enterprise.name},Vegetables,8,2.50,200,g,#{shipping_category.name}\n" + + File.write('/tmp/test.csv', csv_data) + + visit main_app.admin_product_import_path + attach_file 'file', '/tmp/test.csv' + click_button 'Upload' + + expect(page).to have_no_selector '.create-count' + expect(page).to have_no_selector '.update-count' + expect(page).to have_no_selector 'input[type=submit][value="Save"]' + expect(flash_message).to match(I18n.t('admin.product_import.model.malformed_csv', error_message: "")) + + File.delete('/tmp/test.csv') + end end describe "handling enterprise permissions" do diff --git a/spec/models/product_importer_spec.rb b/spec/models/product_importer_spec.rb index 705f99d41e..6f4903ba86 100644 --- a/spec/models/product_importer_spec.rb +++ b/spec/models/product_importer_spec.rb @@ -50,11 +50,11 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "variant_unit_name", "on_demand", "shipping_category"] - csv << ["Carrots", "User Enterprise", "Vegetables", "5", "3.20", "500", "g", "", "", shipping_category.name] - csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "6.50", "2", "kg", "", "", shipping_category.name] - csv << ["Pea Soup", "User Enterprise", "Vegetables", "8", "5.50", "750", "ml", "", "0", shipping_category.name] - csv << ["Salad", "User Enterprise", "Vegetables", "7", "4.50", "1", "", "bags", "", shipping_category.name] - csv << ["Hot Cross Buns", "User Enterprise", "Cake", "7", "3.50", "1", "", "buns", "1", shipping_category.name] + csv << ["Carrots", enterprise.name, "Vegetables", "5", "3.20", "500", "g", "", "", shipping_category.name] + csv << ["Potatoes", enterprise.name, "Vegetables", "6", "6.50", "2", "kg", "", "", shipping_category.name] + csv << ["Pea Soup", enterprise.name, "Vegetables", "8", "5.50", "750", "ml", "", "0", shipping_category.name] + csv << ["Salad", enterprise.name, "Vegetables", "7", "4.50", "1", "", "bags", "", shipping_category.name] + csv << ["Hot Cross Buns", enterprise.name, "Cake", "7", "3.50", "1", "", "buns", "1", shipping_category.name] end } let(:importer) { import_data csv_data } @@ -136,7 +136,7 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "shipping_category"] - csv << ["Good Carrots", "User Enterprise", "Vegetables", "5", "3.20", "500", "g", shipping_category.name] + csv << ["Good Carrots", enterprise.name, "Vegetables", "5", "3.20", "500", "g", shipping_category.name] csv << ["Bad Potatoes", "", "Vegetables", "6", "6.50", "1", "", shipping_category.name] end } @@ -169,11 +169,28 @@ describe ProductImport::ProductImporter do end end + describe "when uploading a spreadsheet with some malformed data" do + # Use a simple string as CVS.generate will do some escaping + let(:csv_data) { + csv = "name,producer,category,on_hand,price,units,unit_type,shipping_category\n" + csv += "Good Carrots,#{enterprise.name},Vegetables,5,3.20,500,g,#{shipping_category.name}\n" + csv += "Malformed \rBrocolli,#{enterprise.name},Vegetables,8,2.50,200,g,#{shipping_category.name}\n" + } + let(:importer) { import_data csv_data } + + # NOTE an unquoted \n will create a non valid line which will fail entry validation hence why we are only testing with \r + it "should raise an unquoted field error if data include unquoted filed with \r character" do + expect(importer.errors.messages.values).to include( + [I18n.t('admin.product_import.model.malformed_csv', error_message: "Unquoted fields do not allow \\r or \\n (line 3).")] + ) + end + end + describe "when shipping category is missing" do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "variant_unit_name", "on_demand", "shipping_category"] - csv << ["Shipping Test", "User Enterprise", "Vegetables", "5", "3.20", "500", "g", "", nil, nil] + csv << ["Shipping Test", enterprise.name, "Vegetables", "5", "3.20", "500", "g", "", nil, nil] end } let(:importer) { import_data csv_data } @@ -191,7 +208,7 @@ describe ProductImport::ProductImporter do CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type"] csv << ["Product 1", "Non-existent Enterprise", "Vegetables", "5", "5.50", "500", "g"] - csv << ["Product 2", "Non-Producer", "Vegetables", "5", "5.50", "500", "g"] + csv << ["Product 2", enterprise4.name, "Vegetables", "5", "5.50", "500", "g"] end } let(:importer) { import_data csv_data } @@ -209,8 +226,8 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "display_name", "shipping_category"] - csv << ["Hypothetical Cake", "Another Enterprise", "Cake", "5", "5.50", "500", "g", "Preexisting Banana", shipping_category.name] - csv << ["Hypothetical Cake", "Another Enterprise", "Cake", "6", "3.50", "500", "g", "Emergent Coffee", shipping_category.name] + csv << ["Hypothetical Cake", enterprise2.name, "Cake", "5", "5.50", "500", "g", "Preexisting Banana", shipping_category.name] + csv << ["Hypothetical Cake", enterprise2.name, "Cake", "6", "3.50", "500", "g", "Emergent Coffee", shipping_category.name] end } let(:importer) { import_data csv_data } @@ -251,7 +268,7 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "description", "category", "on_hand", "price", "units", "unit_type", "display_name", "shipping_category"] - csv << ["Hypothetical Cake", "Another Enterprise", "New Description", "Cake", "5", "5.50", "500", "g", "Preexisting Banana", shipping_category.name] + csv << ["Hypothetical Cake", enterprise2.name, "New Description", "Cake", "5", "5.50", "500", "g", "Preexisting Banana", shipping_category.name] end } let(:importer) { import_data csv_data } @@ -270,11 +287,11 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "display_name", "shipping_category"] - csv << ["Potatoes", "User Enterprise", "Vegetables", "5", "3.50", "500", "g", "Small Bag", shipping_category.name] - csv << ["Chives", "User Enterprise", "Vegetables", "6", "4.50", "500", "g", "Bunch", shipping_category.name] - csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "5.50", "2", "kg", "Big Bag", shipping_category.name] - csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "22.00", "10000", "g", "Small Sack", shipping_category.name] - csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "60.00", "30000", "", "Big Sack", shipping_category.name] + csv << ["Potatoes", enterprise.name, "Vegetables", "5", "3.50", "500", "g", "Small Bag", shipping_category.name] + csv << ["Chives", enterprise.name, "Vegetables", "6", "4.50", "500", "g", "Bunch", shipping_category.name] + csv << ["Potatoes", enterprise.name, "Vegetables", "6", "5.50", "2", "kg", "Big Bag", shipping_category.name] + csv << ["Potatoes", enterprise.name, "Vegetables", "6", "22.00", "10000", "g", "Small Sack", shipping_category.name] + csv << ["Potatoes", enterprise.name, "Vegetables", "6", "60.00", "30000", "", "Big Sack", shipping_category.name] end } let(:importer) { import_data csv_data } @@ -318,8 +335,8 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "on_demand", "sku", "shipping_category"] - csv << ["Beetroot", "And Another Enterprise", "Vegetables", "5", "3.50", "500", "g", "0", nil, shipping_category.name] - csv << ["Tomato", "And Another Enterprise", "Vegetables", "6", "5.50", "500", "g", "1", "TOMS", shipping_category.name] + csv << ["Beetroot", enterprise3.name, "Vegetables", "5", "3.50", "500", "g", "0", nil, shipping_category.name] + csv << ["Tomato", enterprise3.name, "Vegetables", "6", "5.50", "500", "g", "1", "TOMS", shipping_category.name] end } let(:importer) { import_data csv_data } @@ -356,8 +373,8 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type"] - csv << ["Beetroot", "And Another Enterprise", "Meat", "5", "3.50", "500", "g"] - csv << ["Tomato", "And Another Enterprise", "Vegetables", "6", "5.50", "500", "Kg"] + csv << ["Beetroot", enterprise3.name, "Meat", "5", "3.50", "500", "g"] + csv << ["Tomato", enterprise3.name, "Vegetables", "6", "5.50", "500", "Kg"] end } let(:importer) { import_data csv_data } @@ -379,11 +396,11 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "description", "on_hand", "price", "units", "unit_type", "display_name", "shipping_category"] - csv << ["Oats", "User Enterprise", "Cereal", "", "50", "3.50", "500", "g", "Rolled Oats", shipping_category.name] # Update - csv << ["Oats", "User Enterprise", "Cereal", "", "80", "3.75", "500", "g", "Flaked Oats", shipping_category.name] # Update - csv << ["Oats", "User Enterprise", "Cereal", "", "60", "5.50", "500", "g", "Magic Oats", shipping_category.name] # Add - csv << ["Oats", "User Enterprise", "Cereal", "", "70", "8.50", "500", "g", "French Oats", shipping_category.name] # Add - csv << ["Oats", "User Enterprise", "Cereal", "", "70", "8.50", "500", "g", "Scottish Oats", shipping_category.name] # Add + csv << ["Oats", enterprise.name, "Cereal", "", "50", "3.50", "500", "g", "Rolled Oats", shipping_category.name] # Update + csv << ["Oats", enterprise.name, "Cereal", "", "80", "3.75", "500", "g", "Flaked Oats", shipping_category.name] # Update + csv << ["Oats", enterprise.name, "Cereal", "", "60", "5.50", "500", "g", "Magic Oats", shipping_category.name] # Add + csv << ["Oats", enterprise.name, "Cereal", "", "70", "8.50", "500", "g", "French Oats", shipping_category.name] # Add + csv << ["Oats", enterprise.name, "Cereal", "", "70", "8.50", "500", "g", "Scottish Oats", shipping_category.name] # Add end } let(:importer) { import_data csv_data } @@ -415,11 +432,11 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "display_name", "shipping_category"] - csv << ["Bag of Oats", "User Enterprise", "Cereal", "60", "5.50", "500", "g", "Magic Oats", shipping_category.name] # Add - csv << ["Bag of Oats", "User Enterprise", "Cereal", "70", "8.50", "500", "g", "French Oats", shipping_category.name] # Add - csv << ["Bag of Oats", "User Enterprise", "Cereal", "80", "9.50", "500", "g", "Organic Oats", shipping_category.name] # Add - csv << ["Bag of Oats", "User Enterprise", "Cereal", "90", "7.50", "500", "g", "Scottish Oats", shipping_category.name] # Add - csv << ["Bag of Oats", "User Enterprise", "Cereal", "30", "6.50", "500", "g", "Breakfast Oats", shipping_category.name] # Add + csv << ["Bag of Oats", enterprise.name, "Cereal", "60", "5.50", "500", "g", "Magic Oats", shipping_category.name] # Add + csv << ["Bag of Oats", enterprise.name, "Cereal", "70", "8.50", "500", "g", "French Oats", shipping_category.name] # Add + csv << ["Bag of Oats", enterprise.name, "Cereal", "80", "9.50", "500", "g", "Organic Oats", shipping_category.name] # Add + csv << ["Bag of Oats", enterprise.name, "Cereal", "90", "7.50", "500", "g", "Scottish Oats", shipping_category.name] # Add + csv << ["Bag of Oats", enterprise.name, "Cereal", "30", "6.50", "500", "g", "Breakfast Oats", shipping_category.name] # Add end } @@ -481,9 +498,9 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "distributor", "producer", "on_hand", "price", "units", "unit_type", "variant_unit_name"] - csv << ["Beans", "Another Enterprise", "User Enterprise", "5", "3.20", "500", "g", ""] - csv << ["Sprouts", "Another Enterprise", "User Enterprise", "6", "6.50", "500", "g", ""] - csv << ["Cabbage", "Another Enterprise", "User Enterprise", "2001", "1.50", "1", "", "Whole"] + csv << ["Beans", enterprise2.name, enterprise.name, "5", "3.20", "500", "g", ""] + csv << ["Sprouts", enterprise2.name, enterprise.name, "6", "6.50", "500", "g", ""] + csv << ["Cabbage", enterprise2.name, enterprise.name, "2001", "1.50", "1", "", "Whole"] end } let(:importer) { import_data csv_data, import_into: 'inventories' } @@ -525,7 +542,7 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "display_name", "distributor", "producer", "on_hand", "price", "units"] - csv << ["Oats", "Porridge Oats", "Another Enterprise", "User Enterprise", "900", "", "500"] + csv << ["Oats", "Porridge Oats", enterprise2.name, enterprise.name, "900", "", "500"] end } let(:importer) { import_data csv_data, import_into: 'inventories' } @@ -548,7 +565,7 @@ describe ProductImport::ProductImporter do let(:csv_data) { CSV.generate do |csv| csv << ["name", "distributor", "producer", "on_hand", "price", "units", "variant_unit_name"] - csv << ["Cabbage", "Another Enterprise", "User Enterprise", "900", "", "1", "Whole"] + csv << ["Cabbage", enterprise2.name, enterprise.name, "900", "", "1", "Whole"] end } let(:importer) { import_data csv_data, import_into: 'inventories' } @@ -571,8 +588,8 @@ describe ProductImport::ProductImporter do it "only allows product import into enterprises the user is permitted to manage" do csv_data = CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "shipping_category"] - csv << ["My Carrots", "User Enterprise", "Vegetables", "5", "3.20", "500", "g", shipping_category.name] - csv << ["Your Potatoes", "Another Enterprise", "Vegetables", "6", "6.50", "1", "kg", shipping_category.name] + csv << ["My Carrots", enterprise.name, "Vegetables", "5", "3.20", "500", "g", shipping_category.name] + csv << ["Your Potatoes", enterprise2.name, "Vegetables", "6", "6.50", "1", "kg", shipping_category.name] end importer = import_data csv_data, import_user: user @@ -596,7 +613,7 @@ describe ProductImport::ProductImporter do it "allows creating inventories for producers that a user's hub has permission for" do csv_data = CSV.generate do |csv| csv << ["name", "producer", "distributor", "on_hand", "price", "units", "unit_type"] - csv << ["Beans", "User Enterprise", "Another Enterprise", "777", "3.20", "500", "g"] + csv << ["Beans", enterprise.name, enterprise2.name, "777", "3.20", "500", "g"] end importer = import_data csv_data, import_into: 'inventories' @@ -620,8 +637,8 @@ describe ProductImport::ProductImporter do it "does not allow creating inventories for producers that a user's hubs don't have permission for" do csv_data = CSV.generate do |csv| csv << ["name", "producer", "on_hand", "price", "units", "unit_type"] - csv << ["Beans", "User Enterprise", "5", "3.20", "500", "g"] - csv << ["Sprouts", "User Enterprise", "6", "6.50", "500", "g"] + csv << ["Beans", enterprise.name, "5", "3.20", "500", "g"] + csv << ["Sprouts", enterprise.name, "6", "6.50", "500", "g"] end importer = import_data csv_data, import_into: 'inventories' @@ -644,8 +661,8 @@ describe ProductImport::ProductImporter do it "can reset all products for an enterprise that are not present in the uploaded file to zero stock" do csv_data = CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "shipping_category"] - csv << ["Carrots", "User Enterprise", "Vegetables", "5", "3.20", "500", "g", shipping_category.name] - csv << ["Beans", "User Enterprise", "Vegetables", "6", "6.50", "500", "g", shipping_category.name] + csv << ["Carrots", enterprise.name, "Vegetables", "5", "3.20", "500", "g", shipping_category.name] + csv << ["Beans", enterprise.name, "Vegetables", "6", "6.50", "500", "g", shipping_category.name] end importer = import_data csv_data, reset_all_absent: true @@ -681,8 +698,8 @@ describe ProductImport::ProductImporter do it "can reset all inventory items for an enterprise that are not present in the uploaded file to zero stock" do csv_data = CSV.generate do |csv| csv << ["name", "distributor", "producer", "on_hand", "price", "units", "unit_type"] - csv << ["Beans", "Another Enterprise", "User Enterprise", "6", "3.20", "500", "g"] - csv << ["Sprouts", "Another Enterprise", "User Enterprise", "7", "6.50", "500", "g"] + csv << ["Beans", enterprise2.name, enterprise.name, "6", "3.20", "500", "g"] + csv << ["Sprouts", enterprise2.name, enterprise.name, "7", "6.50", "500", "g"] end importer = import_data csv_data, import_into: 'inventories', reset_all_absent: true From 7515b9c86c6fe0e6e0403adab35864d4b66654c3 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Mon, 8 Jun 2020 23:20:30 +1000 Subject: [PATCH 376/507] Updating translations for config/locales/it.yml --- config/locales/it.yml | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/config/locales/it.yml b/config/locales/it.yml index 89e40ea4c4..c111c89f68 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -31,6 +31,10 @@ it: taken: "Esiste già un account con questa email. Ti preghiamo di effettuare il login o impostare una nuova password." spree/order: no_card: Non ci sono carte di credito autorizzate disponibili per l'addebito + spree/credit_card: + attributes: + base: + card_expired: "è scaduto" order_cycle: attributes: orders_close_at: @@ -319,6 +323,7 @@ it: show_n_more: Mostra %{num} di più choose: "Scegli..." please_select: Seleziona... + column_save_as_default: Salva Come Predefinito columns: Colonne actions: Azioni viewing: "Vista: %{current_view_name}" @@ -683,6 +688,7 @@ it: ofn_uid_tip: Il codice univoco utilizzato per identificare l'azienda su OFN shipping_methods: name: "Nome" + applies: "Attivo?" manage: "Gestisci metodi di spedizione" create_button: "Crea un nuovo metodo di consegna" create_one_button: "Crea uno ora" @@ -861,6 +867,7 @@ it: incoming: "In arrivo" supplier: "Fornitore" products: "Prodotti" + receival_details: "Dettagli Ricevimento" fees: "Tariffe" save: "Salva" save_and_next: "Salva e continua" @@ -872,6 +879,7 @@ it: distributor: "Distributore" products: "Prodotti" tags: "Tag" + delivery_details: "Dettagli Spedizione" fees: "Tariffe" previous: "Precedente" save: "Salva" @@ -1169,7 +1177,11 @@ it: signup: "Registrati" contact: "contatto" require_customer_login: "Solo utenti approvati hanno accesso a questo negozio" + require_login_html: "Se sei già un cliente approvato, %{login} o %{signup} per procedere." + require_login_2_html: "Vuoi iniziare a acquistare qui? Per favore %{contact}%{enterprise}e chiedi di essere aggiunto." require_customer_html: "Se vuoi iniziare a comprare, per favore %{contact} %{enterprise} per chiedere di raggiungerci." + select_oc: + select_oc_html: "Per favore scegli quando vuoi il tuo ordine , per vedere quali prodotti sono disponibili." card_could_not_be_updated: La Carta non ha potuto essere rinnovata card_could_not_be_saved: La Carta non ha potuto essere salvata spree_gateway_error_flash_for_checkout: "C'è stato un problema con le informazioni sul pagamento: %{error}" @@ -1529,12 +1541,17 @@ it: orders_changeable_orders_alert_html: Questa gentile richiesta è stata confermata, ma puoi effettuare modifiche fino a %{oc_close}. products_clear: Pulisci products_showing: "Mostra:" + products_results_for: "Risultati per" products_or: "o" products_and: "e" + products_filters_in: "in" products_with: con + products_search: "Ricerca..." products_filter_by: "Filtra per" products_filter_selected: "selezionato" + products_filter_heading: "Filtri" products_filter_clear: "Pulisci" + products_filter_done: "Fatto" products_loading: "Caricamento prodotti..." products_updating_cart: "Aggiornamento del carrello..." products_cart_empty: "Carrello vuoto" @@ -1545,6 +1562,8 @@ it: products_update_error_msg: "Salvataggio fallito." products_update_error_data: "Salvataggio fallito per dati non validi:" products_changes_saved: "Modifiche salvate." + products_no_results_html: "Mi spiace, nessun risultato per %{query}" + products_clear_search: "Pulisci ricerca" search_no_results_html: "Mi dispiace, nessun risultato per %{query}. Vuoi provare un'altra ricerca?" components_profiles_popover: "I profili non hanno una vetrina su Open Food Network, ma potrebbero avere il proprio negozio fisico o online altrove" components_profiles_show: "Mostra profili" @@ -1900,6 +1919,7 @@ it: admin_enterprise_relationships_permits: "permessi" admin_enterprise_relationships_seach_placeholder: "Cerca" admin_enterprise_relationships_button_create: "Crea" + admin_enterprise_relationships_to: "a" admin_enterprise_groups: "Gruppi dell'azienda" admin_enterprise_groups_name: "Nome" admin_enterprise_groups_owner: "Proprietario" @@ -2305,6 +2325,10 @@ it: resolve_errors: 'Per favore risolvi i seguenti errori:' more_items: "+ %{count} ancora" default_card_updated: Carta predefinita aggiornata + cart: + add_to_cart_failed: > + C'è stato un problema nell'aggiungere questo prodotto al carrello. Forse + non é più disponibile o il negozio sta chiudendo. admin: enterprise_limit_reached: "Hai raggiunto il limite standard di aziende per account. Scrivi a %{contact_email} se hai bisogno di aumentarlo." modals: @@ -2789,6 +2813,12 @@ it: void: "vuoto" login: "Login" password: "Password" + signature: "Firma" + solution: "Soluzione" + landing_page: "Landing Page" + server: "Server" + test_mode: "Modalità di Test" + logourl: "Logourl" configurations: "Configurazioni" general_settings: "Impostazioni generali" site_name: "Nome del sito" @@ -3012,6 +3042,7 @@ it: tax_invoice: "FATTURA DELLE TASSE" code: "Codice" from: "Da" + to: "Pagamento a" shipping: "Spedizione" form: distribution_fields: @@ -3046,6 +3077,8 @@ it: zone: "Zone" calculator: "Calcolatrice" display: "Visualizza" + both: "Entrambi Checkout e Back office" + back_end: "Solo Back office" no_shipping_methods_found: "Nessun metodo di spedizione trovato" new: new_shipping_method: "Nuovo metodo di spedizione" @@ -3057,6 +3090,9 @@ it: form: categories: "categorie" zones: "Zone" + both: "Entrambi Checkout e Back Office" + back_end: "Solo Back office" + deactivation_warning: "Disattivare un metodo di spedizione può far sparire il metodo di spedizione dalla tua lista. Alternativamente, puoi nascondere il metodo di spedizione dalla pagina di checkout impostando l'opzione 'Visualizza' su 'Solo Back office'." payment_methods: index: payment_methods: "Metodi di pagamento" @@ -3068,8 +3104,11 @@ it: display: "Visualizza" active: "Attivo" both: "Entrambi" + front_end: "Solo checkout" + back_end: "Solo Back office" active_yes: "Sì" active_no: "No" + no_payment_methods_found: "Nessun metodo di pagamento trovato" new: new_payment_method: "Nuovo metodo di pagamento" back_to_payment_methods_list: "Torna all'elenco dei metodi di pagamento" @@ -3098,7 +3137,11 @@ it: active: "Attivo" active_yes: "Sì" active_no: "No" + both: "Entrambi Checkout e Back Office" + front_end: "Solo checkout" + back_end: "Solo Back office" tags: "Tag" + deactivation_warning: "Disattivare un metodo di pagamento può far sparire il metodo di pagamento dalla tua lista. Alternativamente, puoi nascondere il metodo di pagamento dalla pagina di checkout impostando l'opzione 'Visualizza' su 'Solo Back office'." providers: provider: "Provider" payments: @@ -3200,6 +3243,8 @@ it: price: "Prezzo" display_as: "Visualizza come" display_name: "Nome da visualizzare" + display_as_placeholder: 'es. 2 kg' + display_name_placeholder: 'es. Pomodori' autocomplete: producer_name: "Produttore" unit: "Unità" @@ -3238,6 +3283,7 @@ it: format: '%Y-%m-%d' js_format: 'aa-mm-gg' orders: + error_flash_for_unavailable_items: "Un oggetto nel tuo carrello è diventato non disponibile, Per favore aggiorna le quantità selezionate." edit: login_to_view_order: "Effettua il login per visualizzare il tuo ordine." bought: @@ -3265,6 +3311,14 @@ it: invalid: invalido order_mailer: cancel_email: + customer_greeting: "Caro %{name}," + instructions_html: "Il tuo ordine con %{distributor} è stato CANCELLATO. Per favore conserva questa informazione per i tuoi dati." + dont_cancel: "Se hai cambiato idea o non desideri annullare questo ordine, ti preghiamo di contattare%{email}" + order_summary_canceled_html: "Riepilogo Ordine #%{number} [CANCELLATO]" + details: "Qui ci sono i dettagli di quello che hai ordinato:" + unpaid_order: "Il tuo ordine risulta pendente nessun rimborso è stato eseguito" + paid_order: "Il tuo ordine era già stato pagato così %{distributor} ha rimborsato l'intero costo" + credit_order: "Il tuo ordine è stato pagato, quindi il tuo acconto è stato accreditato" subject: "Cancellazione dell'ordine" confirm_email: subject: "Conferma dell'ordine" From dceae2a98b3f70a96c2d4a101024832582d805eb Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Mon, 8 Jun 2020 23:23:41 +1000 Subject: [PATCH 377/507] Updating translations for config/locales/it.yml --- config/locales/it.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/it.yml b/config/locales/it.yml index c111c89f68..c24462f697 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -5,18 +5,18 @@ it: enterprise_fee: fee_type: Tipo di tariffa spree/order: - payment_state: Stato del pagamento - shipment_state: Stato della spedizione - completed_at: Completo al + payment_state: Stato Pagamento + shipment_state: Stato Spedizione + completed_at: Completo Al number: Numero state: Stato - email: Mail consumatore + email: E-Mail Cliente spree/payment: amount: Quantità spree/product: - primary_taxon: "Categoria prodotto" + primary_taxon: "Categoria Prodotto" supplier: "Fornitore" - shipping_category_id: "Categoria di spedizione" + shipping_category_id: "Categoria Spedizioni" variant_unit: "Unità Variante" variant_unit_name: "Nome Unità Variante" spree/credit_card: From c4e910a7c8cd11500a63e70b684a0bda9d70785c Mon Sep 17 00:00:00 2001 From: jeffrey s hill md Date: Fri, 10 Apr 2020 15:41:40 -0500 Subject: [PATCH 378/507] Make clear filters fetch products automatically without filters The spec change is needed: fetchProducts() makes cleared filters values undefined in removeClearedValues. --- app/assets/javascripts/admin/bulk_product_update.js.coffee | 1 + .../javascripts/unit/admin/bulk_product_update_spec.js.coffee | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index d92bc73566..94939f3f91 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -105,6 +105,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout $scope.producerFilter = "0" $scope.categoryFilter = "0" $scope.importDateFilter = "0" + $scope.fetchProducts() $scope.$watch 'sortOptions', (sort) -> return unless sort && sort.predicate != "" diff --git a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee index 4feff89868..d483bec6a8 100644 --- a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee +++ b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee @@ -903,8 +903,8 @@ describe "AdminProductEditCtrl", -> $scope.categoryFilter = "6" $scope.resetSelectFilters() expect($scope.query).toBe "" - expect($scope.producerFilter).toBe "0" - expect($scope.categoryFilter).toBe "0" + expect($scope.producerFilter).toBeUndefined + expect($scope.categoryFilter).toBeUndefined describe "converting arrays of objects with ids to an object with ids as keys", -> From 5fcc0dcd14ed4fba3ae817c008e6e61b0355ec38 Mon Sep 17 00:00:00 2001 From: Steve Roberts Date: Wed, 27 May 2020 15:58:36 +1000 Subject: [PATCH 379/507] Add configuration to enable matomo tag manager - Update embed codes and allow both scripts concurrently - Add lines around blocks - Update MTM copy based on PR feedback - checked cookies unchanged --- app/models/spree/app_configuration_decorator.rb | 1 + app/views/admin/matomo_settings/edit.html.haml | 6 +++++- app/views/layouts/_matomo_tag.html.haml | 15 ++++++++++++--- config/locales/en.yml | 4 +++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/app/models/spree/app_configuration_decorator.rb b/app/models/spree/app_configuration_decorator.rb index 5b11a0ee61..a039ddbd45 100644 --- a/app/models/spree/app_configuration_decorator.rb +++ b/app/models/spree/app_configuration_decorator.rb @@ -26,6 +26,7 @@ Spree::AppConfiguration.class_eval do preference :bugherd_api_key, :string, default: nil preference :matomo_url, :string, default: nil preference :matomo_site_id, :string, default: nil + preference :matomo_tag_manager_url, :string, default: nil # Invoices & Receipts preference :enable_invoices?, :boolean, default: true diff --git a/app/views/admin/matomo_settings/edit.html.haml b/app/views/admin/matomo_settings/edit.html.haml index 51f553bcff..6a6b447da4 100644 --- a/app/views/admin/matomo_settings/edit.html.haml +++ b/app/views/admin/matomo_settings/edit.html.haml @@ -17,7 +17,11 @@ .field = label_tag(:matomo_site_id, t('.matomo_site_id')) + tag(:br) = preference_field_tag("preferences[#{:matomo_site_id}]", Spree::Config[:matomo_site_id], type: Spree::Config.preference_type(:matomo_site_id)) - + + %legend= t('.config_instructions_tag_manager_html') + .field + = label_tag(:matomo_tag_manager_url, t('.matomo_tag_manager_url')) + tag(:br) + = preference_field_tag("preferences[#{:matomo_tag_manager_url}]", Spree::Config[:matomo_tag_manager_url], type: Spree::Config.preference_type(:matomo_tag_manager_url)) .form-buttons{"data-hook" => "buttons"} = button t(:update), 'icon-refresh' diff --git a/app/views/layouts/_matomo_tag.html.haml b/app/views/layouts/_matomo_tag.html.haml index aba1b19528..85a4cf47dc 100644 --- a/app/views/layouts/_matomo_tag.html.haml +++ b/app/views/layouts/_matomo_tag.html.haml @@ -1,6 +1,15 @@ + +- if Spree::Config.matomo_tag_manager_url.present? + :javascript + var _mtm = _mtm || []; + _mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'}); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + var u="#{Spree::Config.matomo_tag_manager_url}"; + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u; s.parentNode.insertBefore(g,s); + - if Spree::Config.matomo_url.present? :javascript - var _paq = _paq || []; + var _paq = window._paq || []; _paq.push(["setDocumentTitle", document.domain + "/" + document.title]); _paq.push(["setCookieDomain", "*.#{Spree::Config.site_url}"]); _paq.push(["setDomains", ["*.#{Spree::Config.site_url}"]]); @@ -8,8 +17,8 @@ _paq.push(['enableLinkTracking']); (function() { var u="#{Spree::Config.matomo_url}"; - _paq.push(['setTrackerUrl', u+'piwik.php']); + _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '#{Spree::Config.matomo_site_id}']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); diff --git a/config/locales/en.yml b/config/locales/en.yml index 63be6d0844..195253f8e1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -415,8 +415,10 @@ en: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." + config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." customers: index: From 6056c1699f58a0a3bb75e8e7accbfe3d75e8f65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Tue, 9 Jun 2020 10:10:34 +0200 Subject: [PATCH 380/507] Use batches in order to fetch orders --- app/services/bulk_invoice_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/bulk_invoice_service.rb b/app/services/bulk_invoice_service.rb index ab69df03ca..b4c096b3c3 100644 --- a/app/services/bulk_invoice_service.rb +++ b/app/services/bulk_invoice_service.rb @@ -8,7 +8,7 @@ class BulkInvoiceService def start_pdf_job(order_ids) pdf = CombinePDF.new - orders_from(order_ids).each do |order| + orders_from(order_ids).find_each do |order| invoice = renderer.render_to_string(order) pdf << CombinePDF.parse(invoice) From 795106aaa28293048c9003dc93d88894d2abb1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Tue, 9 Jun 2020 10:11:11 +0200 Subject: [PATCH 381/507] Use real orders inside spec to extend coverage --- spec/services/bulk_invoice_service_spec.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/services/bulk_invoice_service_spec.rb b/spec/services/bulk_invoice_service_spec.rb index 1874a0fcb4..52fe085288 100644 --- a/spec/services/bulk_invoice_service_spec.rb +++ b/spec/services/bulk_invoice_service_spec.rb @@ -50,8 +50,11 @@ describe BulkInvoiceService do describe "#orders_from" do it "orders with completed desc" do - expect(service.send(:orders_from, [1, 2]).to_sql) - .to include('ORDER BY completed_at DESC') + order_old = create(:order_with_distributor, :completed, completed_at: 2.minutes.ago) + order_older = create(:order_with_distributor, :completed, completed_at: 3.minutes.ago) + + expect(service.send(:orders_from, [order_older.id, order_old.id]).pluck(:id)) + .to eq([order_old.id, order_older.id]) end end end From c4fbce30c8232f33c123d29b2947ae0bcd7571cc Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Tue, 9 Jun 2020 16:07:54 +1000 Subject: [PATCH 382/507] Add translation keys to en.yml file for variant_override error message translation --- config/locales/en.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 63be6d0844..7e1d3e4670 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -44,6 +44,8 @@ en: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: From 79243303217c823425de1d2343f234fc7b4a1292 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 9 Jun 2020 10:52:53 +0100 Subject: [PATCH 383/507] Fix problem with stub_const, we need auto load the controller before the const is stubbed otherwise the controller will be broken See details here: https://github.com/rspec/rspec-mocks/issues/1079#issuecomment-215620243 --- spec/controllers/api/exchange_products_controller_spec.rb | 4 +++- .../complex_editing_multiple_product_pages_spec.rb | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/controllers/api/exchange_products_controller_spec.rb b/spec/controllers/api/exchange_products_controller_spec.rb index c39546358b..f94089280c 100644 --- a/spec/controllers/api/exchange_products_controller_spec.rb +++ b/spec/controllers/api/exchange_products_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module Api @@ -52,7 +54,7 @@ module Api let(:products_relation) { Spree::Product.includes(:variants).where("spree_variants.id": exchange.variants.map(&:id)) } before do - stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) + stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) end describe "when a specific page is requested" do diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb index c74630121d..5ff181e7f5 100644 --- a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb +++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' feature ' @@ -14,7 +16,7 @@ feature ' let!(:new_product) { create(:product, supplier: supplier_enterprise) } before do - stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) + stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) quick_login_as_admin visit admin_order_cycle_incoming_path(order_cycle) From fd5062429ae8dd0561d882e63d55bcff978342b0 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 9 Jun 2020 11:11:48 +0100 Subject: [PATCH 384/507] Add context to delete specs so we can add other specs --- .../admin/shipping_methods_controller_spec.rb | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb index d705972c87..c8fb13f686 100644 --- a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +++ b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb @@ -3,29 +3,31 @@ require 'spec_helper' describe Spree::Admin::ShippingMethodsController, type: :controller do include AuthenticationWorkflow - describe "shipping method not referenced by order" do - let(:shipping_method) { create(:shipping_method) } + describe "#delete" do + describe "shipping method not referenced by order" do + let(:shipping_method) { create(:shipping_method) } - scenario "is soft deleted" do - login_as_admin - expect(shipping_method.deleted_at).to be_nil + scenario "is soft deleted" do + login_as_admin + expect(shipping_method.deleted_at).to be_nil - spree_delete :destroy, "id" => shipping_method.id + spree_delete :destroy, "id" => shipping_method.id - expect(shipping_method.reload.deleted_at).not_to be_nil + expect(shipping_method.reload.deleted_at).not_to be_nil + end end - end - describe "shipping method referenced by order" do - let(:order) { create(:order_with_line_items) } + describe "shipping method referenced by order" do + let(:order) { create(:order_with_line_items) } - scenario "is not soft deleted" do - login_as_admin - expect(order.shipping_method.deleted_at).to be_nil + scenario "is not soft deleted" do + login_as_admin + expect(order.shipping_method.deleted_at).to be_nil - spree_delete :destroy, "id" => order.shipping_method.id + spree_delete :destroy, "id" => order.shipping_method.id - expect(order.shipping_method.reload.deleted_at).to be_nil + expect(order.shipping_method.reload.deleted_at).to be_nil + end end end end From f05b0d1a5736ad531c76f05594a97a87d21fe511 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 9 Jun 2020 12:02:35 +0100 Subject: [PATCH 385/507] Add missing fields to ship method controller permitted params list --- .../spree/admin/shipping_methods_controller.rb | 7 ++++++- .../admin/shipping_methods_controller_spec.rb | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/shipping_methods_controller.rb b/app/controllers/spree/admin/shipping_methods_controller.rb index a8c5dbb1e1..fe3bdb5d86 100644 --- a/app/controllers/spree/admin/shipping_methods_controller.rb +++ b/app/controllers/spree/admin/shipping_methods_controller.rb @@ -86,7 +86,12 @@ module Spree params.require(:shipping_method).permit( :name, :description, :display_on, :require_ship_address, :tag_list, :calculator_type, - distributor_ids: [] + distributor_ids: [], + calculator_attributes: [ + :id, :preferred_currency, :preferred_amount, :preferred_per_kg, :preferred_flat_percent, + :preferred_first_item, :preferred_additional_item, :preferred_max_items, + :preferred_minimal_amount, :preferred_normal_amount, :preferred_discount_amount + ] ) end end diff --git a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb index c8fb13f686..3890540dd2 100644 --- a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +++ b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb @@ -3,6 +3,24 @@ require 'spec_helper' describe Spree::Admin::ShippingMethodsController, type: :controller do include AuthenticationWorkflow + describe "#update" do + describe "calculator details" do + let(:shipping_method) { create(:shipping_method_with, :flat_rate) } + + it "updates flat rate calculator preferred_amount" do + login_as_admin + spree_post :update, id: shipping_method.id, + shipping_method: { + calculator_attributes: { + id: shipping_method.calculator.id, + preferred_amount: 123 + } + } + expect(shipping_method.reload.calculator.preferred_amount).to eq 123 + end + end + end + describe "#delete" do describe "shipping method not referenced by order" do let(:shipping_method) { create(:shipping_method) } From 87292a8ce5b55d6005c7e61e042ade6159036438 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 9 Jun 2020 12:13:44 +0100 Subject: [PATCH 386/507] Refactor spec to add more similar specs --- .../admin/shipping_methods_controller_spec.rb | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb index 3890540dd2..f4e0974a76 100644 --- a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +++ b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb @@ -4,19 +4,29 @@ describe Spree::Admin::ShippingMethodsController, type: :controller do include AuthenticationWorkflow describe "#update" do - describe "calculator details" do + let(:params) { + { + id: shipping_method.id, + shipping_method: { + calculator_attributes: { + id: shipping_method.calculator.id + } + } + } + } + + describe "flat rate calculator details" do let(:shipping_method) { create(:shipping_method_with, :flat_rate) } - it "updates flat rate calculator preferred_amount" do + it "updates preferred_amount and preferred_currency" do login_as_admin - spree_post :update, id: shipping_method.id, - shipping_method: { - calculator_attributes: { - id: shipping_method.calculator.id, - preferred_amount: 123 - } - } + params[:shipping_method][:calculator_attributes][:preferred_amount] = 123 + params[:shipping_method][:calculator_attributes][:preferred_currency] = "EUR" + + spree_post :update, params + expect(shipping_method.reload.calculator.preferred_amount).to eq 123 + expect(shipping_method.reload.calculator.preferred_currency).to eq "EUR" end end end From 0c1ed1731de2207fb93da7265500d249d64a59e6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 9 Jun 2020 12:33:55 +0100 Subject: [PATCH 387/507] Add more specs to ship method controller --- .../admin/shipping_methods_controller_spec.rb | 65 ++++++++++++++++--- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb index f4e0974a76..531d01c11e 100644 --- a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +++ b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb @@ -4,6 +4,7 @@ describe Spree::Admin::ShippingMethodsController, type: :controller do include AuthenticationWorkflow describe "#update" do + let(:shipping_method) { create(:shipping_method) } let(:params) { { id: shipping_method.id, @@ -15,19 +16,63 @@ describe Spree::Admin::ShippingMethodsController, type: :controller do } } - describe "flat rate calculator details" do - let(:shipping_method) { create(:shipping_method_with, :flat_rate) } + before { login_as_admin } - it "updates preferred_amount and preferred_currency" do - login_as_admin - params[:shipping_method][:calculator_attributes][:preferred_amount] = 123 - params[:shipping_method][:calculator_attributes][:preferred_currency] = "EUR" + it "updates preferred_amount and preferred_currency of a FlatRate calculator" do + shipping_method.calculator = create(:calculator_flat_rate, calculable: shipping_method) + params[:shipping_method][:calculator_attributes][:preferred_amount] = 123 + params[:shipping_method][:calculator_attributes][:preferred_currency] = "EUR" - spree_post :update, params + spree_post :update, params - expect(shipping_method.reload.calculator.preferred_amount).to eq 123 - expect(shipping_method.reload.calculator.preferred_currency).to eq "EUR" - end + expect(shipping_method.reload.calculator.preferred_amount).to eq 123 + expect(shipping_method.reload.calculator.preferred_currency).to eq "EUR" + end + + it "updates preferred_per_kg of a Weight calculator" do + shipping_method.calculator = create(:weight_calculator, calculable: shipping_method) + params[:shipping_method][:calculator_attributes][:preferred_per_kg] = 10 + + spree_post :update, params + + expect(shipping_method.reload.calculator.preferred_per_kg).to eq 10 + end + + it "updates preferred_flat_percent of a FlatPercentPerItem calculator" do + shipping_method.calculator = Calculator::FlatPercentPerItem.new(preferred_flat_percent: 20, + + calculable: shipping_method) + params[:shipping_method][:calculator_attributes][:preferred_flat_percent] = 30 + + spree_post :update, params + + expect(shipping_method.reload.calculator.preferred_flat_percent).to eq 30 + end + + it "updates details of a FlexiRate calculator" do + shipping_method.calculator = Spree::Calculator::FlexiRate.new(calculable: shipping_method) + params[:shipping_method][:calculator_attributes][:preferred_first_item] = 10 + params[:shipping_method][:calculator_attributes][:preferred_additional_item] = 20 + params[:shipping_method][:calculator_attributes][:preferred_max_items] = 30 + + spree_post :update, params + + expect(shipping_method.reload.calculator.preferred_first_item).to eq 10 + expect(shipping_method.reload.calculator.preferred_additional_item).to eq 20 + expect(shipping_method.reload.calculator.preferred_max_items).to eq 30 + end + + it "updates details of a PriceSack calculator" do + shipping_method.calculator = Spree::Calculator::PriceSack.new(calculable: shipping_method) + params[:shipping_method][:calculator_attributes][:preferred_minimal_amount] = 10 + params[:shipping_method][:calculator_attributes][:preferred_normal_amount] = 20 + params[:shipping_method][:calculator_attributes][:preferred_discount_amount] = 30 + + spree_post :update, params + + expect(shipping_method.reload.calculator.preferred_minimal_amount).to eq 10 + expect(shipping_method.reload.calculator.preferred_normal_amount).to eq 20 + expect(shipping_method.reload.calculator.preferred_discount_amount).to eq 30 end end From 680ee3dc860da5bf6ad4af1c1b444d788dffeb80 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 10 Jun 2020 10:05:47 +1000 Subject: [PATCH 388/507] Check the bulk invoice rendering order As it turns out, our performance optimisation with `find_each` overrides or custom sorting. --- spec/services/bulk_invoice_service_spec.rb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/spec/services/bulk_invoice_service_spec.rb b/spec/services/bulk_invoice_service_spec.rb index 52fe085288..1ff3d9edab 100644 --- a/spec/services/bulk_invoice_service_spec.rb +++ b/spec/services/bulk_invoice_service_spec.rb @@ -49,12 +49,25 @@ describe BulkInvoiceService do end describe "#orders_from" do + let(:renderer) { InvoiceRenderer.new } + + before do + allow(InvoiceRenderer).to receive(:new).and_return(renderer) + end + it "orders with completed desc" do order_old = create(:order_with_distributor, :completed, completed_at: 2.minutes.ago) + order_oldest = create(:order_with_distributor, :completed, completed_at: 4.minutes.ago) order_older = create(:order_with_distributor, :completed, completed_at: 3.minutes.ago) - expect(service.send(:orders_from, [order_older.id, order_old.id]).pluck(:id)) - .to eq([order_old.id, order_older.id]) + # This is the creation order provided `find_each` which invalidates + # our intended sorting by `completed_at`: + expect(renderer).to receive(:render_to_string).with(order_old).ordered.and_return("") + expect(renderer).to receive(:render_to_string).with(order_oldest).ordered.and_return("") + expect(renderer).to receive(:render_to_string).with(order_older).ordered.and_return("") + + order_ids = [order_oldest, order_old, order_older].map(&:id) + service.start_pdf_job_without_delay(order_ids) end end end From 7d53b12baf029cac51651b59f2f12ca2dc3fd53a Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 10 Jun 2020 10:08:06 +1000 Subject: [PATCH 389/507] Preserve sorting by completion date --- app/services/bulk_invoice_service.rb | 2 +- spec/services/bulk_invoice_service_spec.rb | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/services/bulk_invoice_service.rb b/app/services/bulk_invoice_service.rb index b4c096b3c3..ab69df03ca 100644 --- a/app/services/bulk_invoice_service.rb +++ b/app/services/bulk_invoice_service.rb @@ -8,7 +8,7 @@ class BulkInvoiceService def start_pdf_job(order_ids) pdf = CombinePDF.new - orders_from(order_ids).find_each do |order| + orders_from(order_ids).each do |order| invoice = renderer.render_to_string(order) pdf << CombinePDF.parse(invoice) diff --git a/spec/services/bulk_invoice_service_spec.rb b/spec/services/bulk_invoice_service_spec.rb index 1ff3d9edab..687e680bcc 100644 --- a/spec/services/bulk_invoice_service_spec.rb +++ b/spec/services/bulk_invoice_service_spec.rb @@ -60,11 +60,9 @@ describe BulkInvoiceService do order_oldest = create(:order_with_distributor, :completed, completed_at: 4.minutes.ago) order_older = create(:order_with_distributor, :completed, completed_at: 3.minutes.ago) - # This is the creation order provided `find_each` which invalidates - # our intended sorting by `completed_at`: expect(renderer).to receive(:render_to_string).with(order_old).ordered.and_return("") - expect(renderer).to receive(:render_to_string).with(order_oldest).ordered.and_return("") expect(renderer).to receive(:render_to_string).with(order_older).ordered.and_return("") + expect(renderer).to receive(:render_to_string).with(order_oldest).ordered.and_return("") order_ids = [order_oldest, order_old, order_older].map(&:id) service.start_pdf_job_without_delay(order_ids) From f8673fb57587d35b8d11fec4ef75d0f96042ad3a Mon Sep 17 00:00:00 2001 From: Steve Roberts Date: Wed, 10 Jun 2020 15:06:53 +1000 Subject: [PATCH 390/507] Moved tag manager instructions to be directly below the field --- app/views/admin/matomo_settings/edit.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/matomo_settings/edit.html.haml b/app/views/admin/matomo_settings/edit.html.haml index 6a6b447da4..0c553ae002 100644 --- a/app/views/admin/matomo_settings/edit.html.haml +++ b/app/views/admin/matomo_settings/edit.html.haml @@ -17,11 +17,11 @@ .field = label_tag(:matomo_site_id, t('.matomo_site_id')) + tag(:br) = preference_field_tag("preferences[#{:matomo_site_id}]", Spree::Config[:matomo_site_id], type: Spree::Config.preference_type(:matomo_site_id)) - - %legend= t('.config_instructions_tag_manager_html') + .field = label_tag(:matomo_tag_manager_url, t('.matomo_tag_manager_url')) + tag(:br) = preference_field_tag("preferences[#{:matomo_tag_manager_url}]", Spree::Config[:matomo_tag_manager_url], type: Spree::Config.preference_type(:matomo_tag_manager_url)) + .warning.note= t('.config_instructions_tag_manager_html') .form-buttons{"data-hook" => "buttons"} = button t(:update), 'icon-refresh' From 9a2618cd39fea24e35e01409f5d4da75993716d6 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 11 Jun 2020 01:09:41 +1000 Subject: [PATCH 391/507] Updating translations for config/locales/ca.yml --- config/locales/ca.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 4ee031cc78..4dd66970b6 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -2815,6 +2815,12 @@ ca: void: "Buit" login: "Inicia sessió" password: "Contrasenya" + signature: "Signatura" + solution: "Solució" + landing_page: "Pàgina d'inici" + server: "Servidor" + test_mode: "Mode de prova" + logourl: "URL del logo" configurations: "Configuracions" general_settings: "Configuració general" site_name: "Nom del lloc" @@ -3100,9 +3106,11 @@ ca: display: "Mostra" active: "Actiu" both: "Ambdós" + front_end: "Visible només per al comprador" back_end: "Només pàgina administració (back office) " active_yes: "Sí" active_no: "No" + no_payment_methods_found: "No s'han trobat mètodes de pagament" new: new_payment_method: "Nou mètode de pagament" back_to_payment_methods_list: "Tornar a la llista de mètodes de pagament" @@ -3132,8 +3140,10 @@ ca: active_yes: "Sí" active_no: "No" both: "Ambdues, validació de comanda i administració" + front_end: "Visible només per al comprador" back_end: "Només pàgina administració (back office) " tags: "Etiquetes" + deactivation_warning: "Desactivar un mètode de pagament pot fer que el mètode de pagament desapareixi de la vostra llista. De forma alternativa, podeu amagar un mètode de pagament a la pàgina de compra definint l'opció 'Mostra' com a 'Visible per a l'administrador'." providers: provider: "Proveïdor" payments: From 1abbd7261e33c819620c7458e8fbc5998fbf3764 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 11 Jun 2020 01:13:33 +1000 Subject: [PATCH 392/507] Updating translations for config/locales/es.yml --- config/locales/es.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/locales/es.yml b/config/locales/es.yml index 0fc3a89fe4..3ae8c94f87 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2815,6 +2815,12 @@ es: void: "Vacío" login: "Iniciar sesión" password: "Contraseña" + signature: "Firma" + solution: "Solución" + landing_page: "Página de inicio" + server: "Servidor" + test_mode: "Modo de prueba" + logourl: "URL del logo" configurations: "Configuraciones" general_settings: "Configuración general" site_name: "Nombre del sitio" @@ -3100,9 +3106,11 @@ es: display: "Mostrar" active: "Activo" both: "Ambos" + front_end: "Solo visible para el comprador" back_end: "Solo en Administración" active_yes: "Sí" active_no: "No" + no_payment_methods_found: "No se encontraron métodos de pago." new: new_payment_method: "Nuevo método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" @@ -3132,8 +3140,10 @@ es: active_yes: "Sí" active_no: "No" both: "Tanto en Hacer pedido como en Administración" + front_end: "Solo visible para el comprador" back_end: "Solo en Administración" tags: "Tags" + deactivation_warning: "La desactivación de un método de pago puede hacer que el método de pago desaparezca de su lista. Alternativamente, puede ocultar un método de pago desde la página de pago configurando la opción 'Mostrar' como 'Solo visible para el administrador'." providers: provider: "Proveedor" payments: From 1a700f870c035e6bb27b53954c06be095678fd9e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2020 19:16:40 +0000 Subject: [PATCH 393/507] Bump test-unit from 3.3.5 to 3.3.6 Bumps [test-unit](https://github.com/test-unit/test-unit) from 3.3.5 to 3.3.6. - [Release notes](https://github.com/test-unit/test-unit/releases) - [Commits](https://github.com/test-unit/test-unit/compare/3.3.5...3.3.6) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index fbe58d5b4d..dab1f92496 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -494,7 +494,7 @@ GEM polyamorous (0.5.0) activerecord (~> 3.0) polyglot (0.3.5) - power_assert (1.1.5) + power_assert (1.2.0) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -637,7 +637,7 @@ GEM state_machine (1.2.0) stringex (1.5.1) stripe (5.22.0) - test-unit (3.3.5) + test-unit (3.3.6) power_assert thor (0.20.3) tilt (1.4.1) From 220c84075f89c7df5b38facb203c79f2d103210e Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 11 Jun 2020 16:25:36 +1000 Subject: [PATCH 394/507] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 37dc60af05..352eedea77 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -368,8 +368,10 @@ en_FR: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.orgfor more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." + config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." customers: index: new_customer: "New Customer" @@ -2931,6 +2933,12 @@ en_FR: options: "Options" actions: update: "Update" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 error prohibited this record from being saved:" + other: "%{count} errors prohibited this record from being saved:" + there_were_problems_with_the_following_fields: "There were problems with the following fields" errors: messages: blank: "can't be blank" @@ -3242,6 +3250,7 @@ en_FR: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: From 472338b522af0e161a3f7cc037f6e5a4c7b0f4b5 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 11 Jun 2020 16:32:02 +1000 Subject: [PATCH 395/507] Updating translations for config/locales/fr.yml --- config/locales/fr.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 88e0e981c1..6f4cf8df9b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -368,8 +368,10 @@ fr: title: "Configuration Matomo" matomo_url: "URL de l'instance sur Matomo" matomo_site_id: "ID de l'instance sur Matomo" - info_html: "Matomo est un outil d'analyse de trafic web (ordinateur et téléphone). Vous pouvez installer vous-même Matomo ou utiliser une version hébergée. Voir matomo.org pour plus d'information." + matomo_tag_manager_url: "URL du Matomo Tag Manager" + info_html: "Matomo est un outil de suivi de traffic et de comportement des utilisateurs. Matomo est open source et validée par la CNIL française car non intrusif dans les données personnelles des utilisateurs. Pour plus d'infos : matomo.org." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." + config_instructions_tag_manager_html: "Ajouter l'URL du Tag Manager rend actif Matomo Tag Manager. Cet outil vous permet de suivre des évènements en particulier. Pour trouver l'URL rendez-vous sur l' \"Install Code section\" du Tag Manager. Attention à bien copier le bon contener et le bon environnement, car ils font varier l'URL." customers: index: new_customer: "Nouvel acheteur" @@ -2961,6 +2963,12 @@ fr: options: "Options" actions: update: "Mettre à jour" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 erreur n'a pas permis de sauvegarder:" + other: "%{count} erreurs ne permettent pas de sauvegarder:" + there_were_problems_with_the_following_fields: "Ils a eu des soucis avec les champs suivants" errors: messages: blank: "Champ obligatoire" @@ -3272,6 +3280,7 @@ fr: display_as_placeholder: 'ex. 2 kg' display_name_placeholder: 'ex. Tomates' autocomplete: + out_of_stock: "En rupture de stock" producer_name: "Producteur" unit: "Unité" shared: From d3943bc92af192d74db462874d47cf3d23b8dfa3 Mon Sep 17 00:00:00 2001 From: Gaetan Riou Date: Thu, 11 Jun 2020 16:47:58 +1000 Subject: [PATCH 396/507] refactor error handling of CSV::MalformedCSVError and fix some typos --- app/models/product_import/product_importer.rb | 18 +++++++++++------- spec/models/product_importer_spec.rb | 6 +++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/models/product_import/product_importer.rb b/app/models/product_import/product_importer.rb index f83f2102a2..85600d0407 100644 --- a/app/models/product_import/product_importer.rb +++ b/app/models/product_import/product_importer.rb @@ -238,16 +238,20 @@ module ProductImport end [] rescue CSV::MalformedCSVError => e - # NOTE the init_product_importer method calls build_entries and - # buils_all_entries resulting in the error being raised twice - unless errors.added?(:importer, I18n.t('admin.product_import.model.malformed_csv', - error_message: e.message)) - errors.add(:importer, I18n.t('admin.product_import.model.malformed_csv', - error_message: e.message)) - end + add_malformed_csv_error e.message [] end + # This error is raised twice because init_product_importer calls both + # build_entries and buils_all_entries + def add_malformed_csv_error(error_message) + unless errors.added?(:importer, I18n.t('admin.product_import.model.malformed_csv', + error_message: error_message)) + errors.add(:importer, I18n.t('admin.product_import.model.malformed_csv', + error_message: error_message)) + end + end + def build_entries_in_range # In the JS, start and end are calculated like this: # start = (batchIndex * $scope.batchSize) + 1 diff --git a/spec/models/product_importer_spec.rb b/spec/models/product_importer_spec.rb index 6f4903ba86..5ef78629e2 100644 --- a/spec/models/product_importer_spec.rb +++ b/spec/models/product_importer_spec.rb @@ -170,7 +170,7 @@ describe ProductImport::ProductImporter do end describe "when uploading a spreadsheet with some malformed data" do - # Use a simple string as CVS.generate will do some escaping + # Use a simple string as CSV.generate will do some escaping let(:csv_data) { csv = "name,producer,category,on_hand,price,units,unit_type,shipping_category\n" csv += "Good Carrots,#{enterprise.name},Vegetables,5,3.20,500,g,#{shipping_category.name}\n" @@ -178,8 +178,8 @@ describe ProductImport::ProductImporter do } let(:importer) { import_data csv_data } - # NOTE an unquoted \n will create a non valid line which will fail entry validation hence why we are only testing with \r - it "should raise an unquoted field error if data include unquoted filed with \r character" do + # an unquoted \n will create a non valid line which will fail entry validation hence why we are only testing with \r + it "should raise an unquoted field error if data include unquoted field with \r character" do expect(importer.errors.messages.values).to include( [I18n.t('admin.product_import.model.malformed_csv', error_message: "Unquoted fields do not allow \\r or \\n (line 3).")] ) From 359c0b9d8516ae40ae9e74e5043b10f89300d5af Mon Sep 17 00:00:00 2001 From: Gaetan Riou Date: Thu, 11 Jun 2020 16:54:00 +1000 Subject: [PATCH 397/507] fix typo --- spec/features/admin/product_import_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/product_import_spec.rb b/spec/features/admin/product_import_spec.rb index fc1624980d..7876a0210c 100644 --- a/spec/features/admin/product_import_spec.rb +++ b/spec/features/admin/product_import_spec.rb @@ -378,7 +378,7 @@ feature "Product Import", js: true do File.delete('/tmp/test.csv') end - it "handles cases where files contains malformed data" do + it "handles cases where files contain malformed data" do csv_data = "name,producer,category,on_hand,price,units,unit_type,shipping_category\n" csv_data += "Malformed \rBrocolli,#{enterprise.name},Vegetables,8,2.50,200,g,#{shipping_category.name}\n" From 6ef94febe59eafb281a07e26ac28298671e0a7f1 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 11 Jun 2020 17:10:49 +1000 Subject: [PATCH 398/507] Updating translations for config/locales/ca.yml --- config/locales/ca.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 4dd66970b6..fe72aeeb3a 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -368,8 +368,10 @@ ca: title: "Configuració de Matomo" matomo_url: "URL de Matomo" matomo_site_id: "Identificador de Matomo" - info_html: "Matomo és un analitzador de webs i mòbils. Podeu allotjar Matomo de manera local o utilitzar un servei al núvol. Vegeu matomo.org per obtenir més informació." + matomo_tag_manager_url: "URL de Matomo Tag Manager" + info_html: "Matomo és una aplicació d'analytics web i mòbil. Podeu allotjar Matomo en local o bé utilitzar un servei allotjat al núvol. Consulteu matomo.org per obtenir més informació." config_instructions_html: "Aquí podeu configurar la integració Matomo OFN. L'URL de Matomo que us apareix a continuació ha d'indicar la instància de Matomo en la qual s'enviarà la informació de seguiment de l'usuari; si es deixa buit, el seguiment de l'usuari de Matomo estarà desactivat. El camp d'identificació del lloc no és obligatori, però és útil si fa un seguiment de més d'un lloc web en una sola instància de Matomo; es pot trobar a la consola d'instància de Matomo." + config_instructions_tag_manager_html: "En configurar l'URL de Matomo Tag Manager s'activa Matomo Tag Manager. Aquesta eina us permet configurar esdeveniments d’analítica. L’URL de Matomo Tag Manager es copia de la secció Instal·lar codi de Matomo Tag Manager. Assegureu-vos de seleccionar el contenidor i l’entorn adequats ja que aquestes opcions canvien l’URL." customers: index: new_customer: "Nova consumidora" @@ -2937,6 +2939,12 @@ ca: options: "Opcions" actions: update: "Actualitzar" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "Un error va prohibir guardar aquest registre:" + other: "%{count} errors han impedit guardar aquest registre:" + there_were_problems_with_the_following_fields: "Hi ha hagut problemes amb els camps següents" errors: messages: blank: "no es pot deixar en blanc" @@ -3143,7 +3151,7 @@ ca: front_end: "Visible només per al comprador" back_end: "Només pàgina administració (back office) " tags: "Etiquetes" - deactivation_warning: "Desactivar un mètode de pagament pot fer que el mètode de pagament desapareixi de la vostra llista. De forma alternativa, podeu amagar un mètode de pagament a la pàgina de compra definint l'opció 'Mostra' com a 'Visible per a l'administrador'." + deactivation_warning: "Desactivar un mètode de pagament pot fer que el mètode de pagament desapareixi de la vostra llista. De forma alternativa, podeu amagar un mètode de pagament a la pàgina de compra configurant l'opció \"Mostrar\" a \"només a la pàgina d'administració\" (back end)." providers: provider: "Proveïdor" payments: @@ -3248,6 +3256,7 @@ ca: display_as_placeholder: 'per exemple. 2 kg' display_name_placeholder: 'per exemple. Tomàquets' autocomplete: + out_of_stock: "Fora d'existència" producer_name: "Productor" unit: "Unitat" shared: From e76bc07d7246fe0125c93c12127031968726d8ea Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 11 Jun 2020 17:11:55 +1000 Subject: [PATCH 399/507] Updating translations for config/locales/es.yml --- config/locales/es.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index 3ae8c94f87..f4ea131b1e 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -368,8 +368,10 @@ es: title: "Configuración de Matomo" matomo_url: "URL de Matomo" matomo_site_id: "ID de sitio de Matomo" - info_html: "Matomo es un analizador web y móvil. Puede alojar Matomo en sus servidores o utilizar un servicio alojado en la nube. Consulte matomo.org para obtener más información." + matomo_tag_manager_url: "URL de Matomo Tag Manager" + info_html: "Matomo es una aplicación de análisis web y móvil. Puede alojar Matomo localmente o utilizar un servicio alojado en la nube. Ver matomo.org para más información." config_instructions_html: "Aquí puede configurar la integración de OFN Matomo. La siguiente URL de Matomo debe apuntar a la instancia de Matomo a la que se enviará la información de seguimiento del usuario; si se deja vacío, el seguimiento del usuario Matomo se desactivará. El campo ID del sitio no es obligatorio, pero es útil si está rastreando más de un sitio web en una sola instancia de Matomo; se puede encontrar en la consola de la instancia de Matomo." + config_instructions_tag_manager_html: "La configuración de la URL de Matomo Tag Manager habilita Matomo Tag Manager. Esta herramienta le permite configurar eventos analíticos. La URL de Matomo Tag Manager se copia de la sección Código de instalación de Matomo Tag Manager. Asegúrese de seleccionar el contenedor y el entorno correctos, ya que estas opciones cambian la URL." customers: index: new_customer: "Nuevo Consumidor" @@ -2937,6 +2939,12 @@ es: options: "Opciones" actions: update: "Actualizar" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 error prohibió guardar este registro:" + other: "%{count} errores impidieron que se guardara este registro:" + there_were_problems_with_the_following_fields: "Hubo problemas con los siguientes campos" errors: messages: blank: "no puede estar vacío" @@ -3248,6 +3256,7 @@ es: display_as_placeholder: 'p. ej. 2 Kg' display_name_placeholder: 'p. ej. Tomates' autocomplete: + out_of_stock: "Agotado" producer_name: "Productora" unit: "Unidad" shared: From e84e0aebe6f79a17dd0b342345340c59401230df Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 9 Jun 2020 14:58:07 +0200 Subject: [PATCH 400/507] Fix fatal error in reports helper for orders without payments --- app/helpers/spree/reports_helper.rb | 11 +++++--- .../spree/admin/reports_helper_spec.rb | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 spec/helpers/spree/admin/reports_helper_spec.rb diff --git a/app/helpers/spree/reports_helper.rb b/app/helpers/spree/reports_helper.rb index bc75cfb9e8..3f299c8250 100644 --- a/app/helpers/spree/reports_helper.rb +++ b/app/helpers/spree/reports_helper.rb @@ -11,10 +11,13 @@ module Spree end def report_payment_method_options(orders) - orders.map do |o| - pm = o.payments.first.payment_method - [pm.andand.name, pm.andand.id] - end.uniq + orders.map do |order| + payment_method = order.payments.first.andand.payment_method + + next unless payment_method + + [payment_method.name, payment_method.id] + end.compact.uniq end def report_shipping_method_options(orders) diff --git a/spec/helpers/spree/admin/reports_helper_spec.rb b/spec/helpers/spree/admin/reports_helper_spec.rb new file mode 100644 index 0000000000..9ef4976750 --- /dev/null +++ b/spec/helpers/spree/admin/reports_helper_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + + +describe Spree::ReportsHelper, type: :helper do + describe "#report_payment_method_options" do + let(:order_with_payments) { create(:order_ready_to_ship) } + let(:order_without_payments) { create(:order_with_line_items) } + let(:orders) { [order_with_payments, order_without_payments] } + let(:payment_method) { order_with_payments.payments.first.payment_method } + + it "returns payment method select options for given orders" do + select_options = helper.report_payment_method_options([order_with_payments]) + + expect(select_options).to eq [[payment_method.name, payment_method.id]] + end + + it "handles orders that don't have payments, without error" do + select_options = helper.report_payment_method_options(orders) + + expect(select_options).to eq [[payment_method.name, payment_method.id]] + end + end +end From e725f33318989a320b15b9154332cacf2d498260 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 11 Jun 2020 12:37:51 +0200 Subject: [PATCH 401/507] Defend from an order w/o payments when building table --- lib/open_food_network/order_cycle_management_report.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/open_food_network/order_cycle_management_report.rb b/lib/open_food_network/order_cycle_management_report.rb index 49fb2e7365..73a0ea34db 100644 --- a/lib/open_food_network/order_cycle_management_report.rb +++ b/lib/open_food_network/order_cycle_management_report.rb @@ -77,7 +77,7 @@ module OpenFoodNetwork ba.phone, order.shipping_method.andand.name, order.payments.first.andand.payment_method.andand.name, - order.payments.first.amount, + order.payments.first.andand.amount, OpenFoodNetwork::UserBalanceCalculator.new(order.email, order.distributor).balance] end @@ -92,7 +92,7 @@ module OpenFoodNetwork sa.phone, order.shipping_method.andand.name, order.payments.first.andand.payment_method.andand.name, - order.payments.first.amount, + order.payments.first.andand.amount, OpenFoodNetwork::UserBalanceCalculator.new(order.email, order.distributor).balance, has_temperature_controlled_items?(order), order.special_instructions] From 9d5c657ff999aa5d89f0079d35e71e3dc55f6f61 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Thu, 11 Jun 2020 15:49:05 +0200 Subject: [PATCH 402/507] Update all locales with the latest Transifex translations --- config/locales/ar.yml | 2 +- config/locales/de_DE.yml | 1 - config/locales/en_AU.yml | 2 +- config/locales/en_BE.yml | 2 +- config/locales/en_CA.yml | 2 +- config/locales/en_DE.yml | 2 +- config/locales/en_GB.yml | 2 +- config/locales/en_IE.yml | 2 +- config/locales/en_NZ.yml | 2 +- config/locales/en_PH.yml | 2 +- config/locales/en_US.yml | 2 +- config/locales/en_ZA.yml | 2 +- config/locales/es_CR.yml | 2 +- config/locales/fil_PH.yml | 12 +- config/locales/fr_BE.yml | 2 +- config/locales/fr_CA.yml | 2 +- config/locales/it.yml | 250 +++++++++++++++++++------------------- config/locales/nb.yml | 2 +- config/locales/nl_BE.yml | 2 +- config/locales/pt.yml | 2 +- config/locales/pt_BR.yml | 2 +- config/locales/tr.yml | 32 ++--- 22 files changed, 165 insertions(+), 166 deletions(-) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index f4c0dbbcf7..278d54f8dd 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -363,7 +363,6 @@ ar: title: "إعدادات Matomo" matomo_url: "العنوان الالكتروني ل Matomo " matomo_site_id: "معرف موقع Matomo" - info_html: "Matomo هو تحليلات الويب والجوال. يمكنك إما تنصيب Matomo محليًا أو استخدام خدمة استضافة سحابية. انظر matomo.org لمزيد من المعلومات." config_instructions_html: "هنا يمكنك تهيئة تكامل Matomo لشبكة الغذاء المفتوح. يجب أن يشير عنوان الالكتروني URL الخاص بـ Matomo أدناه إلى مثيل Matomo حيث سيتم إرسال معلومات تتبع المستخدم إلى ؛ إذا تم تركه فارغًا ، فسيتم تعطيل تتبع مستخدم Matomo. حقل معرف الموقع ليس إلزاميًا ولكنه مفيد إذا كنت تتعقب أكثر من موقع ويب على مثيل Matomo ؛ يمكن العثور عليه على وحدة تحكم مثيل Matomo." customers: index: @@ -3168,6 +3167,7 @@ ar: display_as: "عرض ب" display_name: "اسم العرض" autocomplete: + out_of_stock: "غير متوفر" producer_name: "المنتج" unit: "وحدة" shared: diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index ea894331c1..f15957eb07 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -367,7 +367,6 @@ de_DE: title: "Matomo-Einstellungen" matomo_url: "Matomo-URL" matomo_site_id: "Matomo-Site-ID" - info_html: "Matomo ist eine Web- und Mobile Analytics. Sie können Matomo entweder lokal hosten oder einen von der Cloud gehosteten Dienst verwenden. Weitere Informationen finden Sie unter matomo.org ." config_instructions_html: "Hier können Sie die OFN Matomo Integration konfigurieren. Die unten angegebene Matomo-URL sollte auf die Matomo-Instanz verweisen, an die die Benutzerverfolgungsinformationen gesendet werden. Wenn es leer bleibt, wird das Matomo-Benutzer-Tracking deaktiviert. Das Feld Site-ID ist nicht obligatorisch, aber nützlich, wenn Sie mehr als eine Website in einer einzelnen Matomo-Instanz verfolgen. Es kann auf der Matomo-Instanzkonsole gefunden werden." customers: index: diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index 87dd14b521..85e74324b9 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -359,7 +359,6 @@ en_AU: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3114,6 +3113,7 @@ en_AU: display_as: "Display As" display_name: "Display Name" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index ad108f1377..ccefbc27d6 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -354,7 +354,6 @@ en_BE: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3021,6 +3020,7 @@ en_BE: price: "Price" display_as: "Display As" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 2d06220419..8eb65e9a43 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -368,7 +368,6 @@ en_CA: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3231,6 +3230,7 @@ en_CA: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index f3effeead7..43f8f6dd44 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -359,7 +359,6 @@ en_DE: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3037,6 +3036,7 @@ en_DE: price: "Price" display_as: "Display As" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index f18c25b4dd..71358c855d 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -368,7 +368,6 @@ en_GB: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3238,6 +3237,7 @@ en_GB: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_IE.yml b/config/locales/en_IE.yml index 0f838aff2e..69bcb54e04 100644 --- a/config/locales/en_IE.yml +++ b/config/locales/en_IE.yml @@ -368,7 +368,6 @@ en_IE: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3229,6 +3228,7 @@ en_IE: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index 22a9902b96..fa30c62f25 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -368,7 +368,6 @@ en_NZ: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3230,6 +3229,7 @@ en_NZ: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index 154bb93df0..da4c883de1 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -367,7 +367,6 @@ en_PH: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3203,6 +3202,7 @@ en_PH: display_as: "Display As" display_name: "Display Name" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index e1deb0373b..feb491c764 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -363,7 +363,6 @@ en_US: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo locally or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3195,6 +3194,7 @@ en_US: display_as: "Display As" display_name: "Display Name" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 06cd4ee1c4..8017668827 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -368,7 +368,6 @@ en_ZA: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -3097,6 +3096,7 @@ en_ZA: price: "Price" display_as: "Display As" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index bd8f7c51e6..8dce3680ee 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -368,7 +368,6 @@ es_CR: title: "Configuración de Matomo" matomo_url: "URL de Matomo" matomo_site_id: "ID de sitio de Matomo" - info_html: "Matomo es un analizador web y móvil. Puede alojar Matomo en sus servidores o utilizar un servicio alojado en la nube. Consulte matomo.org para obtener más información." config_instructions_html: "Aquí puede configurar la integración de OFN Matomo. La siguiente URL de Matomo debe apuntar a la instancia de Matomo a la que se enviará la información de seguimiento del usuario; si se deja vacío, el seguimiento del usuario Matomo se desactivará. El campo ID del sitio no es obligatorio, pero es útil si está rastreando más de un sitio web en una sola instancia de Matomo; se puede encontrar en la consola de la instancia de Matomo." customers: index: @@ -3211,6 +3210,7 @@ es_CR: display_as: "Mostrar como" display_name: "Nombre para mostrar" autocomplete: + out_of_stock: "Agotado" producer_name: "Productor" unit: "Unidad" shared: diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index 1b4b545419..0c7bf87148 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -368,7 +368,6 @@ fil_PH: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "ang Matomo ay isang Web at Mobile Analytics. Maaari kang mag-host ng Matomo sa mga lugar o gumamit ng mga serbisyong naka-cloud. Tignanmatomo.org para sa karagdagang impormasyon." config_instructions_html: "Dito ay maaaring ayusin ang pagsasama ng OFN Matomo. ang URL ng Matomo sa ibaba ay ituturo ka sa Matomo kung saan ipapadala ang impormasyon ukol sa pagtatrack ng gumagamit; kung iiwanang blanko, ay hindi gagana ang pag-track ng Matomo. ang paglagay ng SITE ID ay hindi sapilitan ngunit maaaring makatulong kung ikaw ay nagta-track na mahigit sa isang website sa isang pagkakataon; ito ay matatagpuan sa Matomo instance console." customers: index: @@ -1909,18 +1908,18 @@ fil_PH: admin_enterprise_relationships_button_create: "gumawa" admin_enterprise_relationships_to: "sa" admin_enterprise_groups: "mga grupo ng enterprise" - admin_enterprise_groups_name: "pangalan" + admin_enterprise_groups_name: "Pangalan" admin_enterprise_groups_owner: "may-ari" admin_enterprise_groups_on_front_page: "sa harapang pahina?" - admin_enterprise_groups_enterprise: "enterprises" + admin_enterprise_groups_enterprise: "Mga Enterprise" admin_enterprise_groups_data_powertip: "ang pangunahing gumagamit na responsable sa grupo na ito" - admin_enterprise_groups_data_powertip_logo: "ito ang logo ng inyong grupo" + admin_enterprise_groups_data_powertip_logo: "ito ang logo para sa grupo" admin_enterprise_groups_data_powertip_promo_image: "ang larawan na ito ay makikita sa taas ng profile ng grupo" admin_enterprise_groups_contact: "Makipag-ugnayan" admin_enterprise_groups_contact_phone_placeholder: "hal. 98 7654 3210" - admin_enterprise_groups_contact_address1_placeholder: "eg. 123 High Street" + admin_enterprise_groups_contact_address1_placeholder: "eg. 123 Kalayaan Street" admin_enterprise_groups_contact_city: "lungsod" - admin_enterprise_groups_contact_city_placeholder: "hal. Northcote" + admin_enterprise_groups_contact_city_placeholder: "hal. Mandaluyong" admin_enterprise_groups_contact_zipcode: "Postcode" admin_enterprise_groups_contact_zipcode_placeholder: "hal. 3070" admin_enterprise_groups_contact_state_id: "Lalawigan" @@ -3217,6 +3216,7 @@ fil_PH: display_as: "Ipakita Bilang" display_name: "Pangalan na nakikita" autocomplete: + out_of_stock: "Walang stock" producer_name: "Producer" unit: "yunit" shared: diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index 5405e9484d..60c840f730 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -367,7 +367,6 @@ fr_BE: title: "Configuration Matomo" matomo_url: "URL de l'instance sur Matomo" matomo_site_id: "ID de l'instance sur Matomo" - info_html: "Matomo est un outil d'analyse de trafic web (ordinateur et téléphone). Vous pouvez installer vous-même Matomo ou utiliser une version hébergée. Voir matomo.org pour plus d'information." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." customers: index: @@ -3154,6 +3153,7 @@ fr_BE: display_as: "Unité affichéé" display_name: "Nom d'affichage" autocomplete: + out_of_stock: "Pas en stock" producer_name: "Producteur·trice" unit: "Unité" shared: diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index fba999a5cd..5f7f23ce5f 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -363,7 +363,6 @@ fr_CA: title: "Configuration Matomo" matomo_url: "URL de l'instance sur Matomo" matomo_site_id: "ID de l'instance sur Matomo" - info_html: "Matomo est un outil d'analyse de trafic web (ordinateur et téléphone). Vous pouvez installer vous-même Matomo ou utiliser une version hébergée. Voir matomo.org pour plus d'information." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." customers: index: @@ -3206,6 +3205,7 @@ fr_CA: display_as: "Afficher comme" display_name: "Nom affiché" autocomplete: + out_of_stock: "En rupture de stock" producer_name: "Producteur" unit: "Unité" shared: diff --git a/config/locales/it.yml b/config/locales/it.yml index c24462f697..13a6c49aeb 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -3,11 +3,11 @@ it: activerecord: attributes: enterprise_fee: - fee_type: Tipo di tariffa + fee_type: Tipo Tariffa spree/order: payment_state: Stato Pagamento shipment_state: Stato Spedizione - completed_at: Completo Al + completed_at: Completato Al number: Numero state: Stato email: E-Mail Cliente @@ -43,7 +43,7 @@ it: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "deve restare vuoto perché si stanno utilizzando le impostazioni di magazzino del produttore" on_demand_but_count_on_hand_set: "deve restare vuoto se su richiesta" - limited_stock_but_no_count_on_hand: "Torna alla lista dei pagamenti" + limited_stock_but_no_count_on_hand: "deve essere specificato a causa di una disponibilità limitata" activemodel: attributes: order_management/reports/enterprise_fee_summary/parameters: @@ -51,10 +51,10 @@ it: end_at: "Fine" distributor_ids: "Distributori" producer_ids: "Produttori" - order_cycle_ids: "Cicli di richieste" - enterprise_fee_ids: "Nome commissione" - shipping_method_ids: "Metodi di spedizione" - payment_method_ids: "Metodi di pagamento" + order_cycle_ids: "Cicli di Richieste" + enterprise_fee_ids: "Nomi Tariffe" + shipping_method_ids: "Metodi di Spedizione" + payment_method_ids: "Metodi di Pagamento" errors: messages: inclusion: "non incluso nella lista" @@ -62,7 +62,7 @@ it: order_management/subscriptions/validator: attributes: subscription_line_items: - at_least_one_product: "^Aggiungi almeno un prodotto" + at_least_one_product: "^Per favore aggiungi almeno un prodotto" not_available: "^%{name} non è disponibile nel programma selezionato" ends_at: after_begins_at: "deve essere dopo l'inizio il" @@ -71,28 +71,28 @@ it: schedule: not_coordinated_by_shop: "non è coordinato da %{shop}" payment_method: - not_available_to_shop: "non è disponibile al %{shop}" - invalid_type: "Il metodo dev'essere Cash o Stripe" - charges_not_allowed: "L'addebito su carta di credito non è consentito da questo consumatore" - no_default_card: "Nessuna carta predefinita è consentita per questo consumatore" + not_available_to_shop: "non è disponibile da %{shop}" + invalid_type: "il metodo deve essere Cash o Stripe" + charges_not_allowed: "L'addebito su carta di credito non è consentito per questo cliente" + no_default_card: "^Nessuna carta predefinita è disponibile per questo cliente" shipping_method: not_available_to_shop: "non è disponibile al %{shop}" devise: confirmations: - send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account." - failed_to_send: "C'è stato un errore nell'invio della tua mail di conferma." - resend_confirmation_email: "Re-invia la mail di conferma" - confirmed: "Grazie per aver confermato la tua mail! Ora puoi effettuare il log in." + send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." + failed_to_send: "C'è stato un errore nell'invio dell'email di conferma." + resend_confirmation_email: "Invia di nuovo l'email di conferma." + confirmed: "Grazie per aver confermato la tua email! Ora puoi effettuare il log in." not_confirmed: "Il tuo indirizzo email non può essere confermato. Forse avevi già completato questo passaggio?" user_confirmations: spree_user: - send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account." + send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." confirmation_sent: "Email di conferma inviata" confirmation_not_sent: "Errore invio emai di conferma" user_registrations: spree_user: signed_up_but_unconfirmed: "Abbiamo inviato un link di conferma al tuo indirizzo email. Per favore apri il link per attivare il tuo account." - unknown_error: "Qualcosa è andato storto durante la creazione del tuo account. Controlla il tuo indirizzo e-mail e riprova" + unknown_error: "Qualcosa è andato storto durante la creazione del tuo account. Controlla il tuo indirizzo email e riprova" failure: invalid: | Email o password non valida. @@ -105,29 +105,29 @@ it: spree_user: updated_not_active: "La tua password è stata resettata, ma la tua email non è ancora stata confermata." updated: "La tua password è stata modificata con successo.\nOra sei collegato." - send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account." + send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." models: order_cycle: cloned_order_cycle_name: "COPIA DI %{order_cycle}" validators: date_time_string_validator: - not_string_error: "Deve essere una linea" - invalid_format_error: "Deve essere valido" + not_string_error: "deve essere una stringa" + invalid_format_error: "deve essere valido" integer_array_validator: - not_array_error: "Deve essere una sequenza" - invalid_element_error: "Deve contenere solo numeri interi" + not_array_error: "deve essere un array" + invalid_element_error: "deve contenere solo numeri interi" enterprise_mailer: confirmation_instructions: - subject: "Per favore conferma l'indirizzo email per %{enterprise}" + subject: "Per favore conferma l'indirizzo email di %{enterprise}" welcome: subject: "%{enterprise} è ora su %{sitename}" email_welcome: "Benvenuto" email_registered: "è ora parte di" - email_userguide_html: "La Guida Utente con supporto dettagliato per l'impostazione del tuo Produttore o Hub è qui: %{link}" - userguide: "Guida di Open Food Network" + email_userguide_html: "La Guida Utente con supporto dettagliato per l'impostazione del tuo Produttore o Distributore è qui: %{link}" + userguide: "Guida Utente di Open Food Network" email_admin_html: "Puoi gestire il tuo profilo facendo il log in al link %{link} o cliccando sull'ingranaggio in alto a destra della homepage, e selezionando Amministrazione" - admin_panel: "Pannello di controllo" - email_community_html: "Abbiamo anche un forum on-line per le discussioni della comunità sul software OFN e le sfide uniche legate all'avere un'impresa del cibo. Sei invitato ad unirti. Ci evolviamo in continuo e il tuo contributo in questo forum plasmerà ciò che sarà. %{link}" + admin_panel: "Panello Amministrativo" + email_community_html: "Abbiamo anche un forum per le discussioni comunitarie legate al software di OFN e le sfide uniche legate all'avere un'impresa alimentare. Ti incoraggiamo a farne parte. Siamo in continua evoluzione e il tuo contributo al forum delineerà quello che succederà in futuro. %{link}" join_community: "Unisciti alla community" invite_manager: subject: "%{enterprise} ti a invitato ad essere un referente" @@ -136,30 +136,30 @@ it: subject: "Resoconto degli ordini per %{producer}" shipment_mailer: shipped_email: - dear_customer: "Caro consumatore," + dear_customer: "Caro Cliente," instructions: "Il tuo ordine è stato spedito" - shipment_summary: "Riepilogo della spedizione" - subject: "Avviso di spedizione" - thanks: "Grazie per utilizzare la piattaforma per il tuo commercio" - track_information: "Informazioni di tracciamento" - track_link: "Link del tracciamento" + shipment_summary: "Riepilogo della Spedizione" + subject: "Notifica di Spedizione" + thanks: "Grazie per il tuo lavoro." + track_information: "Informazioni Tracking: %{tracking}" + track_link: "Tracking Link: %{url}" subscription_mailer: placement_summary_email: subject: Riassunto degli ordini più recenti greeting: "Ciao %{name}," - intro: "Qui sotto un riassunto degli ordini appena inviati per%{shop} ," + intro: "Qui sotto un riassunto degli ordini appena inviati per%{shop}," confirmation_summary_email: subject: Riassunto delle richieste recentemente confermate greeting: "Ciao %{name}," intro: "Qui sotto un riassunto delle richieste che hai appena confermato per %{shop}." summary_overview: - total: Un totale di %{count} abbonamenti sono stati contrassegnati per l'elaborazione automatica.. - success_zero: Di questi, nessuno è stato modificato con successo + total: Un totale di %{count} sottoscrizioni sono stati contrassegnati per l'elaborazione automatica. + success_zero: Di questi, nessuno è stato elaborato con successo. success_some: Di questi, %{count} sono stati elaborati con successo. success_all: Tutti sono stati elaborati con successo. - issues: Qui sotto i dettagli dei problemi incontrati. + issues: Qui sotto i dettagli dei problemi riscontrati. summary_detail: - no_message_provided: 'Nessun messaggio di errore ' + no_message_provided: Nessun messaggio di errore fornito changes: title: Scorte insufficienti (%{count} gentili richieste) explainer: Queste gentili richieste sono state elaborate, ma la quantità richiesta di alcuni prodotti non è disponibile @@ -180,7 +180,7 @@ it: explainer: L'elaborazione automatica di queste gentili richieste non è riuscita per una ragione sconosciuta. Questo non dovrebbe accadere, ti preghiamo di contattarci se visualizzi questo messaggio. home: "OFN" title: Open Food Network - welcome_to: 'Benvenuto a' + welcome_to: 'Benvenuto su' site_meta_description: "Cominciamo da zero. Con i produttori e gli allevatori pronti a raccontare le loro storie, sinceramente e orgogliosamente. Con i distributori pronti a connettere le persone con i prodotti in modo giusto ed equo. Con i compratori che credono che migliori decisioni per l'acquisto settimanale possano..." search_by_name: Cerca per nome o zona... producers_join: I Produttori sono ora invitati ad unirsi ad Open Food Network @@ -188,12 +188,12 @@ it: print_invoice: "Stampa fattura" print_ticket: "Stampa Biglietto" select_ticket_printer: "Seleziona la stampante per i biglietti" - send_invoice: "Manda fattura" - resend_confirmation: "Rimanda conferma" - view_order: "Vedi l'ordine" - edit_order: "Modifica l'ordine" - ship_order: "Invia l'ordine" - cancel_order: "Cancella l'ordine" + send_invoice: "Invia Fattura" + resend_confirmation: "Rimanda Conferma" + view_order: "Vedi Ordine" + edit_order: "Modifica Ordine" + ship_order: "Invia Ordine" + cancel_order: "Cancella Ordine" confirm_send_invoice: "Una fattura per quest'ordine verrà mandata al cliente. Sei sicuro di voler continuare?" confirm_resend_order_confirmation: "Sei sicuro di voler inviare di nuovo l'email di conferma per l'ordine?" must_have_valid_business_number: "%{enterprise_name} deve avere una partita iva valida per poter emettere fattura." @@ -202,11 +202,11 @@ it: say_no: "No" say_yes: "Sì" ongoing: Attivo - bill_address: Indirizzo di fatturazione - ship_address: Indirizzo di consegna - sort_order_cycles_on_shopfront_by: "Ordina cicli d'ordine in vetrina per" + bill_address: Indirizzo Fatturazione + ship_address: Indirizzo Consegna + sort_order_cycles_on_shopfront_by: "Ordina Cicli Ordine in Vetrina per" required_fields: I campi obbligatori sono contrassegnati con un asterisco - select_continue: Seleziona e continua + select_continue: Seleziona e Continua remove: Rimuovi or: o collapse_all: Riduci tutto @@ -219,7 +219,7 @@ it: edit: Modifica clone: Duplica distributors: Distributori - bulk_order_management: Gestione richieste all'ingrosso + bulk_order_management: Gestione Ordini Massivi enterprises: Aziende enterprise_groups: Gruppi reports: Resoconti @@ -227,15 +227,15 @@ it: import: Importazione spree_products: Prodotti Spree all: Tutti - current: Attuali + current: Correnti available: Disponibile dashboard: Pannello di controllo undefined: non definito unused: non in uso admin_and_handling: Admin profile: Profilo - supplier_only: Solo per i fornitori - has_shopfront: Informazioni di tracciamento + supplier_only: Solo Fornitori + has_shopfront: Ha una Vetrina weight: Peso volume: Volume items: Prodotti @@ -250,26 +250,26 @@ it: blocked_cookies_alert: "Il tuo browser sembra stia bloccando i cookies necessari ad usare questa pagina del negozio. Clicca sotto per consentire i cookies e ricaricare la pagina." allow_cookies: "Accetta i cookies" notes: Note - error: Eorrore + error: Errore processing_payment: "Elaborazione pagamento..." - no_pending_payments: "nessun pagamento in sospeso" - invalid_payment_state: "stato del pagamento non valido" + no_pending_payments: "Nessun pagamento in sospeso" + invalid_payment_state: "Stato del pagamento non valido" filter_results: Filtra i risultati quantity: Quantità pick_up: Ritiro copy: Copia change_my_password: "Cambia la mia password" update_password: "Aggiorna password" - password_confirmation: 'Conferma password ' + password_confirmation: 'Conferma Password ' reset_password_token: Token per il reset della password expired: è scaduto, si prega di richiederne uno nuovo - back_to_payments_list: "Torna alla lista dei pagamenti" - maestro_or_solo_cards: "carte Maestro/Solo" - backordered: "ordini arretrati" + back_to_payments_list: "Torna alla Lista dei Pagamenti" + maestro_or_solo_cards: "Carte Maestro/Solo" + backordered: "Ordini arretrati" on hand: "Disponibile" ship: "Spedizione" actions: - create_and_add_another: "Crea e aggiungi un altro" + create_and_add_another: "Crea e Aggiungi un Altro" create: "Crea" cancel: "Annulla" save: "Salva" @@ -279,7 +279,7 @@ it: admin: begins_at: Inizia a begins_on: Inizia da - customer: Consumatore + customer: Cliente date: Data email: Email ends_at: Termina a @@ -368,11 +368,10 @@ it: title: "Impostazioni Matomo" matomo_url: "URL Matomo" matomo_site_id: "Site ID Matomo" - info_html: "Matomo è una Web and Mobile Analytics. È possibile ospitare Matomo in sede o utilizzare un servizio cloud. Vedi matomo.org per maggiori informazionimatomo.org for more information." config_instructions_html: "Qui è possibile configurare l'integrazione OFN Matomo. L'URL di Matomo qui sotto dovrebbe puntare l'istanza di Matomo a cui saranno inviate le informazioni di monitoraggio dell'utente; se lasciato vuoto, il monitoraggio dell'utente da parte di Matomo sarà disabilitato. Il campo Site ID non è obbligatorio ma è utile se si sta tracciando più di un sito web su una singola istanza di Matomo; si può trovare sulla console dell'istanza di Matomo. " customers: index: - new_customer: "Nuovo cliente" + new_customer: "Nuovo Cliente" code: Codice duplicate_code: "Questo codice è già usato." bill_address: "Indirizzo di fatturazione" @@ -390,7 +389,7 @@ it: search_by_email: "Cerca per email/codice..." guest_label: 'Check-out ospite' destroy: - has_associated_orders: 'Cancellazione non riuscita: l''utente ha ordini associati al suo negozio' + has_associated_orders: 'Cancellazione fallita: l''utente ha ordini associati al negozio' contents: edit: title: Contenuto @@ -614,7 +613,7 @@ it: desc_short: Breve descrizione desc_short_placeholder: Raccontaci la tua attività in una o due frasi desc_long: Chi siamo - desc_long_placeholder: Racconta di te ai consumatori. Questa informazione comparirà nel tuo profilo pubblico. + desc_long_placeholder: Racconta di te ai tuoi clienti. Questa informazione comparirà nel tuo profilo pubblico. business_details: abn: ABN abn_placeholder: es. 99 123 456 789 @@ -666,7 +665,7 @@ it: name: Nome name_placeholder: es. Tartufi Biodinamici Alba groups: Gruppi - groups_tip: Seleziona i gruppi o le regioni di cui sei membro. Questo aiuterà i consumatori a trovare la tua azienda. + groups_tip: Seleziona i gruppi o le regioni di cui sei membro. Questo aiuterà i clienti a trovare la tua azienda. groups_placeholder: 'Inizia a digitare per trovare i gruppi ' primary_producer: Produttore primario? primary_producer_tip: Seleziona "Produttore" se sei un produttore primario di cibo @@ -675,9 +674,9 @@ it: none: Nessuno own: Proprio sells: Vende - sells_tip: "Nessuno - L'azienda non vende direttamente ai consumatori.
    Proprio - L'azienda vende i propri prodotti ai consumatori.
    Proprio e altrui - L'azienda può vendere prodotti propri o di altre aziende.
    " + sells_tip: "Nessuno - L'azienda non vende direttamente ai clienti.
    Proprio - L'azienda vende i propri prodotti ai clienti.
    Proprio e altrui - L'azienda può vendere prodotti propri o di altre aziende.
    " visible_in_search: Visibile nella ricerca? - visible_in_search_tip: Determina se questa azienda sarà visibile ai consumatori quando cercano nel sito. + visible_in_search_tip: Determina se questa azienda sarà visibile ai clienti quando cercano nel sito. visible: Visibile not_visible: Non visibile permalink: Permalink (nessuno spazio) @@ -695,7 +694,7 @@ it: no_method_yet: "Non hai ancora un metodo di consegna" shop_preferences: shopfront_requires_login: "Vetrina visibile pubblicamente?" - shopfront_requires_login_tip: "Scegli se i consumatori devono essere registrati per poter vedere la vetrina o se è visibile a tutti" + shopfront_requires_login_tip: "Scegli se i clienti devono essere registrati per poter vedere la vetrina o se è visibile a tutti." shopfront_requires_login_false: "Pubblica" shopfront_requires_login_true: "Visibile solo agli utenti registrati" recommend_require_login: "Consigliamo di richiedere la registrazione quando si dà la possibilità di modificare gli ordini." @@ -704,7 +703,7 @@ it: allow_guest_orders_false: "Richiedi il login per ordinare" allow_guest_orders_true: "Permetti acquisto come ospite" allow_order_changes: "Modifica gentili richieste" - allow_order_changes_tip: "Permetti ai consumatori di modificare le proprie richieste finché il ciclo di richieste è aperto." + allow_order_changes_tip: "Permetti ai clienti di modificare i propri ordini fino a quando il ciclo degli ordini è aperto." allow_order_changes_false: "Le gentili richieste confermate non possono essere modificate / annullate" allow_order_changes_true: "Gli utenti possono modificare / annullare le gentili richieste mentre il ciclo di richieste è aperto" enable_subscriptions: "Sottoscrizioni" @@ -713,7 +712,7 @@ it: enable_subscriptions_true: "Abilitata" shopfront_message: "Messaggio vetrina" shopfront_message_placeholder: > - Un messaggio opzionale per dare in benvenuto ai clienti e spiegare come + Un messaggio opzionale per dare il benvenuto ai clienti e spiegare come acquistare. Il testo inserito qui verrà mostrato nel tab principale della vetrina. shopfront_message_link_tooltip: "Inserisci / modifica link" @@ -741,7 +740,7 @@ it: title: Collegati con Stripe part1: Stripe è un servizio di elaborazione dei pagamenti che permette ai negozi su OFN di accettare pagamenti con carta di credito da parte dei clienti. part2: Per utilizzare questa funzione, è necessario collegare il proprio account Stripe a OFN. Cliccando su 'Accetto' qui sotto sarai reindirizzato al sito web Stripe dove potrai collegare un account Stripe esistente o crearne uno nuovo se non ne hai già uno. - part3: Questo consentirà alla piattaforma di accettare pagamenti con carta di credito da clienti di tua fiducia. Tieni presente che dovrai mantenere il tuo conto Stripe, pagare la tariffa di Strip e gestire gli eventuali rimborsi e i servizi al cliente. + part3: Questo consentirà alla piattaforma di accettare pagamenti con carta di credito da clienti di tua fiducia. Tieni presente che dovrai mantenere il tuo conto Stripe, pagare la commissione di Stripe e gestire gli eventuali rimborsi e i servizi al cliente. i_agree: Sono d'accordo cancel: Annulla tag_rules: @@ -751,7 +750,7 @@ it: add_new_button: ' + Aggiungi una nuova regola predefinita' no_tags_yet: Nessuna etichetta per questa azienda no_rules_yet: Nessuna regola per questa etichetta - for_customers_tagged: 'Per i clienti etichettati' + for_customers_tagged: 'Per i clienti etichettati:' add_new_rule: '+ Aggiungi una nuova regola' add_new_tag: '+ Aggiungi una nuova tag' users: @@ -795,7 +794,7 @@ it: producer_description_text: Aggiungi i tuoi prodotti, permettendo agli hubs di inserire i tuoi prodotti nei loro negozi. producer_shop: Negozio produttore sell_your_produce: Vendi i tuoi prodotti - producer_shop_description_text: Vendi i tuoi prodotti direttamente ai consumatori tramite la tua propria vetrina su OFN + producer_shop_description_text: Vendi i tuoi prodotti direttamente ai clienti tramite la tua personale vetrina su Open Food Network. producer_shop_description_text2: Un Negozio produttore è solo per i tuoi prodotti. Se vuoi vendere prodotti altrui, seleziona "Hub produttore". producer_hub: Hub produttore producer_hub_text: Vendi prodotti tuoi e di altri @@ -891,7 +890,7 @@ it: incoming: "2. Prodotti in entrata" outgoing: "3. Prodotti in uscita" exchange_form: - pickup_time_tip: Quando gli ordini di questa Lista d'ordine saranno pronti per il cliente + pickup_time_tip: Quando gli ordini di questo ciclo saranno pronti per il cliente pickup_instructions_placeholder: "Istruzioni per la consegna" pickup_instructions_tip: Queste istruzioni saranno visibili agli utenti dopo che hanno completato una gentile richiesta pickup_time_placeholder: "Pronto per (es. Data / Ora)" @@ -943,12 +942,12 @@ it: simple_form: ready_for: Pronto per ready_for_placeholder: Data / Ora - customer_instructions: Istruzioni consumatori + customer_instructions: Istruzioni per i consumatori customer_instructions_placeholder: Note per ritiro / consegna products: Prodotti fees: Tariffe destroy_errors: - orders_present: Questo ciclo di richieste è stato selezionato da un consumatore e non può essere cancellato. Per evitare altri accessi, chiudi il ciclo. + orders_present: Questo ciclo di richieste è stato selezionato da un cliente e non può essere cancellato. Per prevenire altri accessi da parte dei clienti, per favore chiudi il ciclo. schedule_present: Questo ciclo di richieste è connesso a un programma e non può essere cancellato. Puoi eliminare il link o cancellare il programma prima. bulk_update: no_data: mmm, qualcosa è andato storto. Nessun dato per ciclo di richieste trovato. @@ -986,7 +985,7 @@ it: supplier_totals: Totali Ciclo di richieste fornitori supplier_totals_by_distributor: Totali Ciclo di richieste fornitori per distributore totals_by_supplier: Totali Ciclo di richieste fornitori per fornitore - customer_totals: Totali ciclo di richieste consumatori + customer_totals: Ciclo Ordini Cliente Totale all_products: Tutti i prodotti inventory: Inventario (in mano) lettuce_share: LettuceShare @@ -996,7 +995,7 @@ it: delivery: Rapporto Consegne tax_types: Tipologia tariffe tax_rates: Aliquote d'imposta - pack_by_customer: Smistato dai consumatori + pack_by_customer: Imballato dal Cliente pack_by_supplier: Smistato dai fornitori orders_and_distributors: name: Gentili richieste e distributori @@ -1010,7 +1009,7 @@ it: orders_and_fulfillment: name: Gentili richieste e resoconti di soddifazione customers: - name: Consumatori + name: Clienti products_and_inventory: name: Prodotti e inventario users_and_enterprises: @@ -1047,7 +1046,7 @@ it: enable_subscriptions_step_2: 2. In "Preferenze Negozio", attiva l'opzione Abbonamenti set_up_shipping_and_payment_methods_html: 'Imposta i metodi %{shipping_link} e %{payment_link} ' set_up_shipping_and_payment_methods_note_html: Nota con gli abbonamenti può
    essere utilizzato solo il metodo Contanti - ensure_at_least_one_customer_html: 'Assicurati che esista almeno un %{customer_link} ' + ensure_at_least_one_customer_html: Assicurati che almeno un %{customer_link} esista create_at_least_one_schedule: Crea almeno un programma create_at_least_one_schedule_step_1_html: '1. Vai alla pagina %{order_cycles_link} ' create_at_least_one_schedule_step_2: 2. Crea un Ciclo di Richieste se non l'hai già fatto @@ -1073,9 +1072,9 @@ it: invalid_error: Oops! Per favore compila i campi obbligatori... allowed_payment_method_types_tip: Al momento può essere utilizzato solo il metodo di pagamento Contanti credit_card: Carta di Credito - charges_not_allowed: Non sono consentiti Oneri per questo cliente + charges_not_allowed: Non sono consentiti ricarichi per questo cliente no_default_card: Il cliente non ha carte disponibili da caricare - card_ok: il cliente ha una carta disponibile da caricare + card_ok: Il cliente ha una carta disponibile da caricare begins_at_placeholder: "Seleziona una data" ends_at_placeholder: "Facoltativo" loading_flash: @@ -1100,9 +1099,9 @@ it: cancel_failure_msg: "Ci dispiace, eliminazione non riuscita!" confirm_pause_msg: "Sei sicura/o di voler mettere in pausa questo abbonamento?" pause_failure_msg: "Spiacente, pausa fallita!" - confirm_unpause_msg: "Se hai un ciclo di richieste aperto durante questa registrazione, sarà creato un ordine per l'utente registrato. Vuoi annullare la registrazione?" + confirm_unpause_msg: "Se hai aperto un Ciclo d'Ordini durante questa sottoscrizione pianificata, un ordine per l'utente verrà creato per questo cliente. Sei sicuro di voler attivare questa sottoscrizione?" unpause_failure_msg: "Ci dispiace, ripresa non riuscita!" - confirm_cancel_open_orders_msg: "Alcune di queste richieste sono attualmente attive. I consumatori sono già stati avvisati che le richieste verranno soddisfatte. Vuoi eliminare questa/e richiesta/e o mantenerla?" + confirm_cancel_open_orders_msg: "Alcuni ordini per questa sottoscrizione sono attualmente aperti. I clienti sono già stati avvisati che le richieste verranno soddisfatte. Vuoi eliminare questa/e richiesta/e o mantenerle?" resume_canceled_orders_msg: "Alcuni ordini per questo abbonamento possono essere ripresi in questo momento. Puoi riprenderli dal menu a discesa degli ordini." yes_cancel_them: Cancella l'articolo no_keep_them: Tieni l'articolo @@ -1176,7 +1175,7 @@ it: login: "fai il login" signup: "Registrati" contact: "contatto" - require_customer_login: "Solo utenti approvati hanno accesso a questo negozio" + require_customer_login: "Solo clienti approvati hanno accesso a questo negozio" require_login_html: "Se sei già un cliente approvato, %{login} o %{signup} per procedere." require_login_2_html: "Vuoi iniziare a acquistare qui? Per favore %{contact}%{enterprise}e chiedi di essere aggiunto." require_customer_html: "Se vuoi iniziare a comprare, per favore %{contact} %{enterprise} per chiedere di raggiungerci." @@ -1189,7 +1188,7 @@ it: invoice_column_tax: "IVA" invoice_column_price: "Prezzo" invoice_column_item: "Articolo" - invoice_column_qty: "Qtà." + invoice_column_qty: "Qtà" invoice_column_unit_price_with_taxes: "Prezzo unitario (incl. tasse)" invoice_column_unit_price_without_taxes: "Prezzo unitario (escl. tasse)" invoice_column_price_with_taxes: "Prezzo totale (incl. tasse)" @@ -1405,14 +1404,14 @@ it: order_paid: PAGATO order_not_paid: NON PAGATO order_total: Totale dell'ordine - order_payment: "Pagamento via:" + order_payment: "Pagamento attraverso:" order_billing_address: Indirizzo di fatturazione order_delivery_on: Consegna il order_delivery_address: Indirizzo di consegna order_delivery_time: Tempo di consegna order_special_instructions: "Tue note:" order_pickup_time: Pronto per il ritiro - order_pickup_instructions: Istruzioni per la raccolta + order_pickup_instructions: Istruzioni per la Distribuzione order_produce: Produrre order_total_price: Totale order_includes_tax: (include le tasse) @@ -1438,17 +1437,17 @@ it: email_social: "Connettiti con Noi:" email_contact: "Scrivici:" email_signoff: "Saluti," - email_signature: "Team di %{sitename}" + email_signature: "Il team di %{sitename}" email_confirm_customer_greeting: "Ciao %{name}," email_confirm_customer_intro_html: "Grazie per aver acquistato presso %{distributor}!" email_confirm_customer_number_html: "Conferma dell'Ordine #%{number}" - email_confirm_customer_details_html: "Qui sono i dettagli del tuo ordine da %{distributor}:" + email_confirm_customer_details_html: "Ecco i dettagli del tuo ordine da %{distributor}:" email_confirm_customer_signoff: "Cordiali saluti," email_confirm_shop_greeting: "Ciao %{name}," email_confirm_shop_order_html: "Ben fatto! Hai un nuovo ordine per %{distributor}!" email_confirm_shop_number_html: "Conferma dell'Ordine #%{number}" email_order_summary_item: "Articolo" - email_order_summary_quantity: "Qtà." + email_order_summary_quantity: "Qtà" email_order_summary_sku: "SKU" email_order_summary_price: "Prezzo" email_order_summary_subtotal: "Subtotale:" @@ -1456,8 +1455,8 @@ it: email_order_summary_includes_tax: "(include le tasse)" email_payment_paid: PAGATO email_payment_not_paid: NON PAGATO - email_payment_summary: Riassunto del pagamento - email_payment_method: "Pagamento via:" + email_payment_summary: Riepilogo di pagamento + email_payment_method: "Pagamento attraverso:" email_so_placement_intro_html: "Hai una nuova gentile richiesta di %{distributor}" email_so_placement_details_html: "Ecco i dettagli della gentile richiesta per %{distributor}:" email_so_placement_changes: "Purtroppo alcuni prodotti richiesti non sono disponibili. Le quantità originali richieste sono barrate qui sotto." @@ -1481,13 +1480,13 @@ it: email_shipping_delivery_address: "Indirizzo di consegna" email_shipping_collection_details: Dettagli della raccolta email_shipping_collection_time: "Pronto per il ritiro:" - email_shipping_collection_instructions: "Istruzioni per la raccolta:" + email_shipping_collection_instructions: "Istruzioni per la distribuzione:" email_special_instructions: "Tue note:" email_signup_greeting: Ciao! email_signup_welcome: "Benvenuto a %{sitename}!" email_signup_confirmed_email: "Grazie di aver confermato la tua mail." email_signup_shop_html: "Puoi effettuare il log in qui: %{link}." - email_signup_text: "Grazie per esserti unito alla rete. Se sei un cliente, non vediamo l'ora di introdurti a molti produttori fantastici, distributori di cibo spettacolari e cibo delizioso! Se sei un produttore o un'impresa del cibo, siamo entusiasti di averti come parte della rete." + email_signup_text: "Grazie per esserti unito alla rete. Se sei un cliente, non vediamo l'ora di introdurti a molti produttori fantastici, distributori di cibo spettacolari e cibo delizioso! Se sei un produttore o un'impresa alimentare, siamo entusiasti di averti come parte della rete." email_signup_help_html: "Accettiamo volentieri tutte le tue domane e i tuoi suggerimenti: puoi usare il bottone Invia Feedback sul sito o scriverci a %{email}" invite_email: greeting: "Ciao!" @@ -1980,7 +1979,7 @@ it: scheduled_for: "Programmato per" customers: "Clienti" please_select_hub: "Seleziona un hub" - loading_customers: "Clienti in caricamento" + loading_customers: "Caricamento Clienti" no_customers_found: "Nessun cliente trovato" go: "Vai" hub: "Distributore" @@ -2130,8 +2129,8 @@ it: report_header_tax_on_fees: "Oneri sulle provvigioni (%{currency_symbol})" report_header_total_tax: "Oneri totali (%{currency_symbol})" report_header_enterprise: Azienda - report_header_customer: Consumatore - report_header_customer_code: Codice cliente + report_header_customer: Cliente + report_header_customer_code: Codice Cliente report_header_product: Prodotto report_header_product_properties: Proprietà prodotto report_header_quantity: Quantità @@ -2175,10 +2174,10 @@ it: report_header_order_id: ID richiesta report_header_item_name: Nome articolo report_header_temp_controlled_items: Articolo a Temperatura Controllata - report_header_customer_name: Nome Consumatore - report_header_customer_email: Email consumatore - report_header_customer_phone: Telefono Consumatore - report_header_customer_city: Città consumatore + report_header_customer_name: Nome Cliente + report_header_customer_email: Email Cliente + report_header_customer_phone: Telefono Cliente + report_header_customer_city: Città Cliente report_header_payment_state: Stato Pagamento report_header_payment_type: Tipo Pagamento report_header_item_price: "Articolo (%{currency})" @@ -2278,12 +2277,12 @@ it: adjustments_tax_rate_error: "^Verificate che l'aliquota d'imposta per questo adeguamento sia corretta." active_distributors_not_ready_for_checkout_message_singular: >- L'hub %{distributor_names} figura in un ciclo di richieste attivo, ma non ha - metodi di consegna e di pagamento validi. Finché non li imposti, i consumatori - non potranno acquistare da questo hub. + metodi di consegna e di pagamento validi. Finché non li imposti, i clienti non + potranno acquistare da questo hub. active_distributors_not_ready_for_checkout_message_plural: >- - Gli hub %{distributor_names}figurano in un ciclo di richieste attivo, ma non - hanno metodi di consegna e di pagamento validi. Finché non li imposti, i consumatori - non potranno acquistare da questi hub. + I distributori %{distributor_names} figurano in un ciclo di richieste attivo, + ma non hanno metodi di consegna e di pagamento validi. Finché non li imposti, + i clienti non potranno acquistare da questi distributori. enterprise_fees_update_notice: Le tariffe della tua azienda sono state aggiornate. enterprise_register_package_error: "Per favore seleziona un pacchetto" enterprise_register_error: "Non abbiamo potuto completare la registrazione per %{enterprise}" @@ -2340,9 +2339,9 @@ it: title: Regole Tag overview: Panoramica overview_text: > - Le regole per le tag forniscono un modo per definire quali elementi - sono visibili, o a quali utenti. Gli elementi possono essere: metodi - di consegna, metodi di pagamento, prodotti e cicli di richieste. + Le regole per le tag forniscono un modo per descrivere quali elementi + sono visibili, o a quali utenti. Gli elementi possono essere: Metodi + di Consegna, Metodi di Pagamento, Prodotti e Cicli d'Ordine. by_default_rules: "Regole predefinite" by_default_rules_text: > Le regole predefinite ti permettono di nascondere gli elementi affinché @@ -2585,7 +2584,7 @@ it: edit_profile: "modifica profilo" add_products_to_inventory: "aggiungi prodotti all'inventario" resources: - could_not_delete_customer: 'Non è possibile annullare utente' + could_not_delete_customer: 'Non è possibile cancellare il cliente' product_import: confirmation: | Questo imposterà il livello delle scorte a zero su tutti i prodotti per questa @@ -2594,7 +2593,7 @@ it: create_failure: "Impossibile creare il ciclo dell'ordine" update_success: 'Il tuo ciclo di richieste è stato aggiornato' update_failure: "Impossibile aggiornare il ciclo dell'ordine" - no_distributors: Non ci sono distributori in questo ciclo dell'ordine. Questo ciclo dell'ordine non sarà visibile ai consumatori fino a quando non ne verrà aggiunto uno. Vuoi continuare a salvare questo ciclo dell'ordine? + no_distributors: Non ci sono distributori in questo ciclo d'ordine. Questo ciclo d'ordine non sarà visibile ai clienti fino a quando non ne verrà aggiunto uno. Vuoi continuare a salvare questo ciclo d'ordine? enterprises: producer: "Produttore" non_producer: "Non-produttore" @@ -2720,7 +2719,7 @@ it: fee_type: "Tipo di tariffa" enterprise_name: "Proprietario dell'azienda" fee_name: "Nome della tariffa" - customer_name: "Consumatore" + customer_name: "Cliente" fee_placement: "Posizionamento della tariffa" fee_calculated_on_transfer_through_name: "Calcolo della commissione sul trasferimento tramite" tax_category_name: "Categoria d'imposta" @@ -2730,7 +2729,7 @@ it: fee_type: "Tipo di tariffa" enterprise_name: "Proprietario dell'azienda" fee_name: "Nome della tariffa" - customer_name: "Consumatore" + customer_name: "Cliente" fee_placement: "Posizionamento della tariffa" fee_calculated_on_transfer_through_name: "Calcolo della commissione sul trasferimento tramite" tax_category_name: "Categoria d'imposta" @@ -2739,7 +2738,7 @@ it: order: "Gentile Richiesta" distribution: "Distribuzione" order_details: "Dettagli ordine" - customer_details: "Dettagli cliente" + customer_details: "Dettagli Cliente" adjustments: "Regolazioni" payments: "Pagamenti" payment: "Pagamento" @@ -2788,8 +2787,8 @@ it: cannot_set_shipping_method_without_address: "Impossibile impostare il metodo di spedizione finché non vengono forniti i dettagli del cliente." no_tracking_present: "Nessun dettaglio di tracciamento fornito." order_total: "Ordine totale" - customer_details: "Dettagli cliente" - customer_search: "Ricerca clienti" + customer_details: "Dettagli Cliente" + customer_search: "Ricerca Clienti" choose_a_customer: "Scegli un cliente" account: "Account" billing_address: "Indirizzo di fatturazione" @@ -2807,7 +2806,7 @@ it: use_billing_address: "Utilizzare l'indirizzo di fatturazione" adjustments: "Regolazioni" continue: "Continua" - fill_in_customer_info: "Si prega di compilare le informazioni del cliente" + fill_in_customer_info: "Per favore compila le informazioni del cliente" new_payment: "Nuovo pagamento" capture: "Cattura" void: "vuoto" @@ -2960,7 +2959,7 @@ it: order_cycles: "Cicli di richieste" enterprises: "Aziende" enterprise_relationships: "permessi" - customers: "Consumatori" + customers: "Clienti" groups: "Gruppi" product_properties: index: @@ -3036,7 +3035,7 @@ it: completed_at: "Completo al" number: "Numero" state: "Stato" - email: "Mail consumatore" + email: "E-mail Cliente" invoice: issued_on: "Emesso il" tax_invoice: "FATTURA DELLE TASSE" @@ -3062,7 +3061,7 @@ it: other: "Hai il %{count} di prodotti disponibili" order_cycles: order_cycles: "Cicli di richieste" - order_cycles_tip: "I cicli di richieste determinano dove e quando i tuoi prodotti sono disponibili per i consumatori." + order_cycles_tip: "I cicli di richieste determinano dove e quando i tuoi prodotti sono disponibili per i clienti." you_have_active: zero: "Non hai nessun ciclo di richieste attivo." one: "Hai un ciclo di richieste attivo." @@ -3201,7 +3200,7 @@ it: bulk_coop_supplier_report: 'Totali per fornitore - tabella' bulk_coop_allocation: 'Assegnazione - tabella' bulk_coop_packing_sheets: 'Imballaggio - tabella' - bulk_coop_customer_payments: 'Pagamenti clienti - tabella' + bulk_coop_customer_payments: 'Bulk Co-op - Pagamenti Clienti' users: index: listing_users: "Elenco Utenti" @@ -3246,6 +3245,7 @@ it: display_as_placeholder: 'es. 2 kg' display_name_placeholder: 'es. Pomodori' autocomplete: + out_of_stock: "Esaurito" producer_name: "Produttore" unit: "Unità" shared: diff --git a/config/locales/nb.yml b/config/locales/nb.yml index 073ed2c232..f25465f87e 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -368,7 +368,6 @@ nb: title: "Matomo Innstillinger" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo er en web- og mobilanalyse. Du kan enten hoste Matomo selv eller bruke en skytjeneste. Se matomo.org for mer informasjon." config_instructions_html: "Her kan du konfigurere OFN-Matomo integrasjonen. URL til Matomo nedenfor skal peke på Matomo-instansen der brukersporingsinformasjonen skal sendes til; Hvis den er tom, blir Matomo-brukersporing deaktivert. Site-ID feltet er ikke obligatorisk, men nyttig hvis du sporer mer enn ett nettsted på en enkelt Matomo-instans; den kan bli funnet på Matomo-konsollen." customers: index: @@ -3206,6 +3205,7 @@ nb: display_as_placeholder: 'f.eks. 2 kg' display_name_placeholder: 'f.eks. Tomater' autocomplete: + out_of_stock: "Ikke på Lager" producer_name: "Produsent" unit: "Enhet" shared: diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index d2aa82ed37..952d7a5579 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -354,7 +354,6 @@ nl_BE: title: "Matomo instellingen" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is een Web en Mobile Analytics. U kunt Matomo on-premises hosten of gebruik maken van een cloud-hosted service. Zie matomo.org voor meer informatie." config_instructions_html: "Hier kunt u de OFN Matomo integratie configureren. De Matomo URL hieronder zou moeten verwijzen naar de Matomo instantie waar de gebruiker tracking informatie naartoe wordt gestuurd; als deze leeg wordt gelaten, wordt Matomo gebruiker tracking uitgeschakeld. Het veld Site ID is niet verplicht, maar handig als je meer dan één website volgt op één Matomo instance; het is te vinden op de Matomo instance console. Vertaald met www.DeepL.com/Translator" customers: index: @@ -3030,6 +3029,7 @@ nl_BE: price: "Prijs" display_as: "Weergeven als" autocomplete: + out_of_stock: "Geen voorraad" producer_name: "Producent" unit: "Unit" shared: diff --git a/config/locales/pt.yml b/config/locales/pt.yml index d7328b6e33..1e8b8f7efe 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -347,7 +347,6 @@ pt: title: "Configurações Matomo" matomo_url: "URL Matomo" matomo_site_id: "Site ID Matomo" - info_html: "Matomo é uma ferramenta de análise web e mobile. Pode instalar o Matomo no seu servidor ou utilizar um serviço na cloud. Veja matomo.org para mais informações." config_instructions_html: "Aqui pode configurar a integração com Matomo. O URL Matomo em baixo deve apontar para o serviror para onde a informação de tracking de utilizadores será enviada; se deixado vazio, o tracking de utilizadores através do Matomo ficará desactivado. O campo Site ID não é obrigatório mas útil se estive a fazer tracking de mais do que um website numa instância única do Matomo; pode ser encontrado na consola da instância Matomo." customers: index: @@ -2967,6 +2966,7 @@ pt: price: "Preço" display_as: "Mostrar como" autocomplete: + out_of_stock: "Sem Stock" producer_name: "Produtor" unit: "Unidade" shared: diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index daab978405..3c2ac7d748 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -368,7 +368,6 @@ pt_BR: title: "Configurações do Matomo" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo é uma Web e Mobile Analytics. Você pode hospedar o Matomo localmente ou usar um serviço hospedado na nuvem. Veja matomo.org para mais informações." config_instructions_html: "Aqui você pode configurar a integração do OFN Matomo. O URL do Matomo abaixo deve apontar para a instância do Matomo para onde as informações de rastreamento do usuário serão enviadas; se for deixado em branco, o rastreamento de usuários do Matomo será desativado. O campo ID do site não é obrigatório, mas é útil se você estiver controlando mais de um site em uma única instância do Matomo. ele pode ser encontrado no console da instância Matomo." customers: index: @@ -3230,6 +3229,7 @@ pt_BR: display_as_placeholder: 'ex. 2 kg' display_name_placeholder: 'ex. Tomates' autocomplete: + out_of_stock: "Sem estoque" producer_name: "Produtor" unit: "Unidade" shared: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 81e7552502..825fab2b41 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -368,7 +368,6 @@ tr: title: "Matomo Ayarları" matomo_url: "Matomo URL'si" matomo_site_id: "Matomo Site Kimliği" - info_html: "Matomo bir Web ve Mobil Analitik programıdır. Matomo'yu şirket içinde kullanabilir veya bulutta saklanan bir hizmet olarak kullanabilirsiniz. Daha fazla bilgi için matomo.org adresini ziyaret edin." config_instructions_html: "Burada OFN Matomo entegrasyonunu yapılandırabilirsiniz. Aşağıdaki Matomo URL'si, kullanıcı izleme bilgilerinin gönderileceği Matomo örneğini göstermelidir; boş bırakılırsa Matomo kullanıcı takibi devre dışı bırakılır. Site Kimliği alanı zorunlu değildir, ancak tek bir Matomo örneğinde birden fazla web sitesini izliyorsanız yararlıdır; Matomo örnek konsolunda bulunabilir." customers: index: @@ -2297,7 +2296,7 @@ tr: order_cycles_no_permission_to_coordinate_error: "Hiçbir işletmenizin sipariş dönemini koordine etme izni yok" order_cycles_no_permission_to_create_error: "Bu işletme tarafından koordine edilen bir sipariş dönemi oluşturma izniniz yok" back_to_orders_list: "Sipariş listesine geri dön" - no_orders_found: "Sipariş bulunamadı" + no_orders_found: "SİPARİŞ BULUNAMADI" order_information: "Sipariş Bilgisi" date_completed: "Tamamlanma Tarihi" amount: "Tutar" @@ -2893,7 +2892,7 @@ tr: default: "varsayılan" calculator: "Hesaplama" zone: "bölge" - display: "Görüntüle" + display: "GÖSTER" environment: "çevre" active: "Aktif" nore: "Daha fazla" @@ -2943,7 +2942,7 @@ tr: admin: tab: dashboard: "KONTROL PANELİ" - orders: "Siparişler" + orders: "SİPARİŞLER" bulk_order_management: "Toplu Sipariş Yönetimi" subscriptions: "Üyelikler" products: "Ürünler" @@ -2982,7 +2981,7 @@ tr: index: new_return_authorization: "Yeni İade Yetkisi" return_authorizations: "İade Yetkileri" - back_to_orders_list: "Siparişler Listesine Geri Dön" + back_to_orders_list: "SİPARİŞLER LİSTESİNE GERİ DÖN" rma_number: "RMA Numarası" status: "Durum" amount: "Miktar" @@ -3011,7 +3010,7 @@ tr: canceled: "İptal edildi" orders: index: - listing_orders: "Siparişler Listeleniyor" + listing_orders: "SİPARİŞLER LİSTELENİYOR" new_order: "Yeni Sipariş" capture: "Tahsilat" ship: "Teslimat" @@ -3023,7 +3022,7 @@ tr: previous: "Önceki" next: "Sonraki" loading: "Yükleniyor" - no_orders_found: "Sipariş Bulunamadı" + no_orders_found: "SİPARİŞ BULUNAMADI" results_found: "%{number} Sonuç bulundu." viewing: "%{start} - %{end} görüntüleniyor." print_invoices: "Faturaları Yazdır" @@ -3073,7 +3072,7 @@ tr: products_distributor: "Dağıtımcı" zone: "bölge" calculator: "Hesaplama" - display: "Görüntüle" + display: "GÖSTER" both: "Ödeme Sayfası ve Panel" back_end: "Sadece panel" no_shipping_methods_found: "Hiçbir teslimat yöntemi bulunamadı" @@ -3097,8 +3096,8 @@ tr: name: "İSİM" products_distributor: "Dağıtımcı" provider: "Sağlayıcı" - environment: "çevre" - display: "Görüntüle" + environment: "Çevre" + display: "GÖSTER" active: "Aktif" both: "Her ikisi de" front_end: "Sadece Ödeme" @@ -3129,8 +3128,8 @@ tr: form: name: "İSİM" description: "Açıklama" - environment: "çevre" - display: "Görüntüle" + environment: "Çevre" + display: "GÖSTER" active: "Aktif" active_yes: "Evet" active_no: "Hayır" @@ -3138,7 +3137,7 @@ tr: front_end: "Sadece Ödeme" back_end: "Sadece panel" tags: "Etiketler" - deactivation_warning: "Bir ödeme yöntemini kaldırmak listenizden silinmesine sebep olabilir. Alternatif olarak, ödeme yöntemini 'Göster' yerine 'Yalnızca " + deactivation_warning: "Bir ödeme yöntemini kaldırmak listenizden silinmesine sebep olabilir. Alternatif olarak, ödeme yöntemi ayarını 'Göster' yerine 'Sadece Panel' olarak değiştirebilirsiniz. " providers: provider: "Sağlayıcı" payments: @@ -3243,6 +3242,7 @@ tr: display_as_placeholder: 'örn. 2 kg' display_name_placeholder: 'örn. Domates' autocomplete: + out_of_stock: "Stok tükendi" producer_name: "Üretici" unit: "Birim" shared: @@ -3360,14 +3360,14 @@ tr: account_settings: Hesap Ayarları show: tabs: - orders: Siparişler + orders: SİPARİŞLER cards: Kredi kartları transactions: İşlemler settings: Hesap ayarları unconfirmed_email: "Bekleyen e-posta onayı: %{unconfirmed_email}. Yeni e-posta onaylandıktan sonra e-posta adresiniz güncellenecektir." orders: - open_orders: Açık Siparişler - past_orders: Geçmiş Siparişler + open_orders: AÇIK SİPARİŞLER + past_orders: GEÇMİŞ SİPARİŞLER transactions: transaction_history: İşlem Geçmişi open_orders: From 6d7c1b79334adc6b569da5c0f7a9402ffe4dbe1c Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 00:35:36 +1000 Subject: [PATCH 403/507] Updating translations for config/locales/es.yml --- config/locales/es.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/es.yml b/config/locales/es.yml index f4ea131b1e..7c8dce9d88 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -23,6 +23,8 @@ es: base: "Tarjeta de crédito" order_cycle: orders_close_at: Fecha de cierre + variant_override: + count_on_hand: "Disponibles" errors: models: spree/user: From 30917c64f5396a93fcd70a891b99afca8f3984e0 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 00:35:44 +1000 Subject: [PATCH 404/507] Updating translations for config/locales/fr.yml --- config/locales/fr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 6f4cf8df9b..a009e94c9f 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -23,6 +23,8 @@ fr: base: "Carte de crédit" order_cycle: orders_close_at: Date de fermeture + variant_override: + count_on_hand: "En stock" errors: models: spree/user: From ab7631986167d16676e1ccbd726e893060bc0b44 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 00:35:51 +1000 Subject: [PATCH 405/507] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 352eedea77..18f601f025 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -23,6 +23,8 @@ en_FR: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: From bfcf5f8ca0c50efd06958a65b55e9df643fc4da2 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 00:38:46 +1000 Subject: [PATCH 406/507] Updating translations for config/locales/ca.yml --- config/locales/ca.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index fe72aeeb3a..2ac40c0d36 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -23,6 +23,8 @@ ca: base: "Targeta de crèdit" order_cycle: orders_close_at: Data de tancament + variant_override: + count_on_hand: "Disponibles" errors: models: spree/user: From e371c5f7888f88239c952cd879f6a0a475574fcf Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 03:48:39 +1000 Subject: [PATCH 407/507] Updating translations for config/locales/en_CA.yml --- config/locales/en_CA.yml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 8eb65e9a43..fea11d0fe2 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -23,6 +23,8 @@ en_CA: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: @@ -259,7 +261,7 @@ en_CA: pick_up: Pick up copy: Copy change_my_password: "Change my password" - update_password: "Update passord" + update_password: "Update password" password_confirmation: Password Confirmation reset_password_token: Reset password token expired: has expired, please request a new one @@ -368,7 +370,10 @@ en_CA: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See 1matomo.org1 for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." + config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." customers: index: new_customer: "New Customer" @@ -1574,7 +1579,7 @@ en_CA: groups_no_groups: "No groups found" groups_about: "About Us" groups_producers: "Our vendors" - groups_hubs: "Our hubs" + groups_hubs: "Go Shopping!" groups_contact_web: Contact groups_contact_social: Follow groups_contact_address: Address @@ -2807,6 +2812,12 @@ en_CA: void: "Void" login: "Login" password: "Password" + signature: "Signature" + solution: "Solution" + landing_page: "Landing Page" + server: "Server" + test_mode: "Test Mode" + logourl: "Logourl" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2923,6 +2934,12 @@ en_CA: options: "Options" actions: update: "Update" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: " 1 errors prohibited this record from being saved:" + other: " %{count}errors prohibited this record from being saved:" + there_were_problems_with_the_following_fields: "There were problems with the following fields" errors: messages: blank: "can't be blank" @@ -3092,9 +3109,11 @@ en_CA: display: "Display" active: "Active" both: "Both" + front_end: "Checkout only" back_end: "Back office only" active_yes: "Yes" active_no: "No" + no_payment_methods_found: "No payment methods found" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" @@ -3124,8 +3143,10 @@ en_CA: active_yes: "Yes" active_no: "No" both: "Both Checkout and Back office" + front_end: "Checkout only" back_end: "Back office only" tags: "Tags" + deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." providers: provider: "Provider" payments: From 17bf16337849f4424ce4649c3fbdafdc8d7d55bc Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 03:53:33 +1000 Subject: [PATCH 408/507] Updating translations for config/locales/fr_CA.yml --- config/locales/fr_CA.yml | 69 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index 5f7f23ce5f..6c78ec8d71 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -23,6 +23,8 @@ fr_CA: base: "Carte de crédit" order_cycle: orders_close_at: Date de fermeture + variant_override: + count_on_hand: "En stock" errors: models: spree/user: @@ -31,6 +33,10 @@ fr_CA: taken: "Un compte existe déjà pour cet e-mail. Connectez-vous ou demandez un nouveau mot de passe." spree/order: no_card: Aucune carte de paiement autorisée disponible + spree/credit_card: + attributes: + base: + card_expired: "a expiré" order_cycle: attributes: orders_close_at: @@ -250,6 +256,7 @@ fr_CA: error: Erreur processing_payment: "Paiement en cours..." no_pending_payments: "Aucun paiement en attente." + invalid_payment_state: "Statut de paiement invalide" filter_results: Filtrer les résultats quantity: Quantité pick_up: Retrait @@ -319,6 +326,7 @@ fr_CA: show_n_more: Montrer %{num} supplémentaires choose: "Choisir..." please_select: Veuillez choisir... + column_save_as_default: Par défaut columns: Colonnes actions: Actions viewing: "Vous regardez: %{current_view_name}" @@ -363,7 +371,10 @@ fr_CA: title: "Configuration Matomo" matomo_url: "URL de l'instance sur Matomo" matomo_site_id: "ID de l'instance sur Matomo" + matomo_tag_manager_url: "URL du Matomo Tag Manager" + info_html: "Matomo est un outil de suivi de traffic et de comportement des utilisateurs. Matomo est open source et validée par la CNIL française car non intrusif dans les données personnelles des utilisateurs. Pour plus d'infos : 1matomo.org1." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." + config_instructions_tag_manager_html: "Ajouter l'URL du Tag Manager rend actif Matomo Tag Manager. Cet outil vous permet de suivre des évènements en particulier. Pour trouver l'URL rendez-vous sur l' \"Install Code section\" du Tag Manager. Attention à bien copier le bon contener et le bon environnement, car ils font varier l'URL." customers: index: new_customer: "Nouveau client" @@ -682,6 +693,7 @@ fr_CA: ofn_uid_tip: L'identifiant unique pour les comptes entreprises sur Open Food Network. shipping_methods: name: "Nom" + applies: "Active ?" manage: "Gérer les méthodes de livraison" create_button: "Créer nouvelle méthode de livraison" create_one_button: "En créer une maintenant" @@ -861,6 +873,7 @@ fr_CA: incoming: "Produits entrants (pouvant être mis en vente par les hubs)" supplier: "Fournisseur" products: "Produits" + receival_details: "Détails livraison" fees: "Commissions" save: "Enregistrer" save_and_next: "Sauvegarder et suivant" @@ -872,6 +885,7 @@ fr_CA: distributor: "Hub-distributeur" products: "Produits" tags: "Tags" + delivery_details: "Détails de livraison" fees: "Commissions" previous: "Précédent" save: "Enregistrer" @@ -1168,7 +1182,11 @@ fr_CA: signup: "inscrivez-vous" contact: "contact" require_customer_login: "Seul les acheteurs autorisés peuvent accéder à cette boutique." + require_login_html: "Si vous êtes déjà autorisé à accéder à la boutique, %{login}ou %{signup}pour continuer." + require_login_2_html: "Vous souhaitez réaliser vos courses ici? Merci de %{contact}%{enterprise} afin d'avoir l'autorisation d'accès à la boutique." require_customer_html: "Si vous voulez demander à y accéder, veuillez %{contact} %{enterprise}." + select_oc: + select_oc_html: "Merci de 1sélectionner une option dans la liste déroulante1, afin de voir quel produits sont disponibles." card_could_not_be_updated: La carte n'a pu être mise à jour card_could_not_be_saved: la carte n'a pas pu être sauvegardée spree_gateway_error_flash_for_checkout: "Il y a eu un problème avec vos informations de paiement : %{error}" @@ -1491,6 +1509,7 @@ fr_CA: shopping_oc_closed_description: "Veuillez attendre l'ouverture du prochain cycle de vente (ou contactez-nous directement pour voir si nous pouvons accepter une commande tardive)" shopping_oc_last_closed: "Le dernier cycle de vente s'est terminé il y a %{distance_of_time}" shopping_oc_next_open: "Le prochain cycle de vente ouvrira dans %{distance_of_time}" + shopping_oc_select: "Sélectionner" shopping_tabs_home: "Accueil" shopping_tabs_shop: "Boutique" shopping_tabs_about: "A propos" @@ -1527,12 +1546,17 @@ fr_CA: orders_changeable_orders_alert_html: Cette commande a été confirmée, mais vous pouvez effectuer des modifications jusqu'à %{oc_close}. products_clear: Effacer products_showing: "Afficher:" + products_results_for: "Résultats pour" products_or: "ou" products_and: "et" + products_filters_in: "dans" products_with: avec + products_search: "Rechercher..." products_filter_by: "Filtrer par" products_filter_selected: "sélectionné" + products_filter_heading: "Filtres" products_filter_clear: "Effacer" + products_filter_done: "Fait" products_loading: "Produits en cours de chargement..." products_updating_cart: "Actualisation du panier..." products_cart_empty: "Panier vide" @@ -1543,6 +1567,8 @@ fr_CA: products_update_error_msg: "Échec de l'enregistrement." products_update_error_data: "Échec de l'enregistrement dû à des données non valides." products_changes_saved: "Modifications enregistrées." + products_no_results_html: "Nous sommes navrés, mais aucun résultat n'a été trouvé pour %{query}" + products_clear_search: "Annuler la recherche" search_no_results_html: "Désolé, aucun résultat pour %{query}. Autre recherche?" components_profiles_popover: "Certaines entreprises ont juste créé leur profil sur Open Food Network mais ne vendent pas via la plateforme. Elles ont peut-être une boutique physique, ou une boutique en ligne sur une autre plateforme." components_profiles_show: "Afficher aussi les profils" @@ -1851,6 +1877,7 @@ fr_CA: headline: "C'est terminé!" thanks: "Merci d'avoir complété le profil de %{enterprise}" login: "Vous pouvez modifier ou mettre à jour les détails de votre entreprise à tout moment en vous connectant sur Open Food Network, rubrique Admin." + action: "Aller vers le tableau de bord" back: "Retour" continue: "Suivant" action_or: "OU" @@ -1897,6 +1924,7 @@ fr_CA: admin_enterprise_relationships_permits: "autorise" admin_enterprise_relationships_seach_placeholder: "Chercher" admin_enterprise_relationships_button_create: "Créer" + admin_enterprise_relationships_to: "à" admin_enterprise_groups: "Groupes d'entreprises" admin_enterprise_groups_name: "Nom" admin_enterprise_groups_owner: "Gérant" @@ -2304,6 +2332,10 @@ fr_CA: resolve_errors: Veuillez corriger les erreurs suivantes more_items: "+ %{count} en plus" default_card_updated: La carte bancaire par défaut a été mise à jour + cart: + add_to_cart_failed: > + Il y a eu un problème lors de l'ajout de votre produit au panier. Peut-être + qu'il n'est plus en stock ou que la boutique sur laquelle vous étiez a fermé. admin: enterprise_limit_reached: "Vous avez atteint le nombre limite d'entreprises autorisées par défaut. Ecrivez à %{contact_email}si vous avez besoin d'augmenter cette limite." modals: @@ -2794,6 +2826,12 @@ fr_CA: void: "Annulé" login: "Se connecter" password: "Mot de passe" + signature: "Signature" + solution: "Solution" + landing_page: "Page d'accueil (landing page)" + server: "Serveur" + test_mode: "Mode test" + logourl: "URL du logo" configurations: "Configurations" general_settings: "Configurations générales" site_name: "Nom du site" @@ -2910,6 +2948,12 @@ fr_CA: options: "Options" actions: update: "Mettre à jour" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 erreur n'a pas permis de sauvegarder:" + other: "1 %{count} erreurs ne permettent pas de sauvegarder:" + there_were_problems_with_the_following_fields: "Ils a eu des soucis avec les champs suivants" errors: messages: blank: "Champ obligatoire" @@ -3017,6 +3061,8 @@ fr_CA: tax_invoice: "FACTURE" code: "Code" from: "De" + to: "Facturer à" + shipping: "Envoi" form: distribution_fields: title: "Distribution" @@ -3050,6 +3096,8 @@ fr_CA: zone: "Zone" calculator: "Calculateur" display: "Afficher" + both: "Visible par l'acheteur sur la boutique" + back_end: "Visible pour l'administration uniquement" no_shipping_methods_found: "Aucune méthode de livraison trouvée" new: new_shipping_method: "Nouvelle méthode de livraison" @@ -3061,6 +3109,9 @@ fr_CA: form: categories: "Conditions de transport" zones: "Zones" + both: "Visible par l'acheteur sur la boutique" + back_end: "Visible pour l'administration uniquement" + deactivation_warning: "Désactiver une méthode de livraison peut engendre sa disparition de la liste ici. Si vous souhaitez uniquement ne plus l'afficher pour l'acheteur, modifiez-là et utilisez l'option d'affichage \"visible pour l'administrateur uniquement\"." payment_methods: index: payment_methods: "Méthodes de paiement" @@ -3072,8 +3123,11 @@ fr_CA: display: "Afficher" active: "Actif" both: "Les deux" + front_end: "Visible par l'acheteur uniquement" + back_end: "Visible pour l'administration uniquement" active_yes: "Oui" active_no: "Non" + no_payment_methods_found: "Aucune méthode de paiement n'a été trouvée" new: new_payment_method: "Nouvelle méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" @@ -3102,7 +3156,11 @@ fr_CA: active: "Actif" active_yes: "Oui" active_no: "Non" + both: "Visible par l'acheteur sur la boutique" + front_end: "Visible par l'acheteur uniquement" + back_end: "Visible pour l'administration uniquement" tags: "Tags" + deactivation_warning: "Désactiver une méthode de paiement peut faire disparaitre cette méthode de votre liste. Si vous souhaitez uniquement la rendre invisible par l'acheteur, modifiez la méthode et utilisez l'affichage pour l'administrateur uniquement." providers: provider: "Fournisseur" payments: @@ -3204,6 +3262,8 @@ fr_CA: price: "Prix" display_as: "Afficher comme" display_name: "Nom affiché" + display_as_placeholder: 'ex. 2 kg' + display_name_placeholder: 'ex. Tomates' autocomplete: out_of_stock: "En rupture de stock" producer_name: "Producteur" @@ -3243,6 +3303,7 @@ fr_CA: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "Un élément de votre panier est épuisé. Veuillez mettre à jour les quantités sélectionnées." edit: login_to_view_order: "Veuillez vous connecter pour voir votre commande." bought: @@ -3270,6 +3331,14 @@ fr_CA: invalid: invalide order_mailer: cancel_email: + customer_greeting: "Bonjour %{name}," + instructions_html: "Votre commande avec 1%{distributor}1a été annulée. Merci de conserver cet email." + dont_cancel: "Si vous avez changé d'avis ou l'annulation a été réalisée par erreur, merci de contacter %{email}" + order_summary_canceled_html: "1[ANNULATION] Commande #%{number}1" + details: "Voici le détail des produits commandés:" + unpaid_order: "Votre commande n'avait pas été réglée, aucun remboursement n'a donc été effectué" + paid_order: "Votre commande avait été réglée, ainsi %{distributor}a remboursé la totalité du montant" + credit_order: "Votre commande avait été payée, votre compte a donc été crédité" subject: "Annulation de Commande" confirm_email: subject: "Confirmation de commande" From e2265dd165fd66a42bf712b690f1904fab4a7d19 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 11 Jun 2020 20:26:57 +0100 Subject: [PATCH 409/507] Fix issue in product_spec --- Gemfile.lock | 2 +- spec/models/spree/product_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2776c9503c..ee01f6b3a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -644,8 +644,8 @@ GEM sprockets (>= 2.8, < 4.0) state_machine (1.2.0) stringex (1.5.1) - temple (0.8.2) stripe (5.22.0) + temple (0.8.2) test-unit (3.3.6) power_assert thor (0.20.3) diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index bae53d89e8..4309d105c9 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -274,10 +274,10 @@ module Spree } it "returns distributed products for a given Enterprise AR relation" do - distributors_relation = Enterprise.where(id: [distributor1.id, distributor2.id]) + distributors = Enterprise.where(id: [distributor1.id, distributor2.id]).to_a - expect(Product.in_distributors(distributors_relation)).to include product1, product2, product3 - expect(Product.in_distributors(distributors_relation)).to_not include product4 + expect(Product.in_distributors(distributors)).to include product1, product2, product3 + expect(Product.in_distributors(distributors)).to_not include product4 end it "returns distributed products for a given array of enterprise ids" do From 2914500d5b305248ecf87162ff1af89a4bbf80d8 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 12:15:53 +1000 Subject: [PATCH 410/507] Updating translations for config/locales/ca.yml --- config/locales/ca.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 2ac40c0d36..61dfc3e907 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -2748,6 +2748,7 @@ ca: customer_details: "Detalls de la consumidora" adjustments: "Ajustaments" payments: "Pagaments" + return_authorizations: "Autoritzacions de devolució" payment: "Pagament" payment_method: "Mètode de pagament" shipment: "Enviament" From ff0e3ed37991aa7d6955cb7911d27765e3c80f5d Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 12:16:00 +1000 Subject: [PATCH 411/507] Updating translations for config/locales/fr.yml --- config/locales/fr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index a009e94c9f..a3a4a3a478 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -2772,6 +2772,7 @@ fr: customer_details: "Informations acheteur" adjustments: "Ajustements" payments: "Paiements" + return_authorizations: "Autorisations de retours" payment: "Paiement" payment_method: "Méthode de paiement" shipment: "Livraison" From 9908692da973d1fbd02e0be0ba618dbb20dde9e1 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 12:16:07 +1000 Subject: [PATCH 412/507] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 18f601f025..ac67a6ee73 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -2742,6 +2742,7 @@ en_FR: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" From fce74bd0084e88b8bb2d81838940d8bdd6acc0d9 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 12:19:00 +1000 Subject: [PATCH 413/507] Updating translations for config/locales/es.yml --- config/locales/es.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/es.yml b/config/locales/es.yml index 7c8dce9d88..8f15a13da5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2748,6 +2748,7 @@ es: customer_details: "Detalles de la consumidora" adjustments: "Ajustes" payments: "Pagos" + return_authorizations: "Autorizaciones de devolución" payment: "Pago" payment_method: "Método de pago" shipment: "Envío" From 10f09588194ae6e7597159f012b8322ca8873aac Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 12 Jun 2020 12:19:08 +1000 Subject: [PATCH 414/507] Updating translations for config/locales/fr_CA.yml --- config/locales/fr_CA.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index 6c78ec8d71..78d26c0da0 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -2755,6 +2755,7 @@ fr_CA: customer_details: "Informations acheteur" adjustments: "ajustements" payments: "Paiements" + return_authorizations: "Autorisations de retours" payment: "Paiement" payment_method: "Méthode de paiement" shipment: "Livraison" From 6a7df0b1658a93cda760f3d6a9be4482da8e9588 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 12 Jun 2020 12:23:02 +0200 Subject: [PATCH 415/507] Fix link from report to order --- app/views/spree/admin/reports/_link_order.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/spree/admin/reports/_link_order.html.haml b/app/views/spree/admin/reports/_link_order.html.haml index 9f0b72b4f7..1efecf6d25 100644 --- a/app/views/spree/admin/reports/_link_order.html.haml +++ b/app/views/spree/admin/reports/_link_order.html.haml @@ -1 +1,2 @@ -%a.edit-order{href: "/admin/orders/#{value}"}= value +- order_number = value += link_to order_number, edit_admin_order_url(order_number), class: 'edit-order' From 86db1b6d688659e530fe8c3bbfea1063db47f001 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 12 Jun 2020 12:55:50 +0200 Subject: [PATCH 416/507] Fix "subquery has too many columns" in reports query --- app/controllers/spree/admin/reports_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index 3ada1fbbcd..4349e554b3 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -247,7 +247,7 @@ module Spree end def suppliers_of_products_distributed_by(distributors) - supplier_ids = Spree::Product.in_distributors(distributors). + supplier_ids = Spree::Product.in_distributors(distributors.select('enterprises.id')). select('spree_products.supplier_id') Enterprise.where(id: supplier_ids) From cf5af684388d4bff182c89022f078a358c10b264 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 2 Jun 2020 20:19:29 +0100 Subject: [PATCH 417/507] Make spec less flaky by making it wait for the Saving text to go away --- spec/features/admin/variant_overrides_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 1869133774..4c2312c7ee 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -199,6 +199,9 @@ feature " expect do click_button 'Save Changes' + + # We need to wait_until because the save action is not fast enough for the have_content matcher + wait_until { page.find("#status-message").text != "Saving..." } expect(page).to have_content "I couldn't get authorisation to save those changes, so they remain unsaved." end.to change(VariantOverride, :count).by(0) end From f56e0ba0c065fe5a47df0939da6ae03f55f7348c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 12 Jun 2020 14:23:45 +0100 Subject: [PATCH 418/507] Mock current_spree_user to return a user without permissions so that the controller does not use an already loaded version of current_spree_user that still has enough permissions --- spec/features/admin/variant_overrides_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 4c2312c7ee..3db611bc42 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -195,7 +195,8 @@ feature " fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '123' expect(page).to have_content "Changes to one override remain unsaved." - user.enterprises.clear + # Set a user without suficient permissions + allow_any_instance_of(Spree::Admin::BaseController).to receive(:current_spree_user).and_return(build(:user)) expect do click_button 'Save Changes' From 6dcb2d4a3b8525459219fa91d63c7590a0ba7197 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 12 Jun 2020 15:33:26 +0100 Subject: [PATCH 419/507] Add xit, spec is still too flaky on semaphore It's not the most important spec, this scenario should never happen as the user will not be able to access the page. --- spec/features/admin/variant_overrides_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 3db611bc42..fdf2572134 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -190,7 +190,7 @@ feature " end end - it "displays an error when unauthorised to access the page" do + xit "displays an error when unauthorised to access the page" do fill_in "variant-overrides-#{variant.id}-price", with: '777.77' fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '123' expect(page).to have_content "Changes to one override remain unsaved." From 29246c15feb2cef918e2d797897a70329decd1e4 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 12 Jun 2020 16:33:00 +0200 Subject: [PATCH 420/507] Defend from order without billing address This a data integrity issue that needs deeper investigation but while this happens, our users can still render their reports. --- lib/open_food_network/order_cycle_management_report.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/open_food_network/order_cycle_management_report.rb b/lib/open_food_network/order_cycle_management_report.rb index 73a0ea34db..e1f35eed6a 100644 --- a/lib/open_food_network/order_cycle_management_report.rb +++ b/lib/open_food_network/order_cycle_management_report.rb @@ -69,12 +69,12 @@ module OpenFoodNetwork def payment_method_row(order) ba = order.billing_address - [ba.firstname, - ba.lastname, + [ba.andand.firstname, + ba.andand.lastname, order.distributor.andand.name, customer_code(order.email), order.email, - ba.phone, + ba.andand.phone, order.shipping_method.andand.name, order.payments.first.andand.payment_method.andand.name, order.payments.first.andand.amount, From 018772bbba5d8592951d626f65900e0525696b68 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 12 Jun 2020 14:02:48 +0200 Subject: [PATCH 421/507] Remove N+1 fetching payments in report --- lib/open_food_network/payments_report.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/open_food_network/payments_report.rb b/lib/open_food_network/payments_report.rb index f9f536171f..3fc8095b36 100644 --- a/lib/open_food_network/payments_report.rb +++ b/lib/open_food_network/payments_report.rb @@ -41,7 +41,7 @@ module OpenFoodNetwork return [] unless @render_table orders = search.result - payments = orders.map { |o| o.payments.select(&:completed?) }.flatten # Only select completed payments + payments = orders.includes(:payments).map { |o| o.payments.select(&:completed?) }.flatten # Only select completed payments case params[:report_type] when "payments_by_payment_type" payments From 02b351b9d518170b3befda56ff97a4ec5a26c85d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 4 Jun 2020 16:26:53 +0100 Subject: [PATCH 422/507] Make display only shops work again, this will show the product list when the OC is open but ship and pay methods are not available Add spec to cover display only shops, it's oficially a feature now :-) --- .../shopping_shared/tabs/_shop.html.haml | 5 ++-- .../consumer/shopping/shopping_spec.rb | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/views/shopping_shared/tabs/_shop.html.haml b/app/views/shopping_shared/tabs/_shop.html.haml index 2c23b4e8c1..0a8df040f5 100644 --- a/app/views/shopping_shared/tabs/_shop.html.haml +++ b/app/views/shopping_shared/tabs/_shop.html.haml @@ -4,7 +4,8 @@ - if no_open_order_cycles? = render partial: "shop/messages/closed_shop" - - else = render partial: "shop/messages/select_oc" - = render partial: "shop/products/form" + + -# Rendering the form, even if there are no open OCs, makes display only shops possible + = render partial: "shop/products/form" diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index e1679791d4..dc24c885ac 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -232,6 +232,28 @@ feature "As a consumer I want to shop with a distributor", js: true do expect(page).not_to have_content variant3.display_name end end + + context "when the distributor has no available payment/shipping methods" do + before do + distributor.update_attributes shipping_methods: [], payment_methods: [] + end + + # Display only shops are a very useful hack that is described in the user guide + it "still renders a display only shop" do + visit shop_path + expect(page).to have_content product.name + + # Add product to cart + fill_in "variants[#{variant.id}]", with: '1' + wait_for_debounce + expect(page).to have_in_cart product.name + wait_until { !cart_dirty } + + # Try to go to cart + visit main_app.cart_path + expect(page).to have_content "The hub you have selected is temporarily closed for orders. Please try again later." + end + end end describe "group buy products" do @@ -463,11 +485,13 @@ feature "As a consumer I want to shop with a distributor", js: true do visit shop_path expect(page).to have_content "Orders are closed" end + it "shows the last order cycle" do oc1 = create(:simple_order_cycle, distributors: [distributor], orders_open_at: 17.days.ago, orders_close_at: 10.days.ago) visit shop_path expect(page).to have_content "The last cycle closed 10 days ago" end + it "shows the next order cycle" do oc1 = create(:simple_order_cycle, distributors: [distributor], orders_open_at: 10.days.from_now, orders_close_at: 17.days.from_now) visit shop_path From ed262a19a9065d96cfd460afa0eae1d11252367b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 12 Jun 2020 20:30:46 +0100 Subject: [PATCH 423/507] Make checkout js error handling a bit more defensive --- .../javascripts/darkswarm/services/checkout.js.coffee | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index 569382d52e..4ec3081ad3 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -27,10 +27,12 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE throw error # generate a BugsnagJS alert handle_checkout_error_response: (response) => - if response.data.path + throw response unless response.data? + + if response.data.path? Navigation.go response.data.path else - throw response unless response.data.flash + throw response unless response.data.flash? @errors = response.data.errors @loadFlash(response.data.flash) From e9ff84a746c0f68d51dbbe19c89b3fd93f186839 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Sat, 13 Jun 2020 12:26:17 +0100 Subject: [PATCH 424/507] Add a partial for the AJAX progress spinner so it can be reused in the spree admin and bare admin layouts. --- app/views/spree/layouts/_admin_body.html.haml | 25 +------------------ .../layouts/admin/_progress_spinner.html.haml | 24 ++++++++++++++++++ app/views/spree/layouts/bare_admin.html.haml | 5 +--- 3 files changed, 26 insertions(+), 28 deletions(-) create mode 100644 app/views/spree/layouts/admin/_progress_spinner.html.haml diff --git a/app/views/spree/layouts/_admin_body.html.haml b/app/views/spree/layouts/_admin_body.html.haml index 0bf05450ed..d5aa05dbee 100644 --- a/app/views/spree/layouts/_admin_body.html.haml +++ b/app/views/spree/layouts/_admin_body.html.haml @@ -9,30 +9,7 @@ - if flash[:success] .flash.success= flash[:success] - #progress - / By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL - %svg{:class => "spinner", :viewbox => "0 0 58 58", :xmlns => "http://www.w3.org/2000/svg"} - %g{:fill => "none", "fill-rule" => "evenodd"} - %g{:stroke => "currentColor", "stroke-width" => "1.5", :transform => "translate(2 1)"} - %circle{:cx => "42.601", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "1", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "1;0;0;0;0;0;0;0"} - %circle{:cx => "49.063", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;1;0;0;0;0;0;0"} - %circle{:cx => "42.601", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;1;0;0;0;0;0"} - %circle{:cx => "27", :cy => "49.125", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;1;0;0;0;0"} - %circle{:cx => "11.399", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;1;0;0;0"} - %circle{:cx => "4.938", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;1;0;0"} - %circle{:cx => "11.399", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;1;0"} - %circle{:cx => "27", :cy => "5", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} - %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;0;1"} - - = Spree.t(:loading) - \... + = render partial: "spree/layouts/admin/progress_spinner" %header#header{"data-hook" => ""} .container diff --git a/app/views/spree/layouts/admin/_progress_spinner.html.haml b/app/views/spree/layouts/admin/_progress_spinner.html.haml new file mode 100644 index 0000000000..a28458afad --- /dev/null +++ b/app/views/spree/layouts/admin/_progress_spinner.html.haml @@ -0,0 +1,24 @@ +#progress + / By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL + %svg{:class => "spinner", :viewbox => "0 0 58 58", :xmlns => "http://www.w3.org/2000/svg"} + %g{:fill => "none", "fill-rule" => "evenodd"} + %g{:stroke => "currentColor", "stroke-width" => "1.5", :transform => "translate(2 1)"} + %circle{:cx => "42.601", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "1", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "1;0;0;0;0;0;0;0"} + %circle{:cx => "49.063", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;1;0;0;0;0;0;0"} + %circle{:cx => "42.601", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;1;0;0;0;0;0"} + %circle{:cx => "27", :cy => "49.125", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;1;0;0;0;0"} + %circle{:cx => "11.399", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;1;0;0;0"} + %circle{:cx => "4.938", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;1;0;0"} + %circle{:cx => "11.399", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;1;0"} + %circle{:cx => "27", :cy => "5", :fill => "currentColor", "fill-opacity" => "0", :r => "5"} + %animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;0;1"} + + = Spree.t(:loading) + \... diff --git a/app/views/spree/layouts/bare_admin.html.haml b/app/views/spree/layouts/bare_admin.html.haml index 1289f9c01b..085f5be86a 100644 --- a/app/views/spree/layouts/bare_admin.html.haml +++ b/app/views/spree/layouts/bare_admin.html.haml @@ -8,10 +8,7 @@ .flash.notice= notice - if flash[:success] .flash.success= flash[:success] - #progress - %img.spinner{ src: "/assets/spinning-circles.svg" } - = Spree.t(:loading) - \... + = render partial: "spree/layouts/admin/progress_spinner" %header#header{"data-hook" => ""} .container From 40dd9a8fda0d6f0153d8a2df7c1b441c08a4a504 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Sun, 14 Jun 2020 08:11:27 +1000 Subject: [PATCH 425/507] Updating translations for config/locales/en_NZ.yml --- config/locales/en_NZ.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index fa30c62f25..c3ed978054 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -23,6 +23,8 @@ en_NZ: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: @@ -368,7 +370,10 @@ en_NZ: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." + config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." customers: index: new_customer: "New Customer" @@ -686,6 +691,7 @@ en_NZ: ofn_uid_tip: The unique id used to identify the enterprise on Open Food Network. shipping_methods: name: "Name" + applies: "Active?" manage: "Manage Shipping Methods" create_button: "Create New Shipping Method" create_one_button: "Create One Now" @@ -2736,6 +2742,7 @@ en_NZ: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" @@ -2807,6 +2814,12 @@ en_NZ: void: "Void" login: "Login" password: "Password" + signature: "Signature" + solution: "Solution" + landing_page: "Landing Page" + server: "Server" + test_mode: "Test Mode" + logourl: "Logourl" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2923,6 +2936,12 @@ en_NZ: options: "Options" actions: update: "Update" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 error prohibited this record from being saved:" + other: "%{count} errors prohibited this record from being saved:" + there_were_problems_with_the_following_fields: "There were problems with the following fields" errors: messages: blank: "can't be blank" @@ -3080,6 +3099,7 @@ en_NZ: zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" + deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: index: payment_methods: "Payment Methods" @@ -3091,9 +3111,11 @@ en_NZ: display: "Display" active: "Active" both: "Both" + front_end: "Checkout only" back_end: "Back office only" active_yes: "Yes" active_no: "No" + no_payment_methods_found: "No payment methods found" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" @@ -3123,8 +3145,10 @@ en_NZ: active_yes: "Yes" active_no: "No" both: "Both Checkout and Back office" + front_end: "Checkout only" back_end: "Back office only" tags: "Tags" + deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." providers: provider: "Provider" payments: @@ -3267,6 +3291,7 @@ en_NZ: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "An item in your cart has become unavailable. Please update the selected quantities." edit: login_to_view_order: "Please log in to view your order." bought: @@ -3294,6 +3319,14 @@ en_NZ: invalid: invalid order_mailer: cancel_email: + customer_greeting: "Dear %{name}," + instructions_html: "Your order with %{distributor} has been CANCELED. Please retain this cancellation information for your records." + dont_cancel: "If you have changed your mind or don't wish to cancel this order please contact %{email}" + order_summary_canceled_html: "Order Summary #%{number} [CANCELED]" + details: "Here are the details of what you ordered:" + unpaid_order: "Your order was unpaid so no refund has been made" + paid_order: "Your order was paid so %{distributor} has refunded the full amount" + credit_order: "Your order was paid so your account has been credited" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" From df887b557659e3ddf0a7e63da43eca8b29c23fe3 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Mon, 15 Jun 2020 09:25:30 +0200 Subject: [PATCH 426/507] Wrap long line pick e84e0aebe Fix fatal error in reports helper for orders without payments pick e725f3331 Defend from an order w/o payments when building table --- lib/open_food_network/payments_report.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/open_food_network/payments_report.rb b/lib/open_food_network/payments_report.rb index 3fc8095b36..3c2fbbd24b 100644 --- a/lib/open_food_network/payments_report.rb +++ b/lib/open_food_network/payments_report.rb @@ -41,7 +41,10 @@ module OpenFoodNetwork return [] unless @render_table orders = search.result - payments = orders.includes(:payments).map { |o| o.payments.select(&:completed?) }.flatten # Only select completed payments + payments = orders.includes(:payments).map do |order| + order.payments.select(&:completed?) + end.flatten + case params[:report_type] when "payments_by_payment_type" payments From 456f369b767c172bec6035be4d7d824c8c7d7c91 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Mon, 15 Jun 2020 10:09:43 +0200 Subject: [PATCH 427/507] Fix outstanding Rubocop violations --- .../admin/enterprise_groups_controller.rb | 4 +++- .../admin/enterprises_controller.rb | 7 +++++-- app/controllers/admin/schedules_controller.rb | 12 +++++------- .../api/enterprise_attachment_controller.rb | 2 ++ .../spree/admin/countries_controller.rb | 1 - .../spree/admin/products_controller.rb | 2 +- .../admin/shipping_categories_controller.rb | 1 - app/models/product_import/entry_processor.rb | 4 +++- app/models/product_import/entry_validator.rb | 4 +++- app/models/spree/adjustment_decorator.rb | 1 - app/models/spree/line_item_decorator.rb | 9 +++++---- app/models/spree/order_decorator.rb | 3 ++- app/models/spree/order_updater_decorator.rb | 4 +++- app/models/spree/payment_decorator.rb | 16 +++++++--------- app/models/spree/user.rb | 1 - app/services/permitted_attributes/checkout.rb | 2 ++ .../permitted_attributes/order_cycle.rb | 9 ++++++--- .../subscriptions/proxy_order_syncer_spec.rb | 18 ++++++++++++------ .../order_cycle_form_applicator.rb | 2 +- lib/open_food_network/permalink_generator.rb | 2 +- .../variant_and_line_item_naming.rb | 3 ++- 21 files changed, 63 insertions(+), 44 deletions(-) diff --git a/app/controllers/admin/enterprise_groups_controller.rb b/app/controllers/admin/enterprise_groups_controller.rb index 5483cdd45e..471d56d5ab 100644 --- a/app/controllers/admin/enterprise_groups_controller.rb +++ b/app/controllers/admin/enterprise_groups_controller.rb @@ -28,7 +28,9 @@ module Admin def build_resource_with_address enterprise_group = build_resource_without_address enterprise_group.address = Spree::Address.new - enterprise_group.address.country = Spree::Country.find_by(id: Spree::Config[:default_country_id]) + enterprise_group.address.country = Spree::Country.find_by( + id: Spree::Config[:default_country_id] + ) enterprise_group end alias_method_chain :build_resource, :address diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 332d939f27..8b8901e211 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -211,7 +211,8 @@ module Admin # record is persisted. This problem is compounded by the use of calculators. @object.transaction do tag_rules_attributes.select{ |_i, attrs| attrs[:type].present? }.each do |_i, attrs| - rule = @object.tag_rules.find_by(id: attrs.delete(:id)) || attrs[:type].constantize.new(enterprise: @object) + rule = @object.tag_rules.find_by(id: attrs.delete(:id)) || + attrs[:type].constantize.new(enterprise: @object) create_calculator_for(rule, attrs) if rule.type == "TagRule::DiscountOrder" && rule.calculator.nil? rule.update_attributes(attrs) end @@ -234,7 +235,9 @@ module Admin def check_can_change_bulk_sells unless spree_current_user.admin? params[:enterprise_set][:collection_attributes].each do |_i, enterprise_params| - enterprise_params.delete :sells unless spree_current_user == Enterprise.find_by(id: enterprise_params[:id]).owner + unless spree_current_user == Enterprise.find_by(id: enterprise_params[:id]).owner + enterprise_params.delete :sells + end end end end diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index d0728ebc18..9532e4db9e 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -29,9 +29,7 @@ module Admin end def create - if params[:order_cycle_ids].blank? - return respond_with(@schedule) - end + return respond_with(@schedule) if params[:order_cycle_ids].blank? @schedule.attributes = permitted_resource_params @@ -42,10 +40,9 @@ module Admin sync_subscriptions_for_create flash[:success] = flash_message_for(@schedule, :successfully_created) - respond_with(@schedule) - else - respond_with(@schedule) end + + respond_with(@schedule) end private @@ -69,7 +66,8 @@ module Admin [:index] end - # In this controller, params like params[:name] are moved into params[:schedule] becoming params[:schedule][:name] + # In this controller, params like params[:name] are moved into + # params[:schedule] becoming params[:schedule][:name]. # For some reason in rails 4, this is not happening for params[:order_cycle_ids] # We do it manually in this filter def adapt_params diff --git a/app/controllers/api/enterprise_attachment_controller.rb b/app/controllers/api/enterprise_attachment_controller.rb index 645a5c092c..3f5f61e5dd 100644 --- a/app/controllers/api/enterprise_attachment_controller.rb +++ b/app/controllers/api/enterprise_attachment_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'api/admin/enterprise_serializer' module Api diff --git a/app/controllers/spree/admin/countries_controller.rb b/app/controllers/spree/admin/countries_controller.rb index 9dc2cc00a3..dedd9fbdb4 100644 --- a/app/controllers/spree/admin/countries_controller.rb +++ b/app/controllers/spree/admin/countries_controller.rb @@ -1,7 +1,6 @@ module Spree module Admin class CountriesController < ResourceController - protected def permitted_resource_params diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb index fe727ac77e..a6099cf021 100644 --- a/app/controllers/spree/admin/products_controller.rb +++ b/app/controllers/spree/admin/products_controller.rb @@ -159,7 +159,7 @@ module Spree private - def product_set_from_params(params) + def product_set_from_params(_params) collection_hash = Hash[products_params.each_with_index.map { |p, i| [i, p] }] Spree::ProductSet.new(collection_attributes: collection_hash) end diff --git a/app/controllers/spree/admin/shipping_categories_controller.rb b/app/controllers/spree/admin/shipping_categories_controller.rb index 91f476e12f..36c6e27db7 100644 --- a/app/controllers/spree/admin/shipping_categories_controller.rb +++ b/app/controllers/spree/admin/shipping_categories_controller.rb @@ -1,7 +1,6 @@ module Spree module Admin class ShippingCategoriesController < ResourceController - protected def permitted_resource_params diff --git a/app/models/product_import/entry_processor.rb b/app/models/product_import/entry_processor.rb index ec092a27bb..5d705bd4bb 100644 --- a/app/models/product_import/entry_processor.rb +++ b/app/models/product_import/entry_processor.rb @@ -160,7 +160,9 @@ module ProductImport end product = Spree::Product.new - product.assign_attributes(entry.assignable_attributes.except('id', 'on_hand', 'on_demand', 'display_name')) + product.assign_attributes( + entry.assignable_attributes.except('id', 'on_hand', 'on_demand', 'display_name') + ) product.supplier_id = entry.producer_id if product.save diff --git a/app/models/product_import/entry_validator.rb b/app/models/product_import/entry_validator.rb index 0dbbac1468..fa2380c07b 100644 --- a/app/models/product_import/entry_validator.rb +++ b/app/models/product_import/entry_validator.rb @@ -299,7 +299,9 @@ module ProductImport def mark_as_new_product(entry) new_product = Spree::Product.new - new_product.assign_attributes(entry.assignable_attributes.except('id', 'on_hand', 'on_demand', 'display_name')) + new_product.assign_attributes( + entry.assignable_attributes.except('id', 'on_hand', 'on_demand', 'display_name') + ) new_product.supplier_id = entry.producer_id entry.on_hand = 0 if entry.on_hand.nil? diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index ecb91ffcea..ece704bdd1 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -12,7 +12,6 @@ module Spree belongs_to :tax_rate, -> { where spree_adjustments: { originator_type: 'Spree::TaxRate' } }, foreign_key: 'originator_id' - scope :enterprise_fee, -> { where(originator_type: 'EnterpriseFee') } scope :admin, -> { where(source_type: nil, originator_type: nil) } scope :included_tax, -> { diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 758cd2f89d..5d22c0fbc4 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -75,11 +75,12 @@ Spree::LineItem.class_eval do where('spree_adjustments.id IS NULL') } - # Overridden so that LineItems always have access to soft-deleted Variant attributes - # In some situations, unscoped super will be nil, in these cases we fetch the variant using the variant_id - # See isssue #4946 for more details + # Overridden so that LineItems always have access to soft-deleted Variant + # attributes. In some situations, unscoped super will be nil, in these cases + # we fetch the variant using the variant_id. See isssue #4946 for more + # details def variant - Spree::Variant.unscoped { super } || Spree::Variant.unscoped.find(self.variant_id) + Spree::Variant.unscoped { super } || Spree::Variant.unscoped.find(variant_id) end def cap_quantity_at_stock! diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index deecbc34e9..82609dccbc 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -36,7 +36,8 @@ Spree::Order.class_eval do callback.raw_filter.attributes.delete :email end end - validates :email, presence: true, format: /\A([\w\.%\+\-']+)@([\w\-]+\.)+([\w]{2,})\z/i, if: :require_email + validates :email, presence: true, format: /\A([\w\.%\+\-']+)@([\w\-]+\.)+([\w]{2,})\z/i, + if: :require_email before_validation :associate_customer, unless: :customer_id? before_validation :ensure_customer, unless: :customer_is_valid? diff --git a/app/models/spree/order_updater_decorator.rb b/app/models/spree/order_updater_decorator.rb index 029e39c74a..b227444c8b 100644 --- a/app/models/spree/order_updater_decorator.rb +++ b/app/models/spree/order_updater_decorator.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + Spree::OrderUpdater.class_eval do # Override spree method to make it update all adjustments as in Spree v2.0.4 def update_shipping_adjustments - order.adjustments.reload.each { |adjustment| adjustment.update! } + order.adjustments.reload.each(&:update!) end end diff --git a/app/models/spree/payment_decorator.rb b/app/models/spree/payment_decorator.rb index 69f4170f19..ec84a83a83 100644 --- a/app/models/spree/payment_decorator.rb +++ b/app/models/spree/payment_decorator.rb @@ -15,9 +15,7 @@ module Spree # We bypass this after_rollback callback that is setup in Spree::Payment # The issues the callback fixes are not experienced in OFN: # if a payment fails on checkout the state "failed" is persisted correctly - def persist_invalid - return - end + def persist_invalid; end def ensure_correct_adjustment revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state) @@ -64,12 +62,12 @@ module Spree record_response(response) if response.success? - self.class.create({ order: order, - source: self, - payment_method: payment_method, - amount: refund_amount.abs * -1, - response_code: response.authorization, - state: 'completed' }) + self.class.create(order: order, + source: self, + payment_method: payment_method, + amount: refund_amount.abs * -1, + response_code: response.authorization, + state: 'completed') else gateway_error(response) end diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index 80b3adc8b8..3df57a9cf8 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -10,7 +10,6 @@ module Spree before_validation :set_login before_destroy :check_completed_orders - users_table_name = User.table_name roles_table_name = Role.table_name scope :admin, lambda { includes(:spree_roles).where("#{roles_table_name}.name" => "admin") } diff --git a/app/services/permitted_attributes/checkout.rb b/app/services/permitted_attributes/checkout.rb index c5bda0739a..da698a02e5 100644 --- a/app/services/permitted_attributes/checkout.rb +++ b/app/services/permitted_attributes/checkout.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module PermittedAttributes class Checkout def initialize(params) diff --git a/app/services/permitted_attributes/order_cycle.rb b/app/services/permitted_attributes/order_cycle.rb index df15b47d58..6da6175a51 100644 --- a/app/services/permitted_attributes/order_cycle.rb +++ b/app/services/permitted_attributes/order_cycle.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module PermittedAttributes class OrderCycle def initialize(params) @@ -22,9 +24,10 @@ module PermittedAttributes :id, :sender_id, :receiver_id, :enterprise_id, :incoming, :active, :select_all_variants, :receival_instructions, :pickup_time, :pickup_instructions, - :tag_list, :tags => [:text], - :enterprise_fee_ids => [], - :variants => permitted_variant_ids + :tag_list, + tags: [:text], + enterprise_fee_ids: [], + variants: permitted_variant_ids ] end diff --git a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb index 304eae01ef..8af99f27f5 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -24,22 +24,28 @@ module OrderManagement create(:simple_order_cycle, orders_open_at: now - 1.minute, orders_close_at: now) } let(:open_oc_closes_before_begins_at_oc) { # Open, but closes before begins at - create(:simple_order_cycle, orders_open_at: now - 1.minute, orders_close_at: now + 59.seconds) + create(:simple_order_cycle, + orders_open_at: now - 1.minute, orders_close_at: now + 59.seconds) } let(:open_oc) { # Open & closes between begins at and ends at - create(:simple_order_cycle, orders_open_at: now - 1.minute, orders_close_at: now + 90.seconds) + create(:simple_order_cycle, + orders_open_at: now - 1.minute, orders_close_at: now + 90.seconds) } let(:upcoming_closes_before_begins_at_oc) { # Upcoming, but closes before begins at - create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 59.seconds) + create(:simple_order_cycle, + orders_open_at: now + 30.seconds, orders_close_at: now + 59.seconds) } let(:upcoming_closes_on_begins_at_oc) { # Upcoming & closes on begins at - create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 1.minute) + create(:simple_order_cycle, + orders_open_at: now + 30.seconds, orders_close_at: now + 1.minute) } let(:upcoming_closes_on_ends_at_oc) { # Upcoming & closes on ends at - create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 2.minutes) + create(:simple_order_cycle, + orders_open_at: now + 30.seconds, orders_close_at: now + 2.minutes) } let(:upcoming_closes_after_ends_at_oc) { # Upcoming & closes after ends at - create(:simple_order_cycle, orders_open_at: now + 30.seconds, orders_close_at: now + 121.seconds) + create(:simple_order_cycle, + orders_open_at: now + 30.seconds, orders_close_at: now + 121.seconds) } let(:subscription) { diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index 63af289913..f42fd427a9 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -142,7 +142,7 @@ module OpenFoodNetwork def find_exchange(sender_id, receiver_id, incoming) @order_cycle.exchanges. - find_by(sender_id:sender_id, receiver_id: receiver_id, incoming: incoming) + find_by(sender_id: sender_id, receiver_id: receiver_id, incoming: incoming) end def incoming_exchange_variant_ids(attrs) diff --git a/lib/open_food_network/permalink_generator.rb b/lib/open_food_network/permalink_generator.rb index eeee1bf18f..c86e6972de 100644 --- a/lib/open_food_network/permalink_generator.rb +++ b/lib/open_food_network/permalink_generator.rb @@ -41,6 +41,6 @@ module PermalinkGenerator self.class.with_deleted else self.class.where(nil) -end + end end end diff --git a/lib/open_food_network/variant_and_line_item_naming.rb b/lib/open_food_network/variant_and_line_item_naming.rb index fca7f25d0d..7eed59b892 100644 --- a/lib/open_food_network/variant_and_line_item_naming.rb +++ b/lib/open_food_network/variant_and_line_item_naming.rb @@ -59,7 +59,8 @@ module OpenFoodNetwork option_type = product.variant_unit_option_type if option_type name = option_value_name - ov = Spree::OptionValue.where(option_type_id: option_type, name: name, presentation: name).first || Spree::OptionValue.create!({ option_type: option_type, name: name, presentation: name }) + ov = Spree::OptionValue.where(option_type_id: option_type, name: name, presentation: name).first || + Spree::OptionValue.create!(option_type: option_type, name: name, presentation: name) option_values << ov end end From ea8c5d2711841c533f6886d54a2bf5ecf9db22bb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 15 Jun 2020 11:01:35 +0100 Subject: [PATCH 428/507] Comment out flaky spec --- spec/services/exchange_products_renderer_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/exchange_products_renderer_spec.rb b/spec/services/exchange_products_renderer_spec.rb index 3293d27709..9e93611f7c 100644 --- a/spec/services/exchange_products_renderer_spec.rb +++ b/spec/services/exchange_products_renderer_spec.rb @@ -36,7 +36,7 @@ describe ExchangeProductsRenderer do expect(variants.first.product.supplier.name).to eq exchange.variants.first.product.supplier.name end - describe "when OC is showing only the coordinators inventory" do + xdescribe "when OC is showing only the coordinators inventory" do let(:exchange_with_visible_variant) { order_cycle.exchanges.incoming.second } let(:exchange_with_hidden_variant) { order_cycle.exchanges.incoming.first } let!(:visible_inventory_item) { create(:inventory_item, enterprise: order_cycle.coordinator, variant: exchange_with_visible_variant.variants.first, visible: true) } From d5bdf306a96af40eb411c5ce30bf229eac0324b1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 15 Jun 2020 11:43:30 +0100 Subject: [PATCH 429/507] Comment out flaky variant overrides spec --- spec/features/admin/variant_overrides_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index fdf2572134..5f48c35fd2 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -207,7 +207,7 @@ feature " end.to change(VariantOverride, :count).by(0) end - it "displays an error when unauthorised to update a particular override" do + xit "displays an error when unauthorised to update a particular override" do fill_in "variant-overrides-#{variant_related.id}-price", with: '777.77' fill_in "variant-overrides-#{variant_related.id}-count_on_hand", with: '123' expect(page).to have_content "Changes to one override remain unsaved." From 2c794c148b076036dff73ea9ec0aeb3ce828482f Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 15 Jun 2020 14:14:53 +0100 Subject: [PATCH 430/507] Update spree rev --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ee01f6b3a6..09adfe5e7b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,7 +22,7 @@ GIT GIT remote: https://github.com/openfoodfoundation/spree.git - revision: f9264ebca0d8dd932a7dbee471514a3b85774c8f + revision: 0b0c422369c82b6dd7e7cb627a24e3a9fca19a6c branch: 2-1-0-stable specs: spree_core (2.1.0) @@ -39,8 +39,8 @@ GIT money (= 5.1.1) paperclip (~> 3.4.1) paranoia (~> 2.0) - rails (~> 4.0.0) - ransack (= 1.0.0) + rails (~> 4.0) + ransack (~> 1.0) state_machine (= 1.2.0) stringex (~> 1.5.1) truncate_html (= 0.9.2) From 0c97278d69e7ac72e8c1f2acc7336e9c291f2da2 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 15 Jun 2020 14:20:34 +0100 Subject: [PATCH 431/507] Upgrade ransack to 1.2.3 --- Gemfile | 2 +- Gemfile.lock | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index bf3570b803..ff3e8c8290 100644 --- a/Gemfile +++ b/Gemfile @@ -33,7 +33,7 @@ gem 'httparty', '~> 0.11' # For checking alerts. gem 'json', '>= 1.7.7' gem 'money', '5.1.1' gem 'paranoia', '~> 2.0' -gem 'ransack', '1.0.0' +gem 'ransack', '~> 1.2.3' gem 'state_machine', '1.2.0' gem 'stringex', '~> 1.5.1' diff --git a/Gemfile.lock b/Gemfile.lock index 09adfe5e7b..860b83f1c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -500,7 +500,7 @@ GEM paypal-sdk-merchant (1.106.1) paypal-sdk-core (~> 0.2.3) pg (0.21.0) - polyamorous (0.6.4) + polyamorous (1.0.0) activerecord (>= 3.0) power_assert (1.2.0) pry (0.12.2) @@ -540,10 +540,12 @@ GEM rainbow (3.0.0) raindrops (0.19.1) rake (13.0.1) - ransack (1.0.0) + ransack (1.2.3) actionpack (>= 3.0) activerecord (>= 3.0) - polyamorous (~> 0.6.0) + activesupport (>= 3.0) + i18n + polyamorous (~> 1.0.0) rb-fsevent (0.10.3) rb-inotify (0.10.1) ffi (~> 1.0) @@ -774,7 +776,7 @@ DEPENDENCIES rails (~> 4.0.13) rails-i18n (~> 4.0) rails_safe_tasks (~> 1.0) - ransack (= 1.0.0) + ransack (~> 1.2.3) redcarpet roadie-rails (~> 1.3.0) roo (~> 2.8.3) From dfdf57746af8c7303cb7e26943b03cf669f6abbb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2020 02:29:08 +0000 Subject: [PATCH 432/507] Bump coffee-rails from 4.0.1 to 4.2.2 Bumps [coffee-rails](https://github.com/rails/coffee-rails) from 4.0.1 to 4.2.2. - [Release notes](https://github.com/rails/coffee-rails/releases) - [Changelog](https://github.com/rails/coffee-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rails/coffee-rails/compare/v4.0.1...v4.2.2) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index bf3570b803..7c5957546f 100644 --- a/Gemfile +++ b/Gemfile @@ -108,7 +108,7 @@ gem 'whenever', require: false gem 'test-unit', '~> 3.3' -gem 'coffee-rails', '~> 4.0.0' +gem 'coffee-rails', '~> 4.2.2' gem 'compass-rails' gem 'mini_racer', '0.2.14' diff --git a/Gemfile.lock b/Gemfile.lock index ee01f6b3a6..9f0e10d82a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -170,9 +170,9 @@ GEM cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) coderay (1.1.2) - coffee-rails (4.0.1) + coffee-rails (4.2.2) coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.0) + railties (>= 4.0.0) coffee-script (2.4.1) coffee-script-source execjs @@ -713,7 +713,7 @@ DEPENDENCIES cancan (~> 1.6.10) capybara (>= 2.18.0) catalog! - coffee-rails (~> 4.0.0) + coffee-rails (~> 4.2.2) combine_pdf compass-rails custom_error_message! From cf214251fa46e24b392f65ada0a62a6b0b6a3ad3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 16 Jun 2020 12:59:58 +0200 Subject: [PATCH 433/507] Set flaky caching spec to pending --- spec/features/consumer/caching/darkwarm_caching_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/consumer/caching/darkwarm_caching_spec.rb b/spec/features/consumer/caching/darkwarm_caching_spec.rb index e53f63ed32..325d94ad08 100644 --- a/spec/features/consumer/caching/darkwarm_caching_spec.rb +++ b/spec/features/consumer/caching/darkwarm_caching_spec.rb @@ -29,7 +29,7 @@ feature "Darkswarm data caching", js: true, caching: true do visit shops_path end - it "invalidates caches for taxons and properties" do + xit "invalidates caches for taxons and properties" do visit shops_path taxon_timestamp1 = CacheService.latest_timestamp_by_class(Spree::Taxon) From c729f64fcff7152a425fa34944a6bf46758b0075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Sun, 24 May 2020 11:52:10 +0200 Subject: [PATCH 434/507] Include adjustments without positive taxes --- app/models/spree/order_decorator.rb | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 82609dccbc..32ad471fae 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -313,12 +313,14 @@ Spree::Order.class_eval do end def tax_adjustments - adjustments.with_tax + - line_items.includes(:adjustments).map { |li| li.adjustments.with_tax }.flatten + adjustments + price_adjustments end def tax_adjustment_totals tax_adjustments.each_with_object({}) do |adjustment, hash| + # No need of dealing with a missing Tax Rate if no tax setup + next if adjustment.included_tax.zero? + tax_rates = TaxRateFinder.tax_rates_of(adjustment) tax_rates_hash = Hash[tax_rates.collect do |tax_rate| tax_amount = tax_rates.one? ? adjustment.included_tax : tax_rate.compute_tax(adjustment.amount) @@ -328,21 +330,6 @@ Spree::Order.class_eval do end end - def price_adjustments - adjustments = [] - - line_items.each { |line_item| adjustments.concat line_item.adjustments } - - adjustments - end - - def price_adjustment_totals - Hash[tax_adjustment_totals.map do |tax_rate, tax_amount| - [tax_rate.name, - Spree::Money.new(tax_amount, currency: currency)] - end] - end - def has_taxes_included !line_items.with_tax.empty? end From 9abe41f6cb61ba1a16d1f7d014e6e66646df367f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Tue, 9 Jun 2020 11:03:11 +0200 Subject: [PATCH 435/507] Use OrderTaxAdjustmentsFetcher service --- app/helpers/checkout_helper.rb | 2 +- app/models/spree/adjustment_decorator.rb | 2 +- app/models/spree/order_decorator.rb | 18 ----- app/services/order_tax_adjustments_fetcher.rb | 28 ++++++++ lib/open_food_network/sales_tax_report.rb | 5 +- spec/models/spree/order_spec.rb | 64 ----------------- .../order_tax_adjustments_fetcher_spec.rb | 69 +++++++++++++++++++ 7 files changed, 102 insertions(+), 86 deletions(-) create mode 100644 app/services/order_tax_adjustments_fetcher.rb create mode 100644 spec/services/order_tax_adjustments_fetcher_spec.rb diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb index 4e9ff57a58..28401f1d7a 100644 --- a/app/helpers/checkout_helper.rb +++ b/app/helpers/checkout_helper.rb @@ -44,7 +44,7 @@ module CheckoutHelper end def display_checkout_taxes_hash(order) - order.tax_adjustment_totals.each_with_object({}) do |(tax_rate, tax_amount), hash| + OrderTaxAdjustmentsFetcher.new(order).totals.each_with_object({}) do |(tax_rate, tax_amount), hash| hash[number_to_percentage(tax_rate.amount * 100, precision: 1)] = Spree::Money.new tax_amount, currency: order.currency end end diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index ece704bdd1..dbbaa6ae95 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -18,7 +18,7 @@ module Spree where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem') } - scope :with_tax, -> { where('spree_adjustments.included_tax > 0') } + scope :with_tax, -> { where('spree_adjustments.included_tax <> 0') } scope :without_tax, -> { where('spree_adjustments.included_tax = 0') } scope :payment_fee, -> { where(AdjustmentScopes::PAYMENT_FEE_SCOPE) } scope :shipping, -> { where(AdjustmentScopes::SHIPPING_SCOPE) } diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 32ad471fae..cc0126399e 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -312,24 +312,6 @@ Spree::Order.class_eval do (adjustments + price_adjustments).sum(&:included_tax) end - def tax_adjustments - adjustments + price_adjustments - end - - def tax_adjustment_totals - tax_adjustments.each_with_object({}) do |adjustment, hash| - # No need of dealing with a missing Tax Rate if no tax setup - next if adjustment.included_tax.zero? - - tax_rates = TaxRateFinder.tax_rates_of(adjustment) - tax_rates_hash = Hash[tax_rates.collect do |tax_rate| - tax_amount = tax_rates.one? ? adjustment.included_tax : tax_rate.compute_tax(adjustment.amount) - [tax_rate, tax_amount] - end] - hash.update(tax_rates_hash) { |_tax_rate, amount1, amount2| amount1 + amount2 } - end - end - def has_taxes_included !line_items.with_tax.empty? end diff --git a/app/services/order_tax_adjustments_fetcher.rb b/app/services/order_tax_adjustments_fetcher.rb new file mode 100644 index 0000000000..3a3420a8c7 --- /dev/null +++ b/app/services/order_tax_adjustments_fetcher.rb @@ -0,0 +1,28 @@ +# This class will be used to get Tax Adjustments related to an order, +# and proceed basic calcultation over them. + +class OrderTaxAdjustmentsFetcher + def initialize(order) + @order = order + end + + def totals + all.each_with_object({}) do |adjustment, hash| + tax_rates = TaxRateFinder.tax_rates_of(adjustment) + tax_rates_hash = Hash[tax_rates.collect do |tax_rate| + tax_amount = tax_rates.one? ? adjustment.included_tax : tax_rate.compute_tax(adjustment.amount) + [tax_rate, tax_amount] + end] + hash.update(tax_rates_hash) { |_tax_rate, amount1, amount2| amount1 + amount2 } + end + end + + private + + attr_reader :order + + def all + order.adjustments.with_tax + + order.line_items.includes(:adjustments).map { |li| li.adjustments.with_tax }.flatten + end +end \ No newline at end of file diff --git a/lib/open_food_network/sales_tax_report.rb b/lib/open_food_network/sales_tax_report.rb index 1281dd28a4..458b4523af 100644 --- a/lib/open_food_network/sales_tax_report.rb +++ b/lib/open_food_network/sales_tax_report.rb @@ -49,8 +49,9 @@ module OpenFoodNetwork when "tax_rates" orders.map do |order| [order.number, order.total - order.total_tax] + - relevant_rates.map { |rate| order.tax_adjustment_totals.fetch(rate, 0) } + - [order.total_tax, order.total] + relevant_rates.map { |rate| + OrderTaxAdjustmentsFetcher.new(order).totals.fetch(rate, 0) + } + [order.total_tax, order.total] end else orders.map do |order| diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 9e821cabd6..2151634bde 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -287,70 +287,6 @@ describe Spree::Order do end end - describe "getting a hash of all taxes" do - let(:zone) { create(:zone_with_member) } - let(:coordinator) { create(:distributor_enterprise, charges_sales_tax: true) } - - let(:tax_rate10) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.1, zone: zone) } - let(:tax_rate15) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.15, zone: zone) } - let(:tax_rate20) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.2, zone: zone) } - let(:tax_rate25) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.25, zone: zone) } - let(:tax_category10) { create(:tax_category, tax_rates: [tax_rate10]) } - let(:tax_category15) { create(:tax_category, tax_rates: [tax_rate15]) } - let(:tax_category20) { create(:tax_category, tax_rates: [tax_rate20]) } - let(:tax_category25) { create(:tax_category, tax_rates: [tax_rate25]) } - - let(:variant) { create(:variant, product: create(:product, tax_category: tax_category10)) } - let(:enterprise_fee) { create(:enterprise_fee, enterprise: coordinator, tax_category: tax_category20, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 48.0)) } - let(:additional_adjustment) { create(:adjustment, amount: 50.0, included_tax: tax_rate25.compute_tax(50.0)) } - - let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, coordinator_fees: [enterprise_fee], distributors: [coordinator], variants: [variant]) } - let(:line_item) { create(:line_item, variant: variant, price: 44.0) } - let(:order) do - create( - :order, - line_items: [line_item], - bill_address: create(:address), - order_cycle: order_cycle, - distributor: coordinator, - adjustments: [additional_adjustment] - ) - end - - before do - allow(Spree::Config).to receive(:shipment_inc_vat).and_return(true) - allow(Spree::Config).to receive(:shipping_tax_rate).and_return(tax_rate15.amount) - end - - let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 46.0)) } - let!(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order) } - - before do - order.create_tax_charge! - order.update_distribution_charge! - end - - it "returns a hash with all 3 taxes" do - expect(order.tax_adjustment_totals.size).to eq(4) - end - - it "contains tax on line_item" do - expect(order.tax_adjustment_totals[tax_rate10]).to eq(4.0) - end - - it "contains tax on shipping_fee" do - expect(order.tax_adjustment_totals[tax_rate15]).to eq(6.0) - end - - it "contains tax on enterprise_fee" do - expect(order.tax_adjustment_totals[tax_rate20]).to eq(8.0) - end - - it "contains tax on order adjustment" do - expect(order.tax_adjustment_totals[tax_rate25]).to eq(10.0) - end - end - describe "setting the distributor" do it "sets the distributor when no order cycle is set" do d = create(:distributor_enterprise) diff --git a/spec/services/order_tax_adjustments_fetcher_spec.rb b/spec/services/order_tax_adjustments_fetcher_spec.rb new file mode 100644 index 0000000000..e56e40d5af --- /dev/null +++ b/spec/services/order_tax_adjustments_fetcher_spec.rb @@ -0,0 +1,69 @@ +require "spec_helper" + +describe OrderTaxAdjustmentsFetcher do + describe "#totals" do + let(:zone) { create(:zone_with_member) } + let(:coordinator) { create(:distributor_enterprise, charges_sales_tax: true) } + + let(:tax_rate10) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.1, zone: zone) } + let(:tax_rate15) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.15, zone: zone) } + let(:tax_rate20) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.2, zone: zone) } + let(:tax_rate25) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.25, zone: zone) } + let(:tax_category10) { create(:tax_category, tax_rates: [tax_rate10]) } + let(:tax_category15) { create(:tax_category, tax_rates: [tax_rate15]) } + let(:tax_category20) { create(:tax_category, tax_rates: [tax_rate20]) } + let(:tax_category25) { create(:tax_category, tax_rates: [tax_rate25]) } + + let(:variant) { create(:variant, product: create(:product, tax_category: tax_category10)) } + let(:enterprise_fee) { create(:enterprise_fee, enterprise: coordinator, tax_category: tax_category20, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 48.0)) } + let(:additional_adjustment) { create(:adjustment, amount: 50.0, included_tax: tax_rate25.compute_tax(50.0)) } + + let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, coordinator_fees: [enterprise_fee], distributors: [coordinator], variants: [variant]) } + let(:line_item) { create(:line_item, variant: variant, price: 44.0) } + let(:order) do + create( + :order, + line_items: [line_item], + bill_address: create(:address), + order_cycle: order_cycle, + distributor: coordinator, + adjustments: [additional_adjustment] + ) + end + + before do + allow(Spree::Config).to receive(:shipment_inc_vat).and_return(true) + allow(Spree::Config).to receive(:shipping_tax_rate).and_return(tax_rate15.amount) + end + + let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 46.0)) } + let!(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order) } + + before do + order.create_tax_charge! + order.update_distribution_charge! + end + + subject { OrderTaxAdjustmentsFetcher.new(order).totals } + + it "returns a hash with all 3 taxes" do + expect(subject.size).to eq(4) + end + + it "contains tax on line_item" do + expect(subject[tax_rate10]).to eq(4.0) + end + + it "contains tax on shipping_fee" do + expect(subject[tax_rate15]).to eq(6.0) + end + + it "contains tax on enterprise_fee" do + expect(subject[tax_rate20]).to eq(8.0) + end + + it "contains tax on order adjustment" do + expect(subject[tax_rate25]).to eq(10.0) + end + end +end From b4952dcbfbd643832b59729d85675a250ffa3448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Tue, 9 Jun 2020 16:09:29 +0200 Subject: [PATCH 436/507] Cosmetics --- app/helpers/checkout_helper.rb | 7 +++-- app/services/order_tax_adjustments_fetcher.rb | 27 ++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb index 28401f1d7a..c87abd0afb 100644 --- a/app/helpers/checkout_helper.rb +++ b/app/helpers/checkout_helper.rb @@ -44,8 +44,11 @@ module CheckoutHelper end def display_checkout_taxes_hash(order) - OrderTaxAdjustmentsFetcher.new(order).totals.each_with_object({}) do |(tax_rate, tax_amount), hash| - hash[number_to_percentage(tax_rate.amount * 100, precision: 1)] = Spree::Money.new tax_amount, currency: order.currency + totals = OrderTaxAdjustmentsFetcher.new(order).totals + + totals.each_with_object({}) do |(tax_rate, tax_amount), hash| + hash[number_to_percentage(tax_rate.amount * 100, precision: 1)] = + Spree::Money.new tax_amount, currency: order.currency end end diff --git a/app/services/order_tax_adjustments_fetcher.rb b/app/services/order_tax_adjustments_fetcher.rb index 3a3420a8c7..8053d9e0ab 100644 --- a/app/services/order_tax_adjustments_fetcher.rb +++ b/app/services/order_tax_adjustments_fetcher.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This class will be used to get Tax Adjustments related to an order, # and proceed basic calcultation over them. @@ -8,11 +10,7 @@ class OrderTaxAdjustmentsFetcher def totals all.each_with_object({}) do |adjustment, hash| - tax_rates = TaxRateFinder.tax_rates_of(adjustment) - tax_rates_hash = Hash[tax_rates.collect do |tax_rate| - tax_amount = tax_rates.one? ? adjustment.included_tax : tax_rate.compute_tax(adjustment.amount) - [tax_rate, tax_amount] - end] + tax_rates_hash = tax_rates_hash(adjustment) hash.update(tax_rates_hash) { |_tax_rate, amount1, amount2| amount1 + amount2 } end end @@ -23,6 +21,21 @@ class OrderTaxAdjustmentsFetcher def all order.adjustments.with_tax + - order.line_items.includes(:adjustments).map { |li| li.adjustments.with_tax }.flatten + order.line_items.includes(:adjustments).map { |li| + li.adjustments.with_tax + }.flatten end -end \ No newline at end of file + + def tax_rates_hash(adjustment) + tax_rates = TaxRateFinder.tax_rates_of(adjustment) + + Hash[tax_rates.collect do |tax_rate| + tax_amount = if tax_rates.one? + adjustment.included_tax + else + tax_rate.compute_tax(adjustment.amount) + end + [tax_rate, tax_amount] + end] + end +end From 00c9dd7ece951260af878367d31d3bfc070cc8da Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 12 Jun 2020 13:01:24 +0200 Subject: [PATCH 437/507] Remove N+1 fetching order and li adjustments --- app/services/order_tax_adjustments_fetcher.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/services/order_tax_adjustments_fetcher.rb b/app/services/order_tax_adjustments_fetcher.rb index 8053d9e0ab..debce057b8 100644 --- a/app/services/order_tax_adjustments_fetcher.rb +++ b/app/services/order_tax_adjustments_fetcher.rb @@ -20,10 +20,15 @@ class OrderTaxAdjustmentsFetcher attr_reader :order def all - order.adjustments.with_tax + - order.line_items.includes(:adjustments).map { |li| - li.adjustments.with_tax - }.flatten + Spree::Adjustment + .with_tax + .where(adjustable_id: order.id, adjustable_type: 'Spree::Order') + .order('created_at ASC') + + + Spree::Adjustment + .with_tax + .where(adjustable_id: order.line_item_ids, adjustable_type: 'Spree::LineItem') + .order('created_at ASC') end def tax_rates_hash(adjustment) From ff4d7fbc45f9ef303cedff64fc0ca710e11a48e2 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 12 Jun 2020 13:23:12 +0200 Subject: [PATCH 438/507] Refactor with Arel to perform a single query --- app/services/order_tax_adjustments_fetcher.rb | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/services/order_tax_adjustments_fetcher.rb b/app/services/order_tax_adjustments_fetcher.rb index debce057b8..085119172c 100644 --- a/app/services/order_tax_adjustments_fetcher.rb +++ b/app/services/order_tax_adjustments_fetcher.rb @@ -22,13 +22,22 @@ class OrderTaxAdjustmentsFetcher def all Spree::Adjustment .with_tax - .where(adjustable_id: order.id, adjustable_type: 'Spree::Order') - .order('created_at ASC') + + .where(order_adjustments.or(line_item_adjustments)) + .order('created_at ASC') + end - Spree::Adjustment - .with_tax - .where(adjustable_id: order.line_item_ids, adjustable_type: 'Spree::LineItem') - .order('created_at ASC') + def order_adjustments + table[:adjustable_id].eq(order.id) + .and(table[:adjustable_type].eq('Spree::Order')) + end + + def line_item_adjustments + table[:adjustable_id].eq(order.line_item_ids.join(',')) + .and(table[:adjustable_type].eq('Spree::LineItem')) + end + + def table + @table ||= Spree::Adjustment.arel_table end def tax_rates_hash(adjustment) From 3f7fb0ecc2879b5659b9bcb334d914c46ea29b56 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 16 Jun 2020 13:56:39 +0100 Subject: [PATCH 439/507] Add missing permitted attributes to zones --- app/controllers/spree/admin/zones_controller.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/zones_controller.rb b/app/controllers/spree/admin/zones_controller.rb index 466729ed03..d8bef6a215 100644 --- a/app/controllers/spree/admin/zones_controller.rb +++ b/app/controllers/spree/admin/zones_controller.rb @@ -24,9 +24,14 @@ module Spree def permitted_resource_params params.require(:zone).permit( - :name, :description, :default_tax + :name, :description, :default_tax, :kind, + zone_members_attributes: [:id, :zoneable_id, :zoneable_type, :_destroy] ) end + + def location_after_save + edit_object_url(@zone) + end end end end From 774b75b64982062b2724a73d83343015773dd048 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 16 Jun 2020 14:06:01 +0100 Subject: [PATCH 440/507] Make zones spec faster by going directly to zone list page withouth repeating the navigation through Configuration menu --- .../admin/configuration/zones_spec.rb | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/spec/features/admin/configuration/zones_spec.rb b/spec/features/admin/configuration/zones_spec.rb index 498f910ddf..f3893c6ae8 100644 --- a/spec/features/admin/configuration/zones_spec.rb +++ b/spec/features/admin/configuration/zones_spec.rb @@ -3,38 +3,37 @@ require 'spec_helper' describe "Zones" do include AuthenticationWorkflow - before(:each) do + before do quick_login_as_admin Spree::Zone.delete_all + end + + scenario "list existing zones" do visit spree.admin_dashboard_path click_link "Configuration" + + create(:zone, name: "eastern", description: "zone is eastern") + create(:zone, name: "western", description: "cool san fran") + click_link "Zones" + + within_row(1) { expect(page).to have_content("eastern") } + within_row(2) { expect(page).to have_content("western") } + + click_link "zones_order_by_description_title" + + within_row(1) { expect(page).to have_content("western") } + within_row(2) { expect(page).to have_content("eastern") } end - context "show" do - it "should display existing zones" do - create(:zone, name: "eastern", description: "zone is eastern") - create(:zone, name: "western", description: "cool san fran") - click_link "Zones" + scenario "create a new zone" do + visit spree.admin_zones_path + click_link "admin_new_zone_link" + expect(page).to have_content("New Zone") - within_row(1) { expect(page).to have_content("eastern") } - within_row(2) { expect(page).to have_content("western") } + fill_in "zone_name", with: "japan" + fill_in "zone_description", with: "japanese time zone" + click_button "Create" - click_link "zones_order_by_description_title" - - within_row(1) { expect(page).to have_content("western") } - within_row(2) { expect(page).to have_content("eastern") } - end - end - - context "create" do - it "should allow an admin to create a new zone" do - click_link "Zones" - click_link "admin_new_zone_link" - expect(page).to have_content("New Zone") - fill_in "zone_name", with: "japan" - fill_in "zone_description", with: "japanese time zone" - click_button "Create" - expect(page).to have_content("successfully created!") - end + expect(page).to have_content("successfully created!") end end From 2fcafdcf4521c78bff04203a066f62a687aefaac Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 16 Jun 2020 15:13:54 +0100 Subject: [PATCH 441/507] Add spec to cover editing zones --- .../features/admin/configuration/zones_spec.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/features/admin/configuration/zones_spec.rb b/spec/features/admin/configuration/zones_spec.rb index f3893c6ae8..11b3f92649 100644 --- a/spec/features/admin/configuration/zones_spec.rb +++ b/spec/features/admin/configuration/zones_spec.rb @@ -36,4 +36,22 @@ describe "Zones" do expect(page).to have_content("successfully created!") end + + scenario "edit existing zone", js: true do + zone = create(:zone_with_member) + visit spree.edit_admin_zone_path(zone.id) + + expect(page).to have_checked_field "country_based" + + # Toggle to state based zone + choose "State Based" + + # click Add State + page.find("#nested-state").click + # select first state available + find('.select2').find(:xpath, 'option[2]').select_option + + click_button "Update" + expect(page).to have_content("successfully updated!") + end end From 6672cfdaf5a1a4c68341a747e60adbd100c9a5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Tue, 16 Jun 2020 16:13:56 +0200 Subject: [PATCH 442/507] Readd price_adustments after bad rebase --- app/models/spree/order_decorator.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index cc0126399e..a36d8e1312 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -312,6 +312,21 @@ Spree::Order.class_eval do (adjustments + price_adjustments).sum(&:included_tax) end + def price_adjustments + adjustments = [] + + line_items.each { |line_item| adjustments.concat line_item.adjustments } + + adjustments + end + + def price_adjustment_totals + Hash[tax_adjustment_totals.map do |tax_rate, tax_amount| + [tax_rate.name, + Spree::Money.new(tax_amount, currency: currency)] + end] + end + def has_taxes_included !line_items.with_tax.empty? end From c370ab04d7482eb1b7d489c34067ab61fa528f3e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 16 Jun 2020 17:01:58 +0200 Subject: [PATCH 443/507] Ensure images in /assets/images** are precompiled and moved correctly to /public/assets folder --- config/application.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/application.rb b/config/application.rb index 9f7e817999..d48b5d2b8b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -160,6 +160,7 @@ module Openfoodnetwork config.assets.precompile += ['mail/all.css'] config.assets.precompile += ['shared/*'] config.assets.precompile += ['qz/*'] + config.assets.precompile += ['*.jpg', '*.jpeg', '*.png', '*.gif' '*.svg'] config.active_support.escape_html_entities_in_json = true end From c07476e22c0050bfc5a8424cdef7ba77e4809fc2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 16 Jun 2020 17:48:07 +0200 Subject: [PATCH 444/507] Use new Rails 4 #image-url SCSS helper Paths should be relative. For example an image under `/app/assets/images/home/banner.jpg` should be: `image-url("home/banner.jpg")` --- app/assets/stylesheets/admin/welcome.css.scss | 2 +- .../stylesheets/darkswarm/_shop-navigation.css.scss | 4 ++-- .../stylesheets/darkswarm/_shop-taxon-flag.css.scss | 2 +- app/assets/stylesheets/darkswarm/footer.scss | 2 +- app/assets/stylesheets/darkswarm/home_panes.css.scss | 10 +++++----- app/assets/stylesheets/darkswarm/home_tagline.css.scss | 2 +- app/assets/stylesheets/darkswarm/mixins.scss | 8 ++++---- app/assets/stylesheets/darkswarm/page_alert.css.scss | 2 +- app/assets/stylesheets/darkswarm/shop_search.css.scss | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/assets/stylesheets/admin/welcome.css.scss b/app/assets/stylesheets/admin/welcome.css.scss index 77cd21e134..89f277db4d 100644 --- a/app/assets/stylesheets/admin/welcome.css.scss +++ b/app/assets/stylesheets/admin/welcome.css.scss @@ -7,7 +7,7 @@ @include fullbg; background-color: black; - background-image: url("/assets/home/tagline-bg.jpg"); + background-image: image-url("home/tagline-bg.jpg"); background-repeat: no-repeat; background-position: center center; margin-bottom: 2em; diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index a360c8f606..d3febdb28f 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -62,7 +62,7 @@ ordercycle { } select { - background-image: url('/assets/white-caret.svg'); + background-image: image-url('white-caret.svg'); background-size: 30px auto; background-position-x: 102%; } @@ -147,7 +147,7 @@ shop ordercycle { select { background-color: $white; - background-image: url('/assets/black-caret.svg'); + background-image: image-url('black-caret.svg'); color: $grey-500; font-style: italic; } diff --git a/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.scss b/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.scss index e1b0d8ccbe..b6b237215e 100644 --- a/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.scss @@ -4,7 +4,7 @@ products { product { .taxon-flag { - background: transparent url("/assets/flag.svg") top center no-repeat; + background: transparent image-url("flag.svg") top center no-repeat; background-size: 34px 39px; min-height: 40px; width: 34px; diff --git a/app/assets/stylesheets/darkswarm/footer.scss b/app/assets/stylesheets/darkswarm/footer.scss index 6a7f12dda6..9826970141 100644 --- a/app/assets/stylesheets/darkswarm/footer.scss +++ b/app/assets/stylesheets/darkswarm/footer.scss @@ -50,7 +50,7 @@ footer { width: 100%; border: 1px solid rgba($dark-grey, 0.35); - background-image: url("/assets/tile-wide.png"); + background-image: image-url("tile-wide.png"); background-position: center center; background-color: #bbb; padding: 12px 0 8px 0; diff --git a/app/assets/stylesheets/darkswarm/home_panes.css.scss b/app/assets/stylesheets/darkswarm/home_panes.css.scss index 60f881462d..20a8d82687 100644 --- a/app/assets/stylesheets/darkswarm/home_panes.css.scss +++ b/app/assets/stylesheets/darkswarm/home_panes.css.scss @@ -42,7 +42,7 @@ } #stats.pane { - background-image: url("/assets/home/background-blurred-oranges.jpg"); + background-image: image-url("home/background-blurred-oranges.jpg"); background-position: center center; background-color: $ofn-grey; @@ -94,7 +94,7 @@ } .home-icon-box { - background-image: url("/assets/ofn-o.png"); + background-image: image-url("ofn-o.png"); background-position: center center; background-repeat: no-repeat; background-size: auto 100%; @@ -121,15 +121,15 @@ background-size: auto 100%; &.search { - background-image: url("/assets/icon-mask-magnifier.png"); + background-image: image-url("icon-mask-magnifier.png"); } &.shop { - background-image: url("/assets/icon-mask-apple.png"); + background-image: image-url("icon-mask-apple.png"); } &.pick-up-delivery { - background-image: url("/assets/icon-mask-truck.png"); + background-image: image-url("icon-mask-truck.png"); } } } diff --git a/app/assets/stylesheets/darkswarm/home_tagline.css.scss b/app/assets/stylesheets/darkswarm/home_tagline.css.scss index ffe4204869..c6cc15c9e8 100644 --- a/app/assets/stylesheets/darkswarm/home_tagline.css.scss +++ b/app/assets/stylesheets/darkswarm/home_tagline.css.scss @@ -13,7 +13,7 @@ @include fullbg; background-color: $ofn-grey; - background-image: url("/assets/home/home.jpg"); + background-image: image-url("home/home.jpg"); position: fixed; left: 0; right: 0; diff --git a/app/assets/stylesheets/darkswarm/mixins.scss b/app/assets/stylesheets/darkswarm/mixins.scss index 2b38d89dea..41f90679fa 100644 --- a/app/assets/stylesheets/darkswarm/mixins.scss +++ b/app/assets/stylesheets/darkswarm/mixins.scss @@ -5,7 +5,7 @@ // Generic \\ @mixin tiledPane { - background-image: url("/assets/tile-wide.png"); + background-image: image-url("tile-wide.png"); background-color: $brand-colour; background-position: center center; @@ -236,7 +236,7 @@ @mixin producersbg { background-color: lighten($clr-turquoise, 68%); - background-image: url("/assets/producers.svg"); + background-image: image-url("producers.svg"); background-position: center 50px; background-repeat: no-repeat; background-size: 922px 763px; @@ -244,13 +244,13 @@ @mixin hubsbg { background-color: $brand-colour; - background-image: url("/assets/hubs-bg.jpg"); + background-image: image-url("hubs-bg.jpg"); background-position: center center; } @mixin groupsbg { background-color: lighten($clr-brick, 56%); - background-image: url("/assets/groups.svg"); + background-image: image-url("groups.svg"); background-position: center 50px; background-repeat: no-repeat; background-size: 922px 922px; diff --git a/app/assets/stylesheets/darkswarm/page_alert.css.scss b/app/assets/stylesheets/darkswarm/page_alert.css.scss index 4be82c8c2e..a9276ab56d 100644 --- a/app/assets/stylesheets/darkswarm/page_alert.css.scss +++ b/app/assets/stylesheets/darkswarm/page_alert.css.scss @@ -14,7 +14,7 @@ $page-alert-height: 55px; border-left: none; border-right: none; background-color: #bbb; - background-image: url("/assets/tile-wide.png"); + background-image: image-url("tile-wide.png"); background-position: center center; padding: 12px 0 8px 0; margin: 0; diff --git a/app/assets/stylesheets/darkswarm/shop_search.css.scss b/app/assets/stylesheets/darkswarm/shop_search.css.scss index cbe0bf6bd4..4b141cd021 100644 --- a/app/assets/stylesheets/darkswarm/shop_search.css.scss +++ b/app/assets/stylesheets/darkswarm/shop_search.css.scss @@ -32,7 +32,7 @@ padding: 0 2.25em 0 2.75em; width: 100%; min-width: 0; - background: $white url("/assets/icn-search-grey.png") 1em center no-repeat; + background: $white image-url("icn-search-grey.png") 1em center no-repeat; font-size: 1rem; // avoid zoom on iphone, see issue #4535 &::placeholder { From add38bf550d46385c4f7657fc25875fa84818274 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 16 Jun 2020 18:24:03 +0200 Subject: [PATCH 445/507] Use #image_path helper correctly Paths should be relative. For example an image under `/app/assets/images/home/banner.jpg` should be: `image_path("home/banner.jpg")` --- app/views/admin/customers/index.html.haml | 2 +- .../admin/enterprises/_enterprise_user_index.html.haml | 2 +- app/views/admin/enterprises/form/_primary_details.html.haml | 2 +- app/views/admin/order_cycles/_loading_flash.html.haml | 2 +- app/views/admin/subscriptions/_loading_flash.html.haml | 2 +- app/views/admin/variant_overrides/_loading_flash.html.haml | 2 +- app/views/groups/show.html.haml | 2 +- app/views/home/_tagline.html.haml | 2 +- app/views/layouts/registration.html.haml | 2 +- app/views/producers/_fat.html.haml | 2 +- app/views/registration/steps/_limit_reached.html.haml | 2 +- app/views/registration/steps/_logo.html.haml | 2 +- app/views/registration/steps/_promo.html.haml | 2 +- app/views/shared/_footer.html.haml | 2 +- app/views/shared/_ie_warning.html.haml | 6 +++--- app/views/shared/menu/_cart.html.haml | 2 +- app/views/shared/menu/_mobile_menu.html.haml | 2 +- app/views/shared/menu/_signed_in.html.haml | 2 +- app/views/shared/menu/_signed_out.html.haml | 2 +- app/views/shop/products/_form.html.haml | 2 +- app/views/shop/products/_searchbar.haml | 2 +- app/views/shops/_fat.html.haml | 2 +- app/views/shops/_hubs.html.haml | 2 +- app/views/spree/admin/orders/bulk_management.html.haml | 2 +- app/views/spree/admin/orders/index.html.haml | 4 ++-- app/views/spree/admin/products/index/_indicators.html.haml | 2 +- app/views/spree/admin/variants/_autocomplete.js.erb | 2 +- 27 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 477e609cde..abf39f47d5 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -35,7 +35,7 @@ .row{ 'ng-if' => 'shop_id && RequestMonitor.loading' } .sixteen.columns.alpha#loading - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %h1 =t :loading_customers diff --git a/app/views/admin/enterprises/_enterprise_user_index.html.haml b/app/views/admin/enterprises/_enterprise_user_index.html.haml index 0afa9317e9..eedfba8d34 100644 --- a/app/views/admin/enterprises/_enterprise_user_index.html.haml +++ b/app/views/admin/enterprises/_enterprise_user_index.html.haml @@ -9,7 +9,7 @@ %columns-dropdown{ action: "#{controller_name}_#{action_name}" } .row{ 'ng-if' => '!loaded' } .sixteen.columns.alpha#loading - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %h1= t('.loading_enterprises') .row{ :class => "sixteen columns alpha", 'ng-show' => 'loaded && filteredEnterprises.length == 0'} %h1#no_results= t('.no_enterprises_found') diff --git a/app/views/admin/enterprises/form/_primary_details.html.haml b/app/views/admin/enterprises/form/_primary_details.html.haml index 30c582f8e2..a6a09106b3 100644 --- a/app/views/admin/enterprises/form/_primary_details.html.haml +++ b/app/views/admin/enterprises/form/_primary_details.html.haml @@ -59,7 +59,7 @@ .six.columns = f.text_field :permalink, { 'ng-model' => "Enterprise.permalink", placeholder: "eg. your-shop-name", 'ng-model-options' => "{ updateOn: 'default blur', debounce: {'default': 300, 'blur': 0} }" } .two.columns.omega - %img.spinner{ src: "/assets/spinning-circles.svg", width: "30px", ng: { show: "checking" } } + %img.spinner{ src: image_path("spinning-circles.svg"), width: "30px", ng: { show: "checking" } } %span{ ng: { class: 'availability.toLowerCase()', hide: "checking" } } {{ availability }} %i{ ng: { class: "{'icon-ok-sign': availability == 'Available', 'icon-remove-sign': availability == 'Unavailable'}" } } diff --git a/app/views/admin/order_cycles/_loading_flash.html.haml b/app/views/admin/order_cycles/_loading_flash.html.haml index ef810e03d1..05aff6b748 100644 --- a/app/views/admin/order_cycles/_loading_flash.html.haml +++ b/app/views/admin/order_cycles/_loading_flash.html.haml @@ -1,5 +1,5 @@ %div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'RequestMonitor.loading' } } - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %h1{ ng: { hide: 'orderCycles.length > 0' } } =t('.loading_order_cycles') %h1{ ng: { show: 'orderCycles.length > 0' } } diff --git a/app/views/admin/subscriptions/_loading_flash.html.haml b/app/views/admin/subscriptions/_loading_flash.html.haml index 59f0cb4e1f..ab37f06a71 100644 --- a/app/views/admin/subscriptions/_loading_flash.html.haml +++ b/app/views/admin/subscriptions/_loading_flash.html.haml @@ -1,3 +1,3 @@ %div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'shop_id && RequestMonitor.loading' } } - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %h1= t('.loading') diff --git a/app/views/admin/variant_overrides/_loading_flash.html.haml b/app/views/admin/variant_overrides/_loading_flash.html.haml index 2baa04a473..d9b2bf46bc 100644 --- a/app/views/admin/variant_overrides/_loading_flash.html.haml +++ b/app/views/admin/variant_overrides/_loading_flash.html.haml @@ -1,3 +1,3 @@ %div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'hub_id && products.length == 0 && RequestMonitor.loading' } } - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %h1= t('.loading_inventory') diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 3d5af8f08e..4701791daa 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -22,7 +22,7 @@ - if @group.logo.present? %img.group-logo{"src" => @group.logo} - else - %img.group-logo{"src" => '/assets/noimage/group.png'} + %img.group-logo{"src" => image_path('noimage/group.png') } %h2.group-name= @group.name %p= @group.description diff --git a/app/views/home/_tagline.html.haml b/app/views/home/_tagline.html.haml index 7685455b3f..5afa5fe21d 100644 --- a/app/views/home/_tagline.html.haml +++ b/app/views/home/_tagline.html.haml @@ -3,7 +3,7 @@ .small-12.text-center.columns %h1 / TODO: Rohan - logo asset & width is content manageable: - %img{src: "/assets/logo-white-notext.png", title: Spree::Config.site_name} + %img{src: image_path("logo-white-notext.png"), title: Spree::Config.site_name} %br/ %a.button.transparent{href: "/shops"} = t :home_shop diff --git a/app/views/layouts/registration.html.haml b/app/views/layouts/registration.html.haml index 2902f6683e..ebbcd9fd17 100644 --- a/app/views/layouts/registration.html.haml +++ b/app/views/layouts/registration.html.haml @@ -13,7 +13,7 @@ = stylesheet_link_tag "darkswarm/all" = csrf_meta_tags - %body.off-canvas{"ng-app" => "Darkswarm", style: 'background-image: url("/assets/tile-wide.png")' } + %body.off-canvas{"ng-app" => "Darkswarm", style: "background-image: url(#{image_path('tile-wide.png')})" } / [if lte IE 8] = render partial: "shared/ie_warning" = javascript_include_tag "iehack" diff --git a/app/views/producers/_fat.html.haml b/app/views/producers/_fat.html.haml index 1526f4f198..9b4e3b68b6 100644 --- a/app/views/producers/_fat.html.haml +++ b/app/views/producers/_fat.html.haml @@ -1,7 +1,7 @@ .row.active_table_row{"ng-if" => "open()", "ng-click" => "toggle($event)", "ng-class" => "{'open' : open()}"} .columns.small-12.fat.text-center{"ng-show" => "open() && shopfront_loading"} %p - %img.spinner.text-center{ src: "/assets/spinning-circles.svg" } + %img.spinner.text-center{ src: image_path("spinning-circles.svg") } .columns.small-12.medium-7.large-7.fat{"ng-show" => "open() && !shopfront_loading"} / Will add in long description available once clean up HTML formatting producer.long_description diff --git a/app/views/registration/steps/_limit_reached.html.haml b/app/views/registration/steps/_limit_reached.html.haml index c8fa25a43c..ba49d0dac3 100644 --- a/app/views/registration/steps/_limit_reached.html.haml +++ b/app/views/registration/steps/_limit_reached.html.haml @@ -6,7 +6,7 @@ %h4= t(".message") .row .small-12.medium-3.large-2.columns.text-right.hide-for-small-only - %img{:src => "/assets/potatoes.png"} + %img{:src => image_path("potatoes.png") } .small-12.medium-9.large-10.columns %p = t(".text") diff --git a/app/views/registration/steps/_logo.html.haml b/app/views/registration/steps/_logo.html.haml index 677653b4bb..4082defaec 100644 --- a/app/views/registration/steps/_logo.html.haml +++ b/app/views/registration/steps/_logo.html.haml @@ -41,6 +41,6 @@ .message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } } = t(".logo_placeholder") .loading{ ng: { hide: "!imageUploader.isUploading" } } - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %br/ = t("registration.steps.images.uploading") diff --git a/app/views/registration/steps/_promo.html.haml b/app/views/registration/steps/_promo.html.haml index 91a8bc9a78..efe29f6994 100644 --- a/app/views/registration/steps/_promo.html.haml +++ b/app/views/registration/steps/_promo.html.haml @@ -39,6 +39,6 @@ .message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } } = t(".promo_image_placeholder") .loading{ ng: { hide: "!imageUploader.isUploading" } } - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %br/ = t("registration.steps.images.uploading") diff --git a/app/views/shared/_footer.html.haml b/app/views/shared/_footer.html.haml index e6374288a5..2ba6278bec 100644 --- a/app/views/shared/_footer.html.haml +++ b/app/views/shared/_footer.html.haml @@ -3,7 +3,7 @@ .row .small-12.columns.text-center .logo - %img{src: "/assets/logo-white-notext.png"} + %img{src: image_path("logo-white-notext.png") } .row .small-12.medium-8.medium-offset-2.columns.text-center .alert-box diff --git a/app/views/shared/_ie_warning.html.haml b/app/views/shared/_ie_warning.html.haml index 2239fa7450..87acc77b4c 100644 --- a/app/views/shared/_ie_warning.html.haml +++ b/app/views/shared/_ie_warning.html.haml @@ -10,17 +10,17 @@ .row .small-4.columns.browserbtn %a.browserlogo{href: "https://www.google.com/intl/en_au/chrome/browser/", target: "_blank"} - %img{src: "assets/browser-logos/chrome.png"} + %img{src: image_path("browser-logos/chrome.png") } %a{href: "https://www.google.com/intl/en_au/chrome/browser/", target: "_blank"} = t :ie_warning_chrome .small-4.columns.browserbtn %a.browserlogo{href: "http://www.mozilla.org/en-US/firefox/new/", target: "_blank"} - %img{src: "assets/browser-logos/firefox.png"} + %img{src: image_path("browser-logos/firefox.png") } %a{href: "http://www.mozilla.org/en-US/firefox/new/", target: "_blank"} = t :ie_warning_firefox .small-4.columns.browserbtn %a.browserlogo{href: "http://windows.microsoft.com/en-AU/internet-explorer/download-ie", target: "_blank"} - %img{src: "assets/browser-logos/internet-explorer.png"} + %img{src: image_path("browser-logos/internet-explorer.png") } %a{href: "http://windows.microsoft.com/en-AU/internet-explorer/download-ie", target: "_blank"} = t :ie_warning_ie .row.ie-msg diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index be7d5bf5fe..d6408dc634 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -3,7 +3,7 @@ %span = t '.cart' %span.count - %img{ src: "/assets/menu/icn-cart.svg" } + %img{ src: image_path("menu/icn-cart.svg") } %span {{ Cart.total_item_count() }} diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index c501d7b365..8ef5ef7b5d 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -14,7 +14,7 @@ %span = t '.cart' %span.count - %img{ src: "/assets/menu/icn-cart.svg" } + %img{ src: image_path("menu/icn-cart.svg") } %span {{ Cart.total_item_count() }} diff --git a/app/views/shared/menu/_signed_in.html.haml b/app/views/shared/menu/_signed_in.html.haml index 269178ffaa..dceb81075a 100644 --- a/app/views/shared/menu/_signed_in.html.haml +++ b/app/views/shared/menu/_signed_in.html.haml @@ -7,7 +7,7 @@ %li.user-menu.has-dropdown.not-click %a{href: "#", class: "top-bar--menu-item-with-icon"} - %img{ src: "/assets/menu/icn-profile.svg" } + %img{ src: image_path("menu/icn-profile.svg") } %span = t '.profile' diff --git a/app/views/shared/menu/_signed_out.html.haml b/app/views/shared/menu/_signed_out.html.haml index fdb827031f..3a886a20e0 100644 --- a/app/views/shared/menu/_signed_out.html.haml +++ b/app/views/shared/menu/_signed_out.html.haml @@ -1,5 +1,5 @@ %li#login-link %a{"auth" => "login"} - %img{ src: "/assets/menu/icn-login.svg" } + %img{ src: image_path("menu/icn-login.svg") } %span = t 'label_login' diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index c4e6ea6908..7d2718c2d5 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -21,7 +21,7 @@ = t :products_loading .row .small-12.columns.text-center - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } .hide-for-medium-down.large-2.columns %h5 diff --git a/app/views/shop/products/_searchbar.haml b/app/views/shop/products/_searchbar.haml index fa9fb962a4..f18d9b9382 100644 --- a/app/views/shop/products/_searchbar.haml +++ b/app/views/shop/products/_searchbar.haml @@ -8,7 +8,7 @@ "ng-debounce" => "200", "ofn-disable-enter" => true} %a.clear{type: 'button', ng: {show: 'query', click: 'clearQuery()'}, 'focus-search' => true} - %img{ src: "/assets/icn-close.png" } + = image_tag "icn-close.png" .hide-for-large-up %button{type: 'button', ng: {click: 'toggleFilterSidebar()'}} diff --git a/app/views/shops/_fat.html.haml b/app/views/shops/_fat.html.haml index da9c579454..56772bde40 100644 --- a/app/views/shops/_fat.html.haml +++ b/app/views/shops/_fat.html.haml @@ -1,7 +1,7 @@ .row.active_table_row{"ng-show" => "open()", "ng-click" => "toggle($event)", "ng-class" => "{'open' : open()}"} .columns.small-12.fat.text-center{"ng-show" => "open() && shopfront_loading"} %p - %img.spinner.text-center{ src: "/assets/spinning-circles.svg" } + %img.spinner.text-center{ src: image_path("spinning-circles.svg") } .columns.small-12.medium-6.large-5.fat{"ng-show" => "open() && !shopfront_loading"} %div{"ng-if" => "::hub.taxons"} diff --git a/app/views/shops/_hubs.html.haml b/app/views/shops/_hubs.html.haml index 6c05561da0..1d19839a03 100644 --- a/app/views/shops/_hubs.html.haml +++ b/app/views/shops/_hubs.html.haml @@ -26,7 +26,7 @@ %a{href: "", "ng-click" => "showDistanceMatches()"} = t :hubs_distance_filter, location: "{{ nameMatchesFiltered[0].name }}" .more-controls - %img.spinner.text-center{ng: {show: "closed_shops_loading"}, src: "/assets/spinning-circles.svg" } + %img.spinner.text-center{ng: {show: "closed_shops_loading"}, src: image_path("spinning-circles.svg") } %span{ng: {if: "!show_closed", cloak: true}} %a.button{href: "", ng: {click: "showClosedShops()"}} = t '.show_closed_shops' diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 4eb6a67aa0..1053235c67 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -102,7 +102,7 @@ %columns-dropdown{ action: "#{controller_name}_#{action_name}" } %div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' } - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %h1 = t("admin.orders.bulk_management.loading") diff --git a/app/views/spree/admin/orders/index.html.haml b/app/views/spree/admin/orders/index.html.haml index 596cd884c9..d2871fe540 100644 --- a/app/views/spree/admin/orders/index.html.haml +++ b/app/views/spree/admin/orders/index.html.haml @@ -81,7 +81,7 @@ %span{'ng-bind-html' => 'order.display_total'} %td.actions %div.row-loading-icons - %img.spinner{src: "/assets/spinning-circles.svg", ng: {show: 'rowStatus[order.id] == "loading"'} } + %img.spinner{src: image_path("spinning-circles.svg"), ng: {show: 'rowStatus[order.id] == "loading"'} } %i.success.icon-ok-sign{ng: {show: 'rowStatus[order.id] == "success"'} } %i.error.icon-remove-sign.with-tip{ng: {show: 'rowStatus[order.id] == "error"'}, 'ofn-with-tip' => t('.order_not_updated')} %a.icon_link.with-tip.icon-edit.no-text{'ng-href' => '{{order.edit_path}}', 'data-action' => 'edit', 'ofn-with-tip' => t('.edit')} @@ -93,7 +93,7 @@ .orders-loading{'ng-show' => 'RequestMonitor.loading'} .row .small-12.columns.fullwidth.text-center - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } .row .small-12.columns.fullwidth.text-center %span= t('.loading') diff --git a/app/views/spree/admin/products/index/_indicators.html.haml b/app/views/spree/admin/products/index/_indicators.html.haml index 4c39f9a5d9..930f4b4337 100644 --- a/app/views/spree/admin/products/index/_indicators.html.haml +++ b/app/views/spree/admin/products/index/_indicators.html.haml @@ -1,6 +1,6 @@ %div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' } %br - %img.spinner{ src: "/assets/spinning-circles.svg" } + %img.spinner{ src: image_path("spinning-circles.svg") } %h1= t('.title') %div.sixteen.columns.alpha{ 'ng-show' => '!RequestMonitor.loading && products.length == 0 && query.length==0' } diff --git a/app/views/spree/admin/variants/_autocomplete.js.erb b/app/views/spree/admin/variants/_autocomplete.js.erb index 5ef095925c..9e4c29a50a 100644 --- a/app/views/spree/admin/variants/_autocomplete.js.erb +++ b/app/views/spree/admin/variants/_autocomplete.js.erb @@ -4,7 +4,7 @@ {{#if variant.image }} {{ else }} - + {{/if}} From 640c9e6d2bfcf3db91cf85b21461ce86f26cc82e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 17 Jun 2020 12:36:42 +0200 Subject: [PATCH 446/507] Re-enable flaky spec --- spec/features/consumer/caching/darkwarm_caching_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/consumer/caching/darkwarm_caching_spec.rb b/spec/features/consumer/caching/darkwarm_caching_spec.rb index 325d94ad08..e53f63ed32 100644 --- a/spec/features/consumer/caching/darkwarm_caching_spec.rb +++ b/spec/features/consumer/caching/darkwarm_caching_spec.rb @@ -29,7 +29,7 @@ feature "Darkswarm data caching", js: true, caching: true do visit shops_path end - xit "invalidates caches for taxons and properties" do + it "invalidates caches for taxons and properties" do visit shops_path taxon_timestamp1 = CacheService.latest_timestamp_by_class(Spree::Taxon) From 86fe032cdb84caf86692b8c5b68e5ac54c7333e1 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 17 Jun 2020 12:37:20 +0200 Subject: [PATCH 447/507] Update calls to #update_attributes! (Rails 4 Rubocop violation) --- spec/features/consumer/caching/darkwarm_caching_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/consumer/caching/darkwarm_caching_spec.rb b/spec/features/consumer/caching/darkwarm_caching_spec.rb index e53f63ed32..361e14bc12 100644 --- a/spec/features/consumer/caching/darkwarm_caching_spec.rb +++ b/spec/features/consumer/caching/darkwarm_caching_spec.rb @@ -45,8 +45,8 @@ feature "Darkswarm data caching", js: true, caching: true do expect(page).to have_content property.presentation end - taxon.update_attributes!(name: "Changed Taxon") - property.update_attributes!(presentation: "Changed Property") + taxon.update!(name: "Changed Taxon") + property.update!(presentation: "Changed Property") # Clear timed shops cache so we can test uncached supplied properties clear_shops_cache From 64b5bde952395310e2885db2b518b5822a3bac6b Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 17 Jun 2020 12:47:08 +0200 Subject: [PATCH 448/507] Wait for page to actually load after `visit shops_path` --- spec/features/consumer/caching/darkwarm_caching_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/features/consumer/caching/darkwarm_caching_spec.rb b/spec/features/consumer/caching/darkwarm_caching_spec.rb index 361e14bc12..55f41aeee1 100644 --- a/spec/features/consumer/caching/darkwarm_caching_spec.rb +++ b/spec/features/consumer/caching/darkwarm_caching_spec.rb @@ -53,6 +53,9 @@ feature "Darkswarm data caching", js: true, caching: true do visit shops_path + # Wait for /shops page to load properly before checking for new timestamps + expect(page).to_not have_selector ".row.filter-row", visible: true + taxon_timestamp2 = CacheService.latest_timestamp_by_class(Spree::Taxon) expect_cached "views/#{CacheService::FragmentCaching.ams_all_taxons[0]}" From a9ed08148810964590fb7e6773dfdc0d363210ed Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 18 Jun 2020 17:01:02 +1000 Subject: [PATCH 449/507] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index ac67a6ee73..e1eaf0fd19 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -479,6 +479,7 @@ en_FR: line_number: "Line %{number}:" encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding" unexpected_error: "Product Import encountered an unexpected error whilst opening the file: %{error_message}" + malformed_csv: "Product Import encountered a malformed CSV: %{error_message}" index: notice: "Notice" beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support." From 0c634c566c93fb68341b723178c06bc38332a146 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 18 Jun 2020 17:08:17 +1000 Subject: [PATCH 450/507] Updating translations for config/locales/fr.yml --- config/locales/fr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index a3a4a3a478..1e2e368003 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -479,6 +479,7 @@ fr: line_number: "Ligne %{number} :" encoding_error: "Veuillez vérifier le paramètre de langue de votre code source et vous assurer qu'il est encodé en UTF-8" unexpected_error: "L'import de fichier produits à rencontré une erreur inconnue à l'ouverture du fichier : %{error_message}" + malformed_csv: "L'outil d'import a rencontré un fichier CSV avec le ou les problèmes suivants : %{error_message}" index: notice: "Notice" beta_notice: "Cette fonctionnalité est en mode bêta : il est possible que vous rencontriez des erreurs en l'utilisant. N'hésitez pas à contacter le support utilisateurs." From fba5f96968a9cc88e522e8949a8881885dd8ca3b Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 18 Jun 2020 17:33:09 +1000 Subject: [PATCH 451/507] Updating translations for config/locales/nb.yml --- config/locales/nb.yml | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/config/locales/nb.yml b/config/locales/nb.yml index f25465f87e..bf8f4cba79 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -23,6 +23,8 @@ nb: base: "Kredittkort" order_cycle: orders_close_at: Lukkedato + variant_override: + count_on_hand: "Tilgjengelig" errors: models: spree/user: @@ -368,7 +370,10 @@ nb: title: "Matomo Innstillinger" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo er en web- og mobilanalyseapplikasjon. Du kan enten sette opp en egen server for Matomo eller bruke en skybasert tjeneste. Se matomo.org for mer informasjon." config_instructions_html: "Her kan du konfigurere OFN-Matomo integrasjonen. URL til Matomo nedenfor skal peke på Matomo-instansen der brukersporingsinformasjonen skal sendes til; Hvis den er tom, blir Matomo-brukersporing deaktivert. Site-ID feltet er ikke obligatorisk, men nyttig hvis du sporer mer enn ett nettsted på en enkelt Matomo-instans; den kan bli funnet på Matomo-konsollen." + config_instructions_tag_manager_html: "Å sette Matomo Tag Manager URL muliggjør Matomo Tag Manager. Dette verktøyet lar deg konfigurere analysehendelser. Matomo Tag Manager URL kopieres fra Installer kode-delen i Matomo Tag Manager. Forsikre deg om at du velger riktig beholder og miljø, da disse alternativene endrer nettadressen." customers: index: new_customer: "Ny kunde" @@ -474,6 +479,7 @@ nb: line_number: "Linje %{number}:" encoding_error: "Vennligst sjekk språkinnstillingen til kildefilen din og kontroller at den er lagret med UTF-8-koding" unexpected_error: "Produktimport støtte på en uventet feil ved åpning av filen: %{error_message}" + malformed_csv: "Produktimport fant feil i CSV: %{error_message}" index: notice: "Beskjed" beta_notice: "Denne funksjonen er fremdeles i beta: du kan oppleve noen feil mens du bruker den. Ikke nøl med å kontakte support." @@ -686,6 +692,7 @@ nb: ofn_uid_tip: Den unike ID-en som brukes til å identifisere bedriften på Open Food Network. shipping_methods: name: "Navn" + applies: "Aktiv?" manage: "Administrer Leveringsmetoder" create_button: "Opprett Ny Leveringsmetode" create_one_button: "Opprett en nå" @@ -864,6 +871,7 @@ nb: incoming: "Innkommende" supplier: "Leverandør" products: "Produkter" + receival_details: "Mottaksdetaljer" fees: "Avgifter" save: "Lagre" save_and_next: "Lagre og Neste" @@ -1173,7 +1181,11 @@ nb: signup: "melde deg på" contact: "kontakt" require_customer_login: "Kun godkjente kunder kan få tilgang til denne butikken." + require_login_html: "Hvis du allerede er en godkjent kunde kan du fortsette til %{login} eller %{signup}." + require_login_2_html: "Vil du begynne å handle her? Vennligst %{contact} %{enterprise} og spør om å bli med." require_customer_html: "Hvis du vil begynne å handle her, vennligst %{contact} %{enterprise} for å spørre om å bli med." + select_oc: + select_oc_html: "Vennligst velg når du vil ha bestillingen din , for å se hvilke produkter som er tilgjengelige." card_could_not_be_updated: Kortet kunne ikke oppdateres card_could_not_be_saved: kort kunne ikke lagres spree_gateway_error_flash_for_checkout: "Det oppstod et problem med betalingsinformasjonen din: %{error}" @@ -1533,12 +1545,17 @@ nb: orders_changeable_orders_alert_html: Denne bestillingen er bekreftet, men du kan gjøre endringer til %{oc_close}. products_clear: Fjern products_showing: "Viser:" + products_results_for: "Resultater for" products_or: "eller" products_and: "og" + products_filters_in: "i" products_with: med + products_search: "Søk..." products_filter_by: "Filtrer på" products_filter_selected: "valgt" + products_filter_heading: "Filtre" products_filter_clear: "Fjern" + products_filter_done: "Ferdig" products_loading: "Laster produkter..." products_updating_cart: "Oppdaterer handlekurv..." products_cart_empty: "Handlekurv tom" @@ -1549,6 +1566,8 @@ nb: products_update_error_msg: "Lagring mislyktes." products_update_error_data: "Lagring mislyktes på grunn av ugyldige data:" products_changes_saved: "Endringene er lagret." + products_no_results_html: "Beklager, ingen resultater for %{query}" + products_clear_search: "Tøm søk" search_no_results_html: "Beklager, ingen treff på %{query}. Prøv på nytt?" components_profiles_popover: "Profiler har ikke butikk på Open Food Network men kan ha sin egen fysiske butikk eller nettbutikk et annet sted" components_profiles_show: "Vis profiler" @@ -2310,6 +2329,10 @@ nb: resolve_errors: Vennligst løse følgende feil more_items: "+ %{count} Flere" default_card_updated: Standardkort oppdatert + cart: + add_to_cart_failed: > + Det oppsto et problem med å legge dette produktet til handlekurven. Kanskje + den har blitt utilgjengelig eller butikken stenger. admin: enterprise_limit_reached: "Du har nådd standardgrensen for bedrifter per konto. Skriv til %{contact_email} hvis du trenger å øke den." modals: @@ -2719,6 +2742,7 @@ nb: customer_details: "Kundedetaljer" adjustments: "Justeringer" payments: "Betalinger" + return_authorizations: "Returautorisasjoner" payment: "Betaling" payment_method: "Betalingsmetode" shipment: "Leveranse" @@ -2790,6 +2814,12 @@ nb: void: "Ugyldig" login: "Logg inn" password: "Passord" + signature: "Signatur" + solution: "Løsning" + landing_page: "Landingsside" + server: "Server" + test_mode: "Testmodus" + logourl: "Logourl" configurations: "Konfigurasjoner" general_settings: "Generelle innstillinger" site_name: "Sidenavn" @@ -2906,6 +2936,12 @@ nb: options: "Valg" actions: update: "Oppdater" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 feil forbød å lagre denne posten:" + other: "%{count} feil forbød at denne posten ble lagret:" + there_were_problems_with_the_following_fields: "Det var problemer med følgende felt" errors: messages: blank: "kan ikke være tomt" @@ -3048,6 +3084,8 @@ nb: zone: "Sone" calculator: "Kalkulator" display: "Visning" + both: "Både Utsjekk og Backoffice" + back_end: "Kun backoffice" no_shipping_methods_found: "Ingen leveringsmetoder funnet" new: new_shipping_method: "Ny Leveringsmetode" @@ -3059,6 +3097,9 @@ nb: form: categories: "Kategorier" zones: "Soner" + both: "Både Utsjekk og Backoffice" + back_end: "Kun backoffice" + deactivation_warning: "Ved å deaktivere en leveringsmetode kan den forsvinne fra listen din. Alternativt kan du skjule en leveringsmetode fra kassen ved å sette alternativet 'Vis' til 'Kun backoffice'." payment_methods: index: payment_methods: "Betalingsmetoder" @@ -3070,8 +3111,11 @@ nb: display: "Visning" active: "Aktiv" both: "Begge" + front_end: "Bare Kasse" + back_end: "Kun backoffice" active_yes: "Ja" active_no: "Nei" + no_payment_methods_found: "Fant ingen betalingsmetoder" new: new_payment_method: "Ny Betalingsmetode" back_to_payment_methods_list: "Tilbake til listen over betalingsmetoder" @@ -3100,7 +3144,11 @@ nb: active: "Aktiv" active_yes: "Ja" active_no: "Nei" + both: "Både Kasse og Backoffice" + front_end: "Kun Kasse" + back_end: "Kun backoffice" tags: "Merkelapper" + deactivation_warning: "Ved å deaktivere en betalingsmetode kan den forsvinne fra listen din. Alternativt kan du skjule en betalingsmetode fra kassen ved å sette alternativet "Vis" til "Kun Backoffice"." providers: provider: "Tilbyder" payments: @@ -3243,6 +3291,7 @@ nb: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "En vare i handlekurven din er blitt utilgjengelig. Oppdater valgte mengder." edit: login_to_view_order: "Vennligst logg inn for å se bestillingen din." bought: @@ -3270,6 +3319,14 @@ nb: invalid: ugyldig order_mailer: cancel_email: + customer_greeting: "Kjære %{name}," + instructions_html: "Bestillingen din med %{distributor} er AVBRUTT . Vennligst ta vare på denne avbestillingsinformasjonen til senere." + dont_cancel: "Hvis du har ombestemt deg eller ikke ønsker å kansellere denne bestillingen, kan du kontakte %{email}" + order_summary_canceled_html: "Sammendrag Bestilling # %{number} [AVBRUTT]" + details: "Her er detaljene om hva du bestilte:" + unpaid_order: "Bestillingen din var ubetalt, så ingen refusjon har blitt gjort" + paid_order: "Bestillingen din ble betalt, så %{distributor} har refundert hele beløpet" + credit_order: "Bestillingen din ble betalt så kontoen din er kreditert" subject: "Kansellering av bestilling" confirm_email: subject: "Ordrebekreftelse" From da7d36cd0ead7287c1957b0657fbc946171c7bc7 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 18 Jun 2020 17:41:48 +1000 Subject: [PATCH 452/507] Updating translations for config/locales/ca.yml --- config/locales/ca.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 61dfc3e907..55204a9c95 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -479,6 +479,7 @@ ca: line_number: "Línia %{number}:" encoding_error: "Comproveu la configuració de l'idioma del vostre fitxer d'origen i assegureu-vos que es desa amb la codificació UTF-8" unexpected_error: "La importació de productes ha detectat un error inesperat mentre obria el fitxer: %{error_message}" + malformed_csv: "La importació de producte ha trobat un CSV mal format: %{error_message}" index: notice: "Avís" beta_notice: "Aquesta funcionalitat continua en fase beta: podeu experimentar alguns errors mentre l'utilitzeu. No dubteu en contactar amb nosaltres." From b5a67e65c5699b35d0c51f4cae949d7727416c96 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 18 Jun 2020 17:42:06 +1000 Subject: [PATCH 453/507] Updating translations for config/locales/es.yml --- config/locales/es.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/es.yml b/config/locales/es.yml index 8f15a13da5..aef7d7c62b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -479,6 +479,7 @@ es: line_number: "Línea %{number}:" encoding_error: "Verifique la configuración de idioma de su archivo fuente y asegúrese de que esté guardado con la codificación UTF-8" unexpected_error: "La importación de productos encontró un error inesperado al abrir el archivo: %{error_message}" + malformed_csv: "La importación de producto encontró un CSV con formato incorrecto: %{error_message}" index: notice: "aviso" beta_notice: "Esta funcionalidad aún está en versión beta: puede experimentar algunos errores mientras la usa. Por favor no dude en ponerse en contacto con nosotros." From f6e3e01a109065fb73813c541d99fd6e70ed27f4 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 12 Jun 2020 17:17:34 +0100 Subject: [PATCH 454/507] Extract permitted payment_source attributes from checkout to use them in the backoffice payments controller Add spec to verify payment source attributes are passed --- .../spree/admin/payments_controller.rb | 6 +++++- app/services/permitted_attributes/checkout.rb | 15 ++------------- .../permitted_attributes/payment_source.rb | 14 ++++++++++++++ .../spree/admin/payments_controller_spec.rb | 18 +++++++++++++++++- 4 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 app/services/permitted_attributes/payment_source.rb diff --git a/app/controllers/spree/admin/payments_controller.rb b/app/controllers/spree/admin/payments_controller.rb index 676e148c6e..ae73760d8d 100644 --- a/app/controllers/spree/admin/payments_controller.rb +++ b/app/controllers/spree/admin/payments_controller.rb @@ -84,7 +84,11 @@ module Spree source_params = params.delete(:payment_source)[params[:payment][:payment_method_id]] params[:payment][:source_attributes] = source_params end - params.require(:payment).permit(:amount, :payment_method_id, :source_attributes) + + params.require(:payment).permit( + :amount, :payment_method_id, + source_attributes: ::PermittedAttributes::PaymentSource.attributes + ) end def load_data diff --git a/app/services/permitted_attributes/checkout.rb b/app/services/permitted_attributes/checkout.rb index da698a02e5..5eb9325f87 100644 --- a/app/services/permitted_attributes/checkout.rb +++ b/app/services/permitted_attributes/checkout.rb @@ -13,24 +13,13 @@ module PermittedAttributes :existing_card_id, :shipping_method_id, payments_attributes: [ :payment_method_id, - source_attributes: payment_source_attributes + source_attributes: PermittedAttributes::PaymentSource.attributes ], ship_address_attributes: PermittedAttributes::Address.attributes, bill_address_attributes: PermittedAttributes::Address.attributes ], - payment_source: payment_source_attributes + payment_source: PermittedAttributes::PaymentSource.attributes ) end - - private - - def payment_source_attributes - [ - :gateway_payment_profile_id, :cc_type, :last_digits, - :month, :year, :first_name, :last_name, - :number, :verification_value, - :save_requested_by_customer - ] - end end end diff --git a/app/services/permitted_attributes/payment_source.rb b/app/services/permitted_attributes/payment_source.rb new file mode 100644 index 0000000000..5ecfd2e3c7 --- /dev/null +++ b/app/services/permitted_attributes/payment_source.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module PermittedAttributes + class PaymentSource + def self.attributes + [ + :gateway_payment_profile_id, :cc_type, :last_digits, + :month, :year, :first_name, :last_name, + :number, :verification_value, + :save_requested_by_customer + ] + end + end +end diff --git a/spec/controllers/spree/admin/payments_controller_spec.rb b/spec/controllers/spree/admin/payments_controller_spec.rb index 53dd604ebd..aeb9156ef2 100644 --- a/spec/controllers/spree/admin/payments_controller_spec.rb +++ b/spec/controllers/spree/admin/payments_controller_spec.rb @@ -92,11 +92,27 @@ describe Spree::Admin::PaymentsController, type: :controller do context "where both payment.process! and payment.authorize! work" do before do allow_any_instance_of(Spree::Payment).to receive(:authorize!) do |payment| - payment.update_attribute :state, "pending" + payment.update state: "pending" end allow_any_instance_of(Spree::Payment).to receive(:process!).and_return(true) end + it "makes a payment with the provided card details" do + source_attributes = { + gateway_payment_profile_id: "pm_123", + cc_type: "visa", + last_digits: "4242", + month: "4", + year: "2100" + } + + spree_post :create, payment: params.merge({ source_attributes: source_attributes }), + order_id: order.number + + payment = order.reload.payments.last + expect(payment.source.attributes.transform_keys(&:to_sym)).to include source_attributes + end + it "redirects to list of payments with success flash" do spree_post :create, payment: params, order_id: order.number From 20c41ce69e04299a6bf821094de21f63f678dcc2 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 18 Jun 2020 19:11:23 +1000 Subject: [PATCH 455/507] Updating translations for config/locales/it.yml --- config/locales/it.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/config/locales/it.yml b/config/locales/it.yml index 13a6c49aeb..21a9a2a5c6 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -23,6 +23,8 @@ it: base: "Carta di Credito" order_cycle: orders_close_at: Data chiusura + variant_override: + count_on_hand: "Disponibile" errors: models: spree/user: @@ -180,7 +182,7 @@ it: explainer: L'elaborazione automatica di queste gentili richieste non è riuscita per una ragione sconosciuta. Questo non dovrebbe accadere, ti preghiamo di contattarci se visualizzi questo messaggio. home: "OFN" title: Open Food Network - welcome_to: 'Benvenuto su' + welcome_to: 'Benvenuto su ' site_meta_description: "Cominciamo da zero. Con i produttori e gli allevatori pronti a raccontare le loro storie, sinceramente e orgogliosamente. Con i distributori pronti a connettere le persone con i prodotti in modo giusto ed equo. Con i compratori che credono che migliori decisioni per l'acquisto settimanale possano..." search_by_name: Cerca per nome o zona... producers_join: I Produttori sono ora invitati ad unirsi ad Open Food Network @@ -368,7 +370,10 @@ it: title: "Impostazioni Matomo" matomo_url: "URL Matomo" matomo_site_id: "Site ID Matomo" + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo è una applicazione Analitica per Web e Mobile. Puoi ospitare Matomo in locale o utilizzare un servizio ospitato su cloud. Visita matomo.org per maggiori informazioni." config_instructions_html: "Qui è possibile configurare l'integrazione OFN Matomo. L'URL di Matomo qui sotto dovrebbe puntare l'istanza di Matomo a cui saranno inviate le informazioni di monitoraggio dell'utente; se lasciato vuoto, il monitoraggio dell'utente da parte di Matomo sarà disabilitato. Il campo Site ID non è obbligatorio ma è utile se si sta tracciando più di un sito web su una singola istanza di Matomo; si può trovare sulla console dell'istanza di Matomo. " + config_instructions_tag_manager_html: "La configurazione di Matomo Tag Manager URL abilita Matomo Tag Manager. Questo strumento consente di impostare eventi di analisi. Il Matomo Tag Manager URL è copiato dalla sezione Install Code di Matomo Tag Manager. Assicurati di selezionare il giusto container e l'ambiente perché queste opzioni modificano l'URL." customers: index: new_customer: "Nuovo Cliente" @@ -474,6 +479,7 @@ it: line_number: "Linea %{number}:" encoding_error: "Controlla l'impostazione della lingua del file sorgente e assicurati che sia salvato con la codifica UTF-8." unexpected_error: "L'importazione del prodotto ha incontrato un errore imprevisto durante l'apertura del file:%{error_message}" + malformed_csv: "L'Importazione Prodotti ha incontro un CSV non valido: %{error_message}" index: notice: "Avviso" beta_notice: "Questa opzione è ancora in fase beta: potresti incontrare errori mentre la usi. Per favore non esitare a contattare il servizio di supporto." @@ -1703,7 +1709,7 @@ it: remember_me: Ricordami are_you_sure: "Sei sicuro?" orders_open: Richieste aperte - closing: "In chiusura" + closing: "In chiusura " going_back_to_home_page: "Reindirizzamento alla homepage" creating: In creazione updating: In aggiornamento @@ -2741,6 +2747,7 @@ it: customer_details: "Dettagli Cliente" adjustments: "Regolazioni" payments: "Pagamenti" + return_authorizations: "Authorizationi reso" payment: "Pagamento" payment_method: "Metodo di pagamento" shipment: "Spedizione" @@ -2934,6 +2941,12 @@ it: options: "Opzioni" actions: update: "Aggiorna" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 errore ha proibito il salvataggio di questo record:" + other: "%{count} errori hanno proibito il salvataggio di questo record:" + there_were_problems_with_the_following_fields: "Si sono verificati problemi con i seguenti campi" errors: messages: blank: "non può essere lasciato vuoto" From 669330ee90c3626f5eed2770eb8e495d919b45d1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2020 02:34:29 +0000 Subject: [PATCH 456/507] Bump httparty from 0.17.3 to 0.18.1 Bumps [httparty](https://github.com/jnunemaker/httparty) from 0.17.3 to 0.18.1. - [Release notes](https://github.com/jnunemaker/httparty/releases) - [Changelog](https://github.com/jnunemaker/httparty/blob/master/Changelog.md) - [Commits](https://github.com/jnunemaker/httparty/compare/v0.17.3...v0.18.1) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 03db94f8a4..d82818b327 100644 --- a/Gemfile +++ b/Gemfile @@ -29,7 +29,7 @@ gem 'awesome_nested_set', '~> 3.0.0.rc.1' gem 'cancan', '~> 1.6.10' gem 'ffaker', '~> 1.16' gem 'highline', '= 1.6.18' # Necessary for the install generator -gem 'httparty', '~> 0.11' # For checking alerts. +gem 'httparty', '~> 0.18' # For checking alerts. gem 'json', '>= 1.7.7' gem 'money', '5.1.1' gem 'paranoia', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index ea173868b8..85817c7ee7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -417,7 +417,7 @@ GEM hashdiff (1.0.1) highline (1.6.18) hike (1.2.3) - httparty (0.17.3) + httparty (0.18.1) mime-types (~> 3.0) multi_xml (>= 0.5.2) i18n (0.6.11) @@ -452,9 +452,9 @@ GEM mail (2.7.1) mini_mime (>= 0.1.1) method_source (0.9.2) - mime-types (3.3) + mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2019.1009) + mime-types-data (3.2020.0512) mini_mime (1.0.2) mini_portile2 (2.4.0) mini_racer (0.2.14) @@ -743,7 +743,7 @@ DEPENDENCIES gmaps4rails haml highline (= 1.6.18) - httparty (~> 0.11) + httparty (~> 0.18) i18n (~> 0.6.11) i18n-js (~> 3.7.0) immigrant From 52dd7ce9167ed8d926e4b89517e6d582b9d48040 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 16 Jun 2020 13:03:54 +0100 Subject: [PATCH 457/507] Improve comment about httparty --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index d82818b327..bb7e2ca3fd 100644 --- a/Gemfile +++ b/Gemfile @@ -29,7 +29,7 @@ gem 'awesome_nested_set', '~> 3.0.0.rc.1' gem 'cancan', '~> 1.6.10' gem 'ffaker', '~> 1.16' gem 'highline', '= 1.6.18' # Necessary for the install generator -gem 'httparty', '~> 0.18' # For checking alerts. +gem 'httparty', '~> 0.18' # Used to check alerts in spree_core, this is not used in OFN. gem 'json', '>= 1.7.7' gem 'money', '5.1.1' gem 'paranoia', '~> 2.0' From 2143122a303e610cdce79d370a7bf4bbb7f20daf Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 18 Jun 2020 12:28:04 +0200 Subject: [PATCH 458/507] Add helper method for correctly generating with fingerprints in Serializers --- app/helpers/serializer_helper.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/helpers/serializer_helper.rb b/app/helpers/serializer_helper.rb index f30d998f73..091c93d145 100644 --- a/app/helpers/serializer_helper.rb +++ b/app/helpers/serializer_helper.rb @@ -13,4 +13,11 @@ module SerializerHelper (serializer_attributes & model_attributes).map { |attr| "#{model.table_name}.#{attr}" } end + + # Since Rails 4 has adjusted the way assets paths are handled, we have to access certain + # asset-based helpers like this, when outside of a view or controller context. + # See: https://stackoverflow.com/a/16609815 + def image_path(path) + ActionController::Base.helpers.image_path(path) + end end From 551daaadea62d1c98b2b20d4a30ebaa7f7d61a91 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 18 Jun 2020 13:53:58 +0200 Subject: [PATCH 459/507] Use #image_path correctly on map marker icons --- .../api/enterprise_shopfront_list_serializer.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/serializers/api/enterprise_shopfront_list_serializer.rb b/app/serializers/api/enterprise_shopfront_list_serializer.rb index dd83ce4323..eb82b96430 100644 --- a/app/serializers/api/enterprise_shopfront_list_serializer.rb +++ b/app/serializers/api/enterprise_shopfront_list_serializer.rb @@ -1,6 +1,8 @@ # Represents the minimum details of an Enterprise when all shopfronts are being listed module Api class EnterpriseShopfrontListSerializer < ActiveModel::Serializer + include SerializerHelper + attributes :name, :id, :latitude, :longitude, :is_primary_producer, :is_distributor, :path, :icon, :icon_font, :producer_icon_font, :address_id, :sells, :permalink @@ -13,13 +15,13 @@ module Api def icon icons = { - hub: "/assets/map_005-hub.svg", - hub_profile: "/assets/map_006-hub-profile.svg", - producer_hub: "/assets/map_005-hub.svg", - producer_shop: "/assets/map_003-producer-shop.svg", - producer: "/assets/map_001-producer-only.svg", + hub: "map_005-hub.svg", + hub_profile: "map_006-hub-profile.svg", + producer_hub: "map_005-hub.svg", + producer_shop: "map_003-producer-shop.svg", + producer: "map_001-producer-only.svg", } - icons[enterprise.category] + image_path icons[enterprise.category] end def icon_font From 9a39cbbbc5a70d0aaeca23d9bbb781dfc5dfc00b Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 18 Jun 2020 13:36:50 +0200 Subject: [PATCH 460/507] Convert MapConfiguration service to .js.erb.coffee --- ...ap_configuration.js.coffee => map_configuration.js.erb.coffee} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/assets/javascripts/darkswarm/services/{map_configuration.js.coffee => map_configuration.js.erb.coffee} (100%) diff --git a/app/assets/javascripts/darkswarm/services/map_configuration.js.coffee b/app/assets/javascripts/darkswarm/services/map_configuration.js.erb.coffee similarity index 100% rename from app/assets/javascripts/darkswarm/services/map_configuration.js.coffee rename to app/assets/javascripts/darkswarm/services/map_configuration.js.erb.coffee From 75e57e5c2c3859ae1592c538905f408cdf38b13d Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 18 Jun 2020 13:41:32 +0200 Subject: [PATCH 461/507] Call #image_path on map cluster icon --- .../darkswarm/services/map_configuration.js.erb.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/darkswarm/services/map_configuration.js.erb.coffee b/app/assets/javascripts/darkswarm/services/map_configuration.js.erb.coffee index 93e4104f0a..61598c414c 100644 --- a/app/assets/javascripts/darkswarm/services/map_configuration.js.erb.coffee +++ b/app/assets/javascripts/darkswarm/services/map_configuration.js.erb.coffee @@ -4,7 +4,7 @@ Darkswarm.factory "MapConfiguration", -> center: latitude: -37.4713077 longitude: 144.7851531 - cluster_icon: 'assets/map_009-cluster.svg' + cluster_icon: "<%= image_path('map_009-cluster.svg') %>" zoom: 12 additional_options: # mapTypeId: 'satellite' From 5338e782f827347986a89e9608cfa7715cf26aed Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 18 Jun 2020 16:42:58 +0200 Subject: [PATCH 462/507] Extract serializer helper method to service so the method isn't globally available --- app/helpers/serializer_helper.rb | 7 ------- .../api/enterprise_shopfront_list_serializer.rb | 4 +--- app/services/image_path_service.rb | 10 ++++++++++ 3 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 app/services/image_path_service.rb diff --git a/app/helpers/serializer_helper.rb b/app/helpers/serializer_helper.rb index 091c93d145..f30d998f73 100644 --- a/app/helpers/serializer_helper.rb +++ b/app/helpers/serializer_helper.rb @@ -13,11 +13,4 @@ module SerializerHelper (serializer_attributes & model_attributes).map { |attr| "#{model.table_name}.#{attr}" } end - - # Since Rails 4 has adjusted the way assets paths are handled, we have to access certain - # asset-based helpers like this, when outside of a view or controller context. - # See: https://stackoverflow.com/a/16609815 - def image_path(path) - ActionController::Base.helpers.image_path(path) - end end diff --git a/app/serializers/api/enterprise_shopfront_list_serializer.rb b/app/serializers/api/enterprise_shopfront_list_serializer.rb index eb82b96430..874e3516d5 100644 --- a/app/serializers/api/enterprise_shopfront_list_serializer.rb +++ b/app/serializers/api/enterprise_shopfront_list_serializer.rb @@ -1,8 +1,6 @@ # Represents the minimum details of an Enterprise when all shopfronts are being listed module Api class EnterpriseShopfrontListSerializer < ActiveModel::Serializer - include SerializerHelper - attributes :name, :id, :latitude, :longitude, :is_primary_producer, :is_distributor, :path, :icon, :icon_font, :producer_icon_font, :address_id, :sells, :permalink @@ -21,7 +19,7 @@ module Api producer_shop: "map_003-producer-shop.svg", producer: "map_001-producer-only.svg", } - image_path icons[enterprise.category] + ImagePathService.image_path(icons[enterprise.category]) end def icon_font diff --git a/app/services/image_path_service.rb b/app/services/image_path_service.rb new file mode 100644 index 0000000000..b7cf5815db --- /dev/null +++ b/app/services/image_path_service.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class ImagePathService + # Since Rails 4 has adjusted the way assets paths are handled, we have to access certain + # asset-based helpers like this when outside of a view or controller context. + # See: https://stackoverflow.com/a/16609815 + def self.image_path(path) + ActionController::Base.helpers.image_path(path) + end +end From 130f639b61db51ccf74ea205ae58ae80201d8f55 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 18 Jun 2020 17:14:50 +0200 Subject: [PATCH 463/507] Rename service and use #call --- app/serializers/api/enterprise_shopfront_list_serializer.rb | 2 +- .../{image_path_service.rb => image_path_generator.rb} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename app/services/{image_path_service.rb => image_path_generator.rb} (85%) diff --git a/app/serializers/api/enterprise_shopfront_list_serializer.rb b/app/serializers/api/enterprise_shopfront_list_serializer.rb index 874e3516d5..0dccfaa1c2 100644 --- a/app/serializers/api/enterprise_shopfront_list_serializer.rb +++ b/app/serializers/api/enterprise_shopfront_list_serializer.rb @@ -19,7 +19,7 @@ module Api producer_shop: "map_003-producer-shop.svg", producer: "map_001-producer-only.svg", } - ImagePathService.image_path(icons[enterprise.category]) + ImagePathGenerator.call(icons[enterprise.category]) end def icon_font diff --git a/app/services/image_path_service.rb b/app/services/image_path_generator.rb similarity index 85% rename from app/services/image_path_service.rb rename to app/services/image_path_generator.rb index b7cf5815db..48c9ee93d1 100644 --- a/app/services/image_path_service.rb +++ b/app/services/image_path_generator.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -class ImagePathService +class ImagePathGenerator # Since Rails 4 has adjusted the way assets paths are handled, we have to access certain # asset-based helpers like this when outside of a view or controller context. # See: https://stackoverflow.com/a/16609815 - def self.image_path(path) + def self.call(path) ActionController::Base.helpers.image_path(path) end end From 7290d6868735e317939cf543baf446a8ffe27fb1 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 18 Jun 2020 20:46:41 +0200 Subject: [PATCH 464/507] Update all locales with the latest Transifex translations --- config/locales/ar.yml | 3 + config/locales/de_DE.yml | 2 + config/locales/en_AU.yml | 3 + config/locales/en_BE.yml | 2 + config/locales/en_CA.yml | 1 + config/locales/en_DE.yml | 3 + config/locales/en_GB.yml | 3 + config/locales/en_IE.yml | 3 + config/locales/en_PH.yml | 3 + config/locales/en_US.yml | 3 + config/locales/en_ZA.yml | 2 + config/locales/es_CR.yml | 3 + config/locales/fil_PH.yml | 169 +++++++++++++++++++------------------- config/locales/fr_BE.yml | 13 +-- config/locales/it.yml | 20 ++--- config/locales/nl_BE.yml | 2 + config/locales/pt.yml | 2 + config/locales/pt_BR.yml | 3 + config/locales/sv.yml | 2 + config/locales/tr.yml | 65 ++++++++------- 20 files changed, 181 insertions(+), 126 deletions(-) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 278d54f8dd..9af7be11b0 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -23,6 +23,8 @@ ar: base: "بطاقة ائتمان" order_cycle: orders_close_at: تاريخ الاغلاق + variant_override: + count_on_hand: "متوفر" errors: models: spree/user: @@ -2683,6 +2685,7 @@ ar: customer_details: "تفاصيل العميل" adjustments: "التعديلات" payments: "المدفوعات" + return_authorizations: "عودة التراخيص" payment: "دفعة" payment_method: "طريقة الدفع او السداد" shipment: "الشحنة" diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index f15957eb07..94dd643337 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -23,6 +23,8 @@ de_DE: base: "Kreditkarte" order_cycle: orders_close_at: Schlussdatum + variant_override: + count_on_hand: "Verfügbar" errors: models: spree/user: diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index 85e74324b9..c940313002 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -23,6 +23,8 @@ en_AU: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: @@ -2634,6 +2636,7 @@ en_AU: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index ccefbc27d6..4b4d63ac8f 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -23,6 +23,8 @@ en_BE: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index fea11d0fe2..8af92b5472 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -2741,6 +2741,7 @@ en_CA: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authoriations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index 43f8f6dd44..3f65f77b11 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -23,6 +23,8 @@ en_DE: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: @@ -2601,6 +2603,7 @@ en_DE: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index 71358c855d..5d928e780f 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -23,6 +23,8 @@ en_GB: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "In Stock" errors: models: spree/user: @@ -2743,6 +2745,7 @@ en_GB: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorisations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" diff --git a/config/locales/en_IE.yml b/config/locales/en_IE.yml index 69bcb54e04..e9b243f1e0 100644 --- a/config/locales/en_IE.yml +++ b/config/locales/en_IE.yml @@ -23,6 +23,8 @@ en_IE: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "In Stock" errors: models: spree/user: @@ -2742,6 +2744,7 @@ en_IE: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorisations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index da4c883de1..2ca3436aa6 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -23,6 +23,8 @@ en_PH: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: @@ -2718,6 +2720,7 @@ en_PH: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index feb491c764..d21e17ed10 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -23,6 +23,8 @@ en_US: base: "Credit Card" order_cycle: orders_close_at: Close Date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: @@ -2711,6 +2713,7 @@ en_US: customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" shipment: "Shipment" diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 8017668827..b105c0fc11 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -23,6 +23,8 @@ en_ZA: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "In Stock" errors: models: spree/user: diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index 8dce3680ee..891c34c21b 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -23,6 +23,8 @@ es_CR: base: "Tarjeta de crédito" order_cycle: orders_close_at: Fecha de cierre + variant_override: + count_on_hand: "Disponibles" errors: models: spree/user: @@ -2726,6 +2728,7 @@ es_CR: customer_details: "Detalles del cliente" adjustments: "Ajustes" payments: "Pagos" + return_authorizations: "Autorizaciones de devolución" payment: "Pago" payment_method: "Método de pago" shipment: "Envío" diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index 0c7bf87148..6bf53bd65f 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -23,6 +23,8 @@ fil_PH: base: "Credit Card" order_cycle: orders_close_at: petsa ng pagsasara + variant_override: + count_on_hand: "on hand" errors: models: spree/user: @@ -521,9 +523,9 @@ fil_PH: validation_overview: pagtingin sa pagpapatunay ng paglipat entries_found: mga entry na nahanap sa inilipat na file entries_with_errors: ang mga item ay naglalaman ng error at hindi maililipat - products_to_create: ang mga produkto ay lilikhain + products_to_create: ang mga produkto ay gagawain products_to_update: ang mga produkto ay i-a-update - inventory_to_create: ang imbentaryo ng mga item ay lilikhain + inventory_to_create: ang imbentaryo ng mga item ay gagawain inventory_to_update: ang mga imbentaryong item ay i-a-update products_to_reset: ang mga produkto ay mari-reset ang stock sa zero inventory_to_reset: ang imbentaryo ng mga item ay mari-reset ang stock sa zero @@ -536,7 +538,7 @@ fil_PH: not_updatable: ang patlang na ito ay hindi maaaring ma-update sa pamamagitan ng maramihang paglipat ng mga produkto save_results: final_results: Ilipat ang pinakahuling mga resulta - products_created: ang mga produkto ay nalikha + products_created: ang mga produkto ay nagawa na products_updated: in-update ang mga produkto inventory_created: ang mga imbentaryo ng item ay nagawa na inventory_updated: inupdate ang mga inimbentaryong item @@ -636,7 +638,7 @@ fil_PH: fee_type: uri ng fee manage_fees: pamahalaan ang fees para sa enterprise no_fees_yet: wala ka pang kahit anong fees para sa enterprise - create_button: lumikha ng isa ngayon + create_button: gumawa ng isa ngayon images: logo: Logo promo_image_placeholder: 'ang larawan na ito ay makikita sa "tungkol sa amin"' @@ -659,8 +661,8 @@ fil_PH: applies: naaangkop? manage: pamahalaan ang mga paraan ng pagbabayad no_method_yet: wala ka pang kahit anong paraan ng pagbabayad. - create_button: lumikha ng bagong paraan ng pagbabayad - create_one_button: lumikha ng isa ngayon + create_button: gumawa ng bagong paraan ng pagbabayad + create_one_button: gumawa ng isa ngayon primary_details: name: pangalan name_placeholder: hal. Professor Plum's Biodynamic Truffles @@ -680,7 +682,7 @@ fil_PH: visible: nakikita not_visible: hindi nakikita permalink: Permalink (walang espasyo) - permalink_tip: "ang permalink na ito ay ginamit para lumikha ng url sa inyong shop: %{link}your-shop-name/shop" + permalink_tip: "ang permalink na ito ay ginamit para gumawa ng url sa inyong shop: %{link}your-shop-name/shop" link_to_front: Link sa shop front link_to_front_tip: direktang link sa inyong shopfront sa Open Food Network. ofn_uid: UID sa OFN @@ -688,8 +690,8 @@ fil_PH: shipping_methods: name: "pangalan" manage: "pamahalaan ang mga paraan ng pagpapadala" - create_button: "lumikha ng bagong paraan ng pagpapadala" - create_one_button: "lumikha ng isa ngayon" + create_button: "gumawa ng bagong paraan ng pagpapadala" + create_one_button: "gumawa ng isa ngayon" no_method_yet: "wala ka pang inilagay na paraan ng pagpapadala." shop_preferences: shopfront_requires_login: "nakikita sa publiko ang shopfront?" @@ -837,7 +839,7 @@ fil_PH: immediate_removal_warning: "ang promo na larawan ay tatanggalin agad pagkatapos mong magkumpirma." welcome: welcome_title: Welcome sa Open Food Network! - welcome_text: matagumpay mong nalikha ang + welcome_text: matagumpay mong nagawa ang next_step: sunod na hakbang choose_starting_point: 'pumili ng package:' profile: 'profile' @@ -850,7 +852,7 @@ fil_PH: loading_order_cycles: NILO-LOAD ANG MGA ORDER CYCLE loading: NILO-LOAD... new: - create: "lumikha" + create: "gumawa" cancel: "kanselahin" back_to_list: "bumalik sa listahan" edit: @@ -970,7 +972,7 @@ fil_PH: has_no_shipping_methods: "%{enterprise}ay walang paraan ng pagpapadala" has_no_enterprise_fees: "%{enterprise}ay walang fees para sa enterpise" enterprise_issues: - create_new: lumikha ng bago + create_new: gumawa ng bago resend_email: ipadala muli ang email has_no_payment_methods: "%{enterprise}ay kasalukuyang walang mga paraan ng pagbabayad" has_no_shipping_methods: "%{enterprise}ay kasalukuyang walang mga paraan ng pagpapadala" @@ -1029,7 +1031,7 @@ fil_PH: subscriptions: subscriptions: mga subscription new: bagong subscription - create: lumikha ng subscription + create: gumawa ng subscription edit: i-edit ang subscription table: edit_subscription: i-edit ang subscription @@ -1046,9 +1048,9 @@ fil_PH: set_up_shipping_and_payment_methods_html: iset-up ang paraan ng%{shipping_link}at%{payment_link} set_up_shipping_and_payment_methods_note_html: tandaan na Cash at Stripe na pamamaraan lamang ang maaaring
    gamitin sa mga subscription ensure_at_least_one_customer_html: siguraduhing mayroong kahit isang%{customer_link}na nakikita - create_at_least_one_schedule: lumikha ng kahit isang iskedyul + create_at_least_one_schedule: gumawa ng kahit isang iskedyul create_at_least_one_schedule_step_1_html: 1. pumunta sa %{order_cycles_link}pahina - create_at_least_one_schedule_step_2: 2. lumikha ng order cycle kung hindi pa ito nagagawa + create_at_least_one_schedule_step_2: 2. gumawa ng order cycle kung hindi pa ito nagagawa create_at_least_one_schedule_step_3: 3. pindutin ang '+ bagong iskedyul' at sagutan ang form once_you_are_done_you_can_html: kapag natapos na ito, maaari mong%{reload_this_page_link} reload_this_page: i-reload ang pahina na ito @@ -1098,7 +1100,7 @@ fil_PH: cancel_failure_msg: "paumanhin ngunit hindi naging matagumpay ang pagkansela!" confirm_pause_msg: "sigurado ka bang nais mong pansamantalang itigil ang subscription na ito?" pause_failure_msg: "paumanhin ngunit hindi matagumpay ang pansamantalang pagtigil" - confirm_unpause_msg: "kung ikaw ay may bukas na order cycle sa iskedyul ng subscription na ito, isang order ang lilikhain para sa customer. sigurado ka bang nais mong ipagpatuloy ang subscription?" + confirm_unpause_msg: "kung ikaw ay may bukas na order cycle sa iskedyul ng subscription na ito, isang order ang gagawin para sa customer. sigurado ka bang nais mong ipagpatuloy ang subscription?" unpause_failure_msg: "paumanhin ngunit hindi naging matagumpay ang pagpatuloy!" confirm_cancel_open_orders_msg: "ang ibang order sa subscription na ito ay kasalukuyang nakabukas. ang customer ay naabisuhang ang order ay magpapatuloy. nais mo bang kanselahin ang order(mga order) o ipagpatuloy ito?" resume_canceled_orders_msg: "ang ibang order sa subsciption na ito ay maaaring ituloy. maaari mo itong ituloy sa dropdown ng mga order." @@ -1421,7 +1423,7 @@ fil_PH: products_in: "sa%{oc}" products_at: "nasa%{distributor}" products_elsewhere: "ang mga produkto ay hindi dito natagpuan" - email_confirmed: "Salamat sa pagkumpirma ng inyong email address." + email_confirmed: "Maraming salamat sa pagkumpirma ng inyong email address." email_confirmation_activate_account: "Bago natin ma-activate ang inyong account, kailangan munang kumpirmahin ang iyong email address." email_confirmation_greeting: "magandang araw, %{contact}!" email_confirmation_profile_created: "ang profile para kay/sa %{name}ay matagumpay na nagawa! para i-activate ang inyong profile, kailangan naming kumpirmahin ang email address na ito." @@ -1434,9 +1436,9 @@ fil_PH: email_signoff: "Mabuhay," email_signature: "%{sitename} Team" email_confirm_customer_greeting: "Magandang araw%{name}," - email_confirm_customer_intro_html: "salamat sa pamimili sa%{distributor}!" + email_confirm_customer_intro_html: "Salamat sa pamimili sa%{distributor}!" email_confirm_customer_number_html: "kumpirmasyon ng order#%{number}" - email_confirm_customer_details_html: "narito ang mga detalye ng niyong order mula sa%{distributor}:" + email_confirm_customer_details_html: "narito ang mga detalye ng inyong order mula sa%{distributor}:" email_confirm_customer_signoff: "Lubos na gumagalang," email_confirm_shop_greeting: "Magandang araw%{name}," email_confirm_shop_order_html: "binabati kita! may bago kang order para sa%{distributor}!" @@ -1452,34 +1454,34 @@ fil_PH: email_payment_not_paid: HINDI PA BAYAD email_payment_summary: buod ng kabayaran email_payment_method: "magbabayad sa pamamagitan ng:" - email_so_placement_intro_html: "mayroon kang bagong order sa%{distributor}" - email_so_placement_details_html: "narito ang mga detalye ng iyong order para sa %{distributor}:" + email_so_placement_intro_html: "mayroon kang bagong order kasama ang%{distributor}" + email_so_placement_details_html: "narito ang mga detalye ng inyong order para sa %{distributor}:" email_so_placement_changes: "sa kasamaang palad, hindi lahat ng produkto na iyong isinama ay available. ang orihinal na dami ng mga isinamang produkto ay naka-ekis sa baba." email_so_payment_success_intro_html: "ang awtomatikong pagbabayad ay naproseso para sa iyong order mula sa%{distributor}." - email_so_placement_explainer_html: "ang order na ito ay awtomatikong binuo para sa iyo." + email_so_placement_explainer_html: "ang order na ito ay awtomatikong ginawa para sa iyo." email_so_edit_true_html: "maaari kang gumawa ng mga pagbabago hanggang magsara ang iyong mga order sa%{orders_close_at}." email_so_edit_false_html: "maari mong tignan ang mga detalye ng order na itokahit kailan." email_so_contact_distributor_html: "Kung ikaw ay may mga katanungan, maaring makipag-ugnayan sa%{distributor} sa%{email}." - email_so_contact_distributor_to_change_order_html: "Ang order na ito ay awtomatikong binuo para sa iyo. Maaari kang gumawa ng mga pagbabago hanggang magsara ang mga order sa%{orders_close_at} sa pamamagitan ng pakikipagugnayan sa%{distributor} sa%{email}." + email_so_contact_distributor_to_change_order_html: "Ang order na ito ay awtomatikong ginawa para sa iyo. Maaari kang gumawa ng mga pagbabago hanggang magsara ang mga order sa%{orders_close_at} sa pamamagitan ng pakikipag-ugnayan sa%{distributor} sa%{email}." email_so_confirmation_intro_html: "ang iyong order kasama ang%{distributor} ay kumpirmado na." email_so_confirmation_explainer_html: "ang order na ito ay awtomatikong na-place para sa iyo at ngayon ay pinalisa na." email_so_confirmation_details_html: "ang lahat ng kailangan mong malaman tungkol sa iyong order mula sa%{distributor} ay narito:" email_so_empty_intro_html: "sinubukan naming mag-place ng bagong order sa%{distributor}, ngunit nagkaroon ng ilang problema..." email_so_empty_explainer_html: "sa kasamaang palad, wala sa mga produkto na inyong inorder ay available sa ngayon kaya walang na-place na order. ang orihinal na dami na inyong inilagay ay naka-ekis sa ilalim." email_so_empty_details_html: "narito ang mga detalye ng hindi na-place na order para sa%{distributor}:" - email_so_failed_payment_intro_html: "sinubukan naming iproseso ang isang bayarin ngunit nagkaroon ng mga problema.." - email_so_failed_payment_explainer_html: "ang iyong bayad para sa subscription sa%{distributor} ay hindi nagpatuloy dahil sa problema sa inyong credit card.%{distributor} ay sinabihan ukol sa bayad na ito." - email_so_failed_payment_details_html: "ito ang mga detalye sa kung bakit hindi nagpatuloy ang bayad na ibinigay ng gateway para sa pagbabayad:" + email_so_failed_payment_intro_html: "sinubukan naming iproseso ang isang bayad ngunit nagkaroon ng ilang problema.." + email_so_failed_payment_explainer_html: "ang bayad para sa iyong subscription kasama ang%{distributor} ay hindi nagpatuloy dahil sa problema sa inyong credit card.%{distributor} ay inabisuhan na ukol sa naudlot na bayad na ito." + email_so_failed_payment_details_html: "ito ang mga detalye na ibinigay ng payment gateway kung bakit hindi nagpatuloy ang bayad :" email_shipping_delivery_details: detalye ng pag-deliver email_shipping_delivery_time: "pagdeliver sa :" email_shipping_delivery_address: "address ng pagdadalahan:" - email_shipping_collection_details: detalye ng pangongolekta + email_shipping_collection_details: mga detalye ng pangongolekta email_shipping_collection_time: "handa para sa koleksyon:" - email_shipping_collection_instructions: "tagubilin sa pangongolekta:" + email_shipping_collection_instructions: "panuto sa pangongolekta:" email_special_instructions: "ang iyong mga tala" email_signup_greeting: Magandang araw! email_signup_welcome: "Welcome sa%{sitename}!" - email_signup_confirmed_email: "salamat sa pagkumpirma ng iyong email." + email_signup_confirmed_email: "maraming salamat sa pagkumpirma ng iyong email." email_signup_shop_html: "maaari ka ng maglog-in sa%{link}." email_signup_text: "maraming salamat sa pagsali sa network na ito. kung ikaw ay isang customer, kami ay nagagalak na ipakilala kayo sa aming mga magsasaka, mga Hub at masasarap na pagkain! kung ikaw ang isang producer o enterprise ng pagkain, kami ay nasasabik na maging parte kayo ng aming network." email_signup_help_html: "para sa inyong mga katanungan at suhestiyon: maaaring gamitin ang Magpadala ng feedback na pindutan sa site o mag-email sa amin sa %{email}" @@ -1487,15 +1489,15 @@ fil_PH: greeting: "Magandang araw!" invited_to_manage: "ikaw ay naanyayahan para pamahalaan ang%{enterprise}sa%{instance}." confirm_your_email: "Maaaring natanggap mo na o matatanggap pa lamang ang email na may link ng kumpirmasyon. hindi mo mapupuntahan ang profile ng%{enterprise}hanggang hindi pa nakukumpirma ang inyong email." - set_a_password: "pagtapos ay dapat kang magset ng password bago mapamahalaan ang enterprise." + set_a_password: "pagkatapos ay dapat kang magset ng password bago mapamahalaan ang enterprise." mistakenly_sent: "Hindi sigurado kung bakit ka nakatanggap ang email na ito? Makipagugnayan sa%{owner_email} para sa karagdagang impormasyon." - producer_mail_greeting: "Minamahal" + producer_mail_greeting: "Minamahal naming" producer_mail_text_before: "ngayon nasa atin na ang lahat ng order ng mga mamimili para sa susunod na pag-drop ng order." producer_mail_order_text: "narito ang buod ng mga order para inyong mga produkto:" - producer_mail_delivery_instructions: "tagubilin sa Stock pickup/delivery:" + producer_mail_delivery_instructions: "panuto sa Stock pickup/delivery:" producer_mail_signoff: "Maraming salamat!" shopping_oc_closed: sarado na ang mga order - shopping_oc_closed_description: "maaaring maghintay sa susunod na pagbukas ng cycle( o makipaguganayan sa amin ng direkta upang malaman kung maaari pa kaming tumanggap ng huling mga order)" + shopping_oc_closed_description: "maghintay sa susunod na pagbukas ng cycle( o makipag-uganayan sa amin nang direkta upang malaman kung maaari pa kaming tumanggap ng huling mga order)" shopping_oc_last_closed: "ang huling cycle ay nagsara%{distance_of_time}ang lumipas" shopping_oc_next_open: "ang susunod na cycle ay magbubukas sa loob ng%{distance_of_time}" shopping_oc_select: "pumili..." @@ -1566,10 +1568,10 @@ fil_PH: groups_hubs: "ang aming mga hub" groups_contact_web: Makipag-ugnayan groups_contact_social: sumunod - groups_contact_address: tirahan + groups_contact_address: Address groups_contact_email: i-email kami groups_contact_website: bisitahin ang aming website - groups_contact_facebook: sundan kami sa Facebook + groups_contact_facebook: i-follow kami sa Facebook groups_signup_title: mag-sign up bilang grupo groups_signup_headline: Sign up ng grupo groups_signup_intro: "kami ay isang kamanghamanghang plataporma para sa nagtutulungang kalakalan, ang pinakamadaling paraan para sa inyong mga miyembro at namumuhunan na makakonekta sa mga bagong pamilihan. Kami ay hindi tumutubo, abot-kaya at simple lamang." @@ -1598,14 +1600,14 @@ fil_PH: producers_filter: i-filter gamit ang producers_filter_type: uri producers_filter_property: ari-arian - producers_title: Producers + producers_title: Mga Producer producers_headline: humanap ng lokal na mga producer producers_signup_title: magsign-up bilang producer - producers_signup_headline: Producer ng pagkain, mas pinalakas. - producers_signup_motivation: Ibenta ang inyong pagkain at magkipagugnayan sa mga iba't ibang pamilihan. makatipid ng oras at pera. Pagbabago ng walang kaakibat na peligro. ginawang patas para sa lahat ang kalakaran. + producers_signup_headline: mga Producer ng pagkain, mas pinalakas. + producers_signup_motivation: Ibenta ang inyong pagkain at magkipag-ugnayan sa iba't ibang mga pamilihan. makatipid ng oras at pera. Pagbabago ng walang kaakibat na peligro. ginawang patas para sa lahat ang kalakaran. producers_signup_send: sumali ngayon producers_signup_enterprise: mga account ng enterprise - producers_signup_studies: mga kwento mula sa ating mga producer + producers_signup_studies: mga kwento mula sa aming mga producer producers_signup_cta_headline: sumali ngayon! producers_signup_cta_action: sumali ngayon producers_signup_detail: 'ito ang mga detalye:' @@ -1621,14 +1623,14 @@ fil_PH: sell_title: "Magrehistro" sell_headline: "pumunta sa Open Food Network!" sell_motivation: "ipagmalaki ang iyong masasarap na pagkain!" - sell_producers: "Producers" - sell_hubs: "Hubs" + sell_producers: "Mga Producer" + sell_hubs: "mga Hub" sell_groups: "mga grupo" sell_producers_detail: "magset-up ng profile para sa inyong negosyo sa OFN sa loob lamang ng ilang minuto. maaari mong i-upgrade ang inyong profile upang maging online store at magbenta ng iyong mga produkto direkta sa mga customer." sell_hubs_detail: "magset-up ng profile para sa inyong Food enterprise o organisasyon sa OFN. maaari mong i-upgrade ang inyong profile upang maging multi-producer na shop kahit kailan mo naisin." sell_groups_detail: "magset-up ng directory ng mga enterprise (mga producer at iba pang enterprise ng pagkain) para sa iyong rehiyon o organisasyon." sell_user_guide: "marami pang maaring malaman sa aming Gabay sa Paggamit" - sell_listing_price: "ang pagpapalista sa OFN ay libre. ang pagbubukas at pagpapatakbo ng shop ay libre hanggang sa $500 na buwanang benta. kung makakabenta ka ng mas marami, maaari kang mamili ng kontribusyon sa komunidad sa pagitan ng 1% at 3% ng kita. para sa karagdagang detalye ukol sa pagpepresyo, maaaring bisitahin ang seksyon ng Software Platform sa pamamagitan ng About link sa taas na menu." + sell_listing_price: "ang pagpapalista sa OFN ay libre. ang pagbubukas at pagpapatakbo ng shop ay libre hanggang sa PHP 5000 na buwanang benta. kung makakabenta ka ng mas marami, maaari kang mamili ng kontribusyon sa komunidad sa pagitan ng 1.5% at 3% ng kita. para sa karagdagang detalye ukol sa pagpepresyo, maaaring bisitahin ang seksyon ng Software Platform sa pamamagitan ng About link sa taas na menu." sell_embed: "maari rin naming ilagay ang OFN sa inyong sariling website o magtayo ng sariling lokal na Food Network website sa inyong rehiyon." sell_ask_services: "magtanong tungkol sa mga serbiyong binibigay ng OFN" shops_title: mga shop @@ -1674,7 +1676,7 @@ fil_PH: orders_bought_edit_button: ayusin ang kumpirmadong mga item orders_bought_already_confirmed: "* kumpirmado na" orders_confirm_cancel: sigurado ka bang nais mo na kanselahin ang order na ito? - order_processed_successfully: "ang inyong order ay matagumpay na nakumpirma" + order_processed_successfully: "ang inyong order ay matagumpay na naproseso" products_cart_distributor_choice: "Distributor ng inyong order:" products_cart_distributor_change: "ang distributor para sa order na ito ay mapapalitan ng%{name} kung idadagdag ang produktong ito sa inyong cart." products_cart_distributor_is: "ang distributor para sa order na ito ay%{name}." @@ -1695,7 +1697,7 @@ fil_PH: going_back_to_home_page: "binabalik ka sa homepage" creating: ginagawa updating: ina-update - failed_to_create_enterprise: "hindi nagtagumpay sa paggawa ng iyong enterprise" + failed_to_create_enterprise: "hindi nagtagumpay sa paggawa ng inyong enterprise." failed_to_create_enterprise_unknown: "hindi nagtagumpay sa paggawa ng iyong enterprise.\nsiguraduhing ang lahat ng patlang ay nasagutan." failed_to_update_enterprise_unknown: "hindi nagtagumpay sa pag-update ng iyong enterprise.\nsiguraduhing ang lahat ng patlang ay nasagutan." enterprise_confirm_delete_message: "mabubura rin ang%{product}na sinusuplay ng enterprise na ito. sigurado ka bang nais mo magpatuloy?" @@ -1743,7 +1745,7 @@ fil_PH: steps: introduction: registration_greeting: "Kumusta?" - registration_intro: "maaari ka ng lumikha ng profile para sa inyong Producer o Hub" + registration_intro: "maaari ka ng gumawa ng profile para sa inyong Producer o Hub" registration_checklist: "ano ang kailangan ko gawin?" registration_time: "5-10 minuto" registration_enterprise_address: "Address ng enterprise" @@ -1796,7 +1798,7 @@ fil_PH: producer_field_error: "pumili ng isa. ikaw ba ay isang producer?" yes_producer_help: "Ang mga producer ay gumagawa ng masasarap na bagay na maaaring makain at/o mainom. Ikaw ay isang producer kung itinatanim mo ito, pinapalaki, binuburo, niluluto, hinuhurno, ginagatasan o hinuhulma." no_producer_help: "kung hindi ka isang producer, malamang ikaw ay nagbebenta at namamahagi ng mga pagkain. maaaring ikaw ay isang Hub, coop, grupo ng mamimili, retailer, wholesaler o iba pa." - create_profile: "lumikha ng profile" + create_profile: "gumawa ng profile" about: title: "tungkol sa" headline: "binabati kita!" @@ -1821,12 +1823,12 @@ fil_PH: continue: "Magpatuloy" back: "bumalik" logo: - select_logo: "hakbang 1, pumili ng larawan ng Logo" + select_logo: "hakbang 1. pumili ng larawan ng Logo" logo_tip: "Tip: pinakamaganda ang mga parisukat na larawan, mas mabuti kung ito ay 300x300px" - logo_label: "pumili ng larawan ng logo" + logo_label: "pumili ng larawan para sa logo" logo_drag: "hilahin at ilagay ang logo dito" review_logo: "hakbang 2. suriin ang iyong logo" - review_logo_tip: "Tip: para sa mas maayos na resulta, ang logo ay dapat matakpan ang lahat ng espasyo" + review_logo_tip: "Tip: para sa mas maayos na resulta, ang logo ay dapat matakpan lahat ng espasyo" logo_placeholder: "ang iyong logo ay makikita dito para masuri kapag na-upload na" promo: select_promo_image: "hakbang 3. pumili ng larawan ng promo" @@ -1841,9 +1843,9 @@ fil_PH: enterprise_final_step: "Huling hakbang!" enterprise_social_text: "paano mahahanap ng mga tao ang%{enterprise}sa internet?" website: "website" - website_placeholder: "hal. openfoodnetwork.org.au" + website_placeholder: "hal. openfoodnetwork.ph" facebook: "Facebook" - facebook_placeholder: "hal. www.facebook.com/pangalanngpahina" + facebook_placeholder: "hal. www.facebook.com/PageNameHere" linkedin: "LinkedIn" linkedin_placeholder: "hal. www.linkedin.com/YourNameHere" twitter: "Twitter" @@ -1862,7 +1864,7 @@ fil_PH: action: "pumunta sa dashboard ng Enterprise" back: "bumalik" continue: "Magpatuloy" - action_or: "O" + action_or: "OR" enterprise_limit: Limitasyon ng enterprise shipping_method_destroy_error: "ang paraan ng pagpapadala ay hindi maaaring tanggalin sapagkat ito ay nakasangguni na sa isang order:%{number}." fees: "fees" @@ -1883,7 +1885,7 @@ fil_PH: price_graph: "graph ng presyo" included_tax: "kasamang tax" balance: "Balanse" - transaction: "transaksyon" + transaction: "transaksiyon" transaction_date: "petsa" payment_state: "status ng bayad" shipping_state: "status ng pagpapadala" @@ -1903,7 +1905,7 @@ fil_PH: outstanding_balance: "natitirang balanse" admin_enterprise_relationships: "mga permiso ng enterprise" admin_enterprise_relationships_everything: "lahat" - admin_enterprise_relationships_permits: "mga permit" + admin_enterprise_relationships_permits: "pinapayagan" admin_enterprise_relationships_seach_placeholder: "hanapin" admin_enterprise_relationships_button_create: "gumawa" admin_enterprise_relationships_to: "sa" @@ -1946,7 +1948,7 @@ fil_PH: tax_category: "kategorya ng tax" calculator: "calculator" calculator_values: "mga halaga sa calculator" - calculator_settings_warning: "kung papalitan ang uri ng calculator, dapat ay i-save muna bago maiayos ang setting ng calculator" + calculator_settings_warning: "kung papalitan ang uri ng calculator, dapat ay mag-save muna bago maisa-ayos ang setting ng calculator" flat_percent_per_item: "Flat percent (kada item)" flat_rate_per_item: "Flat Rate (kada item)" flat_rate_per_order: "Flat rate (kada order)" @@ -1982,10 +1984,10 @@ fil_PH: spree_admin_overview_enterprises_header: "ang aking mga enterprise" spree_admin_overview_enterprises_footer: "PAMAHALAAN ANG AKING MGA ENTERPRISE" spree_admin_enterprises_hubs_name: "pangalan" - spree_admin_enterprises_create_new: "LUMIKHA NG BAGO" + spree_admin_enterprises_create_new: "GUMAWA NG BAGO" spree_admin_enterprises_shipping_methods: "mga paraan ng pagpapadala" spree_admin_enterprises_fees: "bayad para sa enterprise" - spree_admin_enterprises_none_create_a_new_enterprise: "LUMIKHA NG BAGONG ENTERPRISE" + spree_admin_enterprises_none_create_a_new_enterprise: "GUMAWA NG BAGONG ENTERPRISE" spree_admin_enterprises_none_text: "wala ka pang mga enterprise" spree_admin_enterprises_tabs_hubs: "MGA HUB" spree_admin_enterprises_producers_manage_products: "PAMAHALAAN ANG MGA PRODUKTO" @@ -2003,7 +2005,7 @@ fil_PH: spree_admin_variant_unit_name: pangalan ng variant unit unit_name: "pangalan ng yunit" change_package: "palitan ang package" - spree_admin_single_enterprise_hint: "payo: para mahanap ka ng mga tao, i-turn on ang visibility sa ilalim ng" + spree_admin_single_enterprise_hint: "payo: para mahanap ka ng ibang tao, i-turn on ang visibility sa ilalim ng" spree_admin_eg_pickup_from_school: "hal. 'Pick-up mula sa Primary School'" spree_admin_eg_collect_your_order: "hal. 'Kolektahin ang inyong order sa 123 Kapayapaan St., Tobias Fornier, Antique 5716'" spree_classification_primary_taxon_error: "ang Tax sa%{taxon}ay ang pangunahing tax ng %{product}at hindi maaaring tanggalin" @@ -2033,8 +2035,8 @@ fil_PH: last_name_begins_with: "ang apelyido ay nagsisimula sa" enterprise_tos_link: "Link para sa palatuntunan ng serbisyo ng Enterprise" enterprise_tos_message: "nais naming makiisa sa mga taong kapareho ng aming layunin at adhikain. Dahil dito, hinihiling namin sa mga bagong enterprise na sumang-ayon sa aming" - enterprise_tos_link_text: "Palatuntunan ng serbisyo." - enterprise_tos_agree: "ako ay sumasang-ayon sa palatuntunan ng serbisyo na nasa itaas." + enterprise_tos_link_text: "Mga Tuntunin ng Serbisyo." + enterprise_tos_agree: "ako ay sumasang-ayon sa mga tuntunin ng serbisyo na nasa itaas." tax_settings: "settings ng tax" products_require_tax_category: "ang mga produkto ay kailangang may kategorya ng tax" admin_shared_address_1: "address" @@ -2072,7 +2074,7 @@ fil_PH: report_header_user: User report_header_email: email report_header_status: Status - report_header_comments: mga puna + report_header_comments: mga komento report_header_first_name: Pangalan report_header_last_name: Apelyido report_header_phone: telepono @@ -2199,7 +2201,7 @@ fil_PH: report_header_total_untaxable_fees: kabuuang fees na untaxable (walang tax) report_header_total_taxable_fees: kabuuang fees na taxable (may kasamang tax) report_header_delivery_shipping_cost: bayad sa pagdeliver ng pinapadala (kasama ang tax) - report_header_transaction_fee: Bayad sa Transaksyon (walang tax) + report_header_transaction_fee: Bayad sa Transaksiyon (walang tax) report_header_total_untaxable_admin: kabuuang untaxable na pagsasaayos ng admin (walang tax) report_header_total_taxable_admin: kabuuang taxable na pagsasaayos ng admin (kasama ang tax) initial_invoice_number: "paunang numero ng invoice:" @@ -2208,7 +2210,7 @@ fil_PH: account_code: "code ng Account:" equals: "katumbas" contains: "naglalaman" - discount: "Diskwento" + discount: "Diskuwento" filter_products: "i-filter ang mga produkto" delete_product_variant: "ang huling mga variant ay hindi matanggal!" progress: "progreso" @@ -2244,15 +2246,15 @@ fil_PH: shop_preferences: "mga kagustuhan sa shop" enterprise_fee_whole_order: Buong order enterprise_fee_by: "%{type}na bayad ng%{role}%{enterprise_name}" - validation_msg_relationship_already_established: "^ang relasyon ay naitatag na" + validation_msg_relationship_already_established: "^ang relasyon na iyan ay naitatag na" validation_msg_at_least_one_hub: "^kailangang kahit isang Hub ay piliin" validation_msg_tax_category_cant_be_blank: "^ang kategorya ng tax ay hindi maaaring walang sagot" validation_msg_is_associated_with_an_exising_customer: "ay nauugnay na sa isang customer" content_configuration_pricing_table: "(DAPATGAWIN: TALAAN NG PRESYO)" content_configuration_case_studies: "(DAPATGAWIN: mga pag-aaral ng kaso)" content_configuration_detail: "(DAPATGAWIN: detalye)" - enterprise_name_error: "ay nagamit na. kung ito ay iyong enterprise at nais mong kunin ang pagmaymay-ari, o kung nais mong makipagkalakalan sa enterprise na ito, makipag-ugnayan sa kasalukuyang tagapamahala ng profile na ito sa %{email}." - enterprise_owner_error: "^%{email}ay walang permiso na mag-ari ng karagdagang mga enterprise (ang limitasyon ay%{enterprise_limit})." + enterprise_name_error: "ay nakuha na. kung ito ay iyong enterprise at nais mong kunin ang pagmamay-ari, o kung nais mong makipagkalakalan sa enterprise na ito, makipag-ugnayan sa kasalukuyang tagapamahala ng profile na ito sa %{email}." + enterprise_owner_error: "^%{email}ay walang permiso na magmay-ari ng karagdagang mga enterprise (ang limitasyon ay%{enterprise_limit})." enterprise_role_uniqueness_error: "^ang tungkulin na iyon ay may nagmamay-ari na" inventory_item_visibility_error: ay dapat totoo o hindi totoo product_importer_file_error: "error: walang file na na-upload" @@ -2279,11 +2281,11 @@ fil_PH: enterprise_register_success_notice: "maligayang pagbati! ang rehistrasyon para sa%{enterprise}ay kumpleto na!" enterprise_bulk_update_success_notice: "ang mga enterprise ay matagumpay na na-update" enterprise_bulk_update_error: 'hindi matagumpay ang pag-update' - enterprise_shop_show_error: "ang shop na hinahanap mo ay wala o hindi aktibo sa OFN. Maaaring tignan ang ibang shops." + enterprise_shop_show_error: "ang shop na hinahanap mo ay wala o hindi aktibo sa OFN. Maaaring tignan ang ibang mga shop." order_cycles_create_notice: 'ang iyong order cycle ay nagawa na.' order_cycles_update_notice: 'ang iyong order cycle ay na-update na' order_cycles_bulk_update_notice: 'ang mga order cycle ay na-update na' - order_cycles_clone_notice: "ang iyong order cyle %{name}ay kinopya." + order_cycles_clone_notice: "ang iyong order cyle %{name}ay nakopya na." order_cycles_email_to_producers_notice: 'ang mga email na ipapadala sa mga producer ay naghihintay na maipadala.' order_cycles_no_permission_to_coordinate_error: "wala sa inyong mga enterprise ay may pahintulot na magsa-ayos ng order cycle" order_cycles_no_permission_to_create_error: "wala kang pahintulot na gumawa ng order cycle na isinaayos ng enterprise na iyon." @@ -2303,7 +2305,7 @@ fil_PH: all_changes_saved: lahat ng pagbabago ay na-save na unsaved_changes: may mga hindi na-save na pagbabago all_changes_saved_successfully: lahat ng pagbabago ay matagumpay na na-save - oh_no: "paumanin! hindi ko na-save ang mga pagbabagong ginawa mo." + oh_no: "paumanhin! hindi ko na-save ang mga pagbabagong ginawa mo." unauthorized: "ikaw ay hindi awtorisadong i-access ang pahina na ito." error: Error unavailable: hindi available @@ -2315,7 +2317,7 @@ fil_PH: more_items: "+%{count}iba pa" default_card_updated: na-update ang default card admin: - enterprise_limit_reached: "naabot mo na ang karaniwang lmitasyon ng dami ng bilang ng mga enterprise sa bawat account. makipag-ugnayan sa%{contact_email}kung kailangan mo itong dagdagan." + enterprise_limit_reached: "naabot mo na ang pamantayang lmitasyon ng dami ng bilang ng mga enterprise sa bawat account. makipag-ugnayan sa%{contact_email}kung kailangan mo itong dagdagan." modals: got_it: nakuha na close: "isara" @@ -2423,7 +2425,7 @@ fil_PH: shop sa Open Food Network. non_producer: Hindi producer non_producer_text1: > - ang mga hindi producer ay hindi gumagawa ng sarili nilang pagkain, nangangahulgang + ang mga hindi producer ay hindi gumagawa ng sarili nilang pagkain, nangangahulugang wala silang kakayahang gumawa ng sariling mga produkto na maibebenta sa Open Food Network. non_producer_text2: > @@ -2464,8 +2466,8 @@ fil_PH: per_page: "%{results}kada pahina" view_file: "tignan ang file" compiling_invoices: "tinitipon ang mga invoice" - bulk_invoice_created: "nagawa ang maramihang invoice" - bulk_invoice_failed: "hindi nagtagumpay na gumawa ng maramihang invoice" + bulk_invoice_created: "nakagawa ng Bulk invoice" + bulk_invoice_failed: "hindi nagtagumpay sa paggawa ng Bulk invoice" please_wait: "hintayin na maihanda ang PDF bago isara ang modal na ito." order_state: address: "address" @@ -2509,11 +2511,11 @@ fil_PH: schedules: adding_a_new_schedule: "nagdadagdag ng Bagong Iskedyul" updating_a_schedule: "ina-update ang iskedyul" - create_schedule: "Lumikha ng iskedyul" + create_schedule: "gumawa ng iskedyul" update_schedule: "i-update ang iskedyul" delete_schedule: "tanggalin ang iskedyul" schedule_name_placeholder: "pangalan ng iskedyul" - created_schedule: "nakalikha ng iskedyul" + created_schedule: "nakagawa ng iskedyul" updated_schedule: "na-update na iskedyul" deleted_schedule: "binurang iskedyul" name_required_error: "Maglagay ng pangalan para sa iskedyul na ito" @@ -2728,11 +2730,12 @@ fil_PH: invalid_filter_parameters: "ang mga filter na pinili para sa ulat na ito ay hindi valid." order: "order" distribution: "pamamahagi" - order_details: "detalye ng order" - customer_details: "detalye ng customer" + order_details: "mga detalye ng order" + customer_details: "mga detalye ng customer" adjustments: "mga pagsasa-ayos" payments: "mga bayad" - payment: "kabayaran" + return_authorizations: "mga awtorisasyon sa pagbabalik" + payment: "bayad" payment_method: "paraan ng pagbayad" shipment: "kargamento" shipment_inc_vat: "kargamento kasama ang VAT" @@ -2778,7 +2781,7 @@ fil_PH: cannot_set_shipping_method_without_address: "hindi mai-set ang paraan ng pagpapadala hanggang hindi binibigay ang detalye ng customer." no_tracking_present: "walang detalye ng tracking na ibinigay." order_total: "kabuuan ng order" - customer_details: "detalye ng customer" + customer_details: "mga detalye ng customer" customer_search: "paghanap ng customer" choose_a_customer: "pumili ng customer" account: "Account" @@ -2845,7 +2848,7 @@ fil_PH: tax rate: "rate ng mga tax" new_tax_rate: "bagong rate ng tax" tax_category: "kategorya ng tax" - rate: "rate" + rate: "antas" tax_rate_amount_explanation: "ang mga rate ng tax ay mga halagang may decimal na makakatulong sa pagkukuwenta, (hal. kung ang rate ng tax ay 5% ang ilalagay ay 0.05)" included_in_price: "nakasama sa presyo" show_rate_in_label: "ipakita ang rate sa tatak" @@ -2855,7 +2858,7 @@ fil_PH: new_zone: "bagong sona" default_tax: "default na tax" default_tax_zone: "default na sona ng tax" - country_based: "Country Based" + country_based: "nakabase sa bansa" state_based: "Nakabase sa Lalawigan" countries: "Mga Bansa" listing_countries: "Listahan ng mga Bansa" @@ -2941,8 +2944,8 @@ fil_PH: configuration: "pagbabago" users: "mga gumagamit" roles: "mga tungkulin" - order_cycles: "order cycles" - enterprises: "enterprises" + order_cycles: "mga order cycle" + enterprises: "mga enterprise" enterprise_relationships: "mga pahintulot" customers: "mga customer" groups: "mga grupo" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index 60c840f730..5b2e89defd 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -9,7 +9,7 @@ fr_BE: shipment_state: Statut livraison completed_at: 'Passée à ' number: N° commande - state: Province + state: Statut de la commande email: Adresse électronique acheteur spree/payment: amount: Montant @@ -23,6 +23,8 @@ fr_BE: base: "Carte de crédit" order_cycle: orders_close_at: Date de fermeture + variant_override: + count_on_hand: "En stock" errors: models: spree/user: @@ -1632,7 +1634,7 @@ fr_BE: sell_hubs_detail: "Créer un profil pour votre activité sur OFN en quelques minutes. A tout moment vous pourrez créer un comptoir en ligne pour vendre vos produits en direct aux acheteurs." sell_groups_detail: "Créer un répertoire sur mesure (regroupant différents producteurs et comptoirs) pour votre région ou votre organisation." sell_user_guide: "En savoir plus en explorant le guide d'utilisation." - sell_listing_price: "L'inscription à l'OFN est libre de contribution. Ouvrir et utiliser un comptoir sur OFN vous permet de gagner jusqu'à 500 € de ventes mensuelles, le service est gratuit les 6 premiers mois. Ensuite, une contribution entre 1 à 3% de votre chiffre de vente est demandée." + sell_listing_price: "L'inscription sur la plateforme d'OFN est libre de contribution. Le service est gratuit les 6 premiers mois. Ensuite, une contribution de 2% de votre chiffre de vente est demandée." sell_embed: "D’ici là, vous pouvez également participer au projet. \nSoit en co-créant la communauté belge et en contribuant à l’amélioration des fonctionnalité. Soit en mettant à disposition un local pour faciliter les livraisons ou un lieu pour former les utilisateurs·trices à la plateforme, etc. Soit en soutenant le projet par un don (déductible fiscalement à partir de 40€) à verser sur le compte d'Oxfam-Magasins du monde qui facilite la plateforme :  BE41 0682 2264 2410 – en communication Open Food Network Belgium." sell_ask_services: "Contactez-nous pour en savoir plus." shops_title: Comptoirs @@ -2669,6 +2671,7 @@ fr_BE: customer_details: "Données client·e" adjustments: "Corrections" payments: "Paiements" + return_authorizations: "Autorisations de retour" payment: "Paiement" payment_method: "Méthode de paiement" shipment: "Envoi" @@ -3014,12 +3017,12 @@ fr_BE: payment_methods: "Méthodes de paiement" new_payment_method: "Nouvelle méthode de paiement" name: "Nom" - products_distributor: "Distributeur·trice" + products_distributor: "Distributeur" provider: "Fournisseur" environment: "Environnement" display: "Ecran" active: "Actif" - both: "Tou·te·s les deux" + both: "Les deux" active_yes: "Oui" active_no: "Non" new: @@ -3160,7 +3163,7 @@ fr_BE: sortable_header: name: "Nom" number: "N° commande" - state: "Province" + state: "Statut de la commande" payment_state: "Statut du Paiement" shipment_state: "Statut livraison" email: "Email" diff --git a/config/locales/it.yml b/config/locales/it.yml index 21a9a2a5c6..7d0ef72e69 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -158,15 +158,15 @@ it: total: Un totale di %{count} sottoscrizioni sono stati contrassegnati per l'elaborazione automatica. success_zero: Di questi, nessuno è stato elaborato con successo. success_some: Di questi, %{count} sono stati elaborati con successo. - success_all: Tutti sono stati elaborati con successo. + success_all: Sono stati elaborati tutti con successo. issues: Qui sotto i dettagli dei problemi riscontrati. summary_detail: no_message_provided: Nessun messaggio di errore fornito changes: - title: Scorte insufficienti (%{count} gentili richieste) - explainer: Queste gentili richieste sono state elaborate, ma la quantità richiesta di alcuni prodotti non è disponibile + title: Scorte insufficienti (%{count} ordini) + explainer: Questi ordini sono stati processati ma la quantità richiesta di alcuni prodotti non è disponibile empty: - title: Nessuna scorta (%{count} gentili richieste) + title: Nessuna scorta (%{count} ordini) explainer: Queste gentili richieste non sono state confermate perchè alcuni prodotti richiesti non sono disponibili. complete: title: Già elaborate (%{count} gentili richieste) @@ -449,7 +449,7 @@ it: property_name: "Nome della Proprietà" inherited_property: "Proprietà Ereditata" variants: - infinity: "Infinito..." + infinity: "Infinito" to_order_tip: "Gli articoli messi in ordine non hanno un livello di stock impostato, come ad esempio il Pane fresco su ordinazione." back_to_products_list: "Indietro alla lista dei prodotti" editing_product: "Modifica prodotto" @@ -1446,12 +1446,12 @@ it: email_signature: "Il team di %{sitename}" email_confirm_customer_greeting: "Ciao %{name}," email_confirm_customer_intro_html: "Grazie per aver acquistato presso %{distributor}!" - email_confirm_customer_number_html: "Conferma dell'Ordine #%{number}" + email_confirm_customer_number_html: "Conferma ordine #%{number}" email_confirm_customer_details_html: "Ecco i dettagli del tuo ordine da %{distributor}:" email_confirm_customer_signoff: "Cordiali saluti," email_confirm_shop_greeting: "Ciao %{name}," email_confirm_shop_order_html: "Ben fatto! Hai un nuovo ordine per %{distributor}!" - email_confirm_shop_number_html: "Conferma dell'Ordine #%{number}" + email_confirm_shop_number_html: "Conferma ordine #%{number}" email_order_summary_item: "Articolo" email_order_summary_quantity: "Qtà" email_order_summary_sku: "SKU" @@ -1489,7 +1489,7 @@ it: email_shipping_collection_instructions: "Istruzioni per la distribuzione:" email_special_instructions: "Tue note:" email_signup_greeting: Ciao! - email_signup_welcome: "Benvenuto a %{sitename}!" + email_signup_welcome: "Benvenuto su %{sitename}!" email_signup_confirmed_email: "Grazie di aver confermato la tua mail." email_signup_shop_html: "Puoi effettuare il log in qui: %{link}." email_signup_text: "Grazie per esserti unito alla rete. Se sei un cliente, non vediamo l'ora di introdurti a molti produttori fantastici, distributori di cibo spettacolari e cibo delizioso! Se sei un produttore o un'impresa alimentare, siamo entusiasti di averti come parte della rete." @@ -1678,7 +1678,7 @@ it: orders_oc_expired_text_link: "o vedi gli altri cicli d'ordine disponibili per questo hub" orders_oc_expired_email: "Email:" orders_oc_expired_phone: "Telefono:" - orders_show_title: Conferma dell'ordine + orders_show_title: Conferma Ordine orders_show_time: Ordine pronto orders_show_order_number: "Gentile richiesta #%{number}" orders_show_cancelled: Annullato @@ -3334,7 +3334,7 @@ it: credit_order: "Il tuo ordine è stato pagato, quindi il tuo acconto è stato accreditato" subject: "Cancellazione dell'ordine" confirm_email: - subject: "Conferma dell'ordine" + subject: "Conferma Ordine" invoice_email: hi: "Ciao %{name}" invoice_attached_text: 'Aggiunge una fattura per il tuo recente ordine di ' diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index 952d7a5579..2a80116410 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -23,6 +23,8 @@ nl_BE: base: "Kredietkaart" order_cycle: orders_close_at: Sluitingsdatum + variant_override: + count_on_hand: "Bij de Hand" errors: models: spree/user: diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 1e8b8f7efe..2e4d9c06de 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -21,6 +21,8 @@ pt: base: "Cartão de Crédito" order_cycle: orders_close_at: Data de fecho + variant_override: + count_on_hand: "Disponível" errors: models: spree/user: diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 3c2ac7d748..e2cae6de9f 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -23,6 +23,8 @@ pt_BR: base: "Cartão de Crédito" order_cycle: orders_close_at: Dia de fechamento + variant_override: + count_on_hand: "Disponível" errors: models: spree/user: @@ -2740,6 +2742,7 @@ pt_BR: customer_details: "Detalhes do cliente" adjustments: "Ajustes" payments: "Pagamentos" + return_authorizations: "Autorizações de Retorno" payment: "Pagamento" payment_method: "Método de Pagamento" shipment: "Envio" diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 600a91ef7f..addd879f88 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -11,6 +11,8 @@ sv: spree/product: supplier: "Leverantör" variant_unit: "Enhet för variant" + variant_override: + count_on_hand: "På lager" errors: models: spree/user: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 825fab2b41..f9777fb9cd 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -23,6 +23,8 @@ tr: base: "Kredi kartı" order_cycle: orders_close_at: BİTİŞ TARİHİ + variant_override: + count_on_hand: "Mevcut" errors: models: spree/user: @@ -181,9 +183,9 @@ tr: home: "AGA" title: Açık Gıda Ağı welcome_to: 'Hoşgeldiniz' - site_meta_description: "Açık Gıda Ağı, bağımsız, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Kar amacı gütmez, toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." + site_meta_description: "Açık Gıda Ağı, yerel, bağımsız, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." search_by_name: Üretici adına veya konuma göre arama yapın... - producers_join: Temiz gıda üreticileri! Açık Gıda Ağı sizler için kullanıma açıldı. + producers_join: Bağımsız gıda üreticileri! Açık Gıda Ağı sizler için kullanıma açıldı. charges_sales_tax: KDV Uyguluyor mu? print_invoice: "Faturayı yazdır" print_ticket: "Etiketi Yazdır" @@ -891,7 +893,7 @@ tr: pickup_time_tip: Bu sipariş dönemine ait siparişlerin müşteriler için hazır olma tarihi pickup_instructions_placeholder: "Teslimat Talimatları" pickup_instructions_tip: Bu talimatlar, siparişi tamamladıktan sonra müşterilere iletilir - pickup_time_placeholder: "ŞU TARİHTE HAZIR (örn. Tarİh / Saat)" + pickup_time_placeholder: "Teslimat (örn. Tarih / Saat)" receival_instructions_placeholder: "Teslim Alma talimatları" add_fee: 'Ücret ekle' remove: 'Kaldır' @@ -938,7 +940,7 @@ tr: distributors: Dağıtımcılar variants: Varyantlar simple_form: - ready_for: ŞU TARİHTE HAZIR + ready_for: Teslimat ready_for_placeholder: Tarih/saat customer_instructions: Müşteri talimatları customer_instructions_placeholder: Teslimat / Gönderim Notları @@ -1212,7 +1214,7 @@ tr: menu_2_url: "/map" menu_3_title: "ÜRETİCİLER" menu_3_url: "/producers" - menu_4_title: "Gruplar" + menu_4_title: "GRUPLAR" menu_4_url: "/groups" menu_5_title: "HAKKIMIZDA" menu_5_url: "https://hakkimizda.acikgida.com" @@ -1351,15 +1353,15 @@ tr: home_shop: ŞİMDİ ALIŞVERİŞ YAPIN brandstory_headline: "Bağımsız, adil ve temiz gıda ..." brandstory_intro: "Bazen sistemi düzeltmenin en iyi yolu yeni bir sistem yaratmaktır…" - brandstory_part1: "Açık Gıda Ağı, bağımsız, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Kar amacı gütmez, toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." - brandstory_part2: "AGA, üreticilere ve alıcılara aracısız ticaret faydaları sağlar ve toplumsal iletişimi ve güveni cesaretlendirerek üretici-türetici ilişkisi oluşturmayı hedefler. Gıda yetiştiriciliği ve satışının kendine özgü ihtiyaçlarını karşılamaya ve sorunlarını çözmeye yönelik olarak tasarlanmıştır. Temiz gıdaya ulaşım sürecini ve yönetimini kolaylaştırır." - brandstory_part3: "Platform üzerinden yalnızca temiz gıda üreticileri satış yapabilir. Eğer siz de temiz gıda üreticisi iseniz, ürünlerinizi AGA üzerinden oluşturduğunuz tezgah ile doğrudan alıcılara ulaştırabilirsiniz. Dilerseniz bölgenizdeki diğer üreticiler ile bir araya gelerek kendi ortak 'Üretici Pazarı' veya 'Türetici Pazarı' nızı oluşturursunuz. Bu şekilde çeşitliliği ve bereketi artırır, dayanışmanın getirdiği diğer faydalardan da yararlanabilirsiniz." + brandstory_part1: "Açık Gıda Ağı, yerel, bağımsız, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." + brandstory_part2: "AGA, üreticilere ve alıcılara aracısız ticaret faydaları sağlar ve toplumsal iletişimi ve güveni cesaretlendirir. Gıda yetiştiriciliği ve satışının kendine özgü ihtiyaçlarını karşılamak için geliştirilmiştir. Temiz gıdaya ulaşım sürecini kolaylaştırır." + brandstory_part3: "Platform üzerinden yalnızca yerel ve bağımsız gıda üreticileri ve dağıtımcıları satış yapabilir. Siz de ürünlerinizi AGA üzerinden oluşturduğunuz tezgah ile doğrudan alıcılara ulaştırabilir, dilerseniz bölgenizdeki diğer üreticiler ile bir araya gelerek kendi ortak 'Üretici Pazarı' veya 'Türetici Pazarı' nızı oluşturabilirsiniz. Bu şekilde çeşitliliği ve bereketi artırır, dayanışmanın getirdiği faydalardan da yararlanabilirsiniz." brandstory_part4: "Her yerde çalışıyor. Her şeyi değiştiriyor." brandstory_part5_strong: "Biz buna Açık Gıda Ağı diyoruz." brandstory_part6: "Hepimiz gıdamızı seviyoruz. Artık gıda sistemimizi de sevmeye başlayabiliriz." learn_body: "Adil ve temiz gıda işletmenizi veya topluluğunuzu geliştirmenize yardımcı olacak modelleri, hikayeleri ve kaynakları keşfedin. Dostlardan öğrenmek için eğitim, etkinlikler ve diğer fırsatlara göz atın." learn_cta: "İlham Alın" - connect_body: "Yakınınızdaki adil ve temiz gıda noktalarını bulmak için üreticilerin, pazarların ve topluluklarının tümünü gözden geçirin. İşletmenizi veya topluluğunuzu Açık Gıda Ağı üzerinden listeleyin, böylece alıcılar sizi bulabilir. Ortak hareket etmek için diğer hesaplar ile iletişime geçmekten çekinmeyin, birlikte daha güçlüsünüz. Tavsiye almak ve sorunları birlikte çözmek için topluluğa katılın." + connect_body: "Yakınınızdaki adil ve temiz gıda noktalarını bulmak için üreticilerin, pazarların ve topluluklarının tümünü gözden geçirin. İşletmenizi veya topluluğunuzu Açık Gıda Ağı üzerinden listeleyin, böylece alıcılar sizi rahatça bulabilir. Ortak hareket etmek için diğer hesaplar ile iletişime geçmekten çekinmeyin, birlikte daha güçlüsünüz. Tavsiye almak ve sorunları birlikte çözmek için topluluğa katılın." connect_cta: "Keşfedin" system_headline: "Nasıl çalışıyor ?" system_step1: "1. Ara" @@ -1367,17 +1369,17 @@ tr: system_step2: "2. Alışveriş Yap" system_step2_text: "Gıdanızı yerel üretici tezgahlarından, üretici ve türetici pazarlarından temin edin. Yaşanabilir bir dünya için alışkanlıklarınızı şimdi değiştirin. Gıdanızın ve onu size getiren insanların hikayelerini öğrenin!" system_step3: "3. Teslimat " - system_step3_text: "Seçtiğiniz gıdaya ulaşmak için adresinize teslim edilmesini bekleyin veya gıdanız ile daha kişisel bir bağ kurmak için üreticinizi veya pazarını ziyaret edin. Doğayla ve gıdayla istediğiniz şekilde ama gerçek bir bağ kurun. " + system_step3_text: "Gıdanıza ulaşmak için adresinize teslim edilmesini bekleyin. Dilerseniz gıdanız ile daha kişisel bir bağ kurmak için üreticinizi veya pazarını kendiniz ziyaret edin. Doğayla ve gıdayla istediğiniz şekilde ama gerçek bir bağ kurun. " cta_headline: "Dünyayı daha iyi bir yer yapan alışveriş biçimi." cta_label: "Hazırım" stats_headline: "Yeni bir gıda sistemi yaratıyoruz." - stats_producers: "GIDA ÜRETİCİLERİ" - stats_shops: "gıda pazarları" - stats_shoppers: "gıda alıcıları" - stats_orders: "GIDA SİPARİŞLERİ" + stats_producers: "ÜRETİCİ" + stats_shops: "MAĞAZA" + stats_shoppers: "TÜRETİCİ" + stats_orders: "ALIŞVERİŞ" checkout_title: Ödeme Yap checkout_now: Alışverişi Tamamla - checkout_order_ready: SİPARİŞ ŞU TARİHTE HAZIR + checkout_order_ready: Sipariş Teslimat checkout_hide: Gizle checkout_expand: genişlet checkout_headline: "Tamam, ödeme yapmaya hazır mısın?" @@ -1389,7 +1391,7 @@ tr: checkout_default_ship_address: "Varsayılan teslimat adresi olarak kaydet" checkout_method_free: Ücretsiz checkout_address_same: Teslimat adresi fatura adresiyle aynı mı? - checkout_ready_for: "ŞU TARİHTE HAZIR" + checkout_ready_for: "Teslimat:" checkout_instructions: "Yorumlarınız veya özel talimatlarınız var mı?" checkout_payment: Ödeme checkout_send: Şimdi sipariş ver @@ -1408,7 +1410,7 @@ tr: order_delivery_address: Teslimat adresi order_delivery_time: Teslimat zamanı order_special_instructions: "Notların:" - order_pickup_time: TESLİM ALMAK İÇİN HAZIR + order_pickup_time: Teslimat için hazır order_pickup_instructions: Teslim Alma Talimatları order_produce: Üretim order_total_price: Toplam @@ -1477,7 +1479,7 @@ tr: email_shipping_delivery_time: "Teslimat tarihi:" email_shipping_delivery_address: "Teslimat adresi:" email_shipping_collection_details: Teslim Alma Bilgileri - email_shipping_collection_time: "TESLİM ALMAK İÇİN HAZIR" + email_shipping_collection_time: "Teslimat için hazır" email_shipping_collection_instructions: "Teslim Alma talimatları:" email_special_instructions: "Notların:" email_signup_greeting: Merhaba! @@ -1497,13 +1499,13 @@ tr: producer_mail_order_text: "İşte ürünleriniz gelen için siparişlerin bir özeti:" producer_mail_delivery_instructions: "Stok teslimat/gönderim talimatları:" producer_mail_signoff: "En iyi dileklerimle" - shopping_oc_closed: SİPARİŞ KAPANIŞ + shopping_oc_closed: SİPARİŞ DÖNEMİ KAPALI shopping_oc_closed_description: "Lütfen bir sonraki dönem açılana kadar bekleyin (veya geç siparişleri kabul edip edemeyeceğimizi görmek için doğrudan bizimle iletişime geçin)" shopping_oc_last_closed: "Son dönem %{distance_of_time} önce kapandı" shopping_oc_next_open: "Bir sonraki dönem %{distance_of_time}'da açılıyor" shopping_oc_select: "Seçin..." shopping_tabs_home: "Ana sayfa" - shopping_tabs_shop: "Alışveriş yap" + shopping_tabs_shop: "ALIŞVERİŞ YAP" shopping_tabs_about: "Hakkında" shopping_tabs_contact: "İLETİŞİM" shopping_contact_address: "Adres" @@ -1512,13 +1514,13 @@ tr: shopping_groups_part_of: "şunun parçası:" shopping_producers_of_hub: "%{hub} üreticileri:" enterprises_next_closing: "Bir sonraki sipariş kapanışı" - enterprises_ready_for: "ŞU TARİHTE HAZIR" + enterprises_ready_for: "Teslimat" enterprises_choose: "Siparişinizi ne zaman istediğinizi seçin:" maps_open: "Açık" maps_closed: "Kapalı" hubs_buy: "Neler Bulabilirsiniz:" hubs_shopping_here: "Alışveriş noktası" - hubs_orders_closed: "SİPARİŞ KAPANIŞ" + hubs_orders_closed: "Siparişler kapalı" hubs_profile_only: "Yalnızca profil" hubs_delivery_options: "Teslimat seçenekleri" hubs_pickup: "Teslimat Noktası" @@ -1568,7 +1570,7 @@ tr: components_filters_clearfilters: "Tüm filtreleri temizle" groups_title: Gruplar groups_headline: Gruplar - groups_text: "Her üretici özeldir ve her işletmenin ortaya koyabileceği farklı bir değer vardır. Üyelerimiz, ürünlerini ve emeklerini, ya da sadece gıdanın ortak değerleri paylaşan üretici, türetici ve dağıtımcı kolektifleridir. Bu bileşenler, adil ve temiz gıdaya ulaşım yollarını kolaylaştırır ve bozulmuş gıda sistemini hep beraber düzeltmemize yardımcı olur." + groups_text: "Her üretici özeldir ve her işletmenin ortaya koyabileceği farklı bir değer vardır. Üyelerimiz, ürünlerini, emeklerini ve gıdanın ortak değerleri paylaşan üretici, türetici ve dağıtımcı kolektifleridir. Bu bileşenler, adil ve temiz gıdaya ulaşım yollarını kolaylaştırır ve bozulmuş gıda sistemini hep beraber düzeltmemize yardımcı olur." groups_search: "İsim veya anahtar kelime ile ara" groups_no_groups: "Grup bulunamadı" groups_about: "Hakkımızda" @@ -1657,7 +1659,7 @@ tr: orders_fees: Ücretler ... orders_edit_title: Alışveriş Sepeti orders_edit_headline: Alışveriş sepetiniz - orders_edit_time: SİPARİŞ ŞU TARİHTE HAZIR + orders_edit_time: Sipariş Teslimat orders_edit_continue: Alışverişe devam orders_edit_checkout: Ödeme Yap orders_form_empty_cart: "Sepeti Boşalt" @@ -1700,7 +1702,7 @@ tr: password: Parola remember_me: Beni Hatırla are_you_sure: "Emin misiniz?" - orders_open: 'SİPARİŞ AÇILIŞ:' + orders_open: Siparişler açık closing: "Kapanış" going_back_to_home_page: "Ana sayfaya yönlendiriliyorsunuz.." creating: oluşturuluyor @@ -2036,7 +2038,7 @@ tr: edit_profile_details: "Profil bilgilerini düzenle" edit_profile_details_etc: "Profil açıklamanızı, resimlerinizi vb. değiştirin." order_cycle: "Sipariş Dönemi" - order_cycles: "Sipariş Dönemleri" + order_cycles: "SİPARİŞ DÖNEMLERİ" enterprise_relationships: "İŞLETME İZİNLERİ" remove_tax: "Vergiyi kaldır" first_name_begins_with: "Adının BAŞ HARFİ" @@ -2738,6 +2740,7 @@ tr: customer_details: "Müşteri detayları" adjustments: "Düzeltmeler" payments: "Ödemeler" + return_authorizations: "İade Yetkileri" payment: "Ödeme" payment_method: "Ödeme yöntemi" shipment: "Teslimat" @@ -2931,6 +2934,12 @@ tr: options: "Seçenekler" actions: update: "Güncelle" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 hata kaydedilmesini engelledi:" + other: "%{count}hata kaydedilmeyi engelledi:" + there_were_problems_with_the_following_fields: "Gösterilen alanlar ile ilgili sorun oluştu:" errors: messages: blank: "boş olamaz" @@ -2953,7 +2962,7 @@ tr: configuration: "KURULUM" users: "Kullanıcılar" roles: "Roller" - order_cycles: "Sipariş Dönemleri" + order_cycles: "SİPARİŞ DÖNEMLERİ" enterprises: "İşletmeler" enterprise_relationships: "İZİNLER" customers: "Müşteriler" @@ -3057,7 +3066,7 @@ tr: one: "Bir aktif ürününüz var" other: "%{count} aktif ürününüz var" order_cycles: - order_cycles: "Sipariş Dönemleri" + order_cycles: "SİPARİŞ DÖNEMLERİ" order_cycles_tip: "Sipariş dönemleri, ürünlerinizin müşterilere ne zaman ve nerede ulaşacağını belirler." you_have_active: zero: "Aktif sipariş döneminiz yok." From 85abfd2056ed33bf8f3bf44279ac4fdf430818a2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 10:52:13 +0200 Subject: [PATCH 465/507] Create Cart sidebar and controller --- .../cart_dropdown_controller.js.coffee | 5 + .../stylesheets/darkswarm/shop.css.scss | 400 +++++++++--------- app/views/shared/menu/_cart_sidebar.html.haml | 8 + app/views/shared/menu/_menu.html.haml | 10 +- app/views/shared/menu/_mobile_menu.html.haml | 4 +- 5 files changed, 220 insertions(+), 207 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee create mode 100644 app/views/shared/menu/_cart_sidebar.html.haml diff --git a/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee new file mode 100644 index 0000000000..9606db1168 --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee @@ -0,0 +1,5 @@ +Darkswarm.controller "CartDropdownCtrl", ($scope) -> + $scope.showCartSidebar = false + + $scope.toggleCartSidebar = -> + $scope.showCartSidebar = !$scope.showCartSidebar diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss index 0c46523184..885536208c 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.scss +++ b/app/assets/stylesheets/darkswarm/shop.css.scss @@ -16,243 +16,241 @@ $sidebar-medium-width: 65%; $sidebar-large-width: 45%; $sidebar-footer-height: 5em; -.darkswarm { - .shop-filters-sidebar { - display: flex; - flex-direction: column; +.shop-filters-sidebar, .cart-sidebar { + display: flex; + flex-direction: column; + height: 100%; + + .background { + position: fixed; + top: 0; + right: 0; + z-index: 200; height: 100%; + width: 100%; + background-color: $shop-sidebar-overlay; + opacity: 0; + transition: opacity $transition-sidebar; + } + &.shown { .background { - position: fixed; - top: 0; - right: 0; - z-index: 200; - height: 100%; - width: 100%; - background-color: $shop-sidebar-overlay; - opacity: 0; - transition: opacity $transition-sidebar; + opacity: 1; } - &.shown { - .background { - opacity: 1; - } - - .sidebar, .sidebar-footer { - margin-right: 0; - } - } - - .sidebar { - position: fixed; - top: 0; - right: 0; - z-index: 210; - height: 100%; - width: $sidebar-large-width; - margin-right: -$sidebar-large-width; - background-color: rgba($white, 0.95); - padding: 1em; - transition: margin $transition-sidebar; - overflow-y: scroll; - - .property-selectors { - margin-bottom: $sidebar-footer-height + 2em; - } - } - - .sidebar-footer { - background-color: $grey-800; - width: $sidebar-large-width; - margin-right: -$sidebar-large-width; - height: $sidebar-footer-height; - position: fixed; - bottom: 0; - right: 0; - transition: margin $transition-sidebar; - padding: 1em; - - button { - width: 48%; - } - } - - @include breakpoint(tablet) { - .sidebar, .sidebar-footer { - width: $sidebar-medium-width; - margin-right: -$sidebar-medium-width; - } - } - - @include breakpoint(mobile) { - .sidebar, .sidebar-footer { - width: $sidebar-small-width; - margin-right: -$sidebar-small-width; - } + .sidebar, .sidebar-footer { + margin-right: 0; } } - products { + .sidebar { + position: fixed; + top: 0; + right: 0; + z-index: 210; + height: 100%; + width: $sidebar-large-width; + margin-right: -$sidebar-large-width; + background-color: rgba($white, 0.95); + padding: 1em; + transition: margin $transition-sidebar; + overflow-y: scroll; + + .property-selectors { + margin-bottom: $sidebar-footer-height + 2em; + } + } + + .sidebar-footer { + background-color: $grey-800; + width: $sidebar-large-width; + margin-right: -$sidebar-large-width; + height: $sidebar-footer-height; + position: fixed; + bottom: 0; + right: 0; + transition: margin $transition-sidebar; + padding: 1em; + + button { + width: 48%; + } + } + + @include breakpoint(tablet) { + .sidebar, .sidebar-footer { + width: $sidebar-medium-width; + margin-right: -$sidebar-medium-width; + } + } + + @include breakpoint(mobile) { + .sidebar, .sidebar-footer { + width: $sidebar-small-width; + margin-right: -$sidebar-small-width; + } + } +} + +products { + display: block; + + @include breakpoint(tablet) { + input.button.right { + float: left; + } + } + + @include breakpoint(mobile) { + .add_to_cart { + margin-top: 2rem; + } + } + + form { + input.small.button.primary.right.add_to_cart { + &.dirty { + padding-left: 3.2rem; + } + } + + i.cart-spinner { + position: absolute; + top: 14px; + right: 146px; + color: white; + font-size: 1.2em; + + // Necessary to be below Z index of cart popover: + z-index: 98; + -webkit-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; + } + } + + product { + @include csstrans; + + border-bottom: 1px solid #e5e5e5; + border-top: 1px solid #e5e5e5; + padding-bottom: 1px; + margin-bottom: 20px !important; + position: relative; display: block; + color: $med-drk-grey; - @include breakpoint(tablet) { - input.button.right { - float: left; + &:hover, &:focus, &:active { + border-bottom: 1px solid $clr-brick-med-bright; + border-top: 1px solid $clr-brick-med-bright; + } + + // BULK + .bulk-buy { + font-size: 0.875rem; + + @include breakpoint(tablet) { + font-size: 0.75rem; } } - @include breakpoint(mobile) { - .add_to_cart { - margin-top: 2rem; + .bulk-buy, .bulk-buy i { + color: #888; + } + + .inline { + display: inline; + } + + .spinner { + width: 100px; + margin-bottom: 20px; + } + + // ICONS + i { + font-size: 0.75em; + padding-right: 0.9375rem; + + @include breakpoint(phablet) { + padding-right: 0.25rem; } } - form { - input.small.button.primary.right.add_to_cart { - &.dirty { - padding-left: 3.2rem; - } - } - - i.cart-spinner { - position: absolute; - top: 14px; - right: 146px; - color: white; - font-size: 1.2em; - - // Necessary to be below Z index of cart popover: - z-index: 98; - -webkit-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; - } + i.ofn-i_056-bulk { + font-size: 1rem; + padding-right: 0rem; } - product { - @include csstrans; - - border-bottom: 1px solid #e5e5e5; - border-top: 1px solid #e5e5e5; - padding-bottom: 1px; - margin-bottom: 20px !important; - position: relative; - display: block; - color: $med-drk-grey; - - &:hover, &:focus, &:active { - border-bottom: 1px solid $clr-brick-med-bright; - border-top: 1px solid $clr-brick-med-bright; - } - - // BULK - .bulk-buy { - font-size: 0.875rem; - - @include breakpoint(tablet) { - font-size: 0.75rem; - } - } - - .bulk-buy, .bulk-buy i { - color: #888; - } - - .inline { - display: inline; - } - - .spinner { - width: 100px; - margin-bottom: 20px; - } - - // ICONS - i { - font-size: 0.75em; - padding-right: 0.9375rem; - - @include breakpoint(phablet) { - padding-right: 0.25rem; - } - } - - i.ofn-i_056-bulk { - font-size: 1rem; - padding-right: 0rem; - } - - i.ofn-i_036-producers { - padding-left: 0.2rem; - padding-right: 0rem; - font-size: 0.8rem; - } + i.ofn-i_036-producers { + padding-left: 0.2rem; + padding-right: 0rem; + font-size: 0.8rem; } } +} - .alert-box.changeable-orders-alert { - margin-bottom: 0px; +.alert-box.changeable-orders-alert { + margin-bottom: 0px; +} + +.select-oc-message { + margin-top: 1rem; + + .highlighted { + color: $red-700; + font-weight: bold; } +} - .select-oc-message { - margin-top: 1rem; +.open-shop-message { + a { + color: #0096ad; - .highlighted { - color: $red-700; - font-weight: bold; + &:hover, &:focus, &:active { + text-decoration: none; + color: #4aadbd; } } +} - .open-shop-message { - a { - color: #0096ad; +.closed-shop-header { + background-color: $grey-650; + color: $white; - &:hover, &:focus, &:active { - text-decoration: none; - color: #4aadbd; - } - } - } - - .closed-shop-header { - background-color: $grey-650; + h4 { color: $white; - - h4 { - color: $white; - } - - p { - margin: 1rem 0 0.4rem; - } - - .message { - display: inline-block; - } } + p { + margin: 1rem 0 0.4rem; + } + + .message { + display: inline-block; + } +} + .warning-sign { margin: 0 10px 0 5px; display: inline-block; line-height: 1.9rem; - strong { - color: $grey-650; - display: block; - position: relative; - text-align: center; - width: 23px; - } + strong { + color: $grey-650; + display: block; + position: relative; + text-align: center; + width: 23px; + } - .rectangle { - background-color: $white; - border-radius: 4px; - color: $grey-650; - height: 23px; - position: absolute; - top: 27px; - transform: rotate(-315deg); - width: 23px; - } + .rectangle { + background-color: $white; + border-radius: 4px; + color: $grey-650; + height: 23px; + position: absolute; + top: 27px; + transform: rotate(-315deg); + width: 23px; } } diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml new file mode 100644 index 0000000000..56624a8ed9 --- /dev/null +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -0,0 +1,8 @@ +.cart-sidebar{ng: {show: 'showCartSidebar', class: "{'shown': showCartSidebar, 'hidden': !showCartSidebar}"}} + .background{ng: {click: 'toggleCartSidebar()'}} + .sidebar + .sidebar-footer + %button.large.dark.left{type: 'button'} + Edit Cart + %button.large.bright.right{type: 'button', ng: {click: 'toggleCartSidebar()'}} + Checkout diff --git a/app/views/shared/menu/_menu.html.haml b/app/views/shared/menu/_menu.html.haml index 050a3f043e..4559434a8f 100644 --- a/app/views/shared/menu/_menu.html.haml +++ b/app/views/shared/menu/_menu.html.haml @@ -1,4 +1,6 @@ -= render "shared/menu/large_menu" -%ofn-flash -= render "shared/menu/mobile_menu" -= render "shared/menu/offcanvas_menu" +%div{'ng-controller' => 'CartDropdownCtrl'} + = render "shared/menu/large_menu" + %ofn-flash + = render "shared/menu/mobile_menu" + = render "shared/menu/offcanvas_menu" + = render "shared/menu/cart_sidebar" diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index 8ef5ef7b5d..d13dbeae07 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -9,8 +9,8 @@ %img{src: ContentConfig.logo_mobile.url, srcset: ContentConfig.logo_mobile_svg.url, width: "75", height: "26"} %section.right{"ng-cloak" => true} - %span.cart-span{"ng-controller" => "CartCtrl", "ng-class" => "{ dirty: Cart.dirty || Cart.empty(), 'pure-dirty': Cart.dirty }"} - %a.icon{href: main_app.cart_path} + %span.cart-span{"ng-class" => "{ dirty: Cart.dirty || Cart.empty(), 'pure-dirty': Cart.dirty }"} + %a.icon{ng: {click: 'toggleCartSidebar()'}} %span = t '.cart' %span.count From b1ce7f2c155aaea840b4bb58a48837b1b2ad225c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 17:45:31 +0200 Subject: [PATCH 466/507] Simplify product naming in cart --- app/assets/javascripts/darkswarm/services/variants.js.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/javascripts/darkswarm/services/variants.js.coffee b/app/assets/javascripts/darkswarm/services/variants.js.coffee index 456fd00f01..a650db5cd7 100644 --- a/app/assets/javascripts/darkswarm/services/variants.js.coffee +++ b/app/assets/javascripts/darkswarm/services/variants.js.coffee @@ -20,7 +20,6 @@ Darkswarm.factory 'Variants', -> name = variant.product_name else name = "#{variant.product_name} - #{variant.name_to_display}" - name += " (#{variant.options_text})" if variant.options_text name lineItemFor: (variant) -> From a8b981e9cd830a4bb705f2282f4fc899effdf7dc Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 17:46:03 +0200 Subject: [PATCH 467/507] Add product thumbnais to serializer for cart dropdown images --- app/serializers/api/variant_serializer.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/serializers/api/variant_serializer.rb b/app/serializers/api/variant_serializer.rb index e824db8406..e60ec2832d 100644 --- a/app/serializers/api/variant_serializer.rb +++ b/app/serializers/api/variant_serializer.rb @@ -3,7 +3,7 @@ class Api::VariantSerializer < ActiveModel::Serializer :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 + :tag_list, :thumb_url delegate :price, to: :object @@ -30,4 +30,12 @@ class Api::VariantSerializer < ActiveModel::Serializer object.tag_list end + + def thumb_url + if object.images.present? + object.images.first.attachment.url(:mini) + else + "/assets/noimage/mini.png" + end + end end From b4e5542e5fa274e39adf553ee4105a60bfb471f5 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 17:46:58 +0200 Subject: [PATCH 468/507] Extract re-usable sidebar styes --- .../darkswarm/expanding-sidebar.css.scss | 75 +++++++++++++++++ .../stylesheets/darkswarm/shop.css.scss | 81 +------------------ .../stylesheets/darkswarm/variables.css.scss | 5 ++ app/views/shop/products/_form.html.haml | 2 +- 4 files changed, 84 insertions(+), 79 deletions(-) create mode 100644 app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss diff --git a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss new file mode 100644 index 0000000000..07874ef5c3 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss @@ -0,0 +1,75 @@ +@import "mixins"; +@import "variables"; +@import "branding"; + +.expanding-sidebar { + display: flex; + flex-direction: column; + height: 100%; + + .background { + position: fixed; + top: 0; + right: 0; + z-index: 200; + height: 100%; + width: 100%; + background-color: $shop-sidebar-overlay; + opacity: 0; + transition: opacity $transition-sidebar; + } + + &.shown { + .background { + opacity: 1; + } + + .sidebar, .sidebar-footer { + margin-right: 0; + } + } + + .sidebar { + position: fixed; + top: 0; + right: 0; + z-index: 210; + height: 100%; + width: $sidebar-large-width; + margin-right: -$sidebar-large-width; + background-color: rgba($white, 0.95); + padding: 1em; + transition: margin $transition-sidebar; + overflow-y: scroll; + } + + .sidebar-footer { + background-color: $grey-800; + width: $sidebar-large-width; + margin-right: -$sidebar-large-width; + min-height: $sidebar-footer-height; + position: fixed; + bottom: 0; + right: 0; + transition: margin $transition-sidebar; + padding: 1em; + + button { + width: 48%; + } + } + + @include breakpoint(tablet) { + .sidebar, .sidebar-footer { + width: $sidebar-medium-width; + margin-right: -$sidebar-medium-width; + } + } + + @include breakpoint(mobile) { + .sidebar, .sidebar-footer { + width: $sidebar-small-width; + margin-right: -$sidebar-small-width; + } + } +} diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss index 885536208c..367d414d2b 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.scss +++ b/app/assets/stylesheets/darkswarm/shop.css.scss @@ -11,84 +11,9 @@ @import "shop-taxon-flag"; @import "shop-popovers"; -$sidebar-small-width: 75%; -$sidebar-medium-width: 65%; -$sidebar-large-width: 45%; -$sidebar-footer-height: 5em; - -.shop-filters-sidebar, .cart-sidebar { - display: flex; - flex-direction: column; - height: 100%; - - .background { - position: fixed; - top: 0; - right: 0; - z-index: 200; - height: 100%; - width: 100%; - background-color: $shop-sidebar-overlay; - opacity: 0; - transition: opacity $transition-sidebar; - } - - &.shown { - .background { - opacity: 1; - } - - .sidebar, .sidebar-footer { - margin-right: 0; - } - } - - .sidebar { - position: fixed; - top: 0; - right: 0; - z-index: 210; - height: 100%; - width: $sidebar-large-width; - margin-right: -$sidebar-large-width; - background-color: rgba($white, 0.95); - padding: 1em; - transition: margin $transition-sidebar; - overflow-y: scroll; - - .property-selectors { - margin-bottom: $sidebar-footer-height + 2em; - } - } - - .sidebar-footer { - background-color: $grey-800; - width: $sidebar-large-width; - margin-right: -$sidebar-large-width; - height: $sidebar-footer-height; - position: fixed; - bottom: 0; - right: 0; - transition: margin $transition-sidebar; - padding: 1em; - - button { - width: 48%; - } - } - - @include breakpoint(tablet) { - .sidebar, .sidebar-footer { - width: $sidebar-medium-width; - margin-right: -$sidebar-medium-width; - } - } - - @include breakpoint(mobile) { - .sidebar, .sidebar-footer { - width: $sidebar-small-width; - margin-right: -$sidebar-small-width; - } +.shop-filters-sidebar { + .property-selectors { + margin-bottom: $sidebar-footer-height + 2em; } } diff --git a/app/assets/stylesheets/darkswarm/variables.css.scss b/app/assets/stylesheets/darkswarm/variables.css.scss index 115212fc76..08930efd76 100644 --- a/app/assets/stylesheets/darkswarm/variables.css.scss +++ b/app/assets/stylesheets/darkswarm/variables.css.scss @@ -33,6 +33,11 @@ $topbar-dropdown-link-bg-hover: $white; $mobile-nav-height: 2.8em; +$sidebar-small-width: 75%; +$sidebar-medium-width: 65%; +$sidebar-large-width: 45%; +$sidebar-footer-height: 5em; + $radius-small: 0.25em; $radius-medium: 0.5em; diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 7d2718c2d5..ffbc7bdf25 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -31,7 +31,7 @@ = render partial: "shop/products/filters" - .shop-filters-sidebar.hide-for-large-up{ng: {show: 'showFilterSidebar', class: "{'shown': showFilterSidebar}"}} + .expanding-sidebar.shop-filters-sidebar.hide-for-large-up{ng: {show: 'showFilterSidebar', class: "{'shown': showFilterSidebar}"}} .background{ng: {click: 'toggleFilterSidebar()'}} .sidebar %h5 From 400fce8ef9a29bb299264424045e9609f26355d5 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 17:50:17 +0200 Subject: [PATCH 469/507] Separate cart page and cart dropdown styles --- .../stylesheets/darkswarm/cart-page.css.scss | 71 +++++++++ .../darkswarm/shopping-cart.css.scss | 140 ------------------ 2 files changed, 71 insertions(+), 140 deletions(-) create mode 100644 app/assets/stylesheets/darkswarm/cart-page.css.scss delete mode 100644 app/assets/stylesheets/darkswarm/shopping-cart.css.scss diff --git a/app/assets/stylesheets/darkswarm/cart-page.css.scss b/app/assets/stylesheets/darkswarm/cart-page.css.scss new file mode 100644 index 0000000000..9c0d76e11e --- /dev/null +++ b/app/assets/stylesheets/darkswarm/cart-page.css.scss @@ -0,0 +1,71 @@ +@import "mixins"; +@import "branding"; +@import "compass/css3/user-interface"; +@import "variables"; + +#update-cart { + #errorExplanation { + display: none; + } +} + +#cart-detail { + .cart-item-delete, .bought-item-delete { + a { + font-size: 1.125em; + } + } + + .out-of-stock { + color: $clr-brick; + } + + button, .button { + margin: 0; + } + + .toggle-bought { + cursor: pointer; + } + + tr.bought td { + color: $med-grey; + + h5 { + color: $med-grey; + } + + .already-confirmed { + float: right; + } + } + + input { + &.ng-invalid-stock, &.ng-invalid-number { + border: 1px solid $clr-brick; + } + } +} + +.item-thumb-image { + display: none; + + @media screen and (min-width: 640px) { + display: inline-block; + float: left; + padding-right: 0.5em; + width: 36px; + height: 36px; + } +} + +.links { + .button { + padding: 1.125rem 0 1.1875rem; + width: 210px; + + @media all and (max-width: 480px) { + width: 100%; + } + } +} diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss deleted file mode 100644 index d00f3915e7..0000000000 --- a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss +++ /dev/null @@ -1,140 +0,0 @@ -@import "mixins"; -@import "branding"; -@import "compass/css3/user-interface"; -@import 'variables'; - -.cart { - @include user-select(none); - - .cart-span, .cart-span a { - display: inline-block; - } - - .cart-span { - float: left; - } - - .joyride-tip-guide { - display: block; - right: 0; - top: $topbar-height; - width: 480px; - - @media screen and (min-width: 641px) { - overflow-y: auto; - max-height: calc(95vh - 55px); - } - - @media screen and (max-width: 640px) { - width: 96%; - } - - .joyride-nub { - right: 22px !important; - left: auto; - } - - table { - width: 100%; - border: none; - border-spacing: 0px; - margin-bottom: 5px; - - tr.total-cart { - color: #fff; - background-color: #424242; - - td { - color: #fff; - } - } - - tr.product-cart { - background-color: #333333; - border-top: 1px solid #424242; - - td { - padding: 4px 12px; - color: #fff; - } - } - } - - .buttons { - margin-bottom: 0.1em; - - .button { - height: auto; - top: 0px; - } - } - } -} - -// Shopping cart -#update-cart { - #errorExplanation { - display: none; - } -} - -#cart-detail { - .cart-item-delete, .bought-item-delete { - a { - font-size: 1.125em; - } - } - - .out-of-stock { - color: $clr-brick; - } - - button, .button { - margin: 0; - } - - .toggle-bought { - cursor: pointer; - } - - tr.bought td { - color: $med-grey; - - h5 { - color: $med-grey; - } - - .already-confirmed { - float: right; - } - } - - input { - &.ng-invalid-stock, &.ng-invalid-number { - border: 1px solid $clr-brick; - } - } -} - -.item-thumb-image { - display: none; - - @media screen and (min-width: 640px) { - display: inline-block; - float: left; - padding-right: 0.5em; - width: 36px; - height: 36px; - } -} - -.links { - .button { - padding: 1.125rem 0 1.1875rem; - width: 210px; - - @media all and (max-width: 480px) { - width: 100%; - } - } -} From 33a2dd100ebdf5356add6d35a38366fe17298694 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 17:51:00 +0200 Subject: [PATCH 470/507] Add new layout for cart sidebar --- .../darkswarm/cart-dropdown.css.scss | 77 +++++++++++++++++++ app/views/shared/menu/_cart.html.haml | 4 +- app/views/shared/menu/_cart_sidebar.html.haml | 36 +++++++-- 3 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 app/assets/stylesheets/darkswarm/cart-dropdown.css.scss diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss new file mode 100644 index 0000000000..5b7f21b7ea --- /dev/null +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -0,0 +1,77 @@ +@import "mixins"; +@import "variables"; +@import "branding"; + +.expanding-sidebar.cart-sidebar { + .sidebar { + padding: 0; + background-color: $white; + } + + .cart-header { + padding: 1em; + border-bottom: 1px solid $grey-100; + + .title { + color: $grey-800; + margin: 0; + } + + .close { + color: $grey-500; + float: right; + + i { + vertical-align: middle; + } + } + } + + .cart-content { + margin-bottom: $sidebar-footer-height + 2em; + } + + table { + width: 100%; + border: none; + border-spacing: 0; + margin: 0; + + tr.product-cart { + background-color: white; + + td { + border-bottom: 1px solid $grey-100; + padding: 0.75em 1em 0.5em 1em; + vertical-align: top; + + &.image { + width: 42px; + padding: 0.5em 0 0.5em 1em; + } + + span { + color: $grey-800; + font-size: 16px; + line-height: 1.25; + } + + img { + max-width: 56px; + max-height: 56px; + } + + .options-text { + color: $grey-500; + font-size: 14px; + } + } + } + } + + .cart-total { + color: $white; + text-align: center; + margin: -0.5em 0 0.75em 0; + } +} diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index d6408dc634..1fd1b06e89 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -1,10 +1,8 @@ %span.cart-span{"ng-controller" => "CartCtrl", "ng-class" => "{ dirty: Cart.dirty || Cart.empty(), 'pure-dirty': Cart.dirty }"} - %a#cart.icon{"cart-toggle" => true} + %a#cart.icon{"ng-click" => "toggleCartSidebar()"} %span = t '.cart' %span.count %img{ src: image_path("menu/icn-cart.svg") } %span {{ Cart.total_item_count() }} - - = render 'shared/menu/joyride' diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index 56624a8ed9..a5aaf2dec1 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -1,8 +1,34 @@ -.cart-sidebar{ng: {show: 'showCartSidebar', class: "{'shown': showCartSidebar, 'hidden': !showCartSidebar}"}} +.expanding-sidebar.cart-sidebar{ng: {controller: 'CartCtrl', show: 'showCartSidebar', class: "{'shown': showCartSidebar, 'hidden': !showCartSidebar}"}} .background{ng: {click: 'toggleCartSidebar()'}} .sidebar + .cart-header + %span.title + 5 items in your cart + %span.close + Close + %i.ofn-i_009-close + .cart-content + %table + %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items", "id" => "cart-variant-{{ line_item.variant.id }}"} + %td.image + %img{'ng-src' => '{{ line_item.variant.thumb_url }}'} + %td + %span {{ line_item.variant.extended_name }} + %br + %span.options-text {{ line_item.variant.options_text }} + %td.text-right + %span.quantity {{ line_item.quantity }} + %td + %span.total-price.right {{ line_item.total_price | localizeCurrency }} + .sidebar-footer - %button.large.dark.left{type: 'button'} - Edit Cart - %button.large.bright.right{type: 'button', ng: {click: 'toggleCartSidebar()'}} - Checkout + %p.cart-total{"ng-show" => "Cart.line_items.length > 0"} + %strong + = t 'total' + \: + {{ Cart.total() | localizeCurrency }} + + %button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} + = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" + %button.large.bright.right{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} + = t '.checkout' From be8c0f360052b410bdd236c3afe54adaa0e752da Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 17:51:31 +0200 Subject: [PATCH 471/507] Remove old cart dropdown view and directive --- .../directives/cart_toggle.js.coffee | 19 ------ app/views/shared/menu/_joyride.html.haml | 63 ------------------- 2 files changed, 82 deletions(-) delete mode 100644 app/assets/javascripts/darkswarm/directives/cart_toggle.js.coffee delete mode 100644 app/views/shared/menu/_joyride.html.haml diff --git a/app/assets/javascripts/darkswarm/directives/cart_toggle.js.coffee b/app/assets/javascripts/darkswarm/directives/cart_toggle.js.coffee deleted file mode 100644 index cb7e574d87..0000000000 --- a/app/assets/javascripts/darkswarm/directives/cart_toggle.js.coffee +++ /dev/null @@ -1,19 +0,0 @@ -Darkswarm.directive "cartToggle", ($document) -> - # Toggles visibility of the "cart" popover - restrict: 'A' - link: (scope, elem, attr)-> - scope.open = false - - $document.bind 'click', (event) -> - cart_button = elem[0] - element_and_parents = [event.target, event.target.parentElement, event.target.parentElement.parentElement] - cart_button_clicked = (element_and_parents.indexOf(cart_button) != -1) - - if cart_button_clicked - scope.$apply -> - scope.open = !scope.open - else - scope.$apply -> - scope.open = false - - return diff --git a/app/views/shared/menu/_joyride.html.haml b/app/views/shared/menu/_joyride.html.haml deleted file mode 100644 index eb1875f383..0000000000 --- a/app/views/shared/menu/_joyride.html.haml +++ /dev/null @@ -1,63 +0,0 @@ -.cart-dropdown.joyride-tip-guide{"ng-class" => "{ in: open }", "ng-show" => "open"} - %span.joyride-nub.top - .joyride-content-wrapper - %h5 - = t 'cart_headline' - .buttons.text-right - %a.button.secondary.tiny.add_to_cart{ href: main_app.cart_path, type: :submit, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }" } - = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" - %a.button.primary.tiny{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} - = t '.checkout' - %table - %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items", "id" => "cart-variant-{{ line_item.variant.id }}"} - %td - %small - %strong - {{ line_item.variant.extended_name }} - %td.text-right - %small - %span.quantity {{ line_item.quantity }} - %i.ofn-i_009-close - %span.price {{ line_item.variant.price_with_fees | localizeCurrency }} - - %td - %small - \= - %strong - .total-price.right {{ line_item.total_price | localizeCurrency }} - - %table{"ng-show" => "Cart.line_items.length > 0"} - %tr.total-cart - %td - %em - = t 'total' - \: - %td.text-right - %strong {{ Cart.total() | localizeCurrency }} - - .buttons.text-right - %a.button.secondary.tiny.add_to_cart{ href: main_app.cart_path, type: :submit, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }" } - = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" - %a.button.primary.tiny{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} - = t '.checkout' - - if order_changes_allowed? - %h5{"ng-if" => "Cart.line_items_finalised.length", style: 'margin-top: 1em'} - = t '.already_ordered_products' - %table - %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised", - "id" => "cart-variant-{{ line_item.variant.id }}"} - %td - %small - %strong - {{ line_item.variant.extended_name }} - %td.text-right - %small - %span.quantity {{ line_item.quantity }} - %i.ofn-i_009-close - %span.price {{ line_item.variant.price_with_fees | localizeCurrency }} - - %td - %small - \= - %strong - .total-price.right {{ line_item.total_price | localizeCurrency }} \ No newline at end of file From 4362b8b25ba75d06468d5114d3d3c6a44d6ace83 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 18:07:38 +0200 Subject: [PATCH 472/507] Improve line spacing on cart product list --- app/assets/stylesheets/darkswarm/cart-dropdown.css.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index 5b7f21b7ea..e1a969b9f2 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -53,7 +53,7 @@ span { color: $grey-800; font-size: 16px; - line-height: 1.25; + line-height: 1.4em; } img { From 7efccac7bbbaf895a1651169dda81bc923653324 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 18:10:28 +0200 Subject: [PATCH 473/507] Add close functionality to close button --- app/views/shared/menu/_cart_sidebar.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index a5aaf2dec1..d3a5216e86 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -4,7 +4,7 @@ .cart-header %span.title 5 items in your cart - %span.close + %a.close{ng: {click: 'toggleCartSidebar()'}} Close %i.ofn-i_009-close .cart-content From 95686eda78e066b87395a9cef8fe643a2d59aa3a Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 18:16:56 +0200 Subject: [PATCH 474/507] Update translations --- app/views/shared/menu/_cart_sidebar.html.haml | 6 +++--- config/locales/en.yml | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index d3a5216e86..84d85f95e1 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -3,9 +3,9 @@ .sidebar .cart-header %span.title - 5 items in your cart + = t('.items_in_cart', num: "{{ Cart.total_item_count() }}") %a.close{ng: {click: 'toggleCartSidebar()'}} - Close + = t('.close') %i.ofn-i_009-close .cart-content %table @@ -29,6 +29,6 @@ {{ Cart.total() | localizeCurrency }} %button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} - = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" + = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t('.edit_cart')}' ) }}" %button.large.bright.right{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t '.checkout' diff --git a/config/locales/en.yml b/config/locales/en.yml index 5b89620b2b..996294ad01 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1216,6 +1216,11 @@ en: menu: cart: cart: "Cart" + cart_sidebar: + checkout: "Checkout" + edit_cart: "Edit cart" + items_in_cart: "%{num} items in your cart" + close: "Close" signed_in: profile: "Profile" mobile_menu: From 8ca0119f5d7bf57401a6caf009030a41ba3dd4b9 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 18:45:21 +0200 Subject: [PATCH 475/507] Add empty cart feedback --- .../stylesheets/darkswarm/cart-dropdown.css.scss | 13 +++++++++++-- app/views/shared/menu/_cart_sidebar.html.haml | 11 ++++++++--- config/locales/en.yml | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index e1a969b9f2..69e0dc642e 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -10,7 +10,6 @@ .cart-header { padding: 1em; - border-bottom: 1px solid $grey-100; .title { color: $grey-800; @@ -29,6 +28,16 @@ .cart-content { margin-bottom: $sidebar-footer-height + 2em; + + .cart-empty { + text-align: center; + padding-top: 10em; + width: 100%; + + span { + font-size: 1.5em; + } + } } table { @@ -41,7 +50,7 @@ background-color: white; td { - border-bottom: 1px solid $grey-100; + border-top: 1px solid $grey-100; padding: 0.75em 1em 0.5em 1em; vertical-align: top; diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index 84d85f95e1..7be2c0f1fe 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -2,11 +2,12 @@ .background{ng: {click: 'toggleCartSidebar()'}} .sidebar .cart-header - %span.title + %span.title{"ng-show" => "Cart.line_items.length > 0"} = t('.items_in_cart', num: "{{ Cart.total_item_count() }}") %a.close{ng: {click: 'toggleCartSidebar()'}} = t('.close') %i.ofn-i_009-close + .cart-content %table %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items", "id" => "cart-variant-{{ line_item.variant.id }}"} @@ -21,8 +22,12 @@ %td %span.total-price.right {{ line_item.total_price | localizeCurrency }} - .sidebar-footer - %p.cart-total{"ng-show" => "Cart.line_items.length > 0"} + .cart-empty{"ng-show" => "Cart.line_items.length == 0"} + %span + = t('.cart_empty') + + .sidebar-footer{"ng-show" => "Cart.line_items.length > 0"} + %p.cart-total %strong = t 'total' \: diff --git a/config/locales/en.yml b/config/locales/en.yml index 996294ad01..89acb46306 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1221,6 +1221,7 @@ en: edit_cart: "Edit cart" items_in_cart: "%{num} items in your cart" close: "Close" + cart_empty: "Your cart is empty" signed_in: profile: "Profile" mobile_menu: From 439674ad9c90bb49f535be6e5365c410b7e5e6ad Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 18:54:16 +0200 Subject: [PATCH 476/507] Make cart view fullwidth on mobile --- app/assets/stylesheets/darkswarm/cart-dropdown.css.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index 69e0dc642e..71cd0a8cd2 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -83,4 +83,11 @@ text-align: center; margin: -0.5em 0 0.75em 0; } + + @include breakpoint(mobile) { + .sidebar, .sidebar-footer { + width: 100%; + margin-right: -100%; + } + } } From 4a0f43a8313a2f74d40b9b8a9aff7c5394bfa4bf Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 18:58:39 +0200 Subject: [PATCH 477/507] Ensure cart item count is visible in header cart button (for screens smaller than desktop) --- .../darkswarm/controllers/cart_dropdown_controller.js.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee index 9606db1168..f22e237f06 100644 --- a/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee @@ -1,4 +1,5 @@ -Darkswarm.controller "CartDropdownCtrl", ($scope) -> +Darkswarm.controller "CartDropdownCtrl", ($scope, Cart) -> + $scope.Cart = Cart $scope.showCartSidebar = false $scope.toggleCartSidebar = -> From b74b9fbd1dbad33bf7ffee627dc4c1ed00dc5cb8 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 23:19:57 +0200 Subject: [PATCH 478/507] Shift sidebar down vertically (below navigation) and bring navigation up (z-index) --- .../stylesheets/darkswarm/cart-dropdown.css.scss | 11 ++++++++++- app/assets/stylesheets/darkswarm/menu.css.scss | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index 71cd0a8cd2..c098f43d11 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -3,9 +3,18 @@ @import "branding"; .expanding-sidebar.cart-sidebar { + .background { + z-index: 150; + } + .sidebar { - padding: 0; + padding: $topbar-height 0 0; background-color: $white; + z-index: 160; + + @include breakpoint(desktop) { + padding: $mobile-nav-height 0 0; + } } .cart-header { diff --git a/app/assets/stylesheets/darkswarm/menu.css.scss b/app/assets/stylesheets/darkswarm/menu.css.scss index abefec7a23..b48ed93091 100644 --- a/app/assets/stylesheets/darkswarm/menu.css.scss +++ b/app/assets/stylesheets/darkswarm/menu.css.scss @@ -11,6 +11,7 @@ nav.top-bar { font-size: 16px; margin-bottom: 0; height: $topbar-height; + z-index: 190; } @media #{$large-only} { @@ -174,7 +175,7 @@ nav.top-bar { height: $mobile-nav-height; position: fixed; width: 100%; - z-index: 1; + z-index: 190; .cart-span { background-color: #f4704c; From 2f2ef28351e512f9ab24e57967444afbca87620a Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 21 May 2020 23:53:15 +0200 Subject: [PATCH 479/507] Use links instead of buttons and fix up styles --- app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss | 6 +++++- app/assets/stylesheets/darkswarm/ui.css.scss | 2 +- app/views/shared/menu/_cart_sidebar.html.haml | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss index 07874ef5c3..e6b2becbac 100644 --- a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss +++ b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss @@ -54,9 +54,13 @@ transition: margin $transition-sidebar; padding: 1em; - button { + button, a.button { width: 48%; } + + a.button { + line-height: 2.75em; + } } @include breakpoint(tablet) { diff --git a/app/assets/stylesheets/darkswarm/ui.css.scss b/app/assets/stylesheets/darkswarm/ui.css.scss index 66d72d6511..5143d52cab 100644 --- a/app/assets/stylesheets/darkswarm/ui.css.scss +++ b/app/assets/stylesheets/darkswarm/ui.css.scss @@ -124,7 +124,7 @@ button.success, .button.success { } } -button.large { +button.large, a.button.large { height: 3em; font-size: 1em; color: $white; diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index 7be2c0f1fe..1bfde559f8 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -33,7 +33,7 @@ \: {{ Cart.total() | localizeCurrency }} - %button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} + %a.button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t('.edit_cart')}' ) }}" - %button.large.bright.right{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} + %a.button.large.bright.right{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t '.checkout' From 459e53f43d93cf6b404d9536289e329e3faa9e87 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 15:39:10 +0200 Subject: [PATCH 480/507] Adjust specs for new cart display --- app/views/shared/menu/_cart_sidebar.html.haml | 4 ++-- spec/features/consumer/shopping/shopping_spec.rb | 16 +++++++++------- .../consumer/shopping/variant_overrides_spec.rb | 13 ++++++------- .../darkswarm/services/variants_spec.js.coffee | 16 ---------------- spec/support/request/shop_workflow.rb | 8 ++++---- spec/support/request/ui_component_helper.rb | 6 +++--- 6 files changed, 24 insertions(+), 39 deletions(-) diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index 1bfde559f8..bb00e88b91 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -33,7 +33,7 @@ \: {{ Cart.total() | localizeCurrency }} - %a.button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} + %a.edit-cart.button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t('.edit_cart')}' ) }}" - %a.button.large.bright.right{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} + %a.checkout.button.large.bright.right{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t '.checkout' diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index e1679791d4..85b0a92873 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -105,8 +105,9 @@ feature "As a consumer I want to shop with a distributor", js: true do # -- Cart shows correct price fill_in "variants[#{variant.id}]", with: 1 - show_cart - within("li.cart") { expect(page).to have_content with_currency(1020.99) } + toggle_cart + within(".cart-sidebar") { expect(page).to have_content with_currency(1020.99) } + toggle_cart # -- Changing order cycle accept_alert do @@ -119,8 +120,9 @@ feature "As a consumer I want to shop with a distributor", js: true do # that we are not filling in the quantity on the outgoing row expect(page).not_to have_selector "tr.product-cart" within('product:not(.ng-leave)') { fill_in "variants[#{variant.id}]", with: 1 } - show_cart - within("li.cart") { expect(page).to have_content with_currency(19.99) } + + toggle_cart + within(".cart-sidebar") { expect(page).to have_content with_currency(19.99) } end describe "declining to clear the cart" do @@ -136,9 +138,9 @@ feature "As a consumer I want to shop with a distributor", js: true do it "leaves the cart untouched when the user declines" do handle_js_confirm(false) do select "frogs", from: "order_cycle_id" - show_cart + toggle_cart expect(page).to have_selector "tr.product-cart" - expect(page).to have_selector 'li.cart', text: '1' + expect(page).to have_selector '.cart-sidebar', text: '1' # The order cycle choice should not have changed expect(page).to have_select 'order_cycle_id', selected: 'turtles' @@ -294,7 +296,7 @@ feature "As a consumer I want to shop with a distributor", js: true do expect(li.quantity).to eq(1) fill_in "variants[#{variant.id}]", with: '0' - within('li.cart') { expect(page).not_to have_content product.name } + within('.cart-sidebar') { expect(page).not_to have_content product.name } wait_until { !cart_dirty } expect(Spree::LineItem.where(id: li)).to be_empty diff --git a/spec/features/consumer/shopping/variant_overrides_spec.rb b/spec/features/consumer/shopping/variant_overrides_spec.rb index a4279786da..6dfed074a7 100644 --- a/spec/features/consumer/shopping/variant_overrides_spec.rb +++ b/spec/features/consumer/shopping/variant_overrides_spec.rb @@ -67,8 +67,8 @@ feature "shopping with variant overrides defined", js: true do it "shows the correct prices when products are in the cart" do fill_in "variants[#{product1_variant1.id}]", with: "2" - show_cart - wait_until_enabled 'li.cart a.button' + toggle_cart + wait_until_enabled '.cart-sidebar a.edit-cart' visit shop_path expect(page).to have_price with_currency(61.11) end @@ -78,9 +78,8 @@ feature "shopping with variant overrides defined", js: true do it "shows the overridden price with fees in the quick cart" do fill_in "variants[#{product1_variant1.id}]", with: "2" - show_cart + toggle_cart expect(page).to have_selector "#cart-variant-#{product1_variant1.id} .quantity", text: '2' - expect(page).to have_selector "#cart-variant-#{product1_variant1.id} .price", text: with_currency(61.11) expect(page).to have_selector "#cart-variant-#{product1_variant1.id} .total-price", text: with_currency(122.22) end @@ -202,8 +201,8 @@ feature "shopping with variant overrides defined", js: true do end def click_checkout - show_cart - wait_until_enabled 'li.cart a.button' - first(:link, 'Checkout now').click + toggle_cart + wait_until_enabled '.cart-sidebar a.edit-cart' + first(:link, I18n.t('shared.menu.cart_sidebar.checkout')).click end end diff --git a/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee index 408fecf7ea..2d9d1452f3 100644 --- a/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee @@ -49,25 +49,9 @@ describe 'Variants service', -> variant = {product_name: 'product_name', name_to_display: 'product_name'} expect(Variants.extendedVariantName(variant)).toEqual "product_name" - it "includes the options text even if variant name is same as product", -> - variant = - product_name: 'product_name' - name_to_display: 'product_name' - options_text: 'options_text' - - expect(Variants.extendedVariantName(variant)).toEqual "product_name (options_text)" - describe "when the product name and the variant name differ", -> it "returns a combined name when there is no options text", -> variant = product_name: 'product_name' name_to_display: 'name_to_display' expect(Variants.extendedVariantName(variant)).toEqual "product_name - name_to_display" - - it "returns a combined name when there is some options text", -> - variant = - product_name: 'product_name' - name_to_display: 'name_to_display' - options_text: 'options_text' - - expect(Variants.extendedVariantName(variant)).toEqual "product_name - name_to_display (options_text)" diff --git a/spec/support/request/shop_workflow.rb b/spec/support/request/shop_workflow.rb index cde1437b04..e5123715e0 100644 --- a/spec/support/request/shop_workflow.rb +++ b/spec/support/request/shop_workflow.rb @@ -1,17 +1,17 @@ module ShopWorkflow def wait_for_cart first("#cart").click - within '.cart-dropdown' do + within '.cart-sidebar' do expect(page).to_not have_link "Updating cart..." end end def edit_cart wait_for_cart - within '.cart-dropdown' do - expect(page).to have_link "Edit your cart" + within '.cart-sidebar' do + expect(page).to have_link I18n.t('shared.menu.cart_sidebar.edit_cart') end - first("a.add_to_cart").click + first("a.edit-cart").click end def have_price(price) diff --git a/spec/support/request/ui_component_helper.rb b/spec/support/request/ui_component_helper.rb index 277d8ee88c..b23002e3d7 100644 --- a/spec/support/request/ui_component_helper.rb +++ b/spec/support/request/ui_component_helper.rb @@ -59,13 +59,13 @@ module UIComponentHelper end def have_in_cart(name) - show_cart - within "li.cart" do + toggle_cart + within ".cart-sidebar" do have_content name end end - def show_cart + def toggle_cart page.find("#cart").click end From 8ac971651c6af9b36d476aeff14596e83e858523 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 16:24:27 +0200 Subject: [PATCH 481/507] Fix flaky spec --- spec/features/consumer/shopping/shopping_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 85b0a92873..b33657e6fd 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -121,7 +121,7 @@ feature "As a consumer I want to shop with a distributor", js: true do expect(page).not_to have_selector "tr.product-cart" within('product:not(.ng-leave)') { fill_in "variants[#{variant.id}]", with: 1 } - toggle_cart + wait_for_cart within(".cart-sidebar") { expect(page).to have_content with_currency(19.99) } end From 786348bc71af0388faaabb34c20d2234f180b0d2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 16:30:46 +0200 Subject: [PATCH 482/507] Remove colon from cart total text --- app/views/shared/menu/_cart_sidebar.html.haml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index bb00e88b91..0b153f7c43 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -30,7 +30,6 @@ %p.cart-total %strong = t 'total' - \: {{ Cart.total() | localizeCurrency }} %a.edit-cart.button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} From 4acb08e52b0032be43d35aacce98784b3582eca1 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 22 May 2020 16:42:12 +0200 Subject: [PATCH 483/507] Update hamburger menu icon --- app/assets/images/menu/btn-menu-mobile.png | Bin 0 -> 759 bytes app/assets/stylesheets/darkswarm/menu.css.scss | 9 +-------- app/views/shared/menu/_mobile_menu.html.haml | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) create mode 100644 app/assets/images/menu/btn-menu-mobile.png diff --git a/app/assets/images/menu/btn-menu-mobile.png b/app/assets/images/menu/btn-menu-mobile.png new file mode 100644 index 0000000000000000000000000000000000000000..1d2d414473c197f60510723cde082a6b7c00f994 GIT binary patch literal 759 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$a>cF%}28J29*~C-ahlfoY?si(^Oy z4L`ZM%{(mK+gvo_p^_iFZum{>QV! zJmwBQ^-@p3Qq+ihn07$x1RM_t7+`8@NV^0pnXe} zH*Qw8>o kaS)ZQqxr0#h=Br>mdKI;Vst04A~X?*IS* literal 0 HcmV?d00001 diff --git a/app/assets/stylesheets/darkswarm/menu.css.scss b/app/assets/stylesheets/darkswarm/menu.css.scss index b48ed93091..3c9fea8417 100644 --- a/app/assets/stylesheets/darkswarm/menu.css.scss +++ b/app/assets/stylesheets/darkswarm/menu.css.scss @@ -226,14 +226,7 @@ nav.top-bar { .off-canvas-wrap .tab-bar .menu-icon { @include box-shadow(none); -} - -.off-canvas-wrap.move-right .tab-bar .menu-icon span { - box-shadow: 0 0px 0 1px #666, 0 7px 0 1px #666, 0 14px 0 1px #666; -} - -.tab-bar .menu-icon span::after { - box-shadow: 0 0 0 1px black, 0 7px 0 1px black, 0 14px 0 1px black; + text-indent: 0; } .tab-bar .ofn-logo { diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index d13dbeae07..1c96dd1d64 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -1,7 +1,7 @@ %nav.tab-bar.show-for-medium-down %section.left %a.left-off-canvas-toggle.menu-icon - %span + %img{src: "/assets/menu/btn-menu-mobile.png"} %section.left .ofn-logo From 10b8470e297cb46f2826ea5bacf95cffb03c5b25 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 23 May 2020 12:05:49 +0200 Subject: [PATCH 484/507] Set a fixed width for cart sidebar on tablet up --- app/assets/stylesheets/darkswarm/cart-dropdown.css.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index c098f43d11..a689e1dbd9 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -93,8 +93,11 @@ margin: -0.5em 0 0.75em 0; } - @include breakpoint(mobile) { - .sidebar, .sidebar-footer { + .sidebar, .sidebar-footer { + width: 375px; + margin-right: -375px; + + @include breakpoint(mobile) { width: 100%; margin-right: -100%; } From 387a5ec950bc7558523624c7682fdefc688e0acf Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 23 May 2020 12:48:38 +0200 Subject: [PATCH 485/507] Implement "Take me shopping" button --- .../darkswarm/controllers/cart_controller.js.coffee | 3 ++- .../stylesheets/darkswarm/cart-dropdown.css.scss | 11 ++++++++++- .../stylesheets/darkswarm/expanding-sidebar.css.scss | 4 ---- app/assets/stylesheets/darkswarm/ui.css.scss | 4 ++++ app/views/shared/menu/_cart_sidebar.html.haml | 5 ++++- config/locales/en.yml | 1 + 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee index ebad820ebd..119fb640f3 100644 --- a/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee @@ -1,2 +1,3 @@ -Darkswarm.controller "CartCtrl", ($scope, Cart, $timeout) -> +Darkswarm.controller "CartCtrl", ($scope, Cart, CurrentHub) -> $scope.Cart = Cart + $scope.CurrentHub = CurrentHub diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index a689e1dbd9..c551d7cde2 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -43,12 +43,21 @@ padding-top: 10em; width: 100%; - span { + p { font-size: 1.5em; } } } + .go-shopping { + display: none; + padding: 0 1.5em; + + @include breakpoint(mobile) { + display: inline-block; + } + } + table { width: 100%; border: none; diff --git a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss index e6b2becbac..b4688e2e84 100644 --- a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss +++ b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss @@ -57,10 +57,6 @@ button, a.button { width: 48%; } - - a.button { - line-height: 2.75em; - } } @include breakpoint(tablet) { diff --git a/app/assets/stylesheets/darkswarm/ui.css.scss b/app/assets/stylesheets/darkswarm/ui.css.scss index 5143d52cab..26a371daca 100644 --- a/app/assets/stylesheets/darkswarm/ui.css.scss +++ b/app/assets/stylesheets/darkswarm/ui.css.scss @@ -124,6 +124,10 @@ button.success, .button.success { } } +a.button.large { + line-height: 2.75em; +} + button.large, a.button.large { height: 3em; font-size: 1em; diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index 0b153f7c43..c20b1b21d7 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -23,9 +23,12 @@ %span.total-price.right {{ line_item.total_price | localizeCurrency }} .cart-empty{"ng-show" => "Cart.line_items.length == 0"} - %span + %p = t('.cart_empty') + %a.go-shopping.button.large.bright{ng: {href: "{{ CurrentHub.hub.id ? '#{main_app.shop_path}' : '#{main_app.shops_path}' }}"}} + = t('.take_me_shopping') + .sidebar-footer{"ng-show" => "Cart.line_items.length > 0"} %p.cart-total %strong diff --git a/config/locales/en.yml b/config/locales/en.yml index 89acb46306..614eae8d59 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1222,6 +1222,7 @@ en: items_in_cart: "%{num} items in your cart" close: "Close" cart_empty: "Your cart is empty" + take_me_shopping: "Take me shopping!" signed_in: profile: "Profile" mobile_menu: From 2bcadd52e877aa2bd79a34c02030c6d892cb0cef Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 23 May 2020 12:48:58 +0200 Subject: [PATCH 486/507] Hide "Take me shopping" button on /shop and /shops pages --- app/helpers/shop_helper.rb | 9 +++++++++ app/views/shared/menu/_cart_sidebar.html.haml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/helpers/shop_helper.rb b/app/helpers/shop_helper.rb index a4c89bcd0d..32bb144d5f 100644 --- a/app/helpers/shop_helper.rb +++ b/app/helpers/shop_helper.rb @@ -50,4 +50,13 @@ module ShopHelper def no_open_order_cycles? @no_open_order_cycles ||= @order_cycles&.empty? end + + def show_shopping_cta? + return false if current_page?(main_app.shops_path) + + return false if current_distributor.present? && + current_page?(main_app.enterprise_shop_path(current_distributor)) + + true + end end diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index c20b1b21d7..b4b27766cd 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -26,7 +26,7 @@ %p = t('.cart_empty') - %a.go-shopping.button.large.bright{ng: {href: "{{ CurrentHub.hub.id ? '#{main_app.shop_path}' : '#{main_app.shops_path}' }}"}} + %a.go-shopping.button.large.bright{ng: {show: "#{show_shopping_cta?}", href: "{{ CurrentHub.hub.id ? '#{main_app.shop_path}' : '#{main_app.shops_path}' }}"}} = t('.take_me_shopping') .sidebar-footer{"ng-show" => "Cart.line_items.length > 0"} From bd97939062e4bb1cf806c06578d286361b98c820 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 23 May 2020 14:08:35 +0200 Subject: [PATCH 487/507] Move homepage "register here" CTA to bottom of screen. The CTA breaks the layout when the new cart sidebar is open. I can't see a nice way to keep it at the top without making a mess. --- .../darkswarm/directives/page_alert.js.coffee | 4 ++-- .../directives/smooth_scroll_to.js.coffee | 1 - .../stylesheets/darkswarm/page_alert.css.scss | 17 ++++++++--------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/darkswarm/directives/page_alert.js.coffee b/app/assets/javascripts/darkswarm/directives/page_alert.js.coffee index a3858444ae..666daaec64 100644 --- a/app/assets/javascripts/darkswarm/directives/page_alert.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/page_alert.js.coffee @@ -14,8 +14,8 @@ Darkswarm.directive "ofnPageAlert", ($timeout) -> # Wait a moment after page load before showing the alert. Otherwise we often miss the # start of the animation. $timeout -> - container_elems.addClass("move-down") + container_elems.addClass("move-up") , 1000 scope.close = -> - container_elems.removeClass("move-down") + container_elems.removeClass("move-up") diff --git a/app/assets/javascripts/darkswarm/directives/smooth_scroll_to.js.coffee b/app/assets/javascripts/darkswarm/directives/smooth_scroll_to.js.coffee index c3bcc9590d..34552016c4 100644 --- a/app/assets/javascripts/darkswarm/directives/smooth_scroll_to.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/smooth_scroll_to.js.coffee @@ -10,6 +10,5 @@ Darkswarm.directive "ofnSmoothScrollTo", ($location, $document)-> # Scrolling is confused by our position:fixed top bar and page alert bar # - add an offset to scroll to the correct location, plus 5px buffer offset = $("nav.top-bar").height() - offset += $(".page-alert.move-down").height() offset += 5 $document.scrollTo target, offset, 1000 diff --git a/app/assets/stylesheets/darkswarm/page_alert.css.scss b/app/assets/stylesheets/darkswarm/page_alert.css.scss index a9276ab56d..08f35944c9 100644 --- a/app/assets/stylesheets/darkswarm/page_alert.css.scss +++ b/app/assets/stylesheets/darkswarm/page_alert.css.scss @@ -55,19 +55,18 @@ $page-alert-height: 55px; .off-canvas-fixed nav.tab-bar, .off-canvas-fixed .page-alert { @include transition(all 1000ms ease-in-out); - - &.move-down { - margin-top: $page-alert-height; - } } .off-canvas-wrap .page-alert { - top: -1 * $page-alert-height; + bottom: -1 * $page-alert-height; + top: unset; z-index: 100; -} -.off-canvas-wrap.move-right .inner-wrap.move-down { - .left-off-canvas-menu { - top: -1 * $page-alert-height; + &.move-up { + bottom: 0; + } + + .alert-box { + border-bottom: 0; } } From 042b4fc395f5730fbd8604406b758dd7db5c4ceb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 29 May 2020 23:19:00 +0200 Subject: [PATCH 488/507] Remove tests for viewing previous order items in cart dropdown This behavior has been removed --- spec/features/consumer/shopping/shopping_spec.rb | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index b33657e6fd..0093afe405 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -158,21 +158,6 @@ feature "As a consumer I want to shop with a distributor", js: true do quick_login_as order.user visit shop_path end - - it "shows previous orders if order cycle was selected already" do - select "frogs", from: "order_cycle_id" - expect(page).to have_content "Next order closing in 2 days" - visit shop_path - find("#cart").click - expect(page).to have_text(I18n.t("shared.menu.joyride.already_ordered_products")) - end - - it "shows previous orders after selecting an order cycle" do - select "frogs", from: "order_cycle_id" - expect(page).to have_content "Next order closing in 2 days" - find("#cart").click - expect(page).to have_text(I18n.t("shared.menu.joyride.already_ordered_products")) - end end end end From c0282b57b6141611d6c0f435437cad80a0327783 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 29 May 2020 23:32:14 +0200 Subject: [PATCH 489/507] Fix some linting warnings --- .../stylesheets/darkswarm/cart-dropdown.css.scss | 11 ++++++----- app/assets/stylesheets/darkswarm/cart-page.css.scss | 13 ++++++++----- .../darkswarm/expanding-sidebar.css.scss | 12 ++++++++---- app/assets/stylesheets/darkswarm/ui.css.scss | 3 ++- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index c551d7cde2..db77d66659 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -60,16 +60,16 @@ table { width: 100%; - border: none; + border: 0; border-spacing: 0; margin: 0; tr.product-cart { - background-color: white; + background-color: $white; td { border-top: 1px solid $grey-100; - padding: 0.75em 1em 0.5em 1em; + padding: 0.75em 1em 0.5em; vertical-align: top; &.image { @@ -99,10 +99,11 @@ .cart-total { color: $white; text-align: center; - margin: -0.5em 0 0.75em 0; + margin: -0.5em 0 0.75em; } - .sidebar, .sidebar-footer { + .sidebar, + .sidebar-footer { width: 375px; margin-right: -375px; diff --git a/app/assets/stylesheets/darkswarm/cart-page.css.scss b/app/assets/stylesheets/darkswarm/cart-page.css.scss index 9c0d76e11e..12296f115b 100644 --- a/app/assets/stylesheets/darkswarm/cart-page.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-page.css.scss @@ -10,7 +10,8 @@ } #cart-detail { - .cart-item-delete, .bought-item-delete { + .cart-item-delete, + .bought-item-delete { a { font-size: 1.125em; } @@ -20,7 +21,8 @@ color: $clr-brick; } - button, .button { + button, + .button { margin: 0; } @@ -41,7 +43,8 @@ } input { - &.ng-invalid-stock, &.ng-invalid-number { + &.ng-invalid-stock, + &.ng-invalid-number { border: 1px solid $clr-brick; } } @@ -50,7 +53,7 @@ .item-thumb-image { display: none; - @media screen and (min-width: 640px) { + @include breakpoint(phablet) { display: inline-block; float: left; padding-right: 0.5em; @@ -64,7 +67,7 @@ padding: 1.125rem 0 1.1875rem; width: 210px; - @media all and (max-width: 480px) { + @include breakpoint(mobile) { width: 100%; } } diff --git a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss index b4688e2e84..04ec836112 100644 --- a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss +++ b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss @@ -24,7 +24,8 @@ opacity: 1; } - .sidebar, .sidebar-footer { + .sidebar, + .sidebar-footer { margin-right: 0; } } @@ -54,20 +55,23 @@ transition: margin $transition-sidebar; padding: 1em; - button, a.button { + button, + a.button { width: 48%; } } @include breakpoint(tablet) { - .sidebar, .sidebar-footer { + .sidebar, + .sidebar-footer { width: $sidebar-medium-width; margin-right: -$sidebar-medium-width; } } @include breakpoint(mobile) { - .sidebar, .sidebar-footer { + .sidebar, + .sidebar-footer { width: $sidebar-small-width; margin-right: -$sidebar-small-width; } diff --git a/app/assets/stylesheets/darkswarm/ui.css.scss b/app/assets/stylesheets/darkswarm/ui.css.scss index 26a371daca..856b3dc0ca 100644 --- a/app/assets/stylesheets/darkswarm/ui.css.scss +++ b/app/assets/stylesheets/darkswarm/ui.css.scss @@ -128,7 +128,8 @@ a.button.large { line-height: 2.75em; } -button.large, a.button.large { +button.large, +a.button.large { height: 3em; font-size: 1em; color: $white; From 1d8386bee87447f1c8b78563f9137f1cebf09df7 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 30 May 2020 14:43:26 +0200 Subject: [PATCH 490/507] Disable two SCSS-lint rules --- .codeclimate.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.codeclimate.yml b/.codeclimate.yml index 3880986cad..1892bc1fb8 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -16,6 +16,10 @@ plugins: enabled: false PropertySortOrder: enabled: false + StringQuotes: + enabled: false + DeclarationOrder: + enabled: false duplication: enabled: true exclude_patterns: From 656c23f4074c5b2792380afdd1c304f2908bd7fb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 1 Jun 2020 16:33:54 +0200 Subject: [PATCH 491/507] Replace previous min-width breakpoint. This was mistakenly changed to use a max-width breakpoint in a previous commit. --- app/assets/stylesheets/darkswarm/cart-page.css.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/cart-page.css.scss b/app/assets/stylesheets/darkswarm/cart-page.css.scss index 12296f115b..5886b5dbe9 100644 --- a/app/assets/stylesheets/darkswarm/cart-page.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-page.css.scss @@ -53,7 +53,7 @@ .item-thumb-image { display: none; - @include breakpoint(phablet) { + @media screen and (min-width: 640px) { display: inline-block; float: left; padding-right: 0.5em; From 17c2721ab65c87e8fb7f122ec6b69af46789ff64 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 1 Jun 2020 16:47:41 +0200 Subject: [PATCH 492/507] Remove unused translation keys --- config/locales/en.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 614eae8d59..23a380cfdf 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1227,9 +1227,6 @@ en: profile: "Profile" mobile_menu: cart: "Cart" - joyride: - checkout: "Checkout now" - already_ordered_products: "Already ordered in this order cycle" register_call: selling_on_ofn: "Interested in getting on the Open Food Network?" register: "Register here" From 1eb9d11e27ad1501b5746d6d93ae697e0380a6a4 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 1 Jun 2020 16:51:54 +0200 Subject: [PATCH 493/507] Update colour variables --- app/assets/stylesheets/darkswarm/shop.css.scss | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss index 367d414d2b..4f6ac716ce 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.scss +++ b/app/assets/stylesheets/darkswarm/shop.css.scss @@ -129,11 +129,13 @@ products { .open-shop-message { a { - color: #0096ad; + color: $teal-500; - &:hover, &:focus, &:active { + &:hover, + &:focus, + &:active { text-decoration: none; - color: #4aadbd; + color: $teal-400; } } } From 9c6dd1b3247792613f0df36c97644889506c8b2c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 1 Jun 2020 16:56:33 +0200 Subject: [PATCH 494/507] Add comment on z-index --- app/assets/stylesheets/darkswarm/menu.css.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/menu.css.scss b/app/assets/stylesheets/darkswarm/menu.css.scss index 3c9fea8417..774d2bc146 100644 --- a/app/assets/stylesheets/darkswarm/menu.css.scss +++ b/app/assets/stylesheets/darkswarm/menu.css.scss @@ -175,7 +175,7 @@ nav.top-bar { height: $mobile-nav-height; position: fixed; width: 100%; - z-index: 190; + z-index: 190; // Above cart sidebar and shaded overlay .cart-span { background-color: #f4704c; From 234f0f94cf346b09c4b993b298f7ec17ed8ae956 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 1 Jun 2020 17:02:43 +0200 Subject: [PATCH 495/507] Change images in serializer to use `product.images` over `variant.images` --- app/serializers/api/variant_serializer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/serializers/api/variant_serializer.rb b/app/serializers/api/variant_serializer.rb index e60ec2832d..38cc649910 100644 --- a/app/serializers/api/variant_serializer.rb +++ b/app/serializers/api/variant_serializer.rb @@ -32,8 +32,8 @@ class Api::VariantSerializer < ActiveModel::Serializer end def thumb_url - if object.images.present? - object.images.first.attachment.url(:mini) + if object.product.images.present? + object.product.images.first.attachment.url(:mini) else "/assets/noimage/mini.png" end From b58ccc02eebd5fd6ec8d8ac88a3424c220a431fd Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 4 Jun 2020 10:54:29 +0200 Subject: [PATCH 496/507] Adjust shop.css.scss and remove indentation --- .../stylesheets/darkswarm/shop.css.scss | 332 +++++++++--------- 1 file changed, 167 insertions(+), 165 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss index 4f6ac716ce..6f411db6e9 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.scss +++ b/app/assets/stylesheets/darkswarm/shop.css.scss @@ -11,173 +11,175 @@ @import "shop-taxon-flag"; @import "shop-popovers"; +.darkswarm { + products { + display: block; + + @include breakpoint(tablet) { + input.button.right { + float: left; + } + } + + @include breakpoint(mobile) { + .add_to_cart { + margin-top: 2rem; + } + } + + form { + input.small.button.primary.right.add_to_cart { + &.dirty { + padding-left: 3.2rem; + } + } + + i.cart-spinner { + position: absolute; + top: 14px; + right: 146px; + color: white; + font-size: 1.2em; + + // Necessary to be below Z index of cart popover: + z-index: 98; + -webkit-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; + } + } + + product { + @include csstrans; + + border-bottom: 1px solid #e5e5e5; + border-top: 1px solid #e5e5e5; + padding-bottom: 1px; + margin-bottom: 20px !important; + position: relative; + display: block; + color: $med-drk-grey; + + &:hover, &:focus, &:active { + border-bottom: 1px solid $clr-brick-med-bright; + border-top: 1px solid $clr-brick-med-bright; + } + + // BULK + .bulk-buy { + font-size: 0.875rem; + + @include breakpoint(tablet) { + font-size: 0.75rem; + } + } + + .bulk-buy, .bulk-buy i { + color: #888; + } + + .inline { + display: inline; + } + + .spinner { + width: 100px; + margin-bottom: 20px; + } + + // ICONS + i { + font-size: 0.75em; + padding-right: 0.9375rem; + + @include breakpoint(phablet) { + padding-right: 0.25rem; + } + } + + i.ofn-i_056-bulk { + font-size: 1rem; + padding-right: 0rem; + } + + i.ofn-i_036-producers { + padding-left: 0.2rem; + padding-right: 0rem; + font-size: 0.8rem; + } + } + } + + .alert-box.changeable-orders-alert { + margin-bottom: 0px; + } + + .select-oc-message { + margin-top: 1rem; + + .highlighted { + color: $red-700; + font-weight: bold; + } + } + + .open-shop-message { + a { + color: $teal-500; + + &:hover, + &:focus, + &:active { + text-decoration: none; + color: $teal-400; + } + } + } + + .closed-shop-header { + background-color: $grey-650; + color: $white; + + h4 { + color: $white; + } + + p { + margin: 1rem 0 0.4rem; + } + + .message { + display: inline-block; + } + } + +.warning-sign { + margin: 0 10px 0 5px; + display: inline-block; + line-height: 1.9rem; + + strong { + color: $grey-650; + display: block; + position: relative; + text-align: center; + width: 23px; + } + + .rectangle { + background-color: $white; + border-radius: 4px; + color: $grey-650; + height: 23px; + position: absolute; + top: 27px; + transform: rotate(-315deg); + width: 23px; + } + } +} + .shop-filters-sidebar { .property-selectors { margin-bottom: $sidebar-footer-height + 2em; } } - -products { - display: block; - - @include breakpoint(tablet) { - input.button.right { - float: left; - } - } - - @include breakpoint(mobile) { - .add_to_cart { - margin-top: 2rem; - } - } - - form { - input.small.button.primary.right.add_to_cart { - &.dirty { - padding-left: 3.2rem; - } - } - - i.cart-spinner { - position: absolute; - top: 14px; - right: 146px; - color: white; - font-size: 1.2em; - - // Necessary to be below Z index of cart popover: - z-index: 98; - -webkit-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; - } - } - - product { - @include csstrans; - - border-bottom: 1px solid #e5e5e5; - border-top: 1px solid #e5e5e5; - padding-bottom: 1px; - margin-bottom: 20px !important; - position: relative; - display: block; - color: $med-drk-grey; - - &:hover, &:focus, &:active { - border-bottom: 1px solid $clr-brick-med-bright; - border-top: 1px solid $clr-brick-med-bright; - } - - // BULK - .bulk-buy { - font-size: 0.875rem; - - @include breakpoint(tablet) { - font-size: 0.75rem; - } - } - - .bulk-buy, .bulk-buy i { - color: #888; - } - - .inline { - display: inline; - } - - .spinner { - width: 100px; - margin-bottom: 20px; - } - - // ICONS - i { - font-size: 0.75em; - padding-right: 0.9375rem; - - @include breakpoint(phablet) { - padding-right: 0.25rem; - } - } - - i.ofn-i_056-bulk { - font-size: 1rem; - padding-right: 0rem; - } - - i.ofn-i_036-producers { - padding-left: 0.2rem; - padding-right: 0rem; - font-size: 0.8rem; - } - } -} - -.alert-box.changeable-orders-alert { - margin-bottom: 0px; -} - -.select-oc-message { - margin-top: 1rem; - - .highlighted { - color: $red-700; - font-weight: bold; - } -} - -.open-shop-message { - a { - color: $teal-500; - - &:hover, - &:focus, - &:active { - text-decoration: none; - color: $teal-400; - } - } -} - -.closed-shop-header { - background-color: $grey-650; - color: $white; - - h4 { - color: $white; - } - - p { - margin: 1rem 0 0.4rem; - } - - .message { - display: inline-block; - } -} - - .warning-sign { - margin: 0 10px 0 5px; - display: inline-block; - line-height: 1.9rem; - - strong { - color: $grey-650; - display: block; - position: relative; - text-align: center; - width: 23px; - } - - .rectangle { - background-color: $white; - border-radius: 4px; - color: $grey-650; - height: 23px; - position: absolute; - top: 27px; - transform: rotate(-315deg); - width: 23px; - } -} From 850e1b03648ed1c96975b2efa43dd3fc0e99e1c2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 4 Jun 2020 10:55:12 +0200 Subject: [PATCH 497/507] Reduce specificity in cart css rules --- app/assets/stylesheets/darkswarm/cart-dropdown.css.scss | 2 +- app/assets/stylesheets/darkswarm/cart-page.css.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index db77d66659..1c17d1b517 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -64,7 +64,7 @@ border-spacing: 0; margin: 0; - tr.product-cart { + .product-cart { background-color: $white; td { diff --git a/app/assets/stylesheets/darkswarm/cart-page.css.scss b/app/assets/stylesheets/darkswarm/cart-page.css.scss index 5886b5dbe9..8e58dde24e 100644 --- a/app/assets/stylesheets/darkswarm/cart-page.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-page.css.scss @@ -30,7 +30,7 @@ cursor: pointer; } - tr.bought td { + .bought td { color: $med-grey; h5 { From 7093e0f7a33fbc5cd79540b172ebada0e3030b54 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 9 Jun 2020 15:36:06 +0200 Subject: [PATCH 498/507] Use plural or singular description in cart, depending on number of items --- app/views/shared/menu/_cart_sidebar.html.haml | 6 ++++-- config/locales/en.yml | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index b4b27766cd..a792026afc 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -2,8 +2,10 @@ .background{ng: {click: 'toggleCartSidebar()'}} .sidebar .cart-header - %span.title{"ng-show" => "Cart.line_items.length > 0"} - = t('.items_in_cart', num: "{{ Cart.total_item_count() }}") + %span.title{"ng-show" => "Cart.line_items.length == 1"} + = t('.items_in_cart_singular', num: "{{ Cart.total_item_count() }}") + %span.title{"ng-show" => "Cart.line_items.length > 1"} + = t('.items_in_cart_plural', num: "{{ Cart.total_item_count() }}") %a.close{ng: {click: 'toggleCartSidebar()'}} = t('.close') %i.ofn-i_009-close diff --git a/config/locales/en.yml b/config/locales/en.yml index 23a380cfdf..27cf49f93b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1219,7 +1219,8 @@ en: cart_sidebar: checkout: "Checkout" edit_cart: "Edit cart" - items_in_cart: "%{num} items in your cart" + items_in_cart_singular: "%{num} item in your cart" + items_in_cart_plural: "%{num} items in your cart" close: "Close" cart_empty: "Your cart is empty" take_me_shopping: "Take me shopping!" From 076ecfdb43708d44ca0112d39b916bf95cd62db3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 9 Jun 2020 16:32:25 +0200 Subject: [PATCH 499/507] Adjust scrollbar visibility in sidebar --- .../stylesheets/darkswarm/cart-dropdown.css.scss | 4 ++++ .../stylesheets/darkswarm/expanding-sidebar.css.scss | 2 +- app/views/shared/menu/_cart_sidebar.html.haml | 11 ++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index 1c17d1b517..78a1241f54 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -112,4 +112,8 @@ margin-right: -100%; } } + + .sidebar-footer { + z-index: 170; + } } diff --git a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss index 04ec836112..da1034cf42 100644 --- a/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss +++ b/app/assets/stylesheets/darkswarm/expanding-sidebar.css.scss @@ -41,7 +41,7 @@ background-color: rgba($white, 0.95); padding: 1em; transition: margin $transition-sidebar; - overflow-y: scroll; + overflow-y: auto; } .sidebar-footer { diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index a792026afc..070beb3983 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -31,12 +31,13 @@ %a.go-shopping.button.large.bright{ng: {show: "#{show_shopping_cta?}", href: "{{ CurrentHub.hub.id ? '#{main_app.shop_path}' : '#{main_app.shops_path}' }}"}} = t('.take_me_shopping') - .sidebar-footer{"ng-show" => "Cart.line_items.length > 0"} - %p.cart-total - %strong - = t 'total' - {{ Cart.total() | localizeCurrency }} + .sidebar-footer{"ng-show" => "Cart.line_items.length > 0"} + %p.cart-total + %strong + = t 'total' + {{ Cart.total() | localizeCurrency }} + %div.fullwidth %a.edit-cart.button.large.dark.left{href: main_app.cart_path, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }"} = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t('.edit_cart')}' ) }}" %a.checkout.button.large.bright.right{href: main_app.checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} From 886df0e87ddeb38c067277b7efbaee572b997968 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 12 Jun 2020 10:39:56 +0200 Subject: [PATCH 500/507] Fix cart page button style regression --- app/assets/stylesheets/darkswarm/cart-page.css.scss | 1 + app/views/spree/orders/form/_cart_links.html.haml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/cart-page.css.scss b/app/assets/stylesheets/darkswarm/cart-page.css.scss index 8e58dde24e..b2b17fa0bb 100644 --- a/app/assets/stylesheets/darkswarm/cart-page.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-page.css.scss @@ -66,6 +66,7 @@ .button { padding: 1.125rem 0 1.1875rem; width: 210px; + font-size: 1.1em; @include breakpoint(mobile) { width: 100%; diff --git a/app/views/spree/orders/form/_cart_links.html.haml b/app/views/spree/orders/form/_cart_links.html.haml index 798a428f7c..89a63d70fd 100644 --- a/app/views/spree/orders/form/_cart_links.html.haml +++ b/app/views/spree/orders/form/_cart_links.html.haml @@ -1,5 +1,5 @@ .row.links{'data-hook' => "cart_buttons"} - %a.continue-shopping.button.large.secondary{href: current_shop_products_path, "ng-disabled" => "#{@insufficient_stock_lines.any?}", "disable-dynamically" => true} + %a.continue-shopping.button.secondary{href: current_shop_products_path, "ng-disabled" => "#{@insufficient_stock_lines.any?}", "disable-dynamically" => true} = t :orders_edit_continue - %a#checkout-link.button.large.primary.right{href: main_app.checkout_path, "ng-disabled" => "#{@insufficient_stock_lines.any?}", "disable-dynamically" => true} + %a#checkout-link.button.primary.right{href: main_app.checkout_path, "ng-disabled" => "#{@insufficient_stock_lines.any?}", "disable-dynamically" => true} = t :orders_edit_checkout From 2cc02d971121cc511eaa55d9afc17d3d1b6b9800 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 12 Jun 2020 10:58:25 +0200 Subject: [PATCH 501/507] Make cart header stick to top of cart --- app/assets/stylesheets/darkswarm/cart-dropdown.css.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index 78a1241f54..890633d2ee 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -18,7 +18,11 @@ } .cart-header { + background-color: $white; + border-bottom: 1px solid $grey-100; padding: 1em; + position: sticky; + top: 0; .title { color: $grey-800; @@ -68,7 +72,7 @@ background-color: $white; td { - border-top: 1px solid $grey-100; + border-bottom: 1px solid $grey-100; padding: 0.75em 1em 0.5em; vertical-align: top; From ed086c2db595714719af2ebef062e581bcce9697 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 12 Jun 2020 11:17:59 +0200 Subject: [PATCH 502/507] Add character limit to product and variant names in cart sidebar --- .../darkswarm/controllers/cart_controller.js.coffee | 1 + app/views/shared/menu/_cart_sidebar.html.haml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee index 119fb640f3..28d6cb4cfe 100644 --- a/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/cart_controller.js.coffee @@ -1,3 +1,4 @@ Darkswarm.controller "CartCtrl", ($scope, Cart, CurrentHub) -> $scope.Cart = Cart $scope.CurrentHub = CurrentHub + $scope.max_characters = 20 diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml index 070beb3983..03c3f52222 100644 --- a/app/views/shared/menu/_cart_sidebar.html.haml +++ b/app/views/shared/menu/_cart_sidebar.html.haml @@ -16,9 +16,9 @@ %td.image %img{'ng-src' => '{{ line_item.variant.thumb_url }}'} %td - %span {{ line_item.variant.extended_name }} + %span {{ line_item.variant.extended_name | truncate: max_characters }} %br - %span.options-text {{ line_item.variant.options_text }} + %span.options-text {{ line_item.variant.options_text | truncate: max_characters }} %td.text-right %span.quantity {{ line_item.quantity }} %td From a6edc1c97356fa564ae78e67cece576f7bde7fcb Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 12 Jun 2020 12:34:52 +0200 Subject: [PATCH 503/507] Enable control over body scroll with BodyScroll service --- .../controllers/cart_dropdown_controller.js.coffee | 3 ++- .../darkswarm/directives/body_scroll.js.coffee | 9 +++++++++ .../javascripts/darkswarm/services/body_scroll.js.coffee | 7 +++++++ app/assets/stylesheets/darkswarm/ui.css.scss | 4 ++++ app/views/layouts/darkswarm.html.haml | 2 +- 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee create mode 100644 app/assets/javascripts/darkswarm/services/body_scroll.js.coffee diff --git a/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee index f22e237f06..048459ecd8 100644 --- a/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/cart_dropdown_controller.js.coffee @@ -1,6 +1,7 @@ -Darkswarm.controller "CartDropdownCtrl", ($scope, Cart) -> +Darkswarm.controller "CartDropdownCtrl", ($scope, Cart, BodyScroll) -> $scope.Cart = Cart $scope.showCartSidebar = false $scope.toggleCartSidebar = -> $scope.showCartSidebar = !$scope.showCartSidebar + BodyScroll.toggle() diff --git a/app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee b/app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee new file mode 100644 index 0000000000..183d828d03 --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/body_scroll.js.coffee @@ -0,0 +1,9 @@ +Darkswarm.directive "bodyScroll", ($rootScope, BodyScroll) -> + restrict: 'A' + scope: true + link: (scope, elem, attrs) -> + $rootScope.$on "toggleBodyScroll", -> + if BodyScroll.disabled + elem.addClass "disable-scroll" + else + elem.removeClass "disable-scroll" diff --git a/app/assets/javascripts/darkswarm/services/body_scroll.js.coffee b/app/assets/javascripts/darkswarm/services/body_scroll.js.coffee new file mode 100644 index 0000000000..84c8ed9337 --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/body_scroll.js.coffee @@ -0,0 +1,7 @@ +angular.module("Darkswarm").factory "BodyScroll", ($rootScope) -> + new class BodyScroll + disabled: false + + toggle: -> + @disabled = !@disabled + $rootScope.$broadcast "toggleBodyScroll" diff --git a/app/assets/stylesheets/darkswarm/ui.css.scss b/app/assets/stylesheets/darkswarm/ui.css.scss index 856b3dc0ca..d6b0988ad6 100644 --- a/app/assets/stylesheets/darkswarm/ui.css.scss +++ b/app/assets/stylesheets/darkswarm/ui.css.scss @@ -163,3 +163,7 @@ a.button.large { padding-right: 0; padding-left: 0; } + +.disable-scroll { + overflow: hidden; +} diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index fdf2cd4f17..f45b157a51 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -18,7 +18,7 @@ = stylesheet_link_tag "darkswarm/all" = csrf_meta_tags - %body{class: body_classes, ng: {app: "Darkswarm"}} + %body{class: body_classes, "body-scroll" => true , ng: {app: "Darkswarm"}} / [if lte IE 8] = render partial: "shared/ie_warning" = javascript_include_tag "iehack" From 5a480439ca63582073a3b5103a7bea04b09a0c99 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 12 Jun 2020 13:29:14 +0200 Subject: [PATCH 504/507] Remove test for items from previous orders looking in cart dropdown This feature has been removed --- spec/features/consumer/shopping/cart_spec.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index 9068504be6..e7785dcdb4 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -282,11 +282,6 @@ feature "full-page cart", js: true do expect(page).to have_no_content item1.variant.name expect(page).to have_content item2.variant.name - # open the dropdown cart and check there as well - find('#cart').click - expect(page).to have_no_content item1.variant.name - expect(page).to have_content item2.variant.name - visit main_app.cart_path find("td.toggle-bought").click From 7c7ab322bb08def96af11c1d035b5d292112b454 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 16 Jun 2020 11:25:43 +0200 Subject: [PATCH 505/507] Ensure cart-header has the same height when the cart is empty Fixes a minor visual bug --- app/assets/stylesheets/darkswarm/cart-dropdown.css.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss index 890633d2ee..ca3dd6a1a2 100644 --- a/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss +++ b/app/assets/stylesheets/darkswarm/cart-dropdown.css.scss @@ -20,6 +20,7 @@ .cart-header { background-color: $white; border-bottom: 1px solid $grey-100; + min-height: 3.5em; padding: 1em; position: sticky; top: 0; From ff6ba8819f4fbc3464c7f7168ebb554cd6638e24 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 16 Jun 2020 13:56:53 +0200 Subject: [PATCH 506/507] Use image_tag helper with relative paths when loading static images in /app/assets/images folder This seems to be needed for Rails 4 --- app/views/shared/menu/_mobile_menu.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index 1c96dd1d64..716db01f73 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -1,7 +1,7 @@ %nav.tab-bar.show-for-medium-down %section.left %a.left-off-canvas-toggle.menu-icon - %img{src: "/assets/menu/btn-menu-mobile.png"} + = image_tag "menu/btn-menu-mobile.png" %section.left .ofn-logo @@ -14,7 +14,7 @@ %span = t '.cart' %span.count - %img{ src: image_path("menu/icn-cart.svg") } + = image_tag "menu/icn-cart.svg" %span {{ Cart.total_item_count() }} From b189d06eb76ab7b061ea81d25f88b3f153e9e7da Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 17 Jun 2020 11:19:32 +0200 Subject: [PATCH 507/507] Update shopping CTA logic Shows "Take me shopping!" button on /shops page if a shop is selected --- app/helpers/shop_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/shop_helper.rb b/app/helpers/shop_helper.rb index 32bb144d5f..8da650c4ef 100644 --- a/app/helpers/shop_helper.rb +++ b/app/helpers/shop_helper.rb @@ -52,7 +52,7 @@ module ShopHelper end def show_shopping_cta? - return false if current_page?(main_app.shops_path) + return false if current_page?(main_app.shops_path) && current_distributor.blank? return false if current_distributor.present? && current_page?(main_app.enterprise_shop_path(current_distributor))