diff --git a/Gemfile b/Gemfile index 257f9cf14bc..2b09728c389 100644 --- a/Gemfile +++ b/Gemfile @@ -11,15 +11,19 @@ gem 'i18n-js', '~> 3.0.0' gem 'nokogiri', '>= 1.6.7.1' gem 'pg' -gem 'spree', github: 'openfoodfoundation/spree', branch: 'step-6a', ref: '69db1c090f3711088d84b524f1b94d25e6d21616' + +# OFN-maintained and patched version of Spree v2.0.4. See +# https://github.com/openfoodfoundation/openfoodnetwork/wiki/Spree-2.0-upgrade +# for details. +gem 'spree', github: 'openfoodfoundation/spree', branch: '2-0-4-stable' + gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable' -gem 'spree_auth_devise', github: 'openfoodfoundation/spree_auth_devise', branch: 'spree-upgrade-intermediate' +gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-0-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: "spree-upgrade-intermediate" -#gem 'spree_paypal_express', github: "spree-contrib/better_spree_paypal_express", branch: "1-3-stable" +gem 'spree_paypal_express', github: "spree-contrib/better_spree_paypal_express", branch: "2-0-stable" gem 'stripe', '~> 3.3.2' # We need at least this version to have Digicert's root certificate # which is needed for Pin Payments (and possibly others). @@ -53,8 +57,8 @@ gem 'rabl' # Once Rails is updated to 5.x we should bump directly to 0.10.x gem "active_model_serializers", "0.8.4" gem 'oj' -gem 'deface', github: 'spree/deface', ref: '1110a13' -gem 'paperclip' +gem 'deface', '1.0.0' +gem 'paperclip', '~> 3.4.1' gem 'dalli' gem 'geocoder' gem 'gmaps4rails' @@ -101,7 +105,7 @@ end gem "foundation-rails" gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: "rails3" -gem 'jquery-rails' +gem 'jquery-rails', '3.0.0' gem 'jquery-migrate-rails' gem 'css_splitter' diff --git a/Gemfile.lock b/Gemfile.lock index 0b6cbeb91a8..f10b627ea12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,15 +12,6 @@ GIT specs: custom_error_message (1.1.1) -GIT - remote: https://github.com/openfoodfoundation/better_spree_paypal_express.git - revision: 8d95f4544c682634812becaf50999fba0cd04df0 - branch: spree-upgrade-intermediate - specs: - spree_paypal_express (2.0.3) - paypal-sdk-merchant (= 1.106.1) - spree_core (~> 1.3.99) - GIT remote: https://github.com/openfoodfoundation/ofn-qz.git revision: 60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c @@ -31,87 +22,81 @@ GIT GIT remote: https://github.com/openfoodfoundation/spree.git - revision: 69db1c090f3711088d84b524f1b94d25e6d21616 - ref: 69db1c090f3711088d84b524f1b94d25e6d21616 - branch: step-6a + revision: 94b1f395bbf2cffbb1e33cdab5809511150da814 + branch: 2-0-4-stable specs: - spree (1.3.99) - spree_api (= 1.3.99) - spree_backend (= 1.3.99) - spree_cmd (= 1.3.99) - spree_core (= 1.3.99) - spree_dash (= 1.3.99) - spree_frontend (= 1.3.99) - spree_sample (= 1.3.99) - spree_api (1.3.99) - rabl (= 0.7.2) - spree_core (= 1.3.99) - versioncake (= 0.4.0) - spree_backend (1.3.99) + spree (2.0.4) + spree_api (= 2.0.4) + spree_backend (= 2.0.4) + spree_cmd (= 2.0.4) + spree_core (= 2.0.4) + spree_frontend (= 2.0.4) + spree_sample (= 2.0.4) + spree_api (2.0.4) + rabl (= 0.8.4) + spree_core (= 2.0.4) + versioncake (= 1.0.0) + spree_backend (2.0.4) deface (>= 0.9.0) - jquery-rails (~> 2.0) + jquery-rails (~> 3.0.0) + jquery-ui-rails (~> 4.0.0) rails (~> 3.2.8) - select2-rails (~> 3.2) - spree_api (= 1.3.99) - spree_core (= 1.3.99) - stringex (~> 1.3.2) - spree_cmd (1.3.99) + select2-rails (~> 3.4.7) + spree_api (= 2.0.4) + spree_core (= 2.0.4) + spree_cmd (2.0.4) thor (>= 0.14.6) - spree_core (1.3.99) - activemerchant (~> 1.50) - acts_as_list (= 0.1.9) + spree_core (2.0.4) + activemerchant (~> 1.34) + acts_as_list (= 0.2.0) awesome_nested_set (= 2.1.5) - aws-sdk (~> 1.11.1) - cancan (= 1.6.8) - deface (>= 0.9.0) - ffaker (~> 1.15.0) - highline (= 1.6.15) - httparty (= 0.9.0) - json (>= 1.5.5) - kaminari (= 0.13.0) - money (= 5.1.0) - paperclip (~> 3.0) - rails (~> 3.2.13) + aws-sdk (~> 1.3.4) + cancan (~> 1.6.10) + deface (>= 0.9.1) + ffaker (~> 1.16) + highline (= 1.6.18) + httparty (~> 0.11) + json (>= 1.7.7) + kaminari (~> 0.14.1) + money (= 5.1.1) + paperclip (~> 3.4.1) + paranoia (~> 1.3) + rails (~> 3.2.14) ransack (= 0.7.2) state_machine (= 1.2.0) - stringex (~> 1.3.2) + stringex (~> 1.5.1) truncate_html (= 0.9.2) - spree_dash (1.3.99) - httparty (~> 0.9.0) - spree_backend (= 1.3.99) - spree_frontend (= 1.3.99) - spree_frontend (1.3.99) + spree_frontend (2.0.4) + canonical-rails deface (>= 0.9.0) - jquery-rails (~> 2.2.1) - rails (~> 3.2.8) - select2-rails (~> 3.2) - spree_api (= 1.3.99) - spree_core (= 1.3.99) - stringex (~> 1.3.2) - spree_sample (1.3.99) - spree_core (= 1.3.99) + jquery-rails (~> 3.0.0) + rails (~> 3.2.13) + spree_api (= 2.0.4) + spree_core (= 2.0.4) + stringex (~> 1.5.1) + spree_sample (2.0.4) + spree_core (= 2.0.4) GIT - remote: https://github.com/openfoodfoundation/spree_auth_devise.git - revision: da9eecefc6fe13dedf4c6f3febec79caad839ec3 - branch: spree-upgrade-intermediate + remote: https://github.com/spree-contrib/better_spree_paypal_express.git + revision: 1206925d1c85bdc4b68b728d6676150ab0785486 + branch: 2-0-stable specs: - spree_auth_devise (2.0.0) - devise (~> 2.2.5) - devise-encryptable (= 0.1.2) - spree_backend (~> 1.3.6) - spree_core (~> 1.3.6) - spree_frontend (~> 1.3.6) + spree_paypal_express (2.0.3) + paypal-sdk-merchant (= 1.106.1) + spree_core (~> 2.0.3) GIT - remote: https://github.com/spree/deface.git - revision: 1110a1336252109bce7f98f9182042e0bc2930ae - ref: 1110a13 + remote: https://github.com/spree/spree_auth_devise.git + revision: 0181835fb6ac77a05191d26f6f32a0f4a548d851 + branch: 2-0-stable specs: - deface (1.0.0.rc3) - colorize (>= 0.5.8) - nokogiri (~> 1.6.0) - rails (>= 3.1) + spree_auth_devise (2.0.0) + devise (~> 2.2.5) + devise-encryptable (= 0.1.2) + spree_backend (~> 2.0.0) + spree_core (~> 2.0.0) + spree_frontend (~> 2.0.0) GIT remote: https://github.com/spree/spree_i18n.git @@ -173,7 +158,8 @@ GEM multi_json (~> 1.0) acts-as-taggable-on (3.5.0) activerecord (>= 3.2, < 5) - acts_as_list (0.1.9) + acts_as_list (0.2.0) + activerecord (>= 3.0) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) andand (1.3.3) @@ -189,7 +175,8 @@ GEM awesome_nested_set (2.1.5) activerecord (>= 3.0.0) awesome_print (1.0.2) - aws-sdk (1.11.1) + aws-sdk (1.3.9) + httparty (~> 0.7) json (~> 1.4) nokogiri (>= 1.4.4) uuidtools (~> 2.1) @@ -200,7 +187,9 @@ GEM bugsnag (4.1.0) builder (3.0.4) byebug (9.0.6) - cancan (1.6.8) + cancan (1.6.10) + canonical-rails (0.1.0) + rails (>= 3.1, < 5.1) capybara (2.18.0) addressable mini_mime (>= 0.1.3) @@ -210,7 +199,7 @@ GEM xpath (>= 2.0, < 4.0) chronic (0.10.2) chunky_png (1.3.10) - climate_control (0.1.0) + climate_control (0.2.0) cliver (0.3.2) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) @@ -253,6 +242,10 @@ GEM fog (~> 1.0) rails (~> 3.0) debugger-linecache (1.2.0) + deface (1.0.0) + colorize (>= 0.5.8) + nokogiri (~> 1.6.0) + rails (>= 3.1) delayed_job (4.1.4) activesupport (>= 3.0, < 5.2) delayed_job_active_record (4.1.2) @@ -274,14 +267,14 @@ GEM eventmachine (1.2.7) excon (0.45.4) execjs (2.6.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 (0.9.2) multipart-post (>= 1.2, < 3) - ffaker (1.15.0) + ffaker (1.22.1) ffi (1.9.25) figaro (0.7.0) bundler (~> 1.0) @@ -433,12 +426,11 @@ GEM haml (4.0.4) tilt hashdiff (0.3.7) - highline (1.6.15) + highline (1.6.18) hike (1.2.3) http_parser.rb (0.6.0) - httparty (0.9.0) - multi_json (~> 1.0) - multi_xml + httparty (0.16.2) + multi_xml (>= 0.5.2) i18n (0.6.11) i18n-js (3.0.11) i18n (>= 0.6.6, < 2) @@ -448,18 +440,19 @@ GEM ipaddress (0.8.0) journey (1.0.4) jquery-migrate-rails (1.2.1) - jquery-rails (2.2.2) + jquery-rails (3.0.0) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) + jquery-ui-rails (4.0.5) + railties (>= 3.1.0) json (1.8.6) json_spec (1.1.5) multi_json (~> 1.0) rspec (>= 2.0, < 4.0) jwt (1.5.4) - kaminari (0.13.0) + kaminari (0.14.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) - railties (>= 3.0.0) kgio (2.9.3) knapsack (1.16.0) rake @@ -481,7 +474,7 @@ GEM mini_portile2 (2.1.0) momentjs-rails (2.5.1) railties (>= 3.1) - money (5.1.0) + money (5.1.1) i18n (~> 0.6.0) multi_json (1.13.1) multi_xml (0.6.0) @@ -500,19 +493,22 @@ GEM rack (>= 1.2, < 3) oj (2.1.2) orm_adapter (0.5.0) - paper_trail (3.0.9) + paper_trail (3.0.8) activerecord (>= 3.0, < 5.0) activesupport (>= 3.0, < 5.0) - paperclip (3.5.4) + paperclip (3.4.2) activemodel (>= 3.0.0) + activerecord (>= 3.0.0) activesupport (>= 3.0.0) - cocaine (~> 0.5.3) + cocaine (~> 0.5.0) mime-types parallel (1.11.2) parallel_tests (2.14.1) parallel - parser (2.5.1.0) - ast (~> 2.4.0) + paranoia (1.3.4) + activerecord (~> 3.1) + parser (2.4.0.0) + ast (~> 2.2) paypal-sdk-core (0.2.10) multi_json (~> 1.0) xml-simple @@ -534,9 +530,8 @@ GEM byebug (>= 9.0, < 9.1) pry (~> 0.10) public_suffix (3.0.3) - rabl (0.7.2) + rabl (0.8.4) activesupport (>= 2.3.14) - multi_json (~> 1.0) rack (1.4.7) rack-cache (1.8.0) rack (>= 0.4) @@ -563,7 +558,8 @@ GEM rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - rainbow (3.0.0) + rainbow (2.2.2) + rake raindrops (0.13.0) rake (12.3.1) ransack (0.7.2) @@ -623,9 +619,9 @@ GEM rspec-support (3.7.1) rubocop (0.55.0) parallel (~> 1.10) - parser (>= 2.5) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) - rainbow (>= 2.2.2, < 4.0) + rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-ole (1.2.12.1) @@ -637,7 +633,8 @@ GEM railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - select2-rails (3.5.10) + select2-rails (3.4.9) + sass-rails thor (~> 0.14) shellany (0.0.1) shoulda-matchers (2.8.0) @@ -646,7 +643,7 @@ GEM activesupport (>= 3.0.0) spinjs-rails (1.3) rails (>= 3.1) - spreadsheet (1.1.4) + spreadsheet (1.1.7) ruby-ole (>= 1.0) sprockets (2.2.3) hike (~> 1.2) @@ -654,7 +651,7 @@ GEM rack (~> 1.0) tilt (~> 1.1, != 1.3.0) state_machine (1.2.0) - stringex (1.3.3) + stringex (1.5.1) stripe (3.3.2) faraday (~> 0.9) therubyracer (0.12.3) @@ -674,7 +671,7 @@ GEM uglifier (2.7.1) execjs (>= 0.3.0) json (>= 1.8.0) - unicode-display_width (1.3.2) + unicode-display_width (1.3.0) unicorn (4.9.0) kgio (~> 2.6) rack @@ -683,7 +680,7 @@ GEM rack unicorn uuidtools (2.1.5) - versioncake (0.4.0) + versioncake (1.0.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) @@ -732,7 +729,7 @@ DEPENDENCIES database_cleaner (= 0.7.1) db2fog debugger-linecache - deface! + deface (= 1.0.0) delayed_job_active_record diffy eventmachine (>= 1.2.3) @@ -754,7 +751,7 @@ DEPENDENCIES i18n-js (~> 3.0.0) immigrant jquery-migrate-rails - jquery-rails + jquery-rails (= 3.0.0) json_spec (~> 1.1.4) jwt (~> 1.5) knapsack @@ -766,7 +763,7 @@ DEPENDENCIES ofn-qz! oj paper_trail (~> 3.0.8) - paperclip + paperclip (~> 3.4.1) parallel_tests pg poltergeist (>= 1.16.0) diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 292b5e21efc..df8cef60e56 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -8,7 +8,7 @@ //= require jquery //= require jquery-migrate-min //= require jquery_ujs -//= require jquery-ui +//= require jquery.ui.all //= require shared/jquery-ui-timepicker-addon //= require angular //= require angular-resource diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index 90080f0a772..32ee0b2255b 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -1,6 +1,6 @@ #= require jquery #= require jquery_ujs -#= require jquery-ui +#= require jquery.ui.all #= require spin # #= require angular diff --git a/app/mailers/spree/base_mailer_decorator.rb b/app/mailers/spree/base_mailer_decorator.rb index 863f97033a0..44e2b536148 100644 --- a/app/mailers/spree/base_mailer_decorator.rb +++ b/app/mailers/spree/base_mailer_decorator.rb @@ -7,13 +7,6 @@ protected - # This method copies the one defined in Spree's mailers. It should be removed - # once in Spree v2.0 and Spree's BaseMailer class lands in our codebase. - # Then, we'll be able to rely on its #from_address. - def from_address - Spree::MailMethod.current.preferred_mails_from - end - def roadie_options # This lets us specify assets using relative paths in email templates super.merge(url_options: {host: URI(spree.root_url).host }) diff --git a/app/mailers/spree/order_mailer_decorator.rb b/app/mailers/spree/order_mailer_decorator.rb index a4b2db8b70f..0ff7e215589 100644 --- a/app/mailers/spree/order_mailer_decorator.rb +++ b/app/mailers/spree/order_mailer_decorator.rb @@ -3,43 +3,42 @@ helper CheckoutHelper helper SpreeCurrencyHelper - def cancel_email(order, resend = false) - @order = find_order(order) - subject = (resend ? "[#{t(:resend).upcase}] " : '') - subject += "#{Spree::Config[:site_name]} #{t('order_mailer.cancel_email.subject')} ##{order.number}" - mail(to: order.email, from: from_address, subject: subject) - end - - def confirm_email_for_customer(order, resend = false) - find_order(order) # Finds an order instance from an id - subject = (resend ? "[#{t(:resend).upcase}] " : '') - subject += "#{Spree::Config[:site_name]} #{t('order_mailer.confirm_email.subject')} ##{@order.number}" + def confirm_email_for_customer(order_or_order_id, resend = false) + @order = find_order(order_or_order_id) + subject = build_subject(t('order_mailer.confirm_email.subject'), resend) mail(:to => @order.email, :from => from_address, :subject => subject, :reply_to => @order.distributor.contact.email) end - def confirm_email_for_shop(order, resend = false) - find_order(order) # Finds an order instance from an id - subject = (resend ? "[#{t(:resend).upcase}] " : '') - subject += "#{Spree::Config[:site_name]} #{t('order_mailer.confirm_email.subject')} ##{@order.number}" + def confirm_email_for_shop(order_or_order_id, resend = false) + @order = find_order(order_or_order_id) + subject = build_subject(t('order_mailer.confirm_email.subject'), resend) mail(:to => @order.distributor.contact.email, :from => from_address, :subject => subject) end - def invoice_email(order, pdf) - find_order(order) # Finds an order instance from an id + def invoice_email(order_or_order_id, pdf) + @order = find_order(order_or_order_id) + subject = build_subject(t(:invoice)) attachments["invoice-#{@order.number}.pdf"] = pdf if pdf.present? - subject = "#{Spree::Config[:site_name]} #{t(:invoice)} ##{@order.number}" mail(:to => @order.email, :from => from_address, :subject => subject, :reply_to => @order.distributor.contact.email) end - def find_order(order) - @order = order.respond_to?(:id) ? order : Spree::Order.find(order) + private + + # Finds an order instance from an order or from an order id + def find_order(order_or_order_id) + order_or_order_id.respond_to?(:id) ? order_or_order_id : Spree::Order.find(order_or_order_id) + end + + def build_subject( subject_text, resend = false ) + subject = (resend ? "[#{t(:resend).upcase}] " : "") + subject += "#{Spree::Config[:site_name]} #{subject_text} ##{@order.number}" end end diff --git a/app/models/order_updater.rb b/app/models/order_updater.rb new file mode 100644 index 00000000000..c798da087b1 --- /dev/null +++ b/app/models/order_updater.rb @@ -0,0 +1,57 @@ +require 'delegate' + +class OrderUpdater < SimpleDelegator + # TODO: This logic adapted from Spree 2.4, remove when we get there + # Handles state updating in a much more logical way than < 2.4 + # Specifically, doesn't depend on payments.last to determine payment state + # Also swapped: == 0 for .zero?, .size == 0 for empty? and .size > 0 for !empty? + # See: + # https://github.com/spree/spree/commit/38b8456183d11fc1e00e395e7c9154c76ef65b85 + # https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a + def update_payment_state + last_state = order.payment_state + if payments.present? && payments.valid.empty? + order.payment_state = 'failed' + elsif order.state == 'canceled' && order.payment_total.zero? + order.payment_state = 'void' + else + # This part added so that we don't need to override order.outstanding_balance + balance = order.outstanding_balance + balance = -1 * order.payment_total if canceled_and_paid_for? + order.payment_state = 'balance_due' if balance > 0 + order.payment_state = 'credit_owed' if balance < 0 + order.payment_state = 'paid' if balance.zero? + + # Original logic + # order.payment_state = 'balance_due' if order.outstanding_balance > 0 + # order.payment_state = 'credit_owed' if order.outstanding_balance < 0 + # order.payment_state = 'paid' if !order.outstanding_balance? + end + order.state_changed('payment') if last_state != order.payment_state + order.payment_state + end + + def before_save_hook + shipping_address_from_distributor + end + + private + + # Taken from order.outstanding_balance in Spree 2.4 + # See: https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a + def canceled_and_paid_for? + order.canceled? && order.payments.present? && !order.payments.completed.empty? + end + + # Sets the distributor's address as shipping address of the order for those + # shipments using a shipping method that doesn't require address, such us + # a pickup. + def shipping_address_from_distributor + shipments.each do |shipment| + shipping_method = shipment.shipping_method + next if shipping_method.require_ship_address + + order.ship_address = order.distributor.address + end + end +end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 53198251b9f..a30dc22be7c 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -77,7 +77,6 @@ def add_base_abilities(user) def add_group_management_abilities(user) can [:admin, :index], :overview - can [:admin, :sync], :analytic can [:admin, :index], EnterpriseGroup can [:read, :edit, :update], EnterpriseGroup do |group| user.owned_groups.include? group @@ -90,7 +89,6 @@ def add_enterprise_management_abilities(user) can [:create, :search], nil can [:admin, :index], :overview - can [:admin, :sync], :analytic can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty diff --git a/app/models/spree/inventory_unit_decorator.rb b/app/models/spree/inventory_unit_decorator.rb deleted file mode 100644 index 9868596b41f..00000000000 --- a/app/models/spree/inventory_unit_decorator.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Spree - InventoryUnit.class_eval do - def self.assign_opening_inventory(order) - return [] unless order.completed? - - #increase inventory to meet initial requirements - scoper = OpenFoodNetwork::ScopeVariantToHub.new(order.distributor) - order.line_items.each do |line_item| - # Scope variant to hub so that stock levels may be subtracted from VariantOverride. - scoper.scope(line_item.variant) - - increase(order, line_item.variant, line_item.quantity) - end - end - end -end diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 6f74e195304..7af42821f6c 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -110,34 +110,6 @@ def unit_value final_weight_volume / quantity end - # MONKEYPATCH of Spree method - # Enables scoping of variant to hub/shop, stock drawn down from inventory - def update_inventory - return true unless order.completed? - - scoper.scope(variant) # this line added - - if new_record? - Spree::InventoryUnit.increase(order, variant, quantity) - elsif old_quantity = self.changed_attributes['quantity'] - if old_quantity < quantity - Spree::InventoryUnit.increase(order, variant, (quantity - old_quantity)) - elsif old_quantity > quantity - Spree::InventoryUnit.decrease(order, variant, (old_quantity - quantity)) - end - end - end - - # MONKEYPATCH of Spree method - # Enables scoping of variant to hub/shop, stock replaced to inventory - def remove_inventory - return true unless order.completed? - - scoper.scope(variant) # this line added - - Spree::InventoryUnit.decrease(order, variant, quantity) - end - # MONKEYPATCH of Spree method # Enables scoping of variant to hub/shop, so we check stock against relevant overrides if they exist # Also skips stock check if requested quantity is zero diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index bc8142694bc..779162b9b2d 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -19,31 +19,16 @@ validate :disallow_guest_order attr_accessible :order_cycle_id, :distributor_id, :customer_id - before_validation :shipping_address_from_distributor before_validation :associate_customer, unless: :customer_id? before_validation :ensure_customer, unless: :customer_is_valid? before_save :update_shipping_fees!, if: :complete? before_save :update_payment_fees!, if: :complete? - checkout_flow do - go_to_state :address - go_to_state :delivery - go_to_state :payment, :if => lambda { |order| - # Fix for #2191 - if order.shipping_method.andand.delivery? - if order.ship_address.andand.valid? - order.create_shipment! - order.update_totals - end - end - order.payment_required? - } - # NOTE: :confirm step was removed because we were not actually using it - # go_to_state :confirm, :if => lambda { |order| order.confirmation_required? } - go_to_state :complete - remove_transition :from => :delivery, :to => :confirm - end + # Orders are confirmed with their payment, we don't use the confirm step. + # Here we remove that step from Spree's checkout state machine. + # See: https://guides.spreecommerce.org/developer/checkout.html#modifying-the-checkout-flow + remove_checkout_step :confirm # -- Scopes scope :managed_by, lambda { |user| @@ -348,20 +333,15 @@ def pending_payments payments.select {|p| p.state == "checkout"} # Original definition end - private - - def shipping_address_from_distributor - if distributor - # This method is confusing to conform to the vagaries of the multi-step checkout - # We copy over the shipping address when we have no shipping method selected - # We can refactor this when we drop the multi-step checkout option - # - if shipping_method.andand.require_ship_address == false - self.ship_address = address_from_distributor - end - end + # Although Spree 2 supports multi shipments per order, in OFN we keep the rule one shipment per order + # Thus, this method returns the shipping method of the first and only shipment in the order + def shipping_method + return if shipments.empty? + shipments.first.shipping_method end + private + def address_from_distributor address = distributor.address.clone if bill_address diff --git a/app/models/spree/order_updater_decorator.rb b/app/models/spree/order_updater_decorator.rb deleted file mode 100644 index ab1d4eaf26b..00000000000 --- a/app/models/spree/order_updater_decorator.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Spree - OrderUpdater.class_eval do - # TODO: This logic adapted from Spree 2.4, remove when we get there - # Handles state updating in a much more logical way than < 2.4 - # Specifically, doesn't depend on payments.last to determine payment state - # Also swapped: == 0 for .zero?, .size == 0 for empty? and .size > 0 for !empty? - # See: - # https://github.com/spree/spree/commit/38b8456183d11fc1e00e395e7c9154c76ef65b85 - # https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a - def update_payment_state - last_state = order.payment_state - if payments.present? && payments.valid.empty? - order.payment_state = 'failed' - elsif order.state == 'canceled' && order.payment_total.zero? - order.payment_state = 'void' - else - # This part added so that we don't need to override order.outstanding_balance - balance = order.outstanding_balance - balance = -1 * order.payment_total if canceled_and_paid_for? - order.payment_state = 'balance_due' if balance > 0 - order.payment_state = 'credit_owed' if balance < 0 - order.payment_state = 'paid' if balance.zero? - - # Original logic - # order.payment_state = 'balance_due' if order.outstanding_balance > 0 - # order.payment_state = 'credit_owed' if order.outstanding_balance < 0 - # order.payment_state = 'paid' if !order.outstanding_balance? - end - order.state_changed('payment') if last_state != order.payment_state - order.payment_state - end - - private - - # Taken from order.outstanding_balance in Spree 2.4 - # See: https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a - def canceled_and_paid_for? - order.canceled? && order.payments.present? && !order.payments.completed.empty? - end - end -end diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 18220aaafd0..64e5c746774 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -260,7 +260,6 @@ def ensure_standard_variant variant = self.master.dup variant.product = self variant.is_master = false - variant.on_demand = self.on_demand self.variants << variant end end diff --git a/app/models/spree/shipment_decorator.rb b/app/models/spree/shipment_decorator.rb index f544d955172..625cf06decd 100644 --- a/app/models/spree/shipment_decorator.rb +++ b/app/models/spree/shipment_decorator.rb @@ -2,6 +2,7 @@ module Spree Shipment.class_eval do def ensure_correct_adjustment_with_included_tax ensure_correct_adjustment_without_included_tax + return unless adjustment if Config.shipment_inc_vat && (order.distributor.nil? || order.distributor.charges_sales_tax) adjustment.set_included_tax! Config.shipping_tax_rate diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index a900f149366..6a512737bd1 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -42,12 +42,6 @@ def self.services ] end - def available_to_order_with_distributor_check?(order) - available_to_order_without_distributor_check?(order) && - self.distributors.include?(order.distributor) - end - alias_method_chain :available_to_order?, :distributor_check - def within_zone?(order) if order.ship_address zone && zone.include?(order.ship_address) diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index 4c7e6ed5ab2..e53e91ca29a 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -1,5 +1,6 @@ require 'open_food_network/enterprise_fee_calculator' require 'open_food_network/variant_and_line_item_naming' +require 'open_food_network/variant_stock' require 'open_food_network/products_cache' Spree::Variant.class_eval do @@ -9,6 +10,7 @@ # removing the Spree method to prevent error. remove_method :options_text if instance_methods(false).include? :options_text include OpenFoodNetwork::VariantAndLineItemNaming + include OpenFoodNetwork::VariantStock has_many :exchange_variants has_many :exchanges, through: :exchange_variants diff --git a/app/models/stock/package.rb b/app/models/stock/package.rb new file mode 100644 index 00000000000..012e2265d4d --- /dev/null +++ b/app/models/stock/package.rb @@ -0,0 +1,33 @@ +# Extends Spree's Package implementation to skip shipping methods that are not +# valid for OFN. +# +# It requires the following configuration in config/initializers/spree.rb: +# +# Spree.config do |config| +# ... +# config.package_factory = Stock::Package +# end +# +module Stock + class Package < Spree::Stock::Package + # Skips the methods that are not used by the order's distributor + # + # @return [Array] + def shipping_methods + super.delete_if do |shipping_method| + !ships_with?(order.distributor, shipping_method) + end + end + + private + + # Checks whether the given distributor provides the specified shipping method + # + # @param distributor [Spree::Enterprise] + # @param shipping_method [Spree::ShippingMethod] + # @return [Boolean] + def ships_with?(distributor, shipping_method) + distributor.shipping_methods.include?(shipping_method) + end + end +end diff --git a/config/initializers/spree.rb b/config/initializers/spree.rb index 9b62e3ad6e3..83e854a08fb 100644 --- a/config/initializers/spree.rb +++ b/config/initializers/spree.rb @@ -20,6 +20,9 @@ # Auto-capture payments. Without this option, payments must be manually captured in the paypal interface. config.auto_capture = true #config.override_actionmailer_config = false + + config.package_factory = Stock::Package + config.order_updater_decorator = OrderUpdater end # TODO Work out why this is necessary @@ -27,14 +30,3 @@ # unless the empty module is explicity 'registered' here. Something to do with autoloading? module OpenFoodNetwork end - -# Forcing spree to always allow SSL connections -# Since we are using config.force_ssl = true -# Without this we get a redirect loop: see https://groups.google.com/forum/#!topic/spree-user/NwpqGxJ4klk -SslRequirement.module_eval do - protected - - def ssl_allowed? - true - end -end diff --git a/db/migrate/20180426145630_create_spree_stock_items.spree.rb b/db/migrate/20180426145630_create_spree_stock_items.spree.rb new file mode 100644 index 00000000000..cd6f349740f --- /dev/null +++ b/db/migrate/20180426145630_create_spree_stock_items.spree.rb @@ -0,0 +1,15 @@ +# This migration comes from spree (originally 20130211190146) +class CreateSpreeStockItems < ActiveRecord::Migration + def change + create_table :spree_stock_items do |t| + t.belongs_to :stock_location + t.belongs_to :variant + t.integer :count_on_hand, null: false, default: 0 + t.integer :lock_version + + t.timestamps + end + add_index :spree_stock_items, :stock_location_id + add_index :spree_stock_items, [:stock_location_id, :variant_id], :name => 'stock_item_by_loc_and_var_id' + end +end diff --git a/db/migrate/20180426145631_create_spree_stock_locations.spree.rb b/db/migrate/20180426145631_create_spree_stock_locations.spree.rb new file mode 100644 index 00000000000..a3e4d1a4dc8 --- /dev/null +++ b/db/migrate/20180426145631_create_spree_stock_locations.spree.rb @@ -0,0 +1,12 @@ +# This migration comes from spree (originally 20130211191120) +class CreateSpreeStockLocations < ActiveRecord::Migration + def change + create_table :spree_stock_locations do |t| + t.string :name + t.belongs_to :address + + t.timestamps + end + add_index :spree_stock_locations, :address_id + end +end diff --git a/db/migrate/20180426145632_create_default_stock.spree.rb b/db/migrate/20180426145632_create_default_stock.spree.rb new file mode 100644 index 00000000000..b1fc601078f --- /dev/null +++ b/db/migrate/20180426145632_create_default_stock.spree.rb @@ -0,0 +1,27 @@ +# This migration comes from spree (originally 20130213191427) +class CreateDefaultStock < ActiveRecord::Migration + def up + Spree::StockLocation.skip_callback(:create, :after, :create_stock_items) + Spree::StockItem.skip_callback(:save, :after, :process_backorders) + location = Spree::StockLocation.create(name: 'default') + Spree::Variant.all.each do |variant| + stock_item = location.stock_items.build(variant: variant) + stock_item.send(:count_on_hand=, variant.count_on_hand) + stock_item.save! + end + + remove_column :spree_variants, :count_on_hand + end + + def down + add_column :spree_variants, :count_on_hand, :integer + + Spree::StockItem.all.each do |stock_item| + stock_item.variant.update_column :count_on_hand, stock_item.count_on_hand + end + + Spree::StockLocation.delete_all + Spree::StockItem.delete_all + end +end + diff --git a/db/migrate/20180426145633_add_stock_location_id_to_spree_shipments.spree.rb b/db/migrate/20180426145633_add_stock_location_id_to_spree_shipments.spree.rb new file mode 100644 index 00000000000..e102d7febb2 --- /dev/null +++ b/db/migrate/20180426145633_add_stock_location_id_to_spree_shipments.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130226191231) +class AddStockLocationIdToSpreeShipments < ActiveRecord::Migration + def change + add_column :spree_shipments, :stock_location_id, :integer + end +end diff --git a/db/migrate/20180426145634_add_pending_to_inventory_unit.spree.rb b/db/migrate/20180426145634_add_pending_to_inventory_unit.spree.rb new file mode 100644 index 00000000000..c3879d3604c --- /dev/null +++ b/db/migrate/20180426145634_add_pending_to_inventory_unit.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20130227143905) +class AddPendingToInventoryUnit < ActiveRecord::Migration + def change + add_column :spree_inventory_units, :pending, :boolean, :default => true + Spree::InventoryUnit.update_all(:pending => false) + end +end diff --git a/db/migrate/20180426145635_remove_on_demand_from_product_and_variant.spree.rb b/db/migrate/20180426145635_remove_on_demand_from_product_and_variant.spree.rb new file mode 100644 index 00000000000..72ac77b9ec3 --- /dev/null +++ b/db/migrate/20180426145635_remove_on_demand_from_product_and_variant.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20130228164411) +class RemoveOnDemandFromProductAndVariant < ActiveRecord::Migration + def change + remove_column :spree_products, :on_demand + remove_column :spree_variants, :on_demand + end +end diff --git a/db/migrate/20180426145636_create_shipping_method_zone.spree.rb b/db/migrate/20180426145636_create_shipping_method_zone.spree.rb new file mode 100644 index 00000000000..2d99447b139 --- /dev/null +++ b/db/migrate/20180426145636_create_shipping_method_zone.spree.rb @@ -0,0 +1,23 @@ +# This migration comes from spree (originally 20130228210442) +class CreateShippingMethodZone < ActiveRecord::Migration + def up + create_table :shipping_methods_zones, :id => false do |t| + t.integer :shipping_method_id + t.integer :zone_id + end + # This association has been corrected in a latter migration + # but when this database migration runs, the table is still incorrectly named + # 'shipping_methods_zones' instead of 'spre_shipping_methods_zones' + Spree::ShippingMethod.has_and_belongs_to_many :zones, :join_table => 'shipping_methods_zones', + :class_name => 'Spree::Zone', + :foreign_key => 'shipping_method_id' + Spree::ShippingMethod.all.each{|sm| sm.zones << Spree::Zone.find(sm.zone_id)} + + remove_column :spree_shipping_methods, :zone_id + end + + def down + drop_table :shipping_methods_zones + add_column :spree_shipping_methods, :zone_id, :integer + end +end diff --git a/db/migrate/20180426145637_remove_shipping_category_id_from_shipping_method.spree.rb b/db/migrate/20180426145637_remove_shipping_category_id_from_shipping_method.spree.rb new file mode 100644 index 00000000000..f686ac4aa7b --- /dev/null +++ b/db/migrate/20180426145637_remove_shipping_category_id_from_shipping_method.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130301162745) +class RemoveShippingCategoryIdFromShippingMethod < ActiveRecord::Migration + def change + remove_column :spree_shipping_methods, :shipping_category_id + end +end diff --git a/db/migrate/20180426145638_create_shipping_method_categories.spree.rb b/db/migrate/20180426145638_create_shipping_method_categories.spree.rb new file mode 100644 index 00000000000..2af03a7ec04 --- /dev/null +++ b/db/migrate/20180426145638_create_shipping_method_categories.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20130301162924) +class CreateShippingMethodCategories < ActiveRecord::Migration + def change + create_table :spree_shipping_method_categories do |t| + t.integer :shipping_method_id, :null => false + t.integer :shipping_category_id, :null => false + + t.timestamps + end + + add_index :spree_shipping_method_categories, :shipping_method_id + add_index :spree_shipping_method_categories, :shipping_category_id + end +end diff --git a/db/migrate/20180426145639_create_spree_shipping_rates.spree.rb b/db/migrate/20180426145639_create_spree_shipping_rates.spree.rb new file mode 100644 index 00000000000..f2932a57b31 --- /dev/null +++ b/db/migrate/20180426145639_create_spree_shipping_rates.spree.rb @@ -0,0 +1,25 @@ +# This migration comes from spree (originally 20130304162240) +class CreateSpreeShippingRates < ActiveRecord::Migration + def up + create_table :spree_shipping_rates do |t| + t.belongs_to :shipment + t.belongs_to :shipping_method + t.boolean :selected, :default => false + t.decimal :cost, :precision => 8, :scale => 2 + t.timestamps + end + add_index(:spree_shipping_rates, [:shipment_id, :shipping_method_id], + :name => 'spree_shipping_rates_join_index', + :unique => true) + + # Spree::Shipment.all.each do |shipment| + # shipping_method = Spree::ShippingMethod.find(shipment.shipment_method_id) + # shipment.add_shipping_method(shipping_method, true) + # end + end + + def down + # add_column :spree_shipments, :shipping_method_id, :integer + drop_table :spree_shipping_rates + end +end diff --git a/db/migrate/20180426145640_remove_category_match_attributes_from_shipping_method.spree.rb b/db/migrate/20180426145640_remove_category_match_attributes_from_shipping_method.spree.rb new file mode 100644 index 00000000000..1562aecdb2b --- /dev/null +++ b/db/migrate/20180426145640_remove_category_match_attributes_from_shipping_method.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20130304192936) +class RemoveCategoryMatchAttributesFromShippingMethod < ActiveRecord::Migration + def change + remove_column :spree_shipping_methods, :match_none + remove_column :spree_shipping_methods, :match_one + remove_column :spree_shipping_methods, :match_all + end +end diff --git a/db/migrate/20180426145641_create_stock_movements.spree.rb b/db/migrate/20180426145641_create_stock_movements.spree.rb new file mode 100644 index 00000000000..d7c8cb88d35 --- /dev/null +++ b/db/migrate/20180426145641_create_stock_movements.spree.rb @@ -0,0 +1,13 @@ +# This migration comes from spree (originally 20130305143310) +class CreateStockMovements < ActiveRecord::Migration + def change + create_table :spree_stock_movements do |t| + t.belongs_to :stock_item + t.integer :quantity + t.string :action + + t.timestamps + end + add_index :spree_stock_movements, :stock_item_id + end +end diff --git a/db/migrate/20180426145642_add_address_fields_to_stock_location.spree.rb b/db/migrate/20180426145642_add_address_fields_to_stock_location.spree.rb new file mode 100644 index 00000000000..4a16efeb406 --- /dev/null +++ b/db/migrate/20180426145642_add_address_fields_to_stock_location.spree.rb @@ -0,0 +1,23 @@ +# This migration comes from spree (originally 20130306181701) +class AddAddressFieldsToStockLocation < ActiveRecord::Migration + def change + remove_column :spree_stock_locations, :address_id + + add_column :spree_stock_locations, :address1, :string + add_column :spree_stock_locations, :address2, :string + add_column :spree_stock_locations, :city, :string + add_column :spree_stock_locations, :state_id, :integer + add_column :spree_stock_locations, :state_name, :string + add_column :spree_stock_locations, :country_id, :integer + add_column :spree_stock_locations, :zipcode, :string + add_column :spree_stock_locations, :phone, :string + + + usa = Spree::Country.where(:iso => 'US').first + # In case USA isn't found. + # See #3115 + country = usa || Spree::Country.first + Spree::Country.reset_column_information + Spree::StockLocation.update_all(:country_id => country) + end +end diff --git a/db/migrate/20180426145643_add_active_field_to_stock_locations.spree.rb b/db/migrate/20180426145643_add_active_field_to_stock_locations.spree.rb new file mode 100644 index 00000000000..0e69642de23 --- /dev/null +++ b/db/migrate/20180426145643_add_active_field_to_stock_locations.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130306191917) +class AddActiveFieldToStockLocations < ActiveRecord::Migration + def change + add_column :spree_stock_locations, :active, :boolean, :default => true + end +end diff --git a/db/migrate/20180426145644_add_backorderable_to_stock_item.spree.rb b/db/migrate/20180426145644_add_backorderable_to_stock_item.spree.rb new file mode 100644 index 00000000000..839e3b3d090 --- /dev/null +++ b/db/migrate/20180426145644_add_backorderable_to_stock_item.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130306195650) +class AddBackorderableToStockItem < ActiveRecord::Migration + def change + add_column :spree_stock_items, :backorderable, :boolean, :default => true + end +end diff --git a/db/migrate/20180426145645_add_default_quantity_to_stock_movement.spree.rb b/db/migrate/20180426145645_add_default_quantity_to_stock_movement.spree.rb new file mode 100644 index 00000000000..c991b94e4aa --- /dev/null +++ b/db/migrate/20180426145645_add_default_quantity_to_stock_movement.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130307161754) +class AddDefaultQuantityToStockMovement < ActiveRecord::Migration + def change + change_column :spree_stock_movements, :quantity, :integer, :default => 0 + end +end diff --git a/db/migrate/20180426145646_add_source_and_destination_to_stock_movements.spree.rb b/db/migrate/20180426145646_add_source_and_destination_to_stock_movements.spree.rb new file mode 100644 index 00000000000..7e0f0987b79 --- /dev/null +++ b/db/migrate/20180426145646_add_source_and_destination_to_stock_movements.spree.rb @@ -0,0 +1,9 @@ +# This migration comes from spree (originally 20130318151756) +class AddSourceAndDestinationToStockMovements < ActiveRecord::Migration + def change + change_table :spree_stock_movements do |t| + t.references :source, polymorphic: true + t.references :destination, polymorphic: true + end + end +end diff --git a/db/migrate/20180426145647_add_originator_to_stock_movement.spree.rb b/db/migrate/20180426145647_add_originator_to_stock_movement.spree.rb new file mode 100644 index 00000000000..7c1a74679af --- /dev/null +++ b/db/migrate/20180426145647_add_originator_to_stock_movement.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20130319183250) +class AddOriginatorToStockMovement < ActiveRecord::Migration + def change + change_table :spree_stock_movements do |t| + t.references :originator, polymorphic: true + end + end +end diff --git a/db/migrate/20180426145648_drop_source_and_destination_from_stock_movement.spree.rb b/db/migrate/20180426145648_drop_source_and_destination_from_stock_movement.spree.rb new file mode 100644 index 00000000000..6735614f4e3 --- /dev/null +++ b/db/migrate/20180426145648_drop_source_and_destination_from_stock_movement.spree.rb @@ -0,0 +1,16 @@ +# This migration comes from spree (originally 20130319190507) +class DropSourceAndDestinationFromStockMovement < ActiveRecord::Migration + def up + change_table :spree_stock_movements do |t| + t.remove_references :source, :polymorphic => true + t.remove_references :destination, :polymorphic => true + end + end + + def down + change_table :spree_stock_movements do |t| + t.references :source, polymorphic: true + t.references :destination, polymorphic: true + end + end +end diff --git a/db/migrate/20180426145649_migrate_inventory_unit_sold_to_on_hand.spree.rb b/db/migrate/20180426145649_migrate_inventory_unit_sold_to_on_hand.spree.rb new file mode 100644 index 00000000000..4f759427ee9 --- /dev/null +++ b/db/migrate/20180426145649_migrate_inventory_unit_sold_to_on_hand.spree.rb @@ -0,0 +1,10 @@ +# This migration comes from spree (originally 20130325163316) +class MigrateInventoryUnitSoldToOnHand < ActiveRecord::Migration + def up + Spree::InventoryUnit.where(:state => 'sold').update_all(:state => 'on_hand') + end + + def down + Spree::InventoryUnit.where(:state => 'on_hand').update_all(:state => 'sold') + end +end diff --git a/db/migrate/20180426145650_add_stock_location_to_rma.spree.rb b/db/migrate/20180426145650_add_stock_location_to_rma.spree.rb new file mode 100644 index 00000000000..54d85f76a4a --- /dev/null +++ b/db/migrate/20180426145650_add_stock_location_to_rma.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130326175857) +class AddStockLocationToRma < ActiveRecord::Migration + def change + add_column :spree_return_authorizations, :stock_location_id, :integer + end +end diff --git a/db/migrate/20180426145651_update_shipment_state_for_canceled_orders.spree.rb b/db/migrate/20180426145651_update_shipment_state_for_canceled_orders.spree.rb new file mode 100644 index 00000000000..f5c1b5a0cf6 --- /dev/null +++ b/db/migrate/20180426145651_update_shipment_state_for_canceled_orders.spree.rb @@ -0,0 +1,16 @@ +# This migration comes from spree (originally 20130328130308) +class UpdateShipmentStateForCanceledOrders < ActiveRecord::Migration + def up + shipments = Spree::Shipment.joins(:order). + where("spree_orders.state = 'canceled'") + case Spree::Shipment.connection.adapter_name + when "SQLite3" + shipments.update_all("state = 'cancelled'") + when "MySQL" || "PostgreSQL" + shipments.update_all("spree_shipments.state = 'cancelled'") + end + end + + def down + end +end diff --git a/db/migrate/20180426145652_remove_stock_item_and_variant_lock.spree.rb b/db/migrate/20180426145652_remove_stock_item_and_variant_lock.spree.rb new file mode 100644 index 00000000000..c522a765ccd --- /dev/null +++ b/db/migrate/20180426145652_remove_stock_item_and_variant_lock.spree.rb @@ -0,0 +1,15 @@ +# This migration comes from spree (originally 20130329134939) +class RemoveStockItemAndVariantLock < ActiveRecord::Migration + def up + # we are moving to pessimistic locking on stock_items + remove_column :spree_stock_items, :lock_version + + # variants no longer manage their count_on_hand so we are removing their lock + remove_column :spree_variants, :lock_version + end + + def down + add_column :spree_stock_items, :lock_version, :integer + add_column :spree_variants, :lock_version, :integer + end +end diff --git a/db/migrate/20180426145653_add_shipping_rates_to_shipments.spree.rb b/db/migrate/20180426145653_add_shipping_rates_to_shipments.spree.rb new file mode 100644 index 00000000000..a9ae3bd83d5 --- /dev/null +++ b/db/migrate/20180426145653_add_shipping_rates_to_shipments.spree.rb @@ -0,0 +1,16 @@ +# This migration comes from spree (originally 20130417123427) +class AddShippingRatesToShipments < ActiveRecord::Migration + def up + Spree::Shipment.all.each do |shipment| + shipment.shipping_rates.create(:shipping_method_id => shipment.shipping_method_id, + :cost => shipment.cost, + :selected => true) + end + + remove_column :spree_shipments, :shipping_method_id + end + + def down + add_column :spree_shipments, :shipping_method_id, :integer + end +end diff --git a/db/migrate/20180426145654_create_spree_stock_transfers.spree.rb b/db/migrate/20180426145654_create_spree_stock_transfers.spree.rb new file mode 100644 index 00000000000..1b73d9b1762 --- /dev/null +++ b/db/migrate/20180426145654_create_spree_stock_transfers.spree.rb @@ -0,0 +1,15 @@ +# This migration comes from spree (originally 20130418125341) +class CreateSpreeStockTransfers < ActiveRecord::Migration + def change + create_table :spree_stock_transfers do |t| + t.string :type + t.string :reference_number + t.integer :source_location_id + t.integer :destination_location_id + t.timestamps + end + + add_index :spree_stock_transfers, :source_location_id + add_index :spree_stock_transfers, :destination_location_id + end +end diff --git a/db/migrate/20180426145655_drop_products_count_on_hand.spree.rb b/db/migrate/20180426145655_drop_products_count_on_hand.spree.rb new file mode 100644 index 00000000000..29cb947a56e --- /dev/null +++ b/db/migrate/20180426145655_drop_products_count_on_hand.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130423110707) +class DropProductsCountOnHand < ActiveRecord::Migration + def up + remove_column :spree_products, :count_on_hand + end +end diff --git a/db/migrate/20180426145656_set_default_shipping_rate_cost.spree.rb b/db/migrate/20180426145656_set_default_shipping_rate_cost.spree.rb new file mode 100644 index 00000000000..64b9ccb108c --- /dev/null +++ b/db/migrate/20180426145656_set_default_shipping_rate_cost.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130423223847) +class SetDefaultShippingRateCost < ActiveRecord::Migration + def change + change_column :spree_shipping_rates, :cost, :decimal, default: 0, precision: 8, scale: 2 + end +end diff --git a/db/migrate/20180426145657_add_number_to_stock_transfer.spree.rb b/db/migrate/20180426145657_add_number_to_stock_transfer.spree.rb new file mode 100644 index 00000000000..cf06743da0a --- /dev/null +++ b/db/migrate/20180426145657_add_number_to_stock_transfer.spree.rb @@ -0,0 +1,24 @@ +# This migration comes from spree (originally 20130509115210) +class AddNumberToStockTransfer < ActiveRecord::Migration + def up + remove_index :spree_stock_transfers, :source_location_id + remove_index :spree_stock_transfers, :destination_location_id + + rename_column :spree_stock_transfers, :reference_number, :reference + add_column :spree_stock_transfers, :number, :string + + Spree::StockTransfer.all.each do |transfer| + transfer.send(:generate_stock_transfer_number) + transfer.save! + end + + add_index :spree_stock_transfers, :number + add_index :spree_stock_transfers, :source_location_id + add_index :spree_stock_transfers, :destination_location_id + end + + def down + rename_column :spree_stock_transfers, :reference, :reference_number + remove_column :spree_stock_transfers, :number, :string + end +end diff --git a/db/migrate/20180426145658_add_sku_index_to_spree_variants.spree.rb b/db/migrate/20180426145658_add_sku_index_to_spree_variants.spree.rb new file mode 100644 index 00000000000..cd089f846d7 --- /dev/null +++ b/db/migrate/20180426145658_add_sku_index_to_spree_variants.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130514151929) +class AddSkuIndexToSpreeVariants < ActiveRecord::Migration + def change + add_index :spree_variants, :sku + end +end diff --git a/db/migrate/20180426145659_add_backorderable_default_to_spree_stock_location.spree.rb b/db/migrate/20180426145659_add_backorderable_default_to_spree_stock_location.spree.rb new file mode 100644 index 00000000000..29939c59e64 --- /dev/null +++ b/db/migrate/20180426145659_add_backorderable_default_to_spree_stock_location.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130515180736) +class AddBackorderableDefaultToSpreeStockLocation < ActiveRecord::Migration + def change + add_column :spree_stock_locations, :backorderable_default, :boolean, default: true + end +end diff --git a/db/migrate/20180426145660_add_propage_all_variants_to_spree_stock_location.spree.rb b/db/migrate/20180426145660_add_propage_all_variants_to_spree_stock_location.spree.rb new file mode 100644 index 00000000000..bfc55eac56b --- /dev/null +++ b/db/migrate/20180426145660_add_propage_all_variants_to_spree_stock_location.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130516151222) +class AddPropageAllVariantsToSpreeStockLocation < ActiveRecord::Migration + def change + add_column :spree_stock_locations, :propagate_all_variants, :boolean, default: true + end +end diff --git a/db/migrate/20180426145661_rename_shipping_methods_zones_to_spree_shipping_methods_zones.spree.rb b/db/migrate/20180426145661_rename_shipping_methods_zones_to_spree_shipping_methods_zones.spree.rb new file mode 100644 index 00000000000..5c7ee6dd952 --- /dev/null +++ b/db/migrate/20180426145661_rename_shipping_methods_zones_to_spree_shipping_methods_zones.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130611054351) +class RenameShippingMethodsZonesToSpreeShippingMethodsZones < ActiveRecord::Migration + def change + rename_table :shipping_methods_zones, :spree_shipping_methods_zones + end +end diff --git a/db/migrate/20180426145662_add_deleted_at_to_spree_tax_rates.spree.rb b/db/migrate/20180426145662_add_deleted_at_to_spree_tax_rates.spree.rb new file mode 100644 index 00000000000..c804d9a1f70 --- /dev/null +++ b/db/migrate/20180426145662_add_deleted_at_to_spree_tax_rates.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130708052307) +class AddDeletedAtToSpreeTaxRates < ActiveRecord::Migration + def change + add_column :spree_tax_rates, :deleted_at, :datetime + end +end diff --git a/db/migrate/20180426145663_remove_lock_version_from_inventory_units.spree.rb b/db/migrate/20180426145663_remove_lock_version_from_inventory_units.spree.rb new file mode 100644 index 00000000000..42c60bd3f36 --- /dev/null +++ b/db/migrate/20180426145663_remove_lock_version_from_inventory_units.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20130711200933) +class RemoveLockVersionFromInventoryUnits < ActiveRecord::Migration + def change + # we are moving to pessimistic locking on stock_items + remove_column :spree_inventory_units, :lock_version + end +end diff --git a/db/migrate/20180426145664_add_cost_price_to_line_item.spree.rb b/db/migrate/20180426145664_add_cost_price_to_line_item.spree.rb new file mode 100644 index 00000000000..d54222f5592 --- /dev/null +++ b/db/migrate/20180426145664_add_cost_price_to_line_item.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130718042445) +class AddCostPriceToLineItem < ActiveRecord::Migration + def change + add_column :spree_line_items, :cost_price, :decimal, :precision => 8, :scale => 2 + end +end diff --git a/db/migrate/20180426145665_set_backorderable_to_default_to_false.spree.rb b/db/migrate/20180426145665_set_backorderable_to_default_to_false.spree.rb new file mode 100644 index 00000000000..a05f4279a44 --- /dev/null +++ b/db/migrate/20180426145665_set_backorderable_to_default_to_false.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20130718233855) +class SetBackorderableToDefaultToFalse < ActiveRecord::Migration + def change + change_column :spree_stock_items, :backorderable, :boolean, :default => false + change_column :spree_stock_locations, :backorderable_default, :boolean, :default => false + end +end diff --git a/db/migrate/20180426145666_add_created_by_id_to_spree_orders.spree.rb b/db/migrate/20180426145666_add_created_by_id_to_spree_orders.spree.rb new file mode 100644 index 00000000000..fe59c0fc212 --- /dev/null +++ b/db/migrate/20180426145666_add_created_by_id_to_spree_orders.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130725031716) +class AddCreatedByIdToSpreeOrders < ActiveRecord::Migration + def change + add_column :spree_orders, :created_by_id, :integer + end +end diff --git a/db/migrate/20180426145667_index_completed_at_on_spree_orders.spree.rb b/db/migrate/20180426145667_index_completed_at_on_spree_orders.spree.rb new file mode 100644 index 00000000000..c4c279ca4cd --- /dev/null +++ b/db/migrate/20180426145667_index_completed_at_on_spree_orders.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130729214043) +class IndexCompletedAtOnSpreeOrders < ActiveRecord::Migration + def change + add_index :spree_orders, :completed_at + end +end diff --git a/db/migrate/20180426145668_add_tax_category_id_to_spree_line_items.spree.rb b/db/migrate/20180426145668_add_tax_category_id_to_spree_line_items.spree.rb new file mode 100644 index 00000000000..2b7e1a51bc7 --- /dev/null +++ b/db/migrate/20180426145668_add_tax_category_id_to_spree_line_items.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20130802014537) +class AddTaxCategoryIdToSpreeLineItems < ActiveRecord::Migration + def change + add_column :spree_line_items, :tax_category_id, :integer + end +end diff --git a/db/migrate/20180426145669_migrate_tax_categories_to_line_items.spree.rb b/db/migrate/20180426145669_migrate_tax_categories_to_line_items.spree.rb new file mode 100644 index 00000000000..80a82ea1af2 --- /dev/null +++ b/db/migrate/20180426145669_migrate_tax_categories_to_line_items.spree.rb @@ -0,0 +1,10 @@ +# This migration comes from spree (originally 20130802022321) +class MigrateTaxCategoriesToLineItems < ActiveRecord::Migration + def change + Spree::LineItem.includes(:variant => { :product => :tax_category }).find_in_batches do |line_items| + line_items.each do |line_item| + line_item.update_column(:tax_category_id, line_item.product.tax_category.id) + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 13c0c125b85..1d7f1677246 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -510,14 +510,14 @@ end create_table "spree_inventory_units", :force => true do |t| - t.integer "lock_version", :default => 0 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 end add_index "spree_inventory_units", ["order_id"], :name => "index_inventory_units_on_order_id" @@ -536,6 +536,8 @@ t.decimal "distribution_fee", :precision => 10, :scale => 2 t.string "shipping_method_name" 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" @@ -616,8 +618,10 @@ t.string "currency" t.string "last_ip_address" t.integer "customer_id" + t.integer "created_by_id" end + add_index "spree_orders", ["completed_at"], :name => "index_spree_orders_on_completed_at" add_index "spree_orders", ["customer_id"], :name => "index_spree_orders_on_customer_id" add_index "spree_orders", ["number"], :name => "index_orders_on_number" @@ -740,7 +744,7 @@ add_index "spree_product_scopes", ["product_group_id"], :name => "index_product_scopes_on_product_group_id" create_table "spree_products", :force => true do |t| - t.string "name", :default => "", :null => false + t.string "name", :default => "", :null => false t.text "description" t.datetime "available_on" t.datetime "deleted_at" @@ -749,19 +753,17 @@ 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.integer "count_on_hand", :default => 0 + 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" - t.boolean "on_demand", :default => false t.string "variant_unit" 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" @@ -840,11 +842,12 @@ 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| @@ -862,14 +865,14 @@ 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 "shipping_method_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" @@ -882,22 +885,43 @@ 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 + 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" + create_table "spree_shipping_methods", :force => true do |t| t.string "name" - t.integer "zone_id" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false t.string "display_on" - t.integer "shipping_category_id" - t.boolean "match_none" - t.boolean "match_all" - t.boolean "match_one" t.datetime "deleted_at" 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| + t.integer "shipping_method_id" + t.integer "zone_id" + end + + 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 + end + + add_index "spree_shipping_rates", ["shipment_id", "shipping_method_id"], :name => "spree_shipping_rates_join_index", :unique => true + create_table "spree_skrill_transactions", :force => true do |t| t.string "email" t.float "amount" @@ -926,6 +950,61 @@ t.integer "country_id" end + 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 + 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" + + 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.string "address1" + t.string "address2" + t.string "city" + t.integer "state_id" + t.string "state_name" + 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 + end + + create_table "spree_stock_movements", :force => true do |t| + 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.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" + + 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.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" + create_table "spree_tax_categories", :force => true do |t| t.string "name" t.string "description" @@ -944,6 +1023,7 @@ t.boolean "included_in_price", :default => false t.string "name" t.boolean "show_rate_in_label", :default => true + t.datetime "deleted_at" end create_table "spree_taxonomies", :force => true do |t| @@ -1043,11 +1123,8 @@ t.datetime "deleted_at" t.boolean "is_master", :default => false t.integer "product_id" - t.integer "count_on_hand", :default => 0 t.decimal "cost_price", :precision => 8, :scale => 2 t.integer "position" - t.integer "lock_version", :default => 0 - t.boolean "on_demand", :default => false t.string "cost_currency" t.float "unit_value" t.string "unit_description", :default => "" @@ -1057,6 +1134,7 @@ end add_index "spree_variants", ["product_id"], :name => "index_variants_on_product_id" + add_index "spree_variants", ["sku"], :name => "index_spree_variants_on_sku" create_table "spree_zone_members", :force => true do |t| t.integer "zoneable_id" @@ -1323,9 +1401,6 @@ add_foreign_key "spree_shipments", "spree_addresses", name: "spree_shipments_address_id_fk", column: "address_id" add_foreign_key "spree_shipments", "spree_orders", name: "spree_shipments_order_id_fk", column: "order_id" - add_foreign_key "spree_shipping_methods", "spree_shipping_categories", name: "spree_shipping_methods_shipping_category_id_fk", column: "shipping_category_id" - add_foreign_key "spree_shipping_methods", "spree_zones", name: "spree_shipping_methods_zone_id_fk", column: "zone_id" - add_foreign_key "spree_state_changes", "spree_users", name: "spree_state_changes_user_id_fk", column: "user_id" add_foreign_key "spree_states", "spree_countries", name: "spree_states_country_id_fk", column: "country_id" diff --git a/lib/open_food_network/variant_stock.rb b/lib/open_food_network/variant_stock.rb new file mode 100644 index 00000000000..fba38ebd57a --- /dev/null +++ b/lib/open_food_network/variant_stock.rb @@ -0,0 +1,80 @@ +require 'active_support/concern' + +# These methods were available in Spree 1, but were removed in Spree 2. +# We would still like to use them. Therefore we use only a single stock location +# (default stock location) and use it to track the `count_on_hand` value that +# was previously a database column on variants. +# +# We may decide to deprecate these methods after we designed the Network feature. +module OpenFoodNetwork + module VariantStock + extend ActiveSupport::Concern + + included do + after_save :save_stock + end + + def on_hand + if on_demand + Float::INFINITY + else + total_on_hand + end + end + + def count_on_hand + total_on_hand + end + + def on_hand=(new_level) + error = 'Cannot set on_hand value when Spree::Config[:track_inventory_levels] is false' + raise error unless Spree::Config.track_inventory_levels + + self.count_on_hand = new_level + end + + def count_on_hand=(new_level) + raise_error_if_no_stock_item_available + overwrite_stock_levels new_level + end + + def on_demand + stock_items.any?(&:backorderable?) + end + + def on_demand=(new_value) + raise_error_if_no_stock_item_available + + # There should be only one at the default stock location. + stock_items.each do |item| + item.backorderable = new_value + end + end + + private + + def save_stock + stock_items.each(&:save) + end + + def raise_error_if_no_stock_item_available + message = 'You need to save the variant to create a stock item before you can set stock levels.' + raise message if stock_items.empty? + end + + # Backwards compatible setting of stock levels in Spree 2.0. + # It would be better to use `Spree::StockItem.adjust_count_on_hand` which + # takes a value to add to the current stock level and uses proper locking. + # But this should work the same as in Spree 1.3. + def overwrite_stock_levels(new_level) + stock_items.first.send :count_on_hand=, new_level + + # There shouldn't be any other stock items, because we should have only one + # stock location. But in case there are, the total should be new_level, + # so all others need to be zero. + stock_items[1..-1].each do |item| + item.send :count_on_hand=, 0 + end + end + end +end diff --git a/spec/controllers/admin/bulk_line_items_controller_spec.rb b/spec/controllers/admin/bulk_line_items_controller_spec.rb index dd5c1c63268..d6463d5c529 100644 --- a/spec/controllers/admin/bulk_line_items_controller_spec.rb +++ b/spec/controllers/admin/bulk_line_items_controller_spec.rb @@ -11,10 +11,10 @@ let!(:order1) { FactoryBot.create(:order, state: 'complete', completed_at: 1.day.ago, distributor: dist1, billing_address: FactoryBot.create(:address) ) } let!(:order2) { FactoryBot.create(:order, state: 'complete', completed_at: Time.zone.now, distributor: dist1, billing_address: FactoryBot.create(:address) ) } let!(:order3) { FactoryBot.create(:order, state: 'complete', completed_at: Time.zone.now, distributor: dist1, billing_address: FactoryBot.create(:address) ) } - let!(:line_item1) { FactoryBot.create(:line_item, order: order1) } - let!(:line_item2) { FactoryBot.create(:line_item, order: order2) } - let!(:line_item3) { FactoryBot.create(:line_item, order: order2) } - let!(:line_item4) { FactoryBot.create(:line_item, order: order3) } + let!(:line_item1) { FactoryBot.create(:line_item_with_shipment, order: order1) } + let!(:line_item2) { FactoryBot.create(:line_item_with_shipment, order: order2) } + let!(:line_item3) { FactoryBot.create(:line_item_with_shipment, order: order2) } + let!(:line_item4) { FactoryBot.create(:line_item_with_shipment, order: order3) } context "as a normal user" do before { controller.stub spree_current_user: create_enterprise_user } @@ -83,10 +83,10 @@ let(:coordinator) { create(:distributor_enterprise) } let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator) } let!(:order1) { FactoryBot.create(:order, order_cycle: order_cycle, state: 'complete', completed_at: Time.zone.now, distributor: distributor1, billing_address: FactoryBot.create(:address) ) } - let!(:line_item1) { FactoryBot.create(:line_item, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } - let!(:line_item2) { FactoryBot.create(:line_item, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item1) { FactoryBot.create(:line_item_with_shipment, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item2) { FactoryBot.create(:line_item_with_shipment, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } let!(:order2) { FactoryBot.create(:order, order_cycle: order_cycle, state: 'complete', completed_at: Time.zone.now, distributor: distributor2, billing_address: FactoryBot.create(:address) ) } - let!(:line_item3) { FactoryBot.create(:line_item, order: order2, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item3) { FactoryBot.create(:line_item_with_shipment, order: order2, product: FactoryBot.create(:product, supplier: supplier)) } context "producer enterprise" do before do @@ -131,7 +131,11 @@ let(:coordinator) { create(:distributor_enterprise) } let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator) } let!(:order1) { FactoryBot.create(:order, order_cycle: order_cycle, state: 'complete', completed_at: Time.zone.now, distributor: distributor1, billing_address: FactoryBot.create(:address) ) } - let!(:line_item1) { FactoryBot.create(:line_item, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item1) { + line_item1 = FactoryBot.create(:line_item_with_shipment, order: order1, product: FactoryBot.create(:product, supplier: supplier)) + # make sure shipment is available through db reloads of this line_item + line_item1.tap(&:save!) + } let(:line_item_params) { { quantity: 3, final_weight_volume: 3000, price: 3.00 } } let(:params) { { id: line_item1.id, order_id: order1.number, line_item: line_item_params } } @@ -227,7 +231,7 @@ let(:coordinator) { create(:distributor_enterprise) } let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator) } let!(:order1) { FactoryBot.create(:order, order_cycle: order_cycle, state: 'complete', completed_at: Time.zone.now, distributor: distributor1, billing_address: FactoryBot.create(:address) ) } - let!(:line_item1) { FactoryBot.create(:line_item, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item1) { FactoryBot.create(:line_item_with_shipment, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } let(:params) { { id: line_item1.id, order_id: order1.number } } before do diff --git a/spec/controllers/spree/admin/line_items_controller_spec.rb b/spec/controllers/spree/admin/line_items_controller_spec.rb index 5b7575e7e5a..64cf29903e8 100644 --- a/spec/controllers/spree/admin/line_items_controller_spec.rb +++ b/spec/controllers/spree/admin/line_items_controller_spec.rb @@ -26,7 +26,7 @@ let(:coordinator) { create(:distributor_enterprise) } let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator) } let!(:order1) { FactoryBot.create(:order, order_cycle: order_cycle, state: 'complete', completed_at: Time.zone.now, distributor: distributor1, billing_address: FactoryBot.create(:address) ) } - let!(:line_item1) { FactoryBot.create(:line_item, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item1) { FactoryBot.create(:line_item_with_shipment, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } let(:line_item_params) { { quantity: 3, final_weight_volume: 3000, price: 3.00 } } let(:params) { { id: line_item1.id, order_id: order1.number, line_item: line_item_params } } diff --git a/spec/controllers/spree/admin/orders_controller_spec.rb b/spec/controllers/spree/admin/orders_controller_spec.rb index 25c2683d4d6..184a77cb11e 100644 --- a/spec/controllers/spree/admin/orders_controller_spec.rb +++ b/spec/controllers/spree/admin/orders_controller_spec.rb @@ -39,10 +39,10 @@ def self.make_simple_data! let!(:order1) { FactoryBot.create(:order, state: 'complete', completed_at: Time.zone.now, distributor: dist1, billing_address: FactoryBot.create(:address) ) } let!(:order2) { FactoryBot.create(:order, state: 'complete', completed_at: Time.zone.now, distributor: dist1, billing_address: FactoryBot.create(:address) ) } let!(:order3) { FactoryBot.create(:order, state: 'complete', completed_at: Time.zone.now, distributor: dist1, billing_address: FactoryBot.create(:address) ) } - let!(:line_item1) { FactoryBot.create(:line_item, order: order1) } - let!(:line_item2) { FactoryBot.create(:line_item, order: order2) } - let!(:line_item3) { FactoryBot.create(:line_item, order: order2) } - let!(:line_item4) { FactoryBot.create(:line_item, order: order3) } + let!(:line_item1) { FactoryBot.create(:line_item_with_shipment, order: order1) } + let!(:line_item2) { FactoryBot.create(:line_item_with_shipment, order: order2) } + let!(:line_item3) { FactoryBot.create(:line_item_with_shipment, order: order2) } + let!(:line_item4) { FactoryBot.create(:line_item_with_shipment, order: order3) } let(:line_item_attributes) { [:id, :quantity, :max_quantity, :supplier, :units_product, :units_variant] } end @@ -96,10 +96,10 @@ def self.make_simple_data! let(:coordinator) { create(:distributor_enterprise) } let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator) } let!(:order1) { FactoryBot.create(:order, order_cycle: order_cycle, state: 'complete', completed_at: Time.zone.now, distributor: distributor1, billing_address: FactoryBot.create(:address) ) } - let!(:line_item1) { FactoryBot.create(:line_item, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } - let!(:line_item2) { FactoryBot.create(:line_item, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item1) { FactoryBot.create(:line_item_with_shipment, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item2) { FactoryBot.create(:line_item_with_shipment, order: order1, product: FactoryBot.create(:product, supplier: supplier)) } let!(:order2) { FactoryBot.create(:order, order_cycle: order_cycle, state: 'complete', completed_at: Time.zone.now, distributor: distributor2, billing_address: FactoryBot.create(:address) ) } - let!(:line_item3) { FactoryBot.create(:line_item, order: order2, product: FactoryBot.create(:product, supplier: supplier)) } + let!(:line_item3) { FactoryBot.create(:line_item_with_shipment, order: order2, product: FactoryBot.create(:product, supplier: supplier)) } context "producer enterprise" do diff --git a/spec/controllers/spree/api/line_items_controller_spec.rb b/spec/controllers/spree/api/line_items_controller_spec.rb index 47c09f36b60..6a63fe617f1 100644 --- a/spec/controllers/spree/api/line_items_controller_spec.rb +++ b/spec/controllers/spree/api/line_items_controller_spec.rb @@ -13,7 +13,7 @@ module Spree sign_in_as_admin! let(:order) { FactoryBot.create(:order, state: 'complete', completed_at: Time.zone.now) } - let(:line_item) { FactoryBot.create(:line_item, order: order, final_weight_volume: 500) } + let(:line_item) { FactoryBot.create(:line_item_with_shipment, order: order,final_weight_volume: 500) } context "as a line item is updated" do before { allow(controller).to receive(:order) { order } } diff --git a/spec/factories.rb b/spec/factories.rb index fd4e4e1bf54..c405e09c9a4 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -356,6 +356,10 @@ end end + factory :line_item_with_shipment, parent: :line_item do + target_shipment { create(:shipment, order: order) } + end + factory :zone_with_member, :parent => :zone do default_tax true @@ -453,6 +457,20 @@ Spree::Image.create(attachment: image, viewable_id: product.master.id, viewable_type: 'Spree::Variant') end end + + factory :simple_product, parent: :base_product do + transient do + on_demand { false } + on_hand { 5 } + end + after(:create) do |product, evaluator| + product.variants.first.tap do |variant| + variant.on_demand = evaluator.on_demand + variant.count_on_hand = evaluator.on_hand + variant.save + end + end + end end @@ -460,7 +478,8 @@ factory :product do primary_taxon { Spree::Taxon.first || FactoryBot.create(:taxon) } end - factory :simple_product do + + factory :base_product do # Fix product factory name sequence with Kernel.rand so it is not interpreted as a Spree::Product method # Pull request: https://github.com/spree/spree/pull/1964 # When this fix has been merged into a version of Spree that we're using, this line can be removed. @@ -468,7 +487,6 @@ supplier { Enterprise.is_primary_producer.first || FactoryBot.create(:supplier_enterprise) } primary_taxon { Spree::Taxon.first || FactoryBot.create(:taxon) } - on_hand 3 unit_value 1 unit_description '' @@ -479,8 +497,19 @@ end factory :variant do + transient do + on_demand { false } + on_hand { 5 } + end + unit_value 1 unit_description '' + + after(:create) do |variant, evaluator| + variant.on_demand = evaluator.on_demand + variant.count_on_hand = evaluator.on_hand + variant.save + end end factory :shipping_method do diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 602fb99f8cb..4ba023b092f 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -21,8 +21,8 @@ let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o3) { create(:order_with_distributor, state: 'address', completed_at: nil ) } - let!(:li1) { create(:line_item, order: o1 ) } - let!(:li2) { create(:line_item, order: o2 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1) } + let!(:li2) { create(:line_item_with_shipment, order: o2) } let!(:li3) { create(:line_item, order: o3 ) } before :each do @@ -39,8 +39,8 @@ context "displaying individual columns" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, bill_address: create(:address) ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, bill_address: nil ) } - let!(:li1) { create(:line_item, order: o1 ) } - let!(:li2) { create(:line_item, order: o2, product: create(:product_with_option_types) ) } + let!(:li1) { create(:line_item_with_shipment, order: o1) } + let!(:li2) { create(:line_item_with_shipment, order: o2, product: create(:product_with_option_types) ) } before :each do visit '/admin/orders/bulk_management' @@ -86,8 +86,8 @@ describe "sorting of line items" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now) } - let!(:li1) { create(:line_item, order: o1) } - let!(:li2) { create(:line_item, order: o2) } + let!(:li1) { create(:line_item_with_shipment, order: o1) } + let!(:li2) { create(:line_item_with_shipment, order: o2) } before do visit spree.admin_bulk_order_management_path @@ -125,7 +125,7 @@ context "tracking changes" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1, :quantity => 5 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1, :quantity => 5 ) } before :each do visit '/admin/orders/bulk_management' @@ -140,7 +140,7 @@ context "submitting data to the server" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1, :quantity => 5 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1, :quantity => 5 ) } before :each do li1.variant.update_attributes(on_hand: 1, on_demand: false) @@ -182,7 +182,7 @@ let!(:p1) { create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000, variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] ) } let!(:v1) { p1.variants.first } let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1, variant: v1, :quantity => 5, :final_weight_volume => 1000, price: 10.00 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1, variant: v1, :quantity => 5, :final_weight_volume => 1000, price: 10.00 ) } before { v1.update_attribute(:on_hand, 100)} @@ -264,7 +264,7 @@ let!(:s1) { create(:supplier_enterprise) } let!(:s2) { create(:supplier_enterprise) } let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, order_cycle: create(:simple_order_cycle) ) } - let!(:li1) { create(:line_item, order: o1, product: create(:product, supplier: s1) ) } + let!(:li1) { create(:line_item_with_shipment, order: o1, product: create(:product, supplier: s1) ) } let!(:li2) { create(:line_item, order: o1, product: create(:product, supplier: s2) ) } before :each do @@ -302,7 +302,7 @@ let!(:d2) { create(:distributor_enterprise) } let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, distributor: d1, order_cycle: create(:simple_order_cycle) ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, distributor: d2, order_cycle: create(:simple_order_cycle) ) } - let!(:li1) { create(:line_item, order: o1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item, order: o2 ) } before :each do @@ -341,7 +341,7 @@ let!(:oc2) { create(:simple_order_cycle, distributors: [distributor]) } let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, order_cycle: oc1 ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, order_cycle: oc2 ) } - let!(:li1) { create(:line_item, order: o1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item, order: o2 ) } before do @@ -381,7 +381,7 @@ let!(:p2) { create(:product, supplier: s2) } let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, distributor: d1, order_cycle: oc1 ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, distributor: d2, order_cycle: oc2 ) } - let!(:li1) { create(:line_item, order: o1, product: p1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1, product: p1 ) } let!(:li2) { create(:line_item, order: o2, product: p2 ) } before :each do @@ -430,7 +430,7 @@ let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o3) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item, order: o2 ) } let!(:li3) { create(:line_item, order: o3 ) } @@ -458,7 +458,7 @@ let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.today - 7.days) } let!(:o3) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now.end_of_day) } let!(:o4) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now.end_of_day + 1.second) } - let!(:li1) { create(:line_item, order: o1, :quantity => 1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1, :quantity => 1 ) } let!(:li2) { create(:line_item, order: o2, :quantity => 2 ) } let!(:li3) { create(:line_item, order: o3, :quantity => 3 ) } let!(:li4) { create(:line_item, order: o4, :quantity => 4 ) } @@ -528,7 +528,7 @@ context "bulk action controls" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item, order: o2 ) } before :each do @@ -595,7 +595,7 @@ context "using edit buttons" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item, order: o2 ) } before :each do @@ -629,7 +629,7 @@ context "using delete buttons" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item, order: o2 ) } before :each do @@ -650,7 +650,7 @@ context "clicking the link on variant name" do let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } - let!(:li1) { create(:line_item, order: o1 ) } + let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item, order: o2 ) } let!(:p3) { create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000, variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] ) } let!(:v3) { p3.variants.first } @@ -716,8 +716,8 @@ let(:d2) { create(:distributor_enterprise, name: 'Another Distributor') } let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, distributor: d1 ) } let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now, distributor: d2 ) } - let!(:line_item_distributed) { create(:line_item, order: o1, product: create(:product, supplier: s1) ) } - let!(:line_item_not_distributed) { create(:line_item, order: o2, product: create(:product, supplier: s1) ) } + let!(:line_item_distributed) { create(:line_item_with_shipment, order: o1, product: create(:product, supplier: s1) ) } + let!(:line_item_not_distributed) { create(:line_item_with_shipment, order: o2, product: create(:product, supplier: s1) ) } before(:each) do @enterprise_user = create_enterprise_user diff --git a/spec/features/admin/overview_spec.rb b/spec/features/admin/overview_spec.rb index 530363929cf..47e8d878a79 100644 --- a/spec/features/admin/overview_spec.rb +++ b/spec/features/admin/overview_spec.rb @@ -103,44 +103,5 @@ end end end - - context "with the spree dash configured" do - let(:d1) { create(:distributor_enterprise) } - - before do - stub_jirafe - @enterprise_user.enterprise_roles.build(enterprise: d1).save - end - - around do |example| - with_dash_configured { example.run } - end - - it "has permission to sync analytics" do - visit '/admin' - expect(page).to have_content d1.name - end - end - end - - private - - def stub_jirafe - stub_request(:post, "https://api.jirafe.com/v1/applications/abc123/resources?token="). - to_return(:status => 200, :body => "", :headers => {}) - end - - def with_dash_configured(&block) - Spree::Dash::Config.preferred_app_id = 'abc123' - Spree::Dash::Config.preferred_site_id = 'abc123' - Spree::Dash::Config.preferred_token = 'abc123' - expect(Spree::Dash::Config.configured?).to be true - - block.call - ensure - Spree::Dash::Config.preferred_app_id = nil - Spree::Dash::Config.preferred_site_id = nil - Spree::Dash::Config.preferred_token = nil - expect(Spree::Dash::Config.configured?).to be false end end diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb index 6e2f3101759..f11bb6d962d 100644 --- a/spec/features/admin/reports_spec.rb +++ b/spec/features/admin/reports_spec.rb @@ -261,8 +261,8 @@ Timecop.travel(Time.zone.local(2013, 4, 25, 14, 0, 0)) { order1.finalize! } Timecop.travel(Time.zone.local(2013, 4, 25, 16, 0, 0)) { order2.finalize! } - create(:line_item, :product => product, :order => order1) - create(:line_item, :product => product, :order => order2) + create(:line_item_with_shipment, :product => product, :order => order1) + create(:line_item_with_shipment, :product => product, :order => order2) end it "is precise to time of day, not just date" do diff --git a/spec/jobs/subscription_placement_job_spec.rb b/spec/jobs/subscription_placement_job_spec.rb index b1013081d64..453b155962b 100644 --- a/spec/jobs/subscription_placement_job_spec.rb +++ b/spec/jobs/subscription_placement_job_spec.rb @@ -64,9 +64,9 @@ let(:shop) { order_cycle.coordinator } let(:order) { create(:order, order_cycle: order_cycle, distributor: shop) } let(:ex) { create(:exchange, :order_cycle => order_cycle, :sender => shop, :receiver => shop, :incoming => false) } - let(:variant1) { create(:variant, count_on_hand: 5) } - let(:variant2) { create(:variant, count_on_hand: 5) } - let(:variant3) { create(:variant, count_on_hand: 5) } + let(:variant1) { create(:variant, on_hand: 5) } + let(:variant2) { create(:variant, on_hand: 5) } + let(:variant3) { create(:variant, on_hand: 5) } let!(:line_item1) { create(:line_item, order: order, variant: variant1, quantity: 3) } let!(:line_item2) { create(:line_item, order: order, variant: variant2, quantity: 3) } let!(:line_item3) { create(:line_item, order: order, variant: variant3, quantity: 3) } diff --git a/spec/jobs/update_billable_periods_spec.rb b/spec/jobs/update_billable_periods_spec.rb index 5024fd6dac1..1b461e7f2a2 100644 --- a/spec/jobs/update_billable_periods_spec.rb +++ b/spec/jobs/update_billable_periods_spec.rb @@ -586,16 +586,16 @@ def travel_to(time) let!(:order10) { create(:order, completed_at: start_of_july + 19.days, distributor: enterprise) } before do - order1.line_items = [ create(:line_item, price: 12.56, order: order1) ] - order2.line_items = [ create(:line_item, price: 87.44, order: order2) ] - order3.line_items = [ create(:line_item, price: 50.00, order: order3) ] - order4.line_items = [ create(:line_item, price: 73.37, order: order4) ] - order5.line_items = [ create(:line_item, price: 22.46, order: order5) ] - order6.line_items = [ create(:line_item, price: 44.85, order: order6) ] - order7.line_items = [ create(:line_item, price: 93.45, order: order7) ] - order8.line_items = [ create(:line_item, price: 59.38, order: order8) ] - order9.line_items = [ create(:line_item, price: 47.23, order: order9) ] - order10.line_items = [ create(:line_item, price: 2.35, order: order10) ] + order1.line_items = [ create(:line_item_with_shipment, price: 12.56, order: order1) ] + order2.line_items = [ create(:line_item_with_shipment, price: 87.44, order: order2) ] + order3.line_items = [ create(:line_item_with_shipment, price: 50.00, order: order3) ] + order4.line_items = [ create(:line_item_with_shipment, price: 73.37, order: order4) ] + order5.line_items = [ create(:line_item_with_shipment, price: 22.46, order: order5) ] + order6.line_items = [ create(:line_item_with_shipment, price: 44.85, order: order6) ] + order7.line_items = [ create(:line_item_with_shipment, price: 93.45, order: order7) ] + order8.line_items = [ create(:line_item_with_shipment, price: 59.38, order: order8) ] + order9.line_items = [ create(:line_item_with_shipment, price: 47.23, order: order9) ] + order10.line_items = [ create(:line_item_with_shipment, price: 2.35, order: order10) ] [order1, order2, order3, order4, order5, order6, order7, order8, order9, order10].each(&:update!) allow(Enterprise).to receive(:where) { double(:enterprises, select: [enterprise]) } diff --git a/spec/lib/open_food_network/bulk_coop_report_spec.rb b/spec/lib/open_food_network/bulk_coop_report_spec.rb index 7ee263fc55f..695f98359e3 100644 --- a/spec/lib/open_food_network/bulk_coop_report_spec.rb +++ b/spec/lib/open_food_network/bulk_coop_report_spec.rb @@ -8,7 +8,7 @@ module OpenFoodNetwork let(:d1) { create(:distributor_enterprise) } let(:oc1) { create(:simple_order_cycle) } let(:o1) { create(:order, completed_at: 1.day.ago, order_cycle: oc1, distributor: d1) } - let(:li1) { build(:line_item) } + let(:li1) { build(:line_item_with_shipment) } before { o1.line_items << li1 } @@ -24,7 +24,7 @@ module OpenFoodNetwork it "does not show cancelled orders" do o2 = create(:order, state: "canceled", completed_at: 1.day.ago) - o2.line_items << build(:line_item) + o2.line_items << build(:line_item_with_shipment) subject.table_items.should == [li1] end end @@ -80,7 +80,7 @@ module OpenFoodNetwork d2 = create(:distributor_enterprise) d2.enterprise_roles.create!(user: create(:user)) o2 = create(:order, distributor: d2, completed_at: 1.day.ago) - o2.line_items << build(:line_item) + o2.line_items << build(:line_item_with_shipment) subject.table_items.should == [li1] end diff --git a/spec/lib/open_food_network/lettuce_share_report_spec.rb b/spec/lib/open_food_network/lettuce_share_report_spec.rb index 5a871cfbbb5..99a9254abd8 100644 --- a/spec/lib/open_food_network/lettuce_share_report_spec.rb +++ b/spec/lib/open_food_network/lettuce_share_report_spec.rb @@ -36,7 +36,7 @@ module OpenFoodNetwork describe "lists" do let(:v2) { create(:variant) } let(:v3) { create(:variant) } - let(:v4) { create(:variant, count_on_hand: 0, on_demand: true) } + let(:v4) { create(:variant, on_hand: 0, on_demand: true) } let(:hub_address) { create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234") } let(:hub) { create(:distributor_enterprise, :address => hub_address) } let(:v2o) { create(:variant_override, hub: hub, variant: v2) } diff --git a/spec/lib/open_food_network/order_and_distributor_report_spec.rb b/spec/lib/open_food_network/order_and_distributor_report_spec.rb index 4cd03de91c4..f943aabdd0e 100644 --- a/spec/lib/open_food_network/order_and_distributor_report_spec.rb +++ b/spec/lib/open_food_network/order_and_distributor_report_spec.rb @@ -22,7 +22,7 @@ module OpenFoodNetwork let(:order) { create(:order, state: 'complete', completed_at: Time.zone.now, distributor: distributor, bill_address: bill_address, special_instructions: shipping_instructions) } let(:payment_method) { create(:payment_method, distributors: [distributor]) } let(:payment) { create(:payment, payment_method: payment_method, order: order) } - let(:line_item) { create(:line_item, product: product, order: order) } + let(:line_item) { create(:line_item_with_shipment, product: product, order: order) } before do order.payments << payment diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb index a33722859cd..949721afbd3 100644 --- a/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb +++ b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb @@ -8,7 +8,7 @@ module OpenFoodNetwork let(:d1) { create(:distributor_enterprise) } let(:oc1) { create(:simple_order_cycle) } let(:o1) { create(:order, completed_at: 1.day.ago, order_cycle: oc1, distributor: d1) } - let(:li1) { build(:line_item) } + let(:li1) { build(:line_item_with_shipment) } before { o1.line_items << li1 } @@ -24,7 +24,7 @@ module OpenFoodNetwork it "does not show cancelled orders" do o2 = create(:order, state: "canceled", completed_at: 1.day.ago) - o2.line_items << build(:line_item) + o2.line_items << build(:line_item_with_shipment) subject.table_items.should == [li1] end end @@ -80,7 +80,7 @@ module OpenFoodNetwork d2 = create(:distributor_enterprise) d2.enterprise_roles.create!(user: create(:user)) o2 = create(:order, distributor: d2, completed_at: 1.day.ago) - o2.line_items << build(:line_item) + o2.line_items << build(:line_item_with_shipment) subject.table_items.should == [li1] end @@ -98,7 +98,7 @@ module OpenFoodNetwork let(:d1) { create(:distributor_enterprise) } let(:oc1) { create(:simple_order_cycle) } let(:o1) { create(:order, completed_at: 1.day.ago, order_cycle: oc1, distributor: d1) } - let(:li1) { build(:line_item) } + let(:li1) { build(:line_item_with_shipment) } let(:user) { create(:admin_user)} before { o1.line_items << li1 } diff --git a/spec/lib/open_food_network/packing_report_spec.rb b/spec/lib/open_food_network/packing_report_spec.rb index b9074a92bfa..f6c32264b40 100644 --- a/spec/lib/open_food_network/packing_report_spec.rb +++ b/spec/lib/open_food_network/packing_report_spec.rb @@ -8,7 +8,7 @@ module OpenFoodNetwork let(:d1) { create(:distributor_enterprise) } let(:oc1) { create(:simple_order_cycle) } let(:o1) { create(:order, completed_at: 1.day.ago, order_cycle: oc1, distributor: d1) } - let(:li1) { build(:line_item) } + let(:li1) { build(:line_item_with_shipment) } before { o1.line_items << li1 } @@ -24,7 +24,7 @@ module OpenFoodNetwork it "does not show cancelled orders" do o2 = create(:order, state: "canceled", completed_at: 1.day.ago) - o2.line_items << build(:line_item) + o2.line_items << build(:line_item_with_shipment) subject.table_items.should == [li1] end end @@ -41,7 +41,7 @@ module OpenFoodNetwork context "that has granted P-OC to the distributor" do let(:o2) { create(:order, distributor: d1, completed_at: 1.day.ago, bill_address: create(:address), ship_address: create(:address)) } - let(:li2) { build(:line_item, product: create(:simple_product, supplier: s1)) } + let(:li2) { build(:line_item_with_shipment, product: create(:simple_product, supplier: s1)) } before do o2.line_items << li2 @@ -80,7 +80,7 @@ module OpenFoodNetwork d2 = create(:distributor_enterprise) d2.enterprise_roles.create!(user: create(:user)) o2 = create(:order, distributor: d2, completed_at: 1.day.ago) - o2.line_items << build(:line_item) + o2.line_items << build(:line_item_with_shipment) subject.table_items.should == [li1] end diff --git a/spec/lib/open_food_network/scope_variant_to_hub_spec.rb b/spec/lib/open_food_network/scope_variant_to_hub_spec.rb index c3b2f2f8ec6..ac79d943ac8 100644 --- a/spec/lib/open_food_network/scope_variant_to_hub_spec.rb +++ b/spec/lib/open_food_network/scope_variant_to_hub_spec.rb @@ -3,7 +3,7 @@ module OpenFoodNetwork describe ScopeVariantToHub do let(:hub) { create(:distributor_enterprise) } - let(:v) { create(:variant, price: 11.11, count_on_hand: 1, on_demand: true, sku: "VARIANTSKU") } + let(:v) { create(:variant, price: 11.11, on_hand: 1, on_demand: true, sku: "VARIANTSKU") } let(:vo) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: 2, on_demand: false, sku: "VOSKU") } let(:vo_price_only) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: nil) } let(:scoper) { ScopeVariantToHub.new(hub) } diff --git a/spec/mailers/order_mailer_spec.rb b/spec/mailers/order_mailer_spec.rb index 49de9853254..55e4b6b3608 100644 --- a/spec/mailers/order_mailer_spec.rb +++ b/spec/mailers/order_mailer_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe Spree::OrderMailer do - let!(:mail_method) { create(:mail_method, preferred_mails_from: 'spree@example.com') } - describe "order confimation" do after do ActionMailer::Base.deliveries.clear diff --git a/spec/mailers/subscription_mailer_spec.rb b/spec/mailers/subscription_mailer_spec.rb index 7936cd54bd9..6e5f53168e6 100644 --- a/spec/mailers/subscription_mailer_spec.rb +++ b/spec/mailers/subscription_mailer_spec.rb @@ -3,8 +3,6 @@ describe SubscriptionMailer do include ActionView::Helpers::SanitizeHelper - let!(:mail_method) { create(:mail_method, preferred_mails_from: 'spree@example.com') } - describe "order placement" do let(:shop) { create(:enterprise) } let(:customer) { create(:customer, enterprise: shop) } diff --git a/spec/models/order_updater_spec.rb b/spec/models/order_updater_spec.rb new file mode 100644 index 00000000000..054154aadd6 --- /dev/null +++ b/spec/models/order_updater_spec.rb @@ -0,0 +1,152 @@ +require 'spec_helper' + +describe OrderUpdater do + let(:order) { build(:order) } + let(:order_updater) { described_class.new(Spree::OrderUpdater.new(order)) } + + context "#updating_payment_state" do + it "is failed if no valid payments" do + allow(order).to receive_message_chain(:payments, :valid, :empty?) { true } + + order_updater.update_payment_state + expect(order.payment_state).to eq('failed') + end + + context "payment total is greater than order total" do + before do + order.payment_total = 2 + order.total = 1 + end + + it "is credit_owed" do + expect { + order_updater.update_payment_state + }.to change { order.payment_state }.to 'credit_owed' + end + end + + context "order total is greater than payment total" do + before do + order.payment_total = 1 + order.total = 2 + end + + it "is credit_owed" do + expect { + order_updater.update_payment_state + }.to change { order.payment_state }.to 'balance_due' + end + end + + context "order total equals payment total" do + before do + order.payment_total = 30 + order.total = 30 + end + + it "is paid" do + expect { + order_updater.update_payment_state + }.to change { order.payment_state }.to 'paid' + end + end + + context "order is canceled" do + before { order.state = 'canceled' } + + context "and is still unpaid" do + before do + order.payment_total = 0 + order.total = 30 + end + + it "is void" do + expect { + order_updater.update_payment_state + }.to change { order.payment_state }.to 'void' + end + end + + context "and is paid" do + before do + order.payment_total = 30 + order.total = 30 + order.stub_chain(:payments, :valid, :empty?).and_return(false) + order.stub_chain(:payments, :completed, :empty?).and_return(false) + end + + it "is credit_owed" do + expect { + order_updater.update_payment_state + }.to change { order.payment_state }.to 'credit_owed' + end + end + + context "and payment is refunded" do + before do + order.payment_total = 0 + order.total = 30 + order.stub_chain(:payments, :valid, :empty?).and_return(false) + order.stub_chain(:payments, :completed, :empty?).and_return(false) + end + + it "is void" do + expect { + order_updater.update_payment_state + }.to change { order.payment_state }.to 'void' + end + end + end + end + + context '#before_save_hook' do + let(:distributor) { build(:distributor_enterprise) } + let(:order) { build(:order, distributor: distributor) } + let(:shipment) { build(:shipment) } + let(:shipping_rate) do + Spree::ShippingRate.new( + shipping_method: shipping_method, + selected: true + ) + end + + before do + shipment.shipping_rates << shipping_rate + order.shipments << shipment + end + + context 'when any of the shipping methods doesn\'t require a delivery address' do + let(:shipping_method) { build(:base_shipping_method, require_ship_address: false) } + + let(:delivery_shipment) { build(:shipment) } + let(:delivery_shipping_rate) do + Spree::ShippingRate.new( + shipping_method: build(:base_shipping_method, require_ship_address: true), + selected: true + ) + end + + before do + delivery_shipment.shipping_rates << delivery_shipping_rate + order.shipments << delivery_shipment + end + + it "populates the shipping address" do + order_updater.before_save_hook + expect(order.ship_address.firstname).to eq(distributor.address.firstname) + end + end + + context 'when any of the shipping methods requires a delivery address' do + let(:shipping_method) { build(:base_shipping_method, require_ship_address: true) } + let(:address) { build(:address, firstname: 'will') } + + before { order.ship_address = address } + + it "does not populate the shipping address" do + order_updater.before_save_hook + expect(order.ship_address.firstname).to eq("will") + end + end + end +end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 345cbb661f4..4e23a102efc 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -509,41 +509,6 @@ end end - describe "shipping address prepopulation" do - let(:distributor) { create(:distributor_enterprise) } - let(:order) { build(:order, distributor: distributor) } - - before do - order.ship_address = distributor.address.clone - order.save # just to trigger our autopopulate the first time ;) - end - - it "autopopulates the shipping address on save" do - order.should_receive(:shipping_address_from_distributor).and_return true - order.save - end - - it "populates the shipping address if the shipping method doesn't require a delivery address" do - order.shipping_method = create(:shipping_method, require_ship_address: false) - order.ship_address.update_attribute :firstname, "will" - order.save - order.ship_address.firstname.should == distributor.address.firstname - end - - it "does not populate the shipping address if the shipping method requires a delivery address" do - order.shipping_method = create(:shipping_method, require_ship_address: true) - order.ship_address.update_attribute :firstname, "will" - order.save - order.ship_address.firstname.should == "will" - end - - it "doesn't attempt to create a shipment if the order is not yet valid" do - order.shipping_method = create(:shipping_method, require_ship_address: false) - #Shipment.should_not_r - order.create_shipment! - end - end - describe "checking if an order is an account invoice" do let(:accounts_distributor) { create(:distributor_enterprise) } let(:order_account_invoice) { create(:order, distributor: accounts_distributor) } diff --git a/spec/models/spree/order_updater_spec.rb b/spec/models/spree/order_updater_spec.rb deleted file mode 100644 index 50ab49a8c7f..00000000000 --- a/spec/models/spree/order_updater_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -require 'spec_helper' - -describe Spree::OrderUpdater do - # Copied pretty much verbatim from Spree 2.4. Remove this file once we get there, - # assuming the unchanged 2.4 logic still works for us. - # Only changes are stubs of :empty? instead of :size - context "updating payment state" do - let(:order) { Spree::Order.new } - let(:updater) { order.updater } - - it "is failed if no valid payments" do - order.stub_chain(:payments, :valid, :empty?).and_return(true) - - updater.update_payment_state - order.payment_state.should == 'failed' - end - - context "payment total is greater than order total" do - it "is credit_owed" do - order.payment_total = 2 - order.total = 1 - - expect { - updater.update_payment_state - }.to change { order.payment_state }.to 'credit_owed' - end - end - - context "order total is greater than payment total" do - it "is credit_owed" do - order.payment_total = 1 - order.total = 2 - - expect { - updater.update_payment_state - }.to change { order.payment_state }.to 'balance_due' - end - end - - context "order total equals payment total" do - it "is paid" do - order.payment_total = 30 - order.total = 30 - - expect { - updater.update_payment_state - }.to change { order.payment_state }.to 'paid' - end - end - - context "order is canceled" do - before do - order.state = 'canceled' - end - - context "and is still unpaid" do - it "is void" do - order.payment_total = 0 - order.total = 30 - expect { - updater.update_payment_state - }.to change { order.payment_state }.to 'void' - end - end - - context "and is paid" do - it "is credit_owed" do - order.payment_total = 30 - order.total = 30 - order.stub_chain(:payments, :valid, :empty?).and_return(false) - order.stub_chain(:payments, :completed, :empty?).and_return(false) - expect { - updater.update_payment_state - }.to change { order.payment_state }.to 'credit_owed' - end - end - - context "and payment is refunded" do - it "is void" do - order.payment_total = 0 - order.total = 30 - order.stub_chain(:payments, :valid, :empty?).and_return(false) - order.stub_chain(:payments, :completed, :empty?).and_return(false) - expect { - updater.update_payment_state - }.to change { order.payment_state }.to 'void' - end - end - end - end -end diff --git a/spec/models/spree/shipping_method_spec.rb b/spec/models/spree/shipping_method_spec.rb index bd759edcc7d..afb0ea59c4c 100644 --- a/spec/models/spree/shipping_method_spec.rb +++ b/spec/models/spree/shipping_method_spec.rb @@ -35,34 +35,6 @@ module Spree ShippingMethod.by_name.should == [sm2, sm3, sm1] end - - describe "availability" do - let(:sm) { create(:shipping_method) } - let(:currency) { 'AUD' } - - before do - sm.calculator.preferred_currency = currency - end - - it "is available to orders that match its distributor" do - o = create(:order, ship_address: create(:address), - distributor: sm.distributors.first, currency: currency) - sm.should be_available_to_order o - end - - it "is not available to orders that do not match its distributor" do - o = create(:order, ship_address: create(:address), - distributor: create(:distributor_enterprise), currency: currency) - sm.should_not be_available_to_order o - end - - it "is available to orders with no shipping address" do - o = create(:order, ship_address: nil, - distributor: sm.distributors.first, currency: currency) - sm.should be_available_to_order o - end - end - describe "finding services offered by all distributors" do let!(:d1) { create(:distributor_enterprise) } let!(:d2) { create(:distributor_enterprise) } diff --git a/spec/models/stock/package_spec.rb b/spec/models/stock/package_spec.rb new file mode 100644 index 00000000000..2c85b9b0793 --- /dev/null +++ b/spec/models/stock/package_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +module Stock + describe Package do + describe '#shipping_methods' do + let(:stock_location) { double(:stock_location) } + let(:order) { build(:order) } + + subject(:package) { Package.new(stock_location, order, contents) } + + describe '#shipping_methods' do + let(:enterprise) { build(:enterprise) } + let(:other_enterprise) { build(:enterprise) } + + let(:order) { build(:order, distributor: enterprise) } + + let(:variant1) do + instance_double( + Spree::Variant, + shipping_category: shipping_method1.shipping_categories.first + ) + end + let(:variant2) do + instance_double( + Spree::Variant, + shipping_category: shipping_method2.shipping_categories.first + ) + end + let(:variant3) do + instance_double(Spree::Variant, shipping_category: nil) + end + + let(:contents) do + [ + Package::ContentItem.new(variant1, 1), + Package::ContentItem.new(variant1, 1), + Package::ContentItem.new(variant2, 1), + Package::ContentItem.new(variant3, 1) + ] + end + + let(:shipping_method1) { create(:shipping_method, distributors: [enterprise]) } + let(:shipping_method2) { create(:shipping_method, distributors: [other_enterprise]) } + + it 'does not return shipping methods not used by the package\'s order distributor' do + expect(package.shipping_methods).to eq [shipping_method1] + end + end + end + end +end diff --git a/spec/models/variant_override_spec.rb b/spec/models/variant_override_spec.rb index 0a07fdd1af6..8275e820135 100644 --- a/spec/models/variant_override_spec.rb +++ b/spec/models/variant_override_spec.rb @@ -59,7 +59,7 @@ describe "looking up count on hand" do it "returns the numeric stock level when present" do - VariantOverride.create!(variant: variant, hub: hub, count_on_hand: 12) + VariantOverride.create!(variant: variant, hub: hub, on_hand: 12) VariantOverride.count_on_hand_for(hub, variant).should == 12 end diff --git a/spec/services/subscription_form_spec.rb b/spec/services/subscription_form_spec.rb index 2f4a19953e2..3e2e8f5842a 100644 --- a/spec/services/subscription_form_spec.rb +++ b/spec/services/subscription_form_spec.rb @@ -7,7 +7,7 @@ let!(:product3) { create(:product, supplier: shop) } let!(:variant1) { create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: []) } let!(:variant2) { create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: []) } - let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: [], count_on_hand: 1) } + let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: [], on_hand: 1) } let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) } let!(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 9.days.ago, orders_close_at: 2.days.ago) } let!(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.ago, orders_close_at: 5.days.from_now) } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 40dc6cd2565..fe9a64de970 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -114,7 +114,6 @@ def restart_phantomjs spree_config.currency = currency spree_config.shipping_instructions = true spree_config.auto_capture = true - spree_config.allow_backorders = false end Spree::Api::Config[:requires_authentication] = true