From 19569f931624cadb2b74f575aa26c41a7485e860 Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Mon, 27 Mar 2017 13:38:37 +0100 Subject: [PATCH 001/104] #1291 Fix dropdown font-size not to zoom in iOS --- .../stylesheets/darkswarm/_shop-navigation.css.sass | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.sass b/app/assets/stylesheets/darkswarm/_shop-navigation.css.sass index 144a5049f4..174935c2ce 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.sass +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.sass @@ -19,7 +19,7 @@ height: 100px width: 100px margin-right: 12px - + location @include headingFont @media all and (max-width: 768px) @@ -30,7 +30,7 @@ margin-top: 0 @media all and (max-width: 768px) margin-bottom: 8px - + ordercycle text-align: right @@ -47,24 +47,26 @@ p max-width: 100% float: right - form.custom + form.custom text-align: right & > strong line-height: 2.5 font-size: 1.29em padding-right: 14px @media all and (max-width: 768px) - select + select width: inherit display: inline-block border-width: 1px border-color: #999 color: #666 - font-size: 1em + font-size: 1em margin-bottom: 0 padding: 8px 20px 8px 12px @media all and (max-width: 768px) font-size: 0.875em + @media screen and (-webkit-min-device-pixel-ratio:0) + font-size: 16px closing @include headingFont @media all and (max-width: 768px) From 41e91765ca96aa4e3771d46e615c38fd5e98dd2e Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Tue, 4 Apr 2017 12:05:25 +0100 Subject: [PATCH 002/104] Add capybara-screenshot gem for integration tests debugging --- Gemfile | 2 +- Gemfile.lock | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 2b8f6bdddc..fa7fc285c7 100644 --- a/Gemfile +++ b/Gemfile @@ -115,7 +115,7 @@ end group :test do gem 'webmock' - + gem 'capybara-screenshot' # See spec/spec_helper.rb for instructions #gem 'perftools.rb' end diff --git a/Gemfile.lock b/Gemfile.lock index 9f130f9f73..2e313444b7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -190,6 +190,9 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) + capybara-screenshot (1.0.14) + capybara (>= 1.0, < 3) + launchy celluloid (0.15.2) timers (~> 1.1.0) chronic (0.10.2) @@ -667,6 +670,7 @@ DEPENDENCIES blockenspiel bugsnag capybara + capybara-screenshot coffee-rails (~> 3.2.1) compass-rails css_splitter @@ -749,4 +753,4 @@ RUBY VERSION ruby 2.1.5p273 BUNDLED WITH - 1.14.3 + 1.14.6 From dc69c6e8259e287d3a1b7039cd5aa00bd8c7992f Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Tue, 4 Apr 2017 14:01:57 +0100 Subject: [PATCH 003/104] Use currency symbol from config in tests --- spec/features/consumer/shopping/cart_spec.rb | 8 +- .../consumer/shopping/checkout_spec.rb | 18 ++-- .../consumer/shopping/shopping_spec.rb | 18 ++-- .../shopping/variant_overrides_spec.rb | 30 +++--- ...usiness_model_configuration_helper_spec.rb | 96 +++++++++---------- spec/helpers/products_helper_spec.rb | 6 +- spec/spec_helper.rb | 3 + 7 files changed, 91 insertions(+), 88 deletions(-) diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index b604769502..d0c56a4f58 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -32,10 +32,10 @@ feature "full-page cart", js: true do it "rounds fee calculations correctly" do # $0.86 + 20% = $1.032 # Fractional cents should be immediately rounded down and not carried through - expect(page).to have_selector '.cart-item-price', text: '$1.03' - expect(page).to have_selector '.cart-item-total', text: '$8.24' - expect(page).to have_selector '.order-total.item-total', text: '$8.24' - expect(page).to have_selector '.order-total.grand-total', text: '$8.24' + expect(page).to have_selector '.cart-item-price', text: "#{@currency_symbol}1.03" + expect(page).to have_selector '.cart-item-total', text: "#{@currency_symbol}8.24" + expect(page).to have_selector '.order-total.item-total', text: "#{@currency_symbol}8.24" + expect(page).to have_selector '.order-total.grand-total', text: "#{@currency_symbol}8.24" end end diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index d9c9e8bf8f..295091dc57 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -135,9 +135,9 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do toggle_shipping choose sm2.name - page.should have_selector 'orderdetails .cart-total', text: "$11.23" - page.should have_selector 'orderdetails .shipping', text: "$4.56" - page.should have_selector 'orderdetails .total', text: "$15.79" + page.should have_selector 'orderdetails .cart-total', text: "#{@currency_symbol}11.23" + page.should have_selector 'orderdetails .shipping', text: "#{@currency_symbol}4.56" + page.should have_selector 'orderdetails .total', text: "#{@currency_symbol}15.79" # Tax should not be displayed in checkout, as the customer's choice of shipping method # affects the tax and we haven't written code to live-update the tax amount when they @@ -269,7 +269,7 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do # + shipping tax ($ 4.56 @ 25% = $0.91) # = $1.93 page.should have_content "(includes tax)" - page.should have_content "$1.93" + page.should have_content "#{@currency_symbol}1.93" end context "with basic details filled" do @@ -331,14 +331,14 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do context "when we are charged a payment method fee (transaction fee)" do it "creates a payment including the transaction fee" do # Selecting the transaction fee, it is displayed - expect(page).to have_selector ".transaction-fee td", text: "$0.00" - expect(page).to have_selector ".total", text: "$11.23" + expect(page).to have_selector ".transaction-fee td", text: "#{@currency_symbol}0.00" + expect(page).to have_selector ".total", text: "#{@currency_symbol}11.23" toggle_payment - choose "#{pm2.name} ($5.67)" + choose "#{pm2.name} (#{@currency_symbol}5.67)" - expect(page).to have_selector ".transaction-fee td", text: "$5.67" - expect(page).to have_selector ".total", text: "$16.90" + expect(page).to have_selector ".transaction-fee td", text: "#{@currency_symbol}5.67" + expect(page).to have_selector ".total", text: "#{@currency_symbol}16.90" place_order expect(page).to have_content "Your order has been processed successfully" diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index e11f929f6a..bbfb78c247 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -95,23 +95,23 @@ feature "As a consumer I want to shop with a distributor", js: true do # -- Selecting an order cycle visit shop_path select "turtles", from: "order_cycle_id" - page.should have_content "$1020.99" + page.should have_content "#{@currency_symbol}1020.99" # -- Cart shows correct price fill_in "variants[#{variant.id}]", with: 1 show_cart - within("li.cart") { page.should have_content "$1020.99" } + within("li.cart") { page.should have_content "#{@currency_symbol}1020.99" } # -- Changing order cycle select "frogs", from: "order_cycle_id" - page.should have_content "$19.99" + page.should have_content "#{@currency_symbol}19.99" # -- Cart should be cleared # ng-animate means that the old product row is likely to be present, so we explicitly # fill in the quantity in the incoming row page.should_not have_selector "tr.product-cart" within('product.ng-enter') { fill_in "variants[#{variant.id}]", with: 1 } - within("li.cart") { page.should have_content "$19.99" } + within("li.cart") { page.should have_content "#{@currency_symbol}19.99" } end describe "declining to clear the cart" do @@ -164,15 +164,15 @@ feature "As a consumer I want to shop with a distributor", js: true do visit shop_path # Page should not have product.price (with or without fee) - page.should_not have_price "$10.00" - page.should_not have_price "$33.00" + page.should_not have_price "#{@currency_symbol}10.00" + page.should_not have_price "#{@currency_symbol}33.00" # Page should have variant prices (with fee) - page.should have_price "$43.00" - page.should have_price "$53.00" + page.should have_price "#{@currency_symbol}43.00" + page.should have_price "#{@currency_symbol}53.00" # Product price should be listed as the lesser of these - page.should have_price "$43.00" + page.should have_price "#{@currency_symbol}43.00" end it "filters search results properly" do diff --git a/spec/features/consumer/shopping/variant_overrides_spec.rb b/spec/features/consumer/shopping/variant_overrides_spec.rb index f4ee8e6275..0542259df1 100644 --- a/spec/features/consumer/shopping/variant_overrides_spec.rb +++ b/spec/features/consumer/shopping/variant_overrides_spec.rb @@ -40,8 +40,8 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do describe "viewing products" do it "shows the overridden price" do - page.should_not have_price "$12.22" # $11.11 + 10% fee - page.should have_price "$61.11" + page.should_not have_price "#{@currency_symbol}12.22" # $11.11 + 10% fee + page.should have_price "#{@currency_symbol}61.11" end it "looks up stock from the override" do @@ -59,9 +59,9 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do it "calculates fees correctly" do page.find("#variant-#{v1.id} .graph-button").click page.find(".price_breakdown a").click - page.should have_selector 'li.cost div', text: '$55.55' - page.should have_selector 'li.packing-fee div', text: '$5.56' - page.should have_selector 'li.total div', text: '= $61.11' + page.should have_selector 'li.cost div', text: "#{@currency_symbol}55.55" + page.should have_selector 'li.packing-fee div', text: "#{@currency_symbol}5.56" + page.should have_selector 'li.total div', text: "= #{@currency_symbol}61.11" end it "shows the correct prices when products are in the cart" do @@ -69,7 +69,7 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do show_cart wait_until_enabled 'li.cart a.button' visit shop_path - page.should_not have_price '$12.22' + page.should_not have_price "#{@currency_symbol}12.22" end # The two specs below reveal an unrelated issue with fee calculation. See: @@ -79,29 +79,29 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do fill_in "variants[#{v1.id}]", with: "2" show_cart page.should have_selector "#cart-variant-#{v1.id} .quantity", text: '2' - page.should have_selector "#cart-variant-#{v1.id} .price", text: '$61.11' - page.should have_selector "#cart-variant-#{v1.id} .total-price", text: '$122.22' + page.should have_selector "#cart-variant-#{v1.id} .price", text: "#{@currency_symbol}61.11" + page.should have_selector "#cart-variant-#{v1.id} .total-price", text: "#{@currency_symbol}122.22" end it "shows the correct prices in the shopping cart" do fill_in "variants[#{v1.id}]", with: "2" add_to_cart - page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-price", text: '$61.11' + page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-price", text: "#{@currency_symbol}61.11" page.should have_field "order[line_items_attributes][0][quantity]", with: '2' - page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-total", text: '$122.22' + page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-total", text: "#{@currency_symbol}122.22" - page.should have_selector "#edit-cart .item-total", text: '$122.22' - page.should have_selector "#edit-cart .grand-total", text: '$122.22' + page.should have_selector "#edit-cart .item-total", text: "#{@currency_symbol}122.22" + page.should have_selector "#edit-cart .grand-total", text: "#{@currency_symbol}122.22" end it "shows the correct prices in the checkout" do fill_in "variants[#{v1.id}]", with: "2" click_checkout - page.should have_selector 'form.edit_order .cart-total', text: '$122.22' - page.should have_selector 'form.edit_order .shipping', text: '$0.00' - page.should have_selector 'form.edit_order .total', text: '$122.22' + page.should have_selector 'form.edit_order .cart-total', text: "#{@currency_symbol}122.22" + page.should have_selector 'form.edit_order .shipping', text: "#{@currency_symbol}0.00" + page.should have_selector 'form.edit_order .total', text: "#{@currency_symbol}122.22" end end diff --git a/spec/helpers/admin/business_model_configuration_helper_spec.rb b/spec/helpers/admin/business_model_configuration_helper_spec.rb index 632aec302b..0bc011500e 100644 --- a/spec/helpers/admin/business_model_configuration_helper_spec.rb +++ b/spec/helpers/admin/business_model_configuration_helper_spec.rb @@ -20,12 +20,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES PER MONTH, PLUS GST" } end end @@ -34,12 +34,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } end end end @@ -52,7 +52,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do @@ -77,7 +77,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is $100" do + context "when minimum billable turnover is #{@currency_symbol}100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -88,12 +88,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } end end @@ -102,12 +102,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } end end end @@ -120,12 +120,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } end end @@ -160,12 +160,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES PER MONTH" } end end @@ -174,12 +174,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } end end end @@ -192,7 +192,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do @@ -217,7 +217,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is $100" do + context "when minimum billable turnover is #{@currency_symbol}100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -228,12 +228,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } end end @@ -242,12 +242,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "$10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } end end end @@ -260,12 +260,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } end end @@ -304,12 +304,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES PER MONTH, PLUS GST" } end end @@ -318,12 +318,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } end end end @@ -336,7 +336,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do @@ -361,7 +361,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is $100" do + context "when minimum billable turnover is #{@currency_symbol}100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -372,12 +372,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } end end @@ -386,12 +386,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } end end end @@ -404,12 +404,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } end end @@ -444,12 +444,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES PER MONTH" } end end @@ -458,12 +458,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } end end end @@ -476,7 +476,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do @@ -501,7 +501,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is $100" do + context "when minimum billable turnover is #{@currency_symbol}100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -512,12 +512,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } end end @@ -526,12 +526,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN $10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } end end end @@ -544,12 +544,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS $100, CAPPED AT $20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS $100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } end end diff --git a/spec/helpers/products_helper_spec.rb b/spec/helpers/products_helper_spec.rb index e1c61ced5e..b1b4214893 100644 --- a/spec/helpers/products_helper_spec.rb +++ b/spec/helpers/products_helper_spec.rb @@ -4,13 +4,13 @@ module Spree describe ProductsHelper do it "displays variant price differences as absolute, not relative values" do variant = make_variant_stub(10.00, 10.00) - helper.variant_price_diff(variant).should == "($10.00)" + helper.variant_price_diff(variant).should == "(#{@currency_symbol}10.00)" variant = make_variant_stub(10.00, 15.55) - helper.variant_price_diff(variant).should == "($15.55)" + helper.variant_price_diff(variant).should == "(#{@currency_symbol}15.55)" variant = make_variant_stub(10.00, 5.55) - helper.variant_price_diff(variant).should == "($5.55)" + helper.variant_price_diff(variant).should == "(#{@currency_symbol}5.55)" end private diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f1150cc485..b3b66d4afe 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -93,6 +93,9 @@ RSpec.configure do |config| # Ensure we start with consistent config settings config.before(:each) { Spree::Config.products_require_tax_category = false } + # Set currency symbol from config for tests + config.before(:all) { @currency_symbol = ::Money::Currency.new(Spree::Config[:currency]).symbol } + # Helpers config.include Rails.application.routes.url_helpers config.include Spree::UrlHelpers From 7c7933f8bb4e27446026f9a59a1f27086b68fc24 Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Tue, 4 Apr 2017 17:23:07 +0100 Subject: [PATCH 004/104] Use local time zone in tests instead of hardcoded --- spec/features/admin/order_cycles_spec.rb | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index d9bfdfd345..e785dff908 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -147,9 +147,8 @@ feature %q{ page.should have_content 'Your order cycle has been created.' page.should have_selector 'a', text: 'Plums & Avos' - - page.should have_selector "input[value='2040-11-06 06:00:00 +1100']" - page.should have_selector "input[value='2040-11-13 17:00:00 +1100']" + page.should have_selector "input[value='#{Time.zone.local(2040, 11, 06, 06, 00, 00)}']" + page.should have_selector "input[value='#{Time.zone.local(2040, 11, 13, 17, 00, 00)}']" page.should have_content 'My coordinator' page.should have_selector 'td.suppliers', text: 'My supplier' @@ -382,8 +381,8 @@ feature %q{ page.should have_selector 'a', text: 'Plums & Avos' - page.should have_selector "input[value='2040-11-06 06:00:00 +1100']" - page.should have_selector "input[value='2040-11-13 17:00:00 +1100']" + page.should have_selector "input[value='#{Time.zone.local(2040, 11, 06, 06, 00, 00)}']" + page.should have_selector "input[value='#{Time.zone.local(2040, 11, 13, 17, 00, 00)}']" page.should have_content coordinator.name page.should have_selector 'td.suppliers', text: 'My supplier' @@ -907,8 +906,8 @@ feature %q{ # Then my order cycle should have been created page.should have_content 'Your order cycle has been created.' page.should have_selector 'a', text: 'Plums & Avos' - page.should have_selector "input[value='2040-10-17 06:00:00 +1100']" - page.should have_selector "input[value='2040-10-24 17:00:00 +1100']" + page.should have_selector "input[value='#{Time.zone.local(2040, 10, 17, 06, 00, 00)}']" + page.should have_selector "input[value='#{Time.zone.local(2040, 10, 24, 17, 00, 00)}']" # And it should have some variants selected oc = OrderCycle.last @@ -995,8 +994,8 @@ feature %q{ # Then my order cycle should have been updated page.should have_content 'Your order cycle has been updated.' page.should have_selector 'a', text: 'Plums & Avos' - page.should have_selector "input[value='2040-10-17 06:00:00 +1100']" - page.should have_selector "input[value='2040-10-24 17:00:00 +1100']" + page.should have_selector "input[value='#{Time.zone.local(2040, 10, 17, 06, 00, 00)}']" + page.should have_selector "input[value='#{Time.zone.local(2040, 10, 24, 17, 00, 00)}']" # And it should have a variant selected oc = OrderCycle.last From 1e6f4aa73d0afbf3ae5dde9b48a104346226cbc8 Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Tue, 4 Apr 2017 17:26:06 +0100 Subject: [PATCH 005/104] Restore bundler version --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2e313444b7..b89f65b9bb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -753,4 +753,4 @@ RUBY VERSION ruby 2.1.5p273 BUNDLED WITH - 1.14.6 + 1.14.3 From a97bcf74de8d77f0a90dcb0edf8adbe60a669f44 Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Tue, 4 Apr 2017 17:51:10 +0100 Subject: [PATCH 006/104] Use more simple getter to retrieve currency symbol --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b3b66d4afe..49863ec188 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -94,7 +94,7 @@ RSpec.configure do |config| config.before(:each) { Spree::Config.products_require_tax_category = false } # Set currency symbol from config for tests - config.before(:all) { @currency_symbol = ::Money::Currency.new(Spree::Config[:currency]).symbol } + config.before(:all) { @currency_symbol = Spree::Money.currency_symbol } # Helpers config.include Rails.application.routes.url_helpers From e63f1c2991d68f5ef061f7581000bdb1466eb30c Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Wed, 3 May 2017 12:59:16 +0100 Subject: [PATCH 007/104] Refactor time and currency symbol getters --- Gemfile | 1 - Gemfile.lock | 4 - spec/features/admin/order_cycles_spec.rb | 458 +++++++++--------- spec/features/consumer/shopping/cart_spec.rb | 8 +- .../consumer/shopping/checkout_spec.rb | 18 +- .../consumer/shopping/shopping_spec.rb | 18 +- .../shopping/variant_overrides_spec.rb | 30 +- ...usiness_model_configuration_helper_spec.rb | 96 ++-- spec/helpers/products_helper_spec.rb | 6 +- spec/spec_helper.rb | 4 +- spec/support/spree/money_helper.rb | 7 + 11 files changed, 326 insertions(+), 324 deletions(-) create mode 100644 spec/support/spree/money_helper.rb diff --git a/Gemfile b/Gemfile index fa7fc285c7..8964676754 100644 --- a/Gemfile +++ b/Gemfile @@ -115,7 +115,6 @@ end group :test do gem 'webmock' - gem 'capybara-screenshot' # See spec/spec_helper.rb for instructions #gem 'perftools.rb' end diff --git a/Gemfile.lock b/Gemfile.lock index b89f65b9bb..9f130f9f73 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -190,9 +190,6 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - capybara-screenshot (1.0.14) - capybara (>= 1.0, < 3) - launchy celluloid (0.15.2) timers (~> 1.1.0) chronic (0.10.2) @@ -670,7 +667,6 @@ DEPENDENCIES blockenspiel bugsnag capybara - capybara-screenshot coffee-rails (~> 3.2.1) compass-rails css_splitter diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index e785dff908..2f826b51c4 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -58,123 +58,263 @@ feature %q{ end end - scenario "creating an order cycle", js: true do - page.driver.resize(1280, 2000) + context "with specific time" do + let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 06, 06, 00, 00) } + let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 00, 00) } - # Given coordinating, supplying and distributing enterprises with some products with variants - coordinator = create(:distributor_enterprise, name: 'My coordinator') - supplier = create(:supplier_enterprise, name: 'My supplier') - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + scenario "creating an order cycle", js: true do + page.driver.resize(1280, 2000) - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) + # Given coordinating, supplying and distributing enterprises with some products with variants + coordinator = create(:distributor_enterprise, name: 'My coordinator') + supplier = create(:supplier_enterprise, name: 'My supplier') + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - # And some enterprise fees - supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') - coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') - distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - # When I go to the new order cycle page - login_to_admin_section - click_link 'Order Cycles' - click_link 'New Order Cycle' + # And some enterprise fees + supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') + coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') + distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') - # Select a coordinator since there are two available - select2_select 'My coordinator', from: 'coordinator_id' - click_button "Continue >" + # When I go to the new order cycle page + login_to_admin_section + click_link 'Order Cycles' + click_link 'New Order Cycle' - # And I fill in the basic fields - fill_in 'order_cycle_name', with: 'Plums & Avos' - fill_in 'order_cycle_orders_open_at', with: '2040-11-06 06:00:00' - fill_in 'order_cycle_orders_close_at', with: '2040-11-13 17:00:00' + # Select a coordinator since there are two available + select2_select 'My coordinator', from: 'coordinator_id' + click_button "Continue >" - # And I add a coordinator fee - click_button 'Add coordinator fee' - select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' + # And I fill in the basic fields + fill_in 'order_cycle_name', with: 'Plums & Avos' + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - # I should not be able to add a blank supplier - page.should have_select 'new_supplier_id', selected: '' - page.should have_button 'Add supplier', disabled: true + # And I add a coordinator fee + click_button 'Add coordinator fee' + select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' - # And I add a supplier and some products - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' - page.find('table.exchanges tr.supplier td.products').click - check "order_cycle_incoming_exchange_0_variants_#{v1.id}" - check "order_cycle_incoming_exchange_0_variants_#{v2.id}" + # I should not be able to add a blank supplier + page.should have_select 'new_supplier_id', selected: '' + page.should have_button 'Add supplier', disabled: true - # I should not be able to re-add the supplier - page.should_not have_select 'new_supplier_id', with_options: ['My supplier'] - page.should have_button 'Add supplier', disabled: true - page.all("td.supplier_name").map(&:text).should == ['My supplier'] + # And I add a supplier and some products + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' + page.find('table.exchanges tr.supplier td.products').click + check "order_cycle_incoming_exchange_0_variants_#{v1.id}" + check "order_cycle_incoming_exchange_0_variants_#{v2.id}" - # And I add a supplier fee - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' - select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' + # I should not be able to re-add the supplier + page.should_not have_select 'new_supplier_id', with_options: ['My supplier'] + page.should have_button 'Add supplier', disabled: true + page.all("td.supplier_name").map(&:text).should == ['My supplier'] - # And I add a distributor with the same products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' + # And I add a supplier fee + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' + select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' + # And I add a distributor with the same products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' - page.find('table.exchanges tr.distributor td.products').click - check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' - page.find('table.exchanges tr.distributor td.tags').click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" + page.find('table.exchanges tr.distributor td.products').click + check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" + + page.find('table.exchanges tr.distributor td.tags').click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + # And I add a distributor fee + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' + select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' + + # And I click Create + click_button 'Create' + + # Then my order cycle should have been created + page.should have_content 'Your order cycle has been created.' + + page.should have_selector 'a', text: 'Plums & Avos' + page.should have_selector "input[value='#{order_cycle_opening_time}']" + page.should have_selector "input[value='#{order_cycle_closing_time}']" + page.should have_content 'My coordinator' + + page.should have_selector 'td.suppliers', text: 'My supplier' + page.should have_selector 'td.distributors', text: 'My distributor' + + # And it should have some fees + oc = OrderCycle.last + oc.exchanges.incoming.first.enterprise_fees.should == [supplier_fee] + oc.coordinator_fees.should == [coordinator_fee] + oc.exchanges.outgoing.first.enterprise_fees.should == [distributor_fee] + + # And it should have some variants selected + oc.exchanges.first.variants.count.should == 2 + oc.exchanges.last.variants.count.should == 2 + + # And my receival and pickup time and instructions should have been saved + exchange = oc.exchanges.incoming.first + exchange.receival_instructions.should == 'receival instructions' + + exchange = oc.exchanges.outgoing.first + exchange.pickup_time.should == 'pickup time' + exchange.pickup_instructions.should == 'pickup instructions' + exchange.tag_list.should == ['wholesale'] end - # And I add a distributor fee - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' - select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' + scenario "updating an order cycle", js: true do + # Given an order cycle with all the settings + oc = create(:order_cycle) + initial_variants = oc.variants.sort_by &:id - # And I click Create - click_button 'Create' + # And a coordinating, supplying and distributing enterprise with some products with variants + coordinator = oc.coordinator + supplier = create(:supplier_enterprise, name: 'My supplier') + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) - # Then my order cycle should have been created - page.should have_content 'Your order cycle has been created.' + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - page.should have_selector 'a', text: 'Plums & Avos' - page.should have_selector "input[value='#{Time.zone.local(2040, 11, 06, 06, 00, 00)}']" - page.should have_selector "input[value='#{Time.zone.local(2040, 11, 13, 17, 00, 00)}']" - page.should have_content 'My coordinator' + # And some enterprise fees + supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') + supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') + coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') + coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') + distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') + distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') - page.should have_selector 'td.suppliers', text: 'My supplier' - page.should have_selector 'td.distributors', text: 'My distributor' + # When I go to its edit page + login_to_admin_section + click_link 'Order Cycles' + click_link oc.name + wait_until { page.find('#order_cycle_name').value.present? } - # And it should have some fees - oc = OrderCycle.last - oc.exchanges.incoming.first.enterprise_fees.should == [supplier_fee] - oc.coordinator_fees.should == [coordinator_fee] - oc.exchanges.outgoing.first.enterprise_fees.should == [distributor_fee] + # And I update it + fill_in 'order_cycle_name', with: 'Plums & Avos' + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - # And it should have some variants selected - oc.exchanges.first.variants.count.should == 2 - oc.exchanges.last.variants.count.should == 2 + # CAN'T CHANGE COORDINATOR ANYMORE + # select 'My coordinator', from: 'order_cycle_coordinator_id' - # And my receival and pickup time and instructions should have been saved - exchange = oc.exchanges.incoming.first - exchange.receival_instructions.should == 'receival instructions' + # And I configure some coordinator fees + click_button 'Add coordinator fee' + select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' + click_button 'Add coordinator fee' + click_button 'Add coordinator fee' + click_link 'order_cycle_coordinator_fee_2_remove' + select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' - exchange = oc.exchanges.outgoing.first - exchange.pickup_time.should == 'pickup time' - exchange.pickup_instructions.should == 'pickup instructions' - exchange.tag_list.should == ['wholesale'] + # And I add a supplier and some products + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + page.all("table.exchanges tr.supplier td.products").each { |e| e.click } + + page.should have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true + page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) + check "order_cycle_incoming_exchange_2_variants_#{v1.id}" + check "order_cycle_incoming_exchange_2_variants_#{v2.id}" + + # And I configure some supplier fees + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + + # And I add a distributor and some products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' + + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' + fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' + fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' + fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' + fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' + + page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + page.all("table.exchanges tr.distributor td.products").each { |e| e.click } + + uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" + + # And I configure some distributor fees + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + + # And I click Update + expect(page).to have_selector "#save-bar" + click_button 'Update and Close' + + # Then my order cycle should have been updated + page.should have_content 'Your order cycle has been updated.' + + page.should have_selector 'a', text: 'Plums & Avos' + + page.should have_selector "input[value='#{order_cycle_opening_time}']" + page.should have_selector "input[value='#{order_cycle_closing_time}']" + page.should have_content coordinator.name + + page.should have_selector 'td.suppliers', text: 'My supplier' + page.should have_selector 'td.distributors', text: 'My distributor' + + # And my coordinator fees should have been configured + OrderCycle.last.coordinator_fee_ids.should match_array [coordinator_fee1.id, coordinator_fee2.id] + + # And my supplier fees should have been configured + OrderCycle.last.exchanges.incoming.last.enterprise_fee_ids.should == [supplier_fee2.id] + + # And my distributor fees should have been configured + OrderCycle.last.exchanges.outgoing.last.enterprise_fee_ids.should == [distributor_fee2.id] + + # And my tags should have been save + OrderCycle.last.exchanges.outgoing.last.tag_list.should == ['wholesale'] + + # And it should have some variants selected + selected_initial_variants = initial_variants.take initial_variants.size - 1 + OrderCycle.last.variants.map(&:id).should match_array (selected_initial_variants.map(&:id) + [v1.id, v2.id]) + + # And the collection details should have been updated + OrderCycle.last.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0').should be_present + OrderCycle.last.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1').should be_present + end end - scenario "editing an order cycle" do # Given an order cycle with all the settings oc = create(:order_cycle) @@ -272,144 +412,6 @@ feature %q{ page.should_not have_selector 'table.exchanges tr.supplier' end - - scenario "updating an order cycle", js: true do - # Given an order cycle with all the settings - oc = create(:order_cycle) - initial_variants = oc.variants.sort_by &:id - - # And a coordinating, supplying and distributing enterprise with some products with variants - coordinator = oc.coordinator - supplier = create(:supplier_enterprise, name: 'My supplier') - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - - # And some enterprise fees - supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') - supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') - coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') - coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') - distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') - distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') - - # When I go to its edit page - login_to_admin_section - click_link 'Order Cycles' - click_link oc.name - wait_until { page.find('#order_cycle_name').value.present? } - - # And I update it - fill_in 'order_cycle_name', with: 'Plums & Avos' - fill_in 'order_cycle_orders_open_at', with: '2040-11-06 06:00:00' - fill_in 'order_cycle_orders_close_at', with: '2040-11-13 17:00:00' - - # CAN'T CHANGE COORDINATOR ANYMORE - # select 'My coordinator', from: 'order_cycle_coordinator_id' - - # And I configure some coordinator fees - click_button 'Add coordinator fee' - select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' - click_button 'Add coordinator fee' - click_button 'Add coordinator fee' - click_link 'order_cycle_coordinator_fee_2_remove' - select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' - - # And I add a supplier and some products - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - page.all("table.exchanges tr.supplier td.products").each { |e| e.click } - - page.should have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true - page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) - check "order_cycle_incoming_exchange_2_variants_#{v1.id}" - check "order_cycle_incoming_exchange_2_variants_#{v2.id}" - - # And I configure some supplier fees - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - - # And I add a distributor and some products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' - - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' - fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' - fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' - fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' - fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' - - page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" - end - - page.all("table.exchanges tr.distributor td.products").each { |e| e.click } - - uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" - - # And I configure some distributor fees - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - - # And I click Update - expect(page).to have_selector "#save-bar" - click_button 'Update and Close' - - # Then my order cycle should have been updated - page.should have_content 'Your order cycle has been updated.' - - page.should have_selector 'a', text: 'Plums & Avos' - - page.should have_selector "input[value='#{Time.zone.local(2040, 11, 06, 06, 00, 00)}']" - page.should have_selector "input[value='#{Time.zone.local(2040, 11, 13, 17, 00, 00)}']" - page.should have_content coordinator.name - - page.should have_selector 'td.suppliers', text: 'My supplier' - page.should have_selector 'td.distributors', text: 'My distributor' - - # And my coordinator fees should have been configured - OrderCycle.last.coordinator_fee_ids.should match_array [coordinator_fee1.id, coordinator_fee2.id] - - # And my supplier fees should have been configured - OrderCycle.last.exchanges.incoming.last.enterprise_fee_ids.should == [supplier_fee2.id] - - # And my distributor fees should have been configured - OrderCycle.last.exchanges.outgoing.last.enterprise_fee_ids.should == [distributor_fee2.id] - - # And my tags should have been save - OrderCycle.last.exchanges.outgoing.last.tag_list.should == ['wholesale'] - - # And it should have some variants selected - selected_initial_variants = initial_variants.take initial_variants.size - 1 - OrderCycle.last.variants.map(&:id).should match_array (selected_initial_variants.map(&:id) + [v1.id, v2.id]) - - # And the collection details should have been updated - OrderCycle.last.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0').should be_present - OrderCycle.last.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1').should be_present - end - - scenario "updating many order cycle opening/closing times at once", js: true do # Given three order cycles oc1 = create(:simple_order_cycle) diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index d0c56a4f58..1cfb09425f 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -32,10 +32,10 @@ feature "full-page cart", js: true do it "rounds fee calculations correctly" do # $0.86 + 20% = $1.032 # Fractional cents should be immediately rounded down and not carried through - expect(page).to have_selector '.cart-item-price', text: "#{@currency_symbol}1.03" - expect(page).to have_selector '.cart-item-total', text: "#{@currency_symbol}8.24" - expect(page).to have_selector '.order-total.item-total', text: "#{@currency_symbol}8.24" - expect(page).to have_selector '.order-total.grand-total', text: "#{@currency_symbol}8.24" + expect(page).to have_selector '.cart-item-price', text: "#{currency}1.03" + expect(page).to have_selector '.cart-item-total', text: "#{currency}8.24" + expect(page).to have_selector '.order-total.item-total', text: "#{currency}8.24" + expect(page).to have_selector '.order-total.grand-total', text: "#{currency}8.24" end end diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index 295091dc57..dde546f301 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -135,9 +135,9 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do toggle_shipping choose sm2.name - page.should have_selector 'orderdetails .cart-total', text: "#{@currency_symbol}11.23" - page.should have_selector 'orderdetails .shipping', text: "#{@currency_symbol}4.56" - page.should have_selector 'orderdetails .total', text: "#{@currency_symbol}15.79" + page.should have_selector 'orderdetails .cart-total', text: "#{currency}11.23" + page.should have_selector 'orderdetails .shipping', text: "#{currency}4.56" + page.should have_selector 'orderdetails .total', text: "#{currency}15.79" # Tax should not be displayed in checkout, as the customer's choice of shipping method # affects the tax and we haven't written code to live-update the tax amount when they @@ -269,7 +269,7 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do # + shipping tax ($ 4.56 @ 25% = $0.91) # = $1.93 page.should have_content "(includes tax)" - page.should have_content "#{@currency_symbol}1.93" + page.should have_content "#{currency}1.93" end context "with basic details filled" do @@ -331,14 +331,14 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do context "when we are charged a payment method fee (transaction fee)" do it "creates a payment including the transaction fee" do # Selecting the transaction fee, it is displayed - expect(page).to have_selector ".transaction-fee td", text: "#{@currency_symbol}0.00" - expect(page).to have_selector ".total", text: "#{@currency_symbol}11.23" + expect(page).to have_selector ".transaction-fee td", text: "#{currency}0.00" + expect(page).to have_selector ".total", text: "#{currency}11.23" toggle_payment - choose "#{pm2.name} (#{@currency_symbol}5.67)" + choose "#{pm2.name} (#{currency}5.67)" - expect(page).to have_selector ".transaction-fee td", text: "#{@currency_symbol}5.67" - expect(page).to have_selector ".total", text: "#{@currency_symbol}16.90" + expect(page).to have_selector ".transaction-fee td", text: "#{currency}5.67" + expect(page).to have_selector ".total", text: "#{currency}16.90" place_order expect(page).to have_content "Your order has been processed successfully" diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index bbfb78c247..2c949ce834 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -95,23 +95,23 @@ feature "As a consumer I want to shop with a distributor", js: true do # -- Selecting an order cycle visit shop_path select "turtles", from: "order_cycle_id" - page.should have_content "#{@currency_symbol}1020.99" + page.should have_content "#{currency}1020.99" # -- Cart shows correct price fill_in "variants[#{variant.id}]", with: 1 show_cart - within("li.cart") { page.should have_content "#{@currency_symbol}1020.99" } + within("li.cart") { page.should have_content "#{currency}1020.99" } # -- Changing order cycle select "frogs", from: "order_cycle_id" - page.should have_content "#{@currency_symbol}19.99" + page.should have_content "#{currency}19.99" # -- Cart should be cleared # ng-animate means that the old product row is likely to be present, so we explicitly # fill in the quantity in the incoming row page.should_not have_selector "tr.product-cart" within('product.ng-enter') { fill_in "variants[#{variant.id}]", with: 1 } - within("li.cart") { page.should have_content "#{@currency_symbol}19.99" } + within("li.cart") { page.should have_content "#{currency}19.99" } end describe "declining to clear the cart" do @@ -164,15 +164,15 @@ feature "As a consumer I want to shop with a distributor", js: true do visit shop_path # Page should not have product.price (with or without fee) - page.should_not have_price "#{@currency_symbol}10.00" - page.should_not have_price "#{@currency_symbol}33.00" + page.should_not have_price "#{currency}10.00" + page.should_not have_price "#{currency}33.00" # Page should have variant prices (with fee) - page.should have_price "#{@currency_symbol}43.00" - page.should have_price "#{@currency_symbol}53.00" + page.should have_price "#{currency}43.00" + page.should have_price "#{currency}53.00" # Product price should be listed as the lesser of these - page.should have_price "#{@currency_symbol}43.00" + page.should have_price "#{currency}43.00" end it "filters search results properly" do diff --git a/spec/features/consumer/shopping/variant_overrides_spec.rb b/spec/features/consumer/shopping/variant_overrides_spec.rb index 0542259df1..caf6f1f1b2 100644 --- a/spec/features/consumer/shopping/variant_overrides_spec.rb +++ b/spec/features/consumer/shopping/variant_overrides_spec.rb @@ -40,8 +40,8 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do describe "viewing products" do it "shows the overridden price" do - page.should_not have_price "#{@currency_symbol}12.22" # $11.11 + 10% fee - page.should have_price "#{@currency_symbol}61.11" + page.should_not have_price "#{currency}12.22" # $11.11 + 10% fee + page.should have_price "#{currency}61.11" end it "looks up stock from the override" do @@ -59,9 +59,9 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do it "calculates fees correctly" do page.find("#variant-#{v1.id} .graph-button").click page.find(".price_breakdown a").click - page.should have_selector 'li.cost div', text: "#{@currency_symbol}55.55" - page.should have_selector 'li.packing-fee div', text: "#{@currency_symbol}5.56" - page.should have_selector 'li.total div', text: "= #{@currency_symbol}61.11" + page.should have_selector 'li.cost div', text: "#{currency}55.55" + page.should have_selector 'li.packing-fee div', text: "#{currency}5.56" + page.should have_selector 'li.total div', text: "= #{currency}61.11" end it "shows the correct prices when products are in the cart" do @@ -69,7 +69,7 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do show_cart wait_until_enabled 'li.cart a.button' visit shop_path - page.should_not have_price "#{@currency_symbol}12.22" + page.should_not have_price "#{currency}12.22" end # The two specs below reveal an unrelated issue with fee calculation. See: @@ -79,29 +79,29 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do fill_in "variants[#{v1.id}]", with: "2" show_cart page.should have_selector "#cart-variant-#{v1.id} .quantity", text: '2' - page.should have_selector "#cart-variant-#{v1.id} .price", text: "#{@currency_symbol}61.11" - page.should have_selector "#cart-variant-#{v1.id} .total-price", text: "#{@currency_symbol}122.22" + page.should have_selector "#cart-variant-#{v1.id} .price", text: "#{currency}61.11" + page.should have_selector "#cart-variant-#{v1.id} .total-price", text: "#{currency}122.22" end it "shows the correct prices in the shopping cart" do fill_in "variants[#{v1.id}]", with: "2" add_to_cart - page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-price", text: "#{@currency_symbol}61.11" + page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-price", text: "#{currency}61.11" page.should have_field "order[line_items_attributes][0][quantity]", with: '2' - page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-total", text: "#{@currency_symbol}122.22" + page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-total", text: "#{currency}122.22" - page.should have_selector "#edit-cart .item-total", text: "#{@currency_symbol}122.22" - page.should have_selector "#edit-cart .grand-total", text: "#{@currency_symbol}122.22" + page.should have_selector "#edit-cart .item-total", text: "#{currency}122.22" + page.should have_selector "#edit-cart .grand-total", text: "#{currency}122.22" end it "shows the correct prices in the checkout" do fill_in "variants[#{v1.id}]", with: "2" click_checkout - page.should have_selector 'form.edit_order .cart-total', text: "#{@currency_symbol}122.22" - page.should have_selector 'form.edit_order .shipping', text: "#{@currency_symbol}0.00" - page.should have_selector 'form.edit_order .total', text: "#{@currency_symbol}122.22" + page.should have_selector 'form.edit_order .cart-total', text: "#{currency}122.22" + page.should have_selector 'form.edit_order .shipping', text: "#{currency}0.00" + page.should have_selector 'form.edit_order .total', text: "#{currency}122.22" end end diff --git a/spec/helpers/admin/business_model_configuration_helper_spec.rb b/spec/helpers/admin/business_model_configuration_helper_spec.rb index 0bc011500e..1afa3114c3 100644 --- a/spec/helpers/admin/business_model_configuration_helper_spec.rb +++ b/spec/helpers/admin/business_model_configuration_helper_spec.rb @@ -20,12 +20,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES PER MONTH, PLUS GST" } end end @@ -34,12 +34,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } end end end @@ -52,7 +52,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do @@ -77,7 +77,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is #{@currency_symbol}100" do + context "when minimum billable turnover is 100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -88,12 +88,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } end end @@ -102,12 +102,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } end end end @@ -120,12 +120,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } end end @@ -160,12 +160,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES PER MONTH" } end end @@ -174,12 +174,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } end end end @@ -192,7 +192,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do @@ -217,7 +217,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is #{@currency_symbol}100" do + context "when minimum billable turnover is 100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -228,12 +228,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } end end @@ -242,12 +242,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } end end end @@ -260,12 +260,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } end end @@ -304,12 +304,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES PER MONTH, PLUS GST" } end end @@ -318,12 +318,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } end end end @@ -336,7 +336,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do @@ -361,7 +361,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is #{@currency_symbol}100" do + context "when minimum billable turnover is 100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -372,12 +372,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } end end @@ -386,12 +386,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } end end end @@ -404,12 +404,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } end end @@ -444,12 +444,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES PER MONTH" } end end @@ -458,12 +458,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } end end end @@ -476,7 +476,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do @@ -501,7 +501,7 @@ describe Admin::BusinessModelConfigurationHelper do end end - context "when minimum billable turnover is #{@currency_symbol}100" do + context "when minimum billable turnover is 100" do before { Spree::Config.set(:minimum_billable_turnover, 100) } context "when a fixed cost is included" do @@ -512,12 +512,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } end end @@ -526,12 +526,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{@currency_symbol}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } end end end @@ -544,12 +544,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100, CAPPED AT #{@currency_symbol}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{@currency_symbol}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } end end diff --git a/spec/helpers/products_helper_spec.rb b/spec/helpers/products_helper_spec.rb index b1b4214893..1090dc127a 100644 --- a/spec/helpers/products_helper_spec.rb +++ b/spec/helpers/products_helper_spec.rb @@ -4,13 +4,13 @@ module Spree describe ProductsHelper do it "displays variant price differences as absolute, not relative values" do variant = make_variant_stub(10.00, 10.00) - helper.variant_price_diff(variant).should == "(#{@currency_symbol}10.00)" + helper.variant_price_diff(variant).should == "(#{currency}10.00)" variant = make_variant_stub(10.00, 15.55) - helper.variant_price_diff(variant).should == "(#{@currency_symbol}15.55)" + helper.variant_price_diff(variant).should == "(#{currency}15.55)" variant = make_variant_stub(10.00, 5.55) - helper.variant_price_diff(variant).should == "(#{@currency_symbol}5.55)" + helper.variant_price_diff(variant).should == "(#{currency}5.55)" end private diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 49863ec188..00e0b152ba 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -93,13 +93,11 @@ RSpec.configure do |config| # Ensure we start with consistent config settings config.before(:each) { Spree::Config.products_require_tax_category = false } - # Set currency symbol from config for tests - config.before(:all) { @currency_symbol = Spree::Money.currency_symbol } - # Helpers config.include Rails.application.routes.url_helpers config.include Spree::UrlHelpers config.include Spree::CheckoutHelpers + config.include Spree::MoneyHelper config.include Spree::Core::TestingSupport::ControllerRequests, :type => :controller config.include Devise::TestHelpers, :type => :controller config.extend Spree::Api::TestingSupport::Setup, :type => :controller diff --git a/spec/support/spree/money_helper.rb b/spec/support/spree/money_helper.rb new file mode 100644 index 0000000000..01ae204523 --- /dev/null +++ b/spec/support/spree/money_helper.rb @@ -0,0 +1,7 @@ +module Spree + module MoneyHelper + def currency + Spree::Money.currency_symbol + end + end +end From f25e3bc6f7616274f10b041b0ac1e0f41739f59d Mon Sep 17 00:00:00 2001 From: Julius Pabrinkis Date: Thu, 4 May 2017 18:02:38 +0100 Subject: [PATCH 008/104] Implement with_currency rspec helper for money amounts --- spec/features/consumer/shopping/cart_spec.rb | 8 +- .../consumer/shopping/checkout_spec.rb | 18 ++-- .../consumer/shopping/shopping_spec.rb | 18 ++-- .../shopping/variant_overrides_spec.rb | 30 +++---- ...usiness_model_configuration_helper_spec.rb | 88 +++++++++---------- spec/helpers/products_helper_spec.rb | 6 +- spec/support/spree/money_helper.rb | 4 +- 7 files changed, 86 insertions(+), 86 deletions(-) diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index 1cfb09425f..cdf3e5a031 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -32,10 +32,10 @@ feature "full-page cart", js: true do it "rounds fee calculations correctly" do # $0.86 + 20% = $1.032 # Fractional cents should be immediately rounded down and not carried through - expect(page).to have_selector '.cart-item-price', text: "#{currency}1.03" - expect(page).to have_selector '.cart-item-total', text: "#{currency}8.24" - expect(page).to have_selector '.order-total.item-total', text: "#{currency}8.24" - expect(page).to have_selector '.order-total.grand-total', text: "#{currency}8.24" + expect(page).to have_selector '.cart-item-price', text: with_currency(1.03) + expect(page).to have_selector '.cart-item-total', text: with_currency(8.24) + expect(page).to have_selector '.order-total.item-total', text: with_currency(8.24) + expect(page).to have_selector '.order-total.grand-total', text: with_currency(8.24) end end diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index dde546f301..e10a6e0da3 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -135,9 +135,9 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do toggle_shipping choose sm2.name - page.should have_selector 'orderdetails .cart-total', text: "#{currency}11.23" - page.should have_selector 'orderdetails .shipping', text: "#{currency}4.56" - page.should have_selector 'orderdetails .total', text: "#{currency}15.79" + page.should have_selector 'orderdetails .cart-total', text: with_currency(11.23) + page.should have_selector 'orderdetails .shipping', text: with_currency(4.56) + page.should have_selector 'orderdetails .total', text: with_currency(15.79) # Tax should not be displayed in checkout, as the customer's choice of shipping method # affects the tax and we haven't written code to live-update the tax amount when they @@ -269,7 +269,7 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do # + shipping tax ($ 4.56 @ 25% = $0.91) # = $1.93 page.should have_content "(includes tax)" - page.should have_content "#{currency}1.93" + page.should have_content with_currency(1.93) end context "with basic details filled" do @@ -331,14 +331,14 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do context "when we are charged a payment method fee (transaction fee)" do it "creates a payment including the transaction fee" do # Selecting the transaction fee, it is displayed - expect(page).to have_selector ".transaction-fee td", text: "#{currency}0.00" - expect(page).to have_selector ".total", text: "#{currency}11.23" + expect(page).to have_selector ".transaction-fee td", text: with_currency(0.00) + expect(page).to have_selector ".total", text: with_currency(11.23) toggle_payment - choose "#{pm2.name} (#{currency}5.67)" + choose "#{pm2.name} (#{with_currency(5.67)})" - expect(page).to have_selector ".transaction-fee td", text: "#{currency}5.67" - expect(page).to have_selector ".total", text: "#{currency}16.90" + expect(page).to have_selector ".transaction-fee td", text: with_currency(5.67) + expect(page).to have_selector ".total", text: with_currency(16.90) place_order expect(page).to have_content "Your order has been processed successfully" diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 2c949ce834..4331c92fa3 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -95,23 +95,23 @@ feature "As a consumer I want to shop with a distributor", js: true do # -- Selecting an order cycle visit shop_path select "turtles", from: "order_cycle_id" - page.should have_content "#{currency}1020.99" + page.should have_content with_currency(1020.99) # -- Cart shows correct price fill_in "variants[#{variant.id}]", with: 1 show_cart - within("li.cart") { page.should have_content "#{currency}1020.99" } + within("li.cart") { page.should have_content with_currency(1020.99) } # -- Changing order cycle select "frogs", from: "order_cycle_id" - page.should have_content "#{currency}19.99" + page.should have_content with_currency(19.99) # -- Cart should be cleared # ng-animate means that the old product row is likely to be present, so we explicitly # fill in the quantity in the incoming row page.should_not have_selector "tr.product-cart" within('product.ng-enter') { fill_in "variants[#{variant.id}]", with: 1 } - within("li.cart") { page.should have_content "#{currency}19.99" } + within("li.cart") { page.should have_content with_currency(19.99) } end describe "declining to clear the cart" do @@ -164,15 +164,15 @@ feature "As a consumer I want to shop with a distributor", js: true do visit shop_path # Page should not have product.price (with or without fee) - page.should_not have_price "#{currency}10.00" - page.should_not have_price "#{currency}33.00" + page.should_not have_price with_currency(10.00) + page.should_not have_price with_currency(33.00) # Page should have variant prices (with fee) - page.should have_price "#{currency}43.00" - page.should have_price "#{currency}53.00" + page.should have_price with_currency(43.00) + page.should have_price with_currency(53.00) # Product price should be listed as the lesser of these - page.should have_price "#{currency}43.00" + page.should have_price with_currency(43.00) end it "filters search results properly" do diff --git a/spec/features/consumer/shopping/variant_overrides_spec.rb b/spec/features/consumer/shopping/variant_overrides_spec.rb index caf6f1f1b2..49d1b0b2e4 100644 --- a/spec/features/consumer/shopping/variant_overrides_spec.rb +++ b/spec/features/consumer/shopping/variant_overrides_spec.rb @@ -40,8 +40,8 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do describe "viewing products" do it "shows the overridden price" do - page.should_not have_price "#{currency}12.22" # $11.11 + 10% fee - page.should have_price "#{currency}61.11" + page.should_not have_price with_currency(12.22) # $11.11 + 10% fee + page.should have_price with_currency(61.11) end it "looks up stock from the override" do @@ -59,9 +59,9 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do it "calculates fees correctly" do page.find("#variant-#{v1.id} .graph-button").click page.find(".price_breakdown a").click - page.should have_selector 'li.cost div', text: "#{currency}55.55" - page.should have_selector 'li.packing-fee div', text: "#{currency}5.56" - page.should have_selector 'li.total div', text: "= #{currency}61.11" + page.should have_selector 'li.cost div', text: with_currency(55.55) + page.should have_selector 'li.packing-fee div', text: with_currency(5.56) + page.should have_selector 'li.total div', text: "= #{with_currency(61.11)}" end it "shows the correct prices when products are in the cart" do @@ -69,7 +69,7 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do show_cart wait_until_enabled 'li.cart a.button' visit shop_path - page.should_not have_price "#{currency}12.22" + page.should_not have_price with_currency(12.22) end # The two specs below reveal an unrelated issue with fee calculation. See: @@ -79,29 +79,29 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do fill_in "variants[#{v1.id}]", with: "2" show_cart page.should have_selector "#cart-variant-#{v1.id} .quantity", text: '2' - page.should have_selector "#cart-variant-#{v1.id} .price", text: "#{currency}61.11" - page.should have_selector "#cart-variant-#{v1.id} .total-price", text: "#{currency}122.22" + page.should have_selector "#cart-variant-#{v1.id} .price", text: with_currency(61.11) + page.should have_selector "#cart-variant-#{v1.id} .total-price", text: with_currency(122.22) end it "shows the correct prices in the shopping cart" do fill_in "variants[#{v1.id}]", with: "2" add_to_cart - page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-price", text: "#{currency}61.11" + page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-price", text: with_currency(61.11) page.should have_field "order[line_items_attributes][0][quantity]", with: '2' - page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-total", text: "#{currency}122.22" + page.should have_selector "tr.line-item.variant-#{v1.id} .cart-item-total", text: with_currency(122.22) - page.should have_selector "#edit-cart .item-total", text: "#{currency}122.22" - page.should have_selector "#edit-cart .grand-total", text: "#{currency}122.22" + page.should have_selector "#edit-cart .item-total", text: with_currency(122.22) + page.should have_selector "#edit-cart .grand-total", text: with_currency(122.22) end it "shows the correct prices in the checkout" do fill_in "variants[#{v1.id}]", with: "2" click_checkout - page.should have_selector 'form.edit_order .cart-total', text: "#{currency}122.22" - page.should have_selector 'form.edit_order .shipping', text: "#{currency}0.00" - page.should have_selector 'form.edit_order .total', text: "#{currency}122.22" + page.should have_selector 'form.edit_order .cart-total', text: with_currency(122.22) + page.should have_selector 'form.edit_order .shipping', text: with_currency(0.00) + page.should have_selector 'form.edit_order .total', text: with_currency(122.22) end end diff --git a/spec/helpers/admin/business_model_configuration_helper_spec.rb b/spec/helpers/admin/business_model_configuration_helper_spec.rb index 1afa3114c3..329029b6a6 100644 --- a/spec/helpers/admin/business_model_configuration_helper_spec.rb +++ b/spec/helpers/admin/business_model_configuration_helper_spec.rb @@ -20,12 +20,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES PER MONTH, PLUS GST" } end end @@ -34,12 +34,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end end end @@ -52,7 +52,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do @@ -88,12 +88,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH, PLUS GST" } end end @@ -102,12 +102,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end end end @@ -120,12 +120,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH, PLUS GST" } end end @@ -160,12 +160,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES PER MONTH" } end end @@ -174,12 +174,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH" } end end end @@ -192,7 +192,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do @@ -228,12 +228,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH" } end end @@ -242,12 +242,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "#{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "#{with_currency(10, no_cents: true)} PER MONTH" } end end end @@ -260,12 +260,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH" } end end @@ -304,12 +304,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES PER MONTH, PLUS GST" } end end @@ -318,12 +318,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end end end @@ -336,7 +336,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do @@ -372,12 +372,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH, PLUS GST" } end end @@ -386,12 +386,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH, PLUS GST" } end end end @@ -404,12 +404,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH, PLUS GST" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH, PLUS GST" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH, PLUS GST" } end end @@ -444,12 +444,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES PER MONTH" } end end @@ -458,12 +458,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH" } end end end @@ -476,7 +476,7 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do @@ -512,12 +512,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} + 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH" } end end @@ -526,12 +526,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{currency}10 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN #{with_currency(10, no_cents: true)} PER MONTH" } end end end @@ -544,12 +544,12 @@ describe Admin::BusinessModelConfigurationHelper do context "when the bill is capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 20) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100, CAPPED AT #{currency}20 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)}, CAPPED AT #{with_currency(20, no_cents: true)} PER MONTH" } end context "when the bill is not capped" do before { Spree::Config.set(:account_invoices_monthly_cap, 0) } - it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{currency}100 PER MONTH" } + it { expect(helper.monthly_bill_description).to eq "FREE TRIAL THEN 5.0% OF SALES ONCE TURNOVER EXCEEDS #{with_currency(100, no_cents: true)} PER MONTH" } end end diff --git a/spec/helpers/products_helper_spec.rb b/spec/helpers/products_helper_spec.rb index 1090dc127a..3415757722 100644 --- a/spec/helpers/products_helper_spec.rb +++ b/spec/helpers/products_helper_spec.rb @@ -4,13 +4,13 @@ module Spree describe ProductsHelper do it "displays variant price differences as absolute, not relative values" do variant = make_variant_stub(10.00, 10.00) - helper.variant_price_diff(variant).should == "(#{currency}10.00)" + helper.variant_price_diff(variant).should == "(#{with_currency(10.00)})" variant = make_variant_stub(10.00, 15.55) - helper.variant_price_diff(variant).should == "(#{currency}15.55)" + helper.variant_price_diff(variant).should == "(#{with_currency(15.55)})" variant = make_variant_stub(10.00, 5.55) - helper.variant_price_diff(variant).should == "(#{currency}5.55)" + helper.variant_price_diff(variant).should == "(#{with_currency(5.55)})" end private diff --git a/spec/support/spree/money_helper.rb b/spec/support/spree/money_helper.rb index 01ae204523..f0ca8f73d9 100644 --- a/spec/support/spree/money_helper.rb +++ b/spec/support/spree/money_helper.rb @@ -1,7 +1,7 @@ module Spree module MoneyHelper - def currency - Spree::Money.currency_symbol + def with_currency(amount, options = {}) + Spree::Money.new(amount, {delimiter: ''}.merge(options)).to_s # Delimiter is to match js localizeCurrency end end end From 01746ed470fff5f9f42b1d3d4da061019274a41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Tue, 28 Mar 2017 21:52:48 +0200 Subject: [PATCH 009/104] Add missing translations on views --- .../templates/admin/show_more.html.haml | 2 +- .../admin/reports_controller_decorator.rb | 2 +- .../open_food_network/calculator/weight.rb | 2 +- ...add_variant_overrides_tab.html.haml.deface | 2 +- app/views/admin/account/show.html.haml | 2 +- app/views/admin/customers/index.html.haml | 6 +- .../form/_business_details.html.haml | 4 +- .../form/_shipping_methods.html.haml | 2 +- .../form/_shop_preferences.html.haml | 6 +- .../variant_overrides/_filters.html.haml | 2 +- app/views/producers/signup.html.haml | 2 +- .../admin/orders/bulk_management.html.haml | 10 +-- .../products/bulk_edit/_filters.html.haml | 2 +- .../bulk_edit/_products_head.html.haml | 2 +- .../bulk_edit/_products_product.html.haml | 2 +- .../bulk_edit/_save_button_row.html.haml | 2 +- .../spree/admin/reports/bulk_coop.html.haml | 2 +- .../spree/admin/reports/sales_tax.html.haml | 2 +- app/views/spree/products/_source.html.haml | 8 +-- .../confirmation_instructions.text.erb | 4 ++ config/locales/en.yml | 68 ++++++++++++++----- 21 files changed, 85 insertions(+), 49 deletions(-) create mode 100644 app/views/spree/user_mailer/confirmation_instructions.text.erb diff --git a/app/assets/javascripts/templates/admin/show_more.html.haml b/app/assets/javascripts/templates/admin/show_more.html.haml index 0800710927..8e8630ba65 100644 --- a/app/assets/javascripts/templates/admin/show_more.html.haml +++ b/app/assets/javascripts/templates/admin/show_more.html.haml @@ -1,4 +1,4 @@ %div{ ng: { show: "data.length > limit" } } %input{ type: 'button', value: t(:show_more), ng: { click: 'limit = limit + increment' } } or - %input{ type: 'button', value: t(:show_more_with_more, num: '{{ data.length - limit }}'), ng: { click: 'limit = data.length' } } + %input{ type: 'button', value: t(:show_all_with_more, num: '{{ data.length - limit }}'), ng: { click: 'limit = data.length' } } diff --git a/app/controllers/spree/admin/reports_controller_decorator.rb b/app/controllers/spree/admin/reports_controller_decorator.rb index 8a5a5fa2b2..caf81baff2 100644 --- a/app/controllers/spree/admin/reports_controller_decorator.rb +++ b/app/controllers/spree/admin/reports_controller_decorator.rb @@ -231,7 +231,7 @@ Spree::Admin::ReportsController.class_eval do @report_types = REPORT_TYPES[:orders_and_fulfillment] @report_type = params[:report_type] - @include_blank = 'All' + @include_blank = I18n.t(:all) # -- Build Report with Order Grouper @report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new spree_current_user, params diff --git a/app/models/open_food_network/calculator/weight.rb b/app/models/open_food_network/calculator/weight.rb index 7cd44eb7f7..7f0e8807ba 100644 --- a/app/models/open_food_network/calculator/weight.rb +++ b/app/models/open_food_network/calculator/weight.rb @@ -4,7 +4,7 @@ module OpenFoodNetwork attr_accessible :preferred_per_kg def self.description - "Weight (per kg)" + I18n.t('spree.weight') end def compute(object) diff --git a/app/overrides/spree/admin/shared/_product_sub_menu/add_variant_overrides_tab.html.haml.deface b/app/overrides/spree/admin/shared/_product_sub_menu/add_variant_overrides_tab.html.haml.deface index f0e507234a..2915a5a9f6 100644 --- a/app/overrides/spree/admin/shared/_product_sub_menu/add_variant_overrides_tab.html.haml.deface +++ b/app/overrides/spree/admin/shared/_product_sub_menu/add_variant_overrides_tab.html.haml.deface @@ -1,3 +1,3 @@ / insert_bottom "[data-hook='admin_product_sub_tabs']" -= tab :variant_overrides, label: "Inventory", url: main_app.admin_inventory_path, match_path: '/inventory' += tab :variant_overrides, url: main_app.admin_inventory_path, match_path: '/inventory' diff --git a/app/views/admin/account/show.html.haml b/app/views/admin/account/show.html.haml index b052b5b0a0..07c540ba1f 100644 --- a/app/views/admin/account/show.html.haml +++ b/app/views/admin/account/show.html.haml @@ -25,7 +25,7 @@ %col{ width: '62.5%' } %col{ width: '12.5%' } %thead - %th Date + %th= t('admin.date') %th= t(:description) %th= t(:charge) - if order = invoice.order diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 7e08c2e4b3..485a8eb280 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -20,7 +20,7 @@ .filter_select.five.columns.alpha %label{ :for => 'quick_search', ng: {class: '{disabled: !shop_id}'} }=t('admin.quick_search') %br - %input.fullwidth{ :type => "text", :id => 'quick_search', ng: { model: 'quickSearch', disabled: '!shop_id' }, :placeholder => "Search by email/code..." } + %input.fullwidth{ :type => "text", :id => 'quick_search', ng: { model: 'quickSearch', disabled: '!shop_id' }, :placeholder => t('.search_by_email') } .filter_select.four.columns %label{ :for => 'hub_id', ng: { bind: "shop_id ? '#{t('admin.shop')}' : '#{t('admin.variant_overrides.index.select_a_shop')}'" } } %br @@ -94,6 +94,6 @@ -# %show-more.text-center{ data: "filteredCustomers", limit: "customerLimit", increment: "20" } %div.text-center{ ng: { show: "filteredCustomers.length > customerLimit" } } - %input{ type: 'button', value: 'Show More', ng: { click: 'customerLimit = customerLimit + 20' } } + %input{ type: 'button', value: t(:show_more), ng: { click: 'customerLimit = customerLimit + 20' } } or - %input{ type: 'button', value: "Show All ({{ filteredCustomers.length - customerLimit }} More)", ng: { click: 'customerLimit = filteredCustomers.length' } } + %input{ type: 'button', value: t(:show_all_with_more, num: '{{ filteredCustomers.length - customerLimit }}'), ng: { click: 'customerLimit = filteredCustomers.length' } } diff --git a/app/views/admin/enterprises/form/_business_details.html.haml b/app/views/admin/enterprises/form/_business_details.html.haml index e14254ef5d..c5953ba5ef 100644 --- a/app/views/admin/enterprises/form/_business_details.html.haml +++ b/app/views/admin/enterprises/form/_business_details.html.haml @@ -23,11 +23,11 @@ = f.label :charges_sales_tax, t(:say_no), value: 'false' .row .alpha.three.columns - = f.label :display_invoice_logo, 'Display logo in invoices' + = f.label :display_invoice_logo, t('.display_invoice_logo') .omega.eight.columns = f.check_box :display_invoice_logo .row .alpha.three.columns - = f.label :invoice_text, 'Add customized text at the end of invoices' + = f.label :invoice_text, t('.invoice_text') .omega.eight.columns = f.text_area :invoice_text, style: "width: 100%; height: 100px;" diff --git a/app/views/admin/enterprises/form/_shipping_methods.html.haml b/app/views/admin/enterprises/form/_shipping_methods.html.haml index db7daa5b98..877b650c9e 100644 --- a/app/views/admin/enterprises/form/_shipping_methods.html.haml +++ b/app/views/admin/enterprises/form/_shipping_methods.html.haml @@ -10,7 +10,7 @@ %tr{ ng: { controller: 'shippingMethodsCtrl', init: "findShippingMethodByID(#{shipping_method.id})" } } %td= shipping_method.name %td= f.check_box :shipping_method_ids, { :multiple => true, 'ng-model' => 'ShippingMethod.selected' }, shipping_method.id, nil - %td= link_to "Edit", edit_admin_shipping_method_path(shipping_method) + %td= link_to t(:edit), edit_admin_shipping_method_path(shipping_method) %br .row .six.columns.alpha diff --git a/app/views/admin/enterprises/form/_shop_preferences.html.haml b/app/views/admin/enterprises/form/_shop_preferences.html.haml index 0e5a1096f0..c2d118827d 100644 --- a/app/views/admin/enterprises/form/_shop_preferences.html.haml +++ b/app/views/admin/enterprises/form/_shop_preferences.html.haml @@ -1,7 +1,7 @@ .row .alpha.eleven.columns .three.columns.alpha - = f.label "enterprise_preferred_shopfront_message", t(:shopfront_message) + = f.label "enterprise_preferred_shopfront_message", t('.shopfront_message') .eight.columns.omega %text-angular{'ng-model' => 'Enterprise.preferred_shopfront_message', 'id' => 'enterprise_preferred_shopfront_message', 'name' => 'enterprise[preferred_shopfront_message]', 'class' => 'text-angular', 'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]", @@ -9,7 +9,7 @@ .row .alpha.eleven.columns .three.columns.alpha - = f.label "enterprise_preferred_shopfront_closed_message", t(:shopfront_closed_message) + = f.label "enterprise_preferred_shopfront_closed_message", t('.shopfront_closed_message') .eight.columns.omega %text-angular{'ng-model' => 'Enterprise.preferred_shopfront_closed_message', 'id' => 'enterprise_preferred_shopfront_closed_message', 'name' => 'enterprise[preferred_shopfront_closed_message]', 'class' => 'text-angular', 'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]", @@ -17,7 +17,7 @@ .row .alpha.eleven.columns .three.columns.alpha - = f.label "enterprise_preferred_shopfront_taxon_order", t(:shopfront_category_ordering) + = f.label "enterprise_preferred_shopfront_taxon_order", t('.shopfront_category_ordering') %br (top to bottom) .eight.columns.omega diff --git a/app/views/admin/variant_overrides/_filters.html.haml b/app/views/admin/variant_overrides/_filters.html.haml index a1772ed222..b7a1c948ba 100644 --- a/app/views/admin/variant_overrides/_filters.html.haml +++ b/app/views/admin/variant_overrides/_filters.html.haml @@ -11,7 +11,7 @@ .filter_select.four.columns %label{ :for => 'producer_filter', ng: {class: '{disabled: !hub_id}'} }=t('admin.producer') %br - %input.ofn-select2.fullwidth{ :id => 'producer_filter', type: 'number', data: 'producers', blank: "{id: 0, name: 'All'}", ng: { model: 'producerFilter', disabled: '!hub_id' } } + %input.ofn-select2.fullwidth{ :id => 'producer_filter', type: 'number', data: 'producers', blank: "{id: 0, name: '#{t(:all)}'}", ng: { model: 'producerFilter', disabled: '!hub_id' } } -# .filter_select{ :class => "three columns" } -# %label{ :for => 'distributor_filter' }Hub -# %br diff --git a/app/views/producers/signup.html.haml b/app/views/producers/signup.html.haml index 0afead9415..268c02a593 100644 --- a/app/views/producers/signup.html.haml +++ b/app/views/producers/signup.html.haml @@ -38,7 +38,7 @@ .small-12.medium-6.medium-offset-3.columns.text-center %h2 = t :producers_signup_cta_headline - %p.text-big Start with a free profile, and expand when you're ready! + %p.text-big= t('.start_free_profile') %a.button.transparent{href: "/register"} = t :producers_signup_cta_action diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 5f6764e8d9..9efb7b4e28 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -31,21 +31,21 @@ %label{ :for => 'supplier_filter' } = t("admin.producer") %br - %input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', blank: "{ id: 0, name: 'All' }", ng: { model: 'supplierFilter' } } + %input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', blank: "{ id: 0, name: '#{t(:all)}' }", ng: { model: 'supplierFilter' } } .filter_select{ :class => "three columns" } %label{ :for => 'distributor_filter' } = t("admin.shop") %br - %input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', blank: "{ id: 0, name: 'All' }", ng: { model: 'distributorFilter' } } + %input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', blank: "{ id: 0, name: '#{t(:all)}' }", ng: { model: 'distributorFilter' } } .filter_select{ :class => "three columns" } %label{ :for => 'order_cycle_filter' } = t("admin.order_cycle") %br - %input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', blank: "{ id: 0, name: 'All' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } } + %input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', blank: "{ id: 0, name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } } .filter_clear{ :class => "two columns omega" } %label{ :for => 'clear_all_filters' } %br - %input.red.fullwidth{ :type => 'button', :id => 'clear_all_filters', :value => "Clear All", 'ng-click' => "resetSelectFilters()" } + %input.red.fullwidth{ :type => 'button', :id => 'clear_all_filters', :value => t('admin.clear_all'), 'ng-click' => "resetSelectFilters()" } %hr.divider.sixteen.columns.alpha.omega{ ng: { show: 'unitsVariantSelected()' } } @@ -59,7 +59,7 @@ %h6{ :class => "eight columns alpha", 'ng-hide' => 'sharedResource', style: 'text-align: center;' } {{ selectedUnitsVariant.full_name }} %div{ :class => "four columns omega" } %h6{ :class => "four columns alpha", :style => 'text-align: right;' } - %a{ :href => '#', 'ng-click' => 'selectedUnitsVariant = {};selectedUnitsProduct = {};sharedResource=false;' } Clear + %a{ :href => '#', 'ng-click' => 'selectedUnitsVariant = {};selectedUnitsProduct = {};sharedResource=false;' }= t('admin.clear') %hr .row .one.column.alpha   diff --git a/app/views/spree/admin/products/bulk_edit/_filters.html.haml b/app/views/spree/admin/products/bulk_edit/_filters.html.haml index 4ce0c7c053..43ff84be58 100644 --- a/app/views/spree/admin/products/bulk_edit/_filters.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_filters.html.haml @@ -15,4 +15,4 @@ .filter_clear.three.columns.omega %label{ :for => 'clear_all_filters' } %br - %input.fullwidth.red{ :type => 'button', :id => 'clear_all_filters', :value => "Clear Filters", 'ng-click' => "resetSelectFilters()" } + %input.fullwidth.red{ :type => 'button', :id => 'clear_all_filters', :value => t('admin.clear_filters'), 'ng-click' => "resetSelectFilters()" } diff --git a/app/views/spree/admin/products/bulk_edit/_products_head.html.haml b/app/views/spree/admin/products/bulk_edit/_products_head.html.haml index 50789a2f82..9a8f7ad86a 100644 --- a/app/views/spree/admin/products/bulk_edit/_products_head.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_products_head.html.haml @@ -20,7 +20,7 @@ %tr{ ng: { controller: "ColumnsCtrl" } } %th.left-actions %a{ 'ng-click' => 'toggleShowAllVariants()', :style => 'color: red' } - Expand All + = t(:expand_all) %th.producer{ 'ng-show' => 'columns.producer.visible' }=t('admin.producer') %th.sku{ 'ng-show' => 'columns.sku.visible' }=t('admin.sku') %th.name{ 'ng-show' => 'columns.name.visible' }=t('admin.name') diff --git a/app/views/spree/admin/products/bulk_edit/_products_product.html.haml b/app/views/spree/admin/products/bulk_edit/_products_product.html.haml index 01af8014d1..1c11d50cff 100644 --- a/app/views/spree/admin/products/bulk_edit/_products_product.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_products_product.html.haml @@ -26,7 +26,7 @@ %input.fullwidth{ :type => 'text', id: "p{{product.id}}_category_id", 'ng-model' => 'product.category_id', 'ofn-taxon-autocomplete' => '', 'ofn-track-product' => 'category_id', 'multiple-selection' => 'false', placeholder: 'Category' } %td.tax_category{ 'ng-if' => 'columns.tax_category.visible' } %select.select2{ name: 'product_tax_category_id', 'ofn-track-product' => 'tax_category_id', ng: {model: 'product.tax_category_id', options: 'tax_category.id as tax_category.name for tax_category in tax_categories'} } - %option{value: ''} None + %option{value: ''}= t(:none) %td.inherits_properties{ 'ng-show' => 'columns.inherits_properties.visible' } %input{ 'ng-model' => 'product.inherits_properties', :name => 'inherits_properties', 'ofn-track-product' => 'inherits_properties', type: "checkbox" } %td.available_on{ 'ng-show' => 'columns.available_on.visible' } diff --git a/app/views/spree/admin/products/bulk_edit/_save_button_row.html.haml b/app/views/spree/admin/products/bulk_edit/_save_button_row.html.haml index a5f18986c0..529f8034c9 100644 --- a/app/views/spree/admin/products/bulk_edit/_save_button_row.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_save_button_row.html.haml @@ -1,3 +1,3 @@ %div.sixteen.columns.alpha{ 'ng-hide' => 'loading || products.length == 0', style: "margin-bottom: 10px" } %div.four.columns.alpha - %input.four.columns.alpha{ :type => 'button', :value => 'Save Changes', 'ng-click' => 'submitProducts()'} + %input.four.columns.alpha{ :type => 'button', :value => t(:save_changes), 'ng-click' => 'submitProducts()'} diff --git a/app/views/spree/admin/reports/bulk_coop.html.haml b/app/views/spree/admin/reports/bulk_coop.html.haml index 8d9a1234ce..922f32f3a9 100644 --- a/app/views/spree/admin/reports/bulk_coop.html.haml +++ b/app/views/spree/admin/reports/bulk_coop.html.haml @@ -4,7 +4,7 @@ .row .four.columns.alpha = label_tag nil, "Distributor: " - = f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => 'All'}, {:class => "select2 fullwidth"}) + = f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => t(:all)}, {:class => "select2 fullwidth"}) = label_tag nil, "Report Type: " %br = select_tag(:report_type, options_for_select([['Bulk Co-op - Totals by Supplier',:bulk_coop_supplier_report],['Bulk Co-op - Allocation',:bulk_coop_allocation],['Bulk Co-op - Packing Sheets',:bulk_coop_packing_sheets],['Bulk Co-op - Customer Payments',:bulk_coop_customer_payments]], @report_type)) diff --git a/app/views/spree/admin/reports/sales_tax.html.haml b/app/views/spree/admin/reports/sales_tax.html.haml index c90603d001..9971b2c5cb 100644 --- a/app/views/spree/admin/reports/sales_tax.html.haml +++ b/app/views/spree/admin/reports/sales_tax.html.haml @@ -4,7 +4,7 @@ .row .four.columns.alpha = label_tag nil, t(:report_distributor) - = f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => 'All'}, {:class => "select2 fullwidth"}) + = f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => t(:all)}, {:class => "select2 fullwidth"}) = label_tag nil, t(:report_customers_type) %br = select_tag(:report_type, options_for_select([[t(:report_tax_types),:tax_types],[t(:report_tax_rates),:tax_rates]], @report_type)) diff --git a/app/views/spree/products/_source.html.haml b/app/views/spree/products/_source.html.haml index dfcd091d67..7751ba36ef 100644 --- a/app/views/spree/products/_source.html.haml +++ b/app/views/spree/products/_source.html.haml @@ -1,5 +1,5 @@ %div{:data-hook => "product_source"} - %h6.product-section-title SUPPLIER + %h6.product-section-title= t(:supplier) %table#product-source.table-display{:width => "100%"} %tbody - if @product.supplier @@ -7,7 +7,7 @@ %td= link_to @product.supplier.name, [main_app, @product.supplier] - if false %br/ - %h6.product-section-title DISTRIBUTORS + %h6.product-section-title= t(:distributors) %table#product-source.table-display{:width => "100%"} %tbody - order = current_order(false) @@ -18,11 +18,11 @@ %td %b= link_to(distributor.name, [main_app, distributor]) %td - %b Current + %b= t(:current) - elsif order.nil? || validator.can_change_to_distributor?(distributor) %tr.even %td= link_to distributor.name, [main_app, distributor] - %td Available + %td= t(:available) - else %tr.even %td= link_to distributor.name, [main_app, distributor] diff --git a/app/views/spree/user_mailer/confirmation_instructions.text.erb b/app/views/spree/user_mailer/confirmation_instructions.text.erb new file mode 100644 index 0000000000..fabf8936ba --- /dev/null +++ b/app/views/spree/user_mailer/confirmation_instructions.text.erb @@ -0,0 +1,4 @@ +<%= t('.welcome', email: @email) %> + +<%= t('.text') %> +<%= @confirmation_url %> diff --git a/config/locales/en.yml b/config/locales/en.yml index a724c19864..115c7d03bd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -80,6 +80,21 @@ en: show_all: Show all show_all_with_more: "Show All (%{num} More)" cancel: Cancel + edit: Edit + distributors: Distributors + order_cycles: Order Cycles + enterprise_limit: Enterprise Limit + bulk_order_management: Bulk Order Management + enterprises: Enterprises + enterprise_groups: Groups + reports: Reports + variant_overrides: Inventory + more: More + spree_products: Spree Products + all: All + current: Current + available: Available + dashboard: Dashboard admin: # Common properties / models @@ -107,6 +122,8 @@ en: end_date: "End Date" unsaved_changes: "You have unsaved changes" form_invalid: "Form contains missing or invalid fields" + clear_filters: Clear Filters + clear: Clear columns: Columns actions: Actions @@ -190,6 +207,7 @@ en: edit: 'Edit' update_address: 'Update Address' confirm_delete: 'Sure to delete?' + search_by_email: "Search by email/code..." cache_settings: show: @@ -299,6 +317,8 @@ en: abn_placeholder: eg. 99 123 456 789 acn: ACN acn_placeholder: eg. 123 456 789 + display_invoice_logo: Display logo in invoices + invoice_text: Add customized text at the end of invoices contact: name: Name name_placeholder: eg. Gustav Plum @@ -375,13 +395,16 @@ en: allow_guest_orders_tip: "Allow checkout as guest or require a registered user." allow_guest_orders_false: "Require login to order" allow_guest_orders_true: "Allow guest checkout" + shopfront_message: Shopfront Message shopfront_message_placeholder: > An optional explanation for customers detailing how your shopfront works, to be displayed above the product list on your shop page. + shopfront_closed_message: Shopfront Closed Message shopfront_closed_message_placeholder: > A message which provides a more detailed explanation about why your shop is closed and/or when customers can expect it to open again. This is displayed on your shop only when you have no active order cycles (ie. shop is closed). + shopfront_category_ordering: Shopfront Category Ordering open_date: Open Date close_date: Close Date social: @@ -743,6 +766,7 @@ en: order_billing_address: Billing address order_delivery_on: Delivery on order_delivery_address: Delivery address + order_delivery_time: Delivery time order_special_instructions: "Your notes:" order_pickup_time: Ready for collection order_pickup_instructions: Collection Instructions @@ -1122,6 +1146,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using enterprise_long_desc: "Long Description" enterprise_long_desc_placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words." enterprise_long_desc_length: "%{num} characters / up to 600 recommended" + enterprise_limit: Enterprise Limit enterprise_abn: "ABN" enterprise_abn_placeholder: "eg. 99 123 456 789" enterprise_acn: "ACN" @@ -1262,6 +1287,7 @@ Please follow the instructions there to make your enterprise visible on the Open calculator_values: "Calculator values" flat_percent_per_item: "Flat Percent (per item)" new_order_cycles: "New Order Cycles" + new_order_cycle: "New Order Cycle" select_a_coordinator_for_your_order_cycle: "Select a coordinator for your order cycle" edit_order_cycle: "Edit Order Cycle" roles: "Roles" @@ -1542,6 +1568,10 @@ Please follow the instructions there to make your enterprise visible on the Open now_out_of_stock: is now out of stock. only_n_remainging: "now only has %{num} remaining." + producers: + signup: + start_free_profile: "Start with a free profile, and expand when you're ready!" + spree: admin: products: @@ -1558,24 +1588,7 @@ Please follow the instructions there to make your enterprise visible on the Open date_picker: format: ! '%Y-%m-%d' js_format: 'yy-mm-dd' - zipcode: Postcode - shipment_states: - backorder: backorder - partial: partial - pending: pending - ready: ready - shipped: shipped - payment_states: - balance_due: balance due - completed: completed - checkout: checkout - credit_owed: credit owed - failed: failed - paid: paid - pending: pending - processing: processing - void: void - invalid: invalid + inventory: Inventaire order_mailer: invoice_email: hi: "Hi %{name}" @@ -1596,6 +1609,23 @@ Please follow the instructions there to make your enterprise visible on the Open orders: invoice: tax_invoice: "TAX INVOICE: " + payment_states: + balance_due: balance due + completed: completed + checkout: checkout + credit_owed: credit owed + failed: failed + paid: paid + pending: pending + processing: processing + void: void + invalid: invalid + shipment_states: + backorder: backorder + partial: partial + pending: pending + ready: ready + shipped: shipped user_mailer: reset_password_instructions: request_sent_text: | @@ -1606,3 +1636,5 @@ Please follow the instructions there to make your enterprise visible on the Open issue_text: | If the above URL does not work try copying and pasting it into your browser. If you continue to have problems please feel free to contact us. + weight: Weight (per kg) + zipcode: Postcode From 963b4617a985e1a82c7139c382b07ea23f31507e Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 12 Oct 2016 13:56:06 +1100 Subject: [PATCH 010/104] Add allow-order-changes option to enterprise --- .../enterprises/form/_shop_preferences.html.haml | 12 ++++++++++++ config/locales/en.yml | 4 ++++ ...12022142_add_allow_order_changes_to_enterprise.rb | 5 +++++ db/schema.rb | 1 + 4 files changed, 22 insertions(+) create mode 100644 db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb diff --git a/app/views/admin/enterprises/form/_shop_preferences.html.haml b/app/views/admin/enterprises/form/_shop_preferences.html.haml index c2d118827d..066f8a5fe3 100644 --- a/app/views/admin/enterprises/form/_shop_preferences.html.haml +++ b/app/views/admin/enterprises/form/_shop_preferences.html.haml @@ -57,3 +57,15 @@ .five.columns.omega = f.radio_button :allow_guest_orders, false = f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false +.row + .alpha.eleven.columns + .three.columns.alpha + %label= t '.allow_order_changes' + %div{'ofn-with-tip' => t('.allow_order_changes_tip')} + %a= t 'admin.whats_this' + .three.columns + = f.radio_button :allow_order_changes, false + = f.label :allow_order_changes, t('.allow_order_changes_false'), value: :false + .five.columns.omega + = f.radio_button :allow_order_changes, true + = f.label :allow_order_changes, t('.allow_order_changes_true'), value: :true diff --git a/config/locales/en.yml b/config/locales/en.yml index 115c7d03bd..043ada2010 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -395,6 +395,10 @@ en: allow_guest_orders_tip: "Allow checkout as guest or require a registered user." allow_guest_orders_false: "Require login to order" allow_guest_orders_true: "Allow guest checkout" + allow_order_changes: "Change orders" + allow_order_changes_tip: "Allow customers to change their order as long the order cycle is open." + allow_order_changes_false: "Placed orders cannot be changed" + allow_order_changes_true: "Customers can remove items from an order of an open order cycle" shopfront_message: Shopfront Message shopfront_message_placeholder: > An optional explanation for customers detailing how your shopfront works, diff --git a/db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb b/db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb new file mode 100644 index 0000000000..887ce44058 --- /dev/null +++ b/db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb @@ -0,0 +1,5 @@ +class AddAllowOrderChangesToEnterprise < ActiveRecord::Migration + def change + add_column :enterprises, :allow_order_changes, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 65e413e92b..75c43b1d72 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -251,6 +251,7 @@ ActiveRecord::Schema.define(:version => 20161215230219) do t.boolean "allow_guest_orders", :default => true, :null => false t.text "invoice_text" t.boolean "display_invoice_logo", :default => false + t.boolean "allow_order_changes", :default => false, :null => false end add_index "enterprises", ["address_id"], :name => "index_enterprises_on_address_id" From e1b40142b862c3c5b099a48fac7ecce24a71d53d Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 22 Jul 2016 14:30:00 +1000 Subject: [PATCH 011/104] Remove unused translations --- config/locales/en.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 043ada2010..01511e8865 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -662,15 +662,6 @@ en: card_securitycode: "Security Code" card_expiry_date: Expiry Date - ofn_cart_headline: "Current cart for:" - ofn_cart_distributor: "Distributor:" - ofn_cart_oc: "Order cycle:" - ofn_cart_from: "From:" - ofn_cart_to: "To:" - ofn_cart_product: "Product:" - ofn_cart_quantitiy: "Quantity:" - ofn_cart_send: "Buy me" - ie_warning_headline: "Your browser is out of date :-(" ie_warning_text: "For the best Open Food Network experience, we strongly recommend upgrading your browser:" ie_warning_chrome: Download Chrome From fe7bd5e2cd35122245ba5ed93003a315e61c7ff2 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 27 Jul 2016 15:58:54 +1000 Subject: [PATCH 012/104] Serialise tag_list only for variant overrides Don't try to call tag_list on just variants since that will fail. Normally, all variants of `current_order` should be extended to VariantOverrides of the current order cycle. But in development environment, it can happen that the variants are reloaded without being extended again. --- app/serializers/api/variant_serializer.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/serializers/api/variant_serializer.rb b/app/serializers/api/variant_serializer.rb index 6a38fe9b93..c1fa8d213b 100644 --- a/app/serializers/api/variant_serializer.rb +++ b/app/serializers/api/variant_serializer.rb @@ -1,7 +1,6 @@ class Api::VariantSerializer < ActiveModel::Serializer attributes :id, :is_master, :count_on_hand, :name_to_display, :unit_to_display attributes :options_text, :on_demand, :price, :fees, :price_with_fees, :product_name - attributes :tag_list def price object.price @@ -23,4 +22,8 @@ class Api::VariantSerializer < ActiveModel::Serializer def product_name object.product.name end + + def tag_list + object.tag_list if object.is_a? VariantOverride + end end From 65f62c42b94a8575192a243423035dcf3a2e9a56 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 27 Jul 2016 16:05:39 +1000 Subject: [PATCH 013/104] Display products already ordered in this oc Github issue #1083, part of standing orders. For now, just display already bought products within the same order cycle in the popup cart view. The edit cart view should follow. Later, it should be possible to remove items as well. --- .../darkswarm/services/cart.js.coffee | 8 +++++ app/models/spree/order_decorator.rb | 15 +++++++++ .../api/current_order_serializer.rb | 1 + app/views/shared/menu/_cart.html.haml | 20 ++++++++++++ config/locales/en.yml | 3 ++ spec/models/spree/order_spec.rb | 32 +++++++++++++++++++ 6 files changed, 79 insertions(+) diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index 70cbe316e8..e32ca75663 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -97,6 +97,14 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo $(window).bind "beforeunload", -> t 'order_not_saved_yet' + line_items_finalised: => + items = CurrentOrder.order.finalised_line_items + for line_item in items + line_item.variant.line_item = line_item + Variants.extend line_item.variant + line_item.variant.extended_name = @extendedVariantName(line_item.variant) + items + total_item_count: => @line_items.reduce (sum,li) -> sum = sum + li.quantity diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index e1135853ee..66da7a0c68 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -195,6 +195,21 @@ Spree::Order.class_eval do line_items.map(&:variant) end + # Show already bought line items of this order cycle + def finalised_line_items + return [] unless order_cycle && user + orders = self.class.complete.where(user_id: user, order_cycle_id: order_cycle) + items = [] + orders.each do |o| + items += o.line_items + end + scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) + items.each do |li| + scoper.scope(li.variant) + end + items + end + def admin_and_handling_total adjustments.eligible.where("originator_type = ? AND source_type != ?", 'EnterpriseFee', 'Spree::LineItem').sum(&:amount) end diff --git a/app/serializers/api/current_order_serializer.rb b/app/serializers/api/current_order_serializer.rb index 9f939b09c1..87e0e53bb5 100644 --- a/app/serializers/api/current_order_serializer.rb +++ b/app/serializers/api/current_order_serializer.rb @@ -6,6 +6,7 @@ class Api::CurrentOrderSerializer < ActiveModel::Serializer has_one :ship_address, serializer: Api::AddressSerializer has_many :line_items, serializer: Api::LineItemSerializer + has_many :finalised_line_items, serializer: Api::LineItemSerializer def payment_method_id object.payments.first.andand.payment_method_id diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index 73e9fe14be..5a48a45049 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -48,3 +48,23 @@ = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t 'checkout' + %h5{style: 'margin-top: 1em'} + = t '.already_ordered_products' + %table + %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised()", + "ng-controller" => "LineItemCtrl", "id" => "cart-variant-{{ line_item.variant.id }}"} + %td + %small + %strong + {{ line_item.variant.extended_name }} + %td.text-right + %small + %span.quantity {{ line_item.quantity }} + %i.ofn-i_009-close + %span.price {{ line_item.variant.price_with_fees | localizeCurrency }} + + %td + %small + \= + %strong + .total-price.right {{ line_item.total_price | localizeCurrency }} diff --git a/config/locales/en.yml b/config/locales/en.yml index 01511e8865..0547b59d85 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -556,6 +556,9 @@ en: hide_closed_shops: "Hide closed shops" show_on_map: "Show all on the map" shared: + menu: + cart: + already_ordered_products: "Already ordered in this order cycle" register_call: selling_on_ofn: "Interested in getting on the Open Food Network?" register: "Register here" diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 8922380566..1b81f6ba0b 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -650,4 +650,36 @@ describe Spree::Order do end end end + + describe "retrieving previously ordered items" do + let(:distributor) { create(:distributor_enterprise) } + let(:order_cycle) { create(:simple_order_cycle) } + let!(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) } + + it "returns no items if nothing has been ordered" do + expect(order.finalised_line_items).to eq [] + end + + context "when no order has been finalised in this order cycle" do + let(:product) { create(:product) } + + it "returns no items even though the cart contains items" do + order.add_variant(product.master, 1, 3) + expect(order.finalised_line_items).to eq [] + end + end + + context "when an order has been finalised in this order cycle" do + let!(:prev_order) { create(:completed_order_with_totals, distributor: distributor, order_cycle: order_cycle, user: order.user) } + let!(:prev_order2) { create(:completed_order_with_totals, distributor: distributor, order_cycle: order_cycle, user: order.user) } + let(:product) { create(:product) } + + it "returns previous items" do + prev_order.add_variant(product.master, 1, 3) + prev_order2.reload # to get the right response from line_items + expect(order.finalised_line_items.length).to eq 3 + expect(order.finalised_line_items).to match_array(prev_order.line_items + prev_order2.line_items) + end + end + end end From c0d6b68233b30db4c4b951a9e2b53ee1efee6946 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 27 Jul 2016 16:21:56 +1000 Subject: [PATCH 014/104] Apply some style guidelines to older code --- app/models/spree/order_decorator.rb | 37 ++++++++----------- .../api/current_order_serializer.rb | 2 +- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 66da7a0c68..c76e0d9e45 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -9,7 +9,7 @@ end Spree::Order.class_eval do belongs_to :order_cycle - belongs_to :distributor, :class_name => 'Enterprise' + belongs_to :distributor, class_name: 'Enterprise' belongs_to :cart belongs_to :customer @@ -39,7 +39,6 @@ Spree::Order.class_eval do remove_transition :from => :delivery, :to => :confirm end - # -- Scopes scope :managed_by, lambda { |user| if user.has_spree_role?('admin') @@ -88,7 +87,7 @@ Spree::Order.class_eval do unless self.order_cycle == order_cycle self.order_cycle = order_cycle self.distributor = nil unless order_cycle.nil? || order_cycle.has_distributor?(distributor) - self.empty! + empty! save! end end @@ -99,7 +98,6 @@ Spree::Order.class_eval do current_item.andand.destroy end - # Overridden to support max_quantity def add_variant(variant, quantity = 1, max_quantity = nil, currency = nil) line_items(:reload) @@ -126,7 +124,7 @@ Spree::Order.class_eval do current_item.currency = currency unless currency.nil? current_item.save else - current_item = Spree::LineItem.new(:quantity => quantity, max_quantity: max_quantity) + current_item = Spree::LineItem.new(quantity: quantity, max_quantity: max_quantity) current_item.variant = variant if currency current_item.currency = currency unless currency.nil? @@ -134,10 +132,10 @@ Spree::Order.class_eval do else current_item.price = variant.price end - self.line_items << current_item + line_items << current_item end - self.reload + reload current_item end @@ -220,26 +218,26 @@ Spree::Order.class_eval do # Does this order have shipments that can be shipped? def ready_to_ship? - self.shipments.any?{|s| s.can_ship?} + shipments.any?(&:can_ship?) end # Ship all pending orders def ship - self.shipments.each do |s| + shipments.each do |s| s.ship if s.can_ship? end end def shipping_tax - adjustments(:reload).shipping.sum &:included_tax + adjustments(:reload).shipping.sum(&:included_tax) end def enterprise_fee_tax - adjustments(:reload).enterprise_fee.sum &:included_tax + adjustments(:reload).enterprise_fee.sum(&:included_tax) end def total_tax - (adjustments + price_adjustments).sum &:included_tax + (adjustments + price_adjustments).sum(&:included_tax) end def tax_adjustments @@ -269,12 +267,9 @@ Spree::Order.class_eval do # Overrride of Spree method, that allows us to send separate confirmation emails to user and shop owners # And separately, to skip sending confirmation email completely for user invoice orders def deliver_order_confirmation_email - unless account_invoice? - Delayed::Job.enqueue ConfirmOrderJob.new(id) - end + Delayed::Job.enqueue ConfirmOrderJob.new(id) unless account_invoice? end - private def shipping_address_from_distributor @@ -287,9 +282,9 @@ Spree::Order.class_eval do self.ship_address = distributor.address.clone if bill_address - self.ship_address.firstname = bill_address.firstname - self.ship_address.lastname = bill_address.lastname - self.ship_address.phone = bill_address.phone + ship_address.firstname = bill_address.firstname + ship_address.lastname = bill_address.lastname + ship_address.phone = bill_address.phone end end end @@ -301,11 +296,11 @@ Spree::Order.class_eval do end def product_distribution_for(line_item) - line_item.variant.product.product_distribution_for self.distributor + line_item.variant.product.product_distribution_for distributor end def require_customer? - return true unless new_record? or state == 'cart' + return true unless new_record? || state == 'cart' end def customer_is_valid? diff --git a/app/serializers/api/current_order_serializer.rb b/app/serializers/api/current_order_serializer.rb index 87e0e53bb5..77927614f8 100644 --- a/app/serializers/api/current_order_serializer.rb +++ b/app/serializers/api/current_order_serializer.rb @@ -1,6 +1,6 @@ class Api::CurrentOrderSerializer < ActiveModel::Serializer attributes :id, :item_total, :email, :shipping_method_id, - :display_total, :payment_method_id + :display_total, :payment_method_id has_one :bill_address, serializer: Api::AddressSerializer has_one :ship_address, serializer: Api::AddressSerializer From 88c3f414fb6211bcd2c029bff9ee862b9d8c9912 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 29 Jul 2016 10:42:16 +1000 Subject: [PATCH 015/104] Handle missing order in cart --- app/assets/javascripts/darkswarm/services/cart.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index e32ca75663..bc1c2d6504 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -98,7 +98,7 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo t 'order_not_saved_yet' line_items_finalised: => - items = CurrentOrder.order.finalised_line_items + items = CurrentOrder.order?.finalised_line_items || [] for line_item in items line_item.variant.line_item = line_item Variants.extend line_item.variant From e8d2d4d96f91d9990c9b9b4236ac4308273ab001 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 29 Jul 2016 14:53:43 +1000 Subject: [PATCH 016/104] Display already bought items in edit cart view --- app/views/spree/orders/_bought.html.haml | 41 ++++++++++++++++++++++++ app/views/spree/orders/edit.html.haml | 2 ++ config/locales/en.yml | 23 ++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 app/views/spree/orders/_bought.html.haml diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml new file mode 100644 index 0000000000..b3f32b1045 --- /dev/null +++ b/app/views/spree/orders/_bought.html.haml @@ -0,0 +1,41 @@ +%div + %div + %div + .row + .row + .columns.large-12 + %table{style: "width: 100%; margin-top: 2em"} + %col{halign: "left", valign: "middle", width: "60%"}/ + %col{halign: "left", valign: "middle", width: "15%"}/ + %col{halign: "center", valign: "middle", width: "10%"}/ + %col{halign: "center", valign: "middle", width: "10%"}/ + %col{halign: "center", valign: "middle", width: "5%"}/ + %thead + %tr + %th.cart-item-description-header= t('.item') + %th.cart-item-price-header.text-right= t(:price) + %th.text-center.cart-item-quantity-header= t(:qty) + %th.cart-item-total-header.text-right= t(:total) + %th.cart-item-delete-header + + %tbody + - @order.finalised_line_items.each do |line_item| + - variant = line_item.variant + %tr.line-item{class: "variant-#{variant.id}"} + %td.cart-item-description + + %div.item-thumb-image + - if variant.images.length == 0 + = link_to mini_image(variant.product), variant.product + - else + = link_to image_tag(variant.images.first.attachment.url(:mini)), variant.product + + = render 'spree/shared/line_item_name', line_item: line_item + %td.text-right.cart-item-price + = line_item.single_display_amount_with_adjustments.to_html + %td.text-center.cart-item-quantity + = line_item.quantity + %td.cart-item-total.text-right + = line_item.display_amount_with_adjustments.to_html unless line_item.quantity.nil? + + %td.cart-item-delete.text-center diff --git a/app/views/spree/orders/edit.html.haml b/app/views/spree/orders/edit.html.haml index 3417eb5e6a..8edd087e3d 100644 --- a/app/views/spree/orders/edit.html.haml +++ b/app/views/spree/orders/edit.html.haml @@ -44,4 +44,6 @@ = t :orders_edit_checkout %i.ofn-i_007-caret-right + = render 'bought' + = render partial: "shared/footer" diff --git a/config/locales/en.yml b/config/locales/en.yml index 0547b59d85..56555261cd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1586,7 +1586,28 @@ Please follow the instructions there to make your enterprise visible on the Open date_picker: format: ! '%Y-%m-%d' js_format: 'yy-mm-dd' - inventory: Inventaire + inventory: Inventory + zipcode: Postcode + orders: + bought: + item: "Already bought item" + shipment_states: + backorder: backorder + partial: partial + pending: pending + ready: ready + shipped: shipped + payment_states: + balance_due: balance due + completed: completed + checkout: checkout + credit_owed: credit owed + failed: failed + paid: paid + pending: pending + processing: processing + void: void + invalid: invalid order_mailer: invoice_email: hi: "Hi %{name}" From 0fe4030d71312aedc15f674af164650ad20f7233 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 3 Aug 2016 14:25:23 +1000 Subject: [PATCH 017/104] Display bought items only if present --- app/views/shared/menu/_cart.html.haml | 2 +- app/views/spree/orders/edit.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index 5a48a45049..954246dd36 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -48,7 +48,7 @@ = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t 'checkout' - %h5{style: 'margin-top: 1em'} + %h5{"ng-if" => "Cart.line_items_finalised().present()", style: 'margin-top: 1em'} = t '.already_ordered_products' %table %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised()", diff --git a/app/views/spree/orders/edit.html.haml b/app/views/spree/orders/edit.html.haml index 8edd087e3d..4dec61523a 100644 --- a/app/views/spree/orders/edit.html.haml +++ b/app/views/spree/orders/edit.html.haml @@ -44,6 +44,6 @@ = t :orders_edit_checkout %i.ofn-i_007-caret-right - = render 'bought' + = render 'bought' if @order.finalised_line_items.present? = render partial: "shared/footer" From 4112c3cc75ac3dc4565c8659cad23df4b2746db9 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 24 Aug 2016 16:46:33 +1000 Subject: [PATCH 018/104] Set auth token for all JS HTTP requests --- app/assets/javascripts/darkswarm/darkswarm.js.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/darkswarm/darkswarm.js.coffee b/app/assets/javascripts/darkswarm/darkswarm.js.coffee index 2b51bc309c..6d75916894 100644 --- a/app/assets/javascripts/darkswarm/darkswarm.js.coffee +++ b/app/assets/javascripts/darkswarm/darkswarm.js.coffee @@ -11,8 +11,7 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource", 'angularFileUpload', 'angularSlideables' ]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) -> - $httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content') - $httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content') + $httpProvider.defaults.headers['common']['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content') $httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest' $httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*" From 4835ef067f06a20db8a27664e219cdc31e486e50 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 3 Aug 2016 17:23:02 +1000 Subject: [PATCH 019/104] Add feature to remove line items from open order cycle - Add JS controller to send delete requests. - Add resource controller to destroy items. - Add authorisation check to abilities. - Update fees after removing line item. --- .../edit_order_controller.js.coffee | 10 +++++ .../darkswarm/services/cart.js.coffee | 1 - app/controllers/line_items_controller.rb | 24 ++++++++++++ app/models/spree/ability_decorator.rb | 8 ++++ app/views/shared/menu/_cart.html.haml | 4 +- app/views/spree/orders/_bought.html.haml | 6 ++- app/views/spree/orders/_line_item.html.haml | 1 - config/routes.rb | 2 + .../controllers/line_items_controller_spec.rb | 37 +++++++++++++++++++ spec/features/consumer/shopping/cart_spec.rb | 29 +++++++++++++++ 10 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee create mode 100644 app/controllers/line_items_controller.rb create mode 100644 spec/controllers/line_items_controller_spec.rb diff --git a/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee new file mode 100644 index 0000000000..e39b79c48b --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee @@ -0,0 +1,10 @@ +Darkswarm.controller "EditOrderCtrl", ($scope, $resource, Cart) -> + + $scope.deleteLineItem = (id) -> + params = {id: id} + success = (response) -> + $(".line-item-" + id).remove() + fail = (error) -> + console.log error + + $resource("/line_items/:id").delete(params, success, fail) diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index bc1c2d6504..9ad375f873 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -102,7 +102,6 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo for line_item in items line_item.variant.line_item = line_item Variants.extend line_item.variant - line_item.variant.extended_name = @extendedVariantName(line_item.variant) items total_item_count: => diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb new file mode 100644 index 0000000000..5846538411 --- /dev/null +++ b/app/controllers/line_items_controller.rb @@ -0,0 +1,24 @@ +class LineItemsController < Spree::BaseController + respond_to :json + + def destroy + item = Spree::LineItem.find(params[:id]) + authorize! :destroy, item + destroy_with_lock item + respond_with(item) + end + + # Override default which just redirects + # See Spree::BaseController and Spree::Core::ControllerHelpers::Auth + def unauthorized + render text: '', status: 403 + end + + def destroy_with_lock(item) + order = item.order + order.with_lock do + item.destroy + order.update_distribution_charge! + end + end +end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 3814365447..7642c42405 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -4,6 +4,7 @@ class AbilityDecorator # All abilites are allocated from this initialiser, currently in 5 chunks. # Spree also defines other abilities. def initialize(user) + add_shopping_abilities user add_base_abilities user if is_new_user? user add_enterprise_management_abilities user if can_manage_enterprises? user add_group_management_abilities user if can_manage_groups? user @@ -50,6 +51,12 @@ class AbilityDecorator can_manage_enterprises? user end + def add_shopping_abilities(user) + can [:destroy], Spree::LineItem do |item| + item.andand.order.andand.order_cycle.andand.open? && item.order.user_id == user.id + end + end + # New users can create an enterprise, and gain other permissions from doing this. def add_base_abilities(user) can [:create], Enterprise @@ -184,6 +191,7 @@ class AbilityDecorator can [:admin , :for_line_items], Enterprise can [:admin, :index, :create], Spree::LineItem can [:destroy, :update], Spree::LineItem do |item| + order = item.order user.admin? || user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user) end diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index 954246dd36..cfad66bb6a 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -48,11 +48,11 @@ = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t 'checkout' - %h5{"ng-if" => "Cart.line_items_finalised().present()", style: 'margin-top: 1em'} + %h5{"ng-if" => "Cart.line_items_finalised().length", style: 'margin-top: 1em'} = t '.already_ordered_products' %table %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised()", - "ng-controller" => "LineItemCtrl", "id" => "cart-variant-{{ line_item.variant.id }}"} + "id" => "cart-variant-{{ line_item.variant.id }}"} %td %small %strong diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml index b3f32b1045..2cc33d52aa 100644 --- a/app/views/spree/orders/_bought.html.haml +++ b/app/views/spree/orders/_bought.html.haml @@ -1,4 +1,4 @@ -%div +%div{ng: {controller: "EditOrderCtrl"}} %div %div .row @@ -21,7 +21,7 @@ %tbody - @order.finalised_line_items.each do |line_item| - variant = line_item.variant - %tr.line-item{class: "variant-#{variant.id}"} + %tr.line-item{class: "line-item-#{line_item.id} variant-#{variant.id}"} %td.cart-item-description %div.item-thumb-image @@ -39,3 +39,5 @@ = line_item.display_amount_with_adjustments.to_html unless line_item.quantity.nil? %td.cart-item-delete.text-center + %a.delete{ng: {click: "deleteLineItem(#{line_item.id})"}} + %i.delete.ofn-i_026-trash diff --git a/app/views/spree/orders/_line_item.html.haml b/app/views/spree/orders/_line_item.html.haml index 5976332a18..14219c4e73 100644 --- a/app/views/spree/orders/_line_item.html.haml +++ b/app/views/spree/orders/_line_item.html.haml @@ -35,6 +35,5 @@ = line_item.display_amount_with_adjustments.to_html unless line_item.quantity.nil? %td.cart-item-delete.text-center{"data-hook" => "cart_item_delete"} - {{ quantity }} %a.delete{href: "#", id: "delete_#{dom_id(line_item)}"} %i.delete.ofn-i_026-trash diff --git a/config/routes.rb b/config/routes.rb index 90700d89b0..26a7b85df2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -42,6 +42,8 @@ Openfoodnetwork::Application.routes.draw do end end + resources :line_items, only: [:destroy] + resources :groups, only: [:index, :show] do collection do get :signup diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb new file mode 100644 index 0000000000..4081e1fc86 --- /dev/null +++ b/spec/controllers/line_items_controller_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe LineItemsController do + let(:item) { create(:line_item) } + let(:item_with_oc) do + order_cycle = create(:simple_order_cycle) + item.order.order_cycle = order_cycle + item.order.save + item + end + + it "fails without line item id" do + expect { delete :destroy }.to raise_error + end + + it "denies deletion without order cycle" do + request = { format: :json, id: item } + delete :destroy, request + expect(response.status).to be 403 + expect { item.reload }.to_not raise_error + end + + it "denies deletion without user" do + request = { format: :json, id: item_with_oc } + delete :destroy, request + expect(response.status).to be 403 + expect { item.reload }.to_not raise_error + end + + it "deletes the line item" do + controller.stub spree_current_user: item.order.user + request = { format: :json, id: item_with_oc } + delete :destroy, request + expect(response.status).to be 204 + expect { item.reload }.to raise_error + end +end diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index b604769502..18d1166a72 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -84,5 +84,34 @@ feature "full-page cart", js: true do page.should have_content "Insufficient stock available, only 2 remaining" end end + + context "when ordered in the same order cycle" do + let(:address) { create(:address) } + let(:user) { create(:user, bill_address: address, ship_address: address) } + let!(:prev_order1) { create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor, user: user) } + let!(:prev_order2) { create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor, user: user) } + + before do + order.user = user + order.save + add_product_to_cart order, product_tax + quick_login_as user + visit spree.cart_path + end + + it "shows already ordered line items" do + item1 = prev_order1.line_items.first + item2 = prev_order2.line_items.first + expect(page).to have_content item1.variant.name + expect(page).to have_content item2.variant.name + page.find(".line-item-#{item1.id} a.delete").click + expect(page).to have_no_content item1.variant.name + expect(page).to have_content item2.variant.name + + visit spree.cart_path + expect(page).to have_no_content item1.variant.name + expect(page).to have_content item2.variant.name + end + end end end From d49469a3e6bffc65f34f02694f6f2bbccefb8e29 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 14 Oct 2016 15:50:45 +1100 Subject: [PATCH 020/104] Show bought items only if changes are allowed An enterprise can decide to allow changes to orders in open order cycles. The items of these orders are then displayed in the shopping cart and can be removed on the cart edit page. --- app/helpers/enterprises_helper.rb | 4 ++ app/models/spree/ability_decorator.rb | 2 +- app/models/spree/order_decorator.rb | 4 ++ app/views/shared/menu/_cart.html.haml | 39 ++++++++++--------- app/views/spree/orders/edit.html.haml | 2 +- .../controllers/line_items_controller_spec.rb | 27 +++++++++++-- spec/features/consumer/shopping/cart_spec.rb | 2 + 7 files changed, 55 insertions(+), 25 deletions(-) diff --git a/app/helpers/enterprises_helper.rb b/app/helpers/enterprises_helper.rb index 0e2a630fff..441e8fd763 100644 --- a/app/helpers/enterprises_helper.rb +++ b/app/helpers/enterprises_helper.rb @@ -88,4 +88,8 @@ module EnterprisesHelper def remaining_trial_days(enterprise) distance_of_time_in_words(Time.zone.now, enterprise.shop_trial_start_date + Spree::Config[:shop_trial_length_days].days) end + + def show_bought_items? + current_order.andand.distributor.andand.allow_order_changes? && current_order.finalised_line_items.present? + end end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 7642c42405..b2ceffd1b0 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -53,7 +53,7 @@ class AbilityDecorator def add_shopping_abilities(user) can [:destroy], Spree::LineItem do |item| - item.andand.order.andand.order_cycle.andand.open? && item.order.user_id == user.id + item.andand.order.andand.can_remove_items? user end end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index c76e0d9e45..7b57d2a678 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -270,6 +270,10 @@ Spree::Order.class_eval do Delayed::Job.enqueue ConfirmOrderJob.new(id) unless account_invoice? end + def can_remove_items?(user) + user_id == user.id && distributor.andand.allow_order_changes? && order_cycle.andand.open? + end + private def shipping_address_from_distributor diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index cfad66bb6a..f37e32e728 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -48,23 +48,24 @@ = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t 'checkout' - %h5{"ng-if" => "Cart.line_items_finalised().length", style: 'margin-top: 1em'} - = t '.already_ordered_products' - %table - %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised()", - "id" => "cart-variant-{{ line_item.variant.id }}"} - %td - %small - %strong - {{ line_item.variant.extended_name }} - %td.text-right - %small - %span.quantity {{ line_item.quantity }} - %i.ofn-i_009-close - %span.price {{ line_item.variant.price_with_fees | localizeCurrency }} + - if show_bought_items? + %h5{"ng-if" => "Cart.line_items_finalised().length", style: 'margin-top: 1em'} + = t '.already_ordered_products' + %table + %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised()", + "id" => "cart-variant-{{ line_item.variant.id }}"} + %td + %small + %strong + {{ line_item.variant.extended_name }} + %td.text-right + %small + %span.quantity {{ line_item.quantity }} + %i.ofn-i_009-close + %span.price {{ line_item.variant.price_with_fees | localizeCurrency }} - %td - %small - \= - %strong - .total-price.right {{ line_item.total_price | localizeCurrency }} + %td + %small + \= + %strong + .total-price.right {{ line_item.total_price | localizeCurrency }} diff --git a/app/views/spree/orders/edit.html.haml b/app/views/spree/orders/edit.html.haml index 4dec61523a..58124ffa71 100644 --- a/app/views/spree/orders/edit.html.haml +++ b/app/views/spree/orders/edit.html.haml @@ -44,6 +44,6 @@ = t :orders_edit_checkout %i.ofn-i_007-caret-right - = render 'bought' if @order.finalised_line_items.present? + = render 'bought' if show_bought_items? = render partial: "shared/footer" diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 4081e1fc86..4d5cfb1801 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -4,10 +4,18 @@ describe LineItemsController do let(:item) { create(:line_item) } let(:item_with_oc) do order_cycle = create(:simple_order_cycle) + distributor = create(:distributor_enterprise) item.order.order_cycle = order_cycle + item.order.distributor = distributor item.order.save item end + let(:distributor) do + distributor = create(:distributor_enterprise) + item.order.distributor = distributor + item.order.save + distributor + end it "fails without line item id" do expect { delete :destroy }.to raise_error @@ -16,22 +24,33 @@ describe LineItemsController do it "denies deletion without order cycle" do request = { format: :json, id: item } delete :destroy, request - expect(response.status).to be 403 + expect(response.status).to eq 403 expect { item.reload }.to_not raise_error end it "denies deletion without user" do request = { format: :json, id: item_with_oc } delete :destroy, request - expect(response.status).to be 403 + expect(response.status).to eq 403 expect { item.reload }.to_not raise_error end - it "deletes the line item" do + it "denies deletion if editing is not allowed" do controller.stub spree_current_user: item.order.user request = { format: :json, id: item_with_oc } delete :destroy, request - expect(response.status).to be 204 + expect(response.status).to eq 403 + expect { item.reload }.to_not raise_error + end + + it "deletes the line item if allowed" do + controller.stub spree_current_user: item.order.user + distributor = item_with_oc.order.distributor + distributor.allow_order_changes = true + distributor.save + request = { format: :json, id: item_with_oc } + delete :destroy, request + expect(response.status).to eq 204 expect { item.reload }.to raise_error end end diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index 18d1166a72..cc808d7116 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -94,6 +94,8 @@ feature "full-page cart", js: true do before do order.user = user order.save + order.distributor.allow_order_changes = true + order.distributor.save add_product_to_cart order, product_tax quick_login_as user visit spree.cart_path From a7d8028d5a420830a66385ea0d4c667b5e3e24a9 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 14 Oct 2016 16:04:16 +1100 Subject: [PATCH 021/104] Add `retry: 3` to intermittently failing spec --- spec/features/consumer/shopping/checkout_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index d9c9e8bf8f..18360b806a 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -402,7 +402,7 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do o.save! end - it "checks out successfully" do + it "checks out successfully", retry: 3 do visit checkout_path checkout_as_guest choose sm2.name From 219ad4a3a7604f050044c2494838616072981b31 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 4 Nov 2016 15:38:17 +1100 Subject: [PATCH 022/104] Reload bought products after choosing order cycle --- .../order_cycle_controller.js.coffee | 1 + .../darkswarm/services/cart.js.coffee | 21 +++++++++------ app/controllers/line_items_controller.rb | 14 +++++++++- app/helpers/enterprises_helper.rb | 2 +- app/models/order_cycle.rb | 12 +++++++++ app/models/spree/order_decorator.rb | 13 ++-------- app/views/shared/menu/_cart.html.haml | 4 +-- config/routes.rb | 2 +- .../controllers/line_items_controller_spec.rb | 16 ++++++++---- .../consumer/shopping/shopping_spec.rb | 26 +++++++++++++++++++ 10 files changed, 82 insertions(+), 29 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee index 42d4c1c44d..79c826165c 100644 --- a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee @@ -30,3 +30,4 @@ Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Prod Variants.clear() Cart.clear() Products.update() + Cart.reloadFinalisedLineItems() diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index 9ad375f873..690f31deef 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, localStorageService)-> +Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, $resource, localStorageService) -> # Handles syncing of current cart/order state to server new class Cart dirty: false @@ -6,11 +6,15 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo update_enqueued: false order: CurrentOrder.order line_items: CurrentOrder.order?.line_items || [] + line_items_finalised: CurrentOrder.order?.finalised_line_items || [] constructor: -> for line_item in @line_items line_item.variant.line_item = line_item Variants.register line_item.variant + for line_item in @line_items_finalised + line_item.variant.line_item = line_item + Variants.extend line_item.variant adjust: (line_item) => line_item.total_price = line_item.variant.price_with_fees * line_item.quantity @@ -97,13 +101,6 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo $(window).bind "beforeunload", -> t 'order_not_saved_yet' - line_items_finalised: => - items = CurrentOrder.order?.finalised_line_items || [] - for line_item in items - line_item.variant.line_item = line_item - Variants.extend line_item.variant - items - total_item_count: => @line_items.reduce (sum,li) -> sum = sum + li.quantity @@ -122,3 +119,11 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo clear: -> @line_items = [] localStorageService.clearAll() # One day this will have to be moar GRANULAR + + reloadFinalisedLineItems: => + @line_items_finalised = [] + $resource("/line_items").query (items) => + for line_item in items + line_item.variant.line_item = line_item + Variants.extend line_item.variant + @line_items_finalised = items diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index 5846538411..c00d3380d5 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -1,6 +1,10 @@ -class LineItemsController < Spree::BaseController +class LineItemsController < BaseController respond_to :json + def index + respond_with bought_items, each_serializer: Api::LineItemSerializer + end + def destroy item = Spree::LineItem.find(params[:id]) authorize! :destroy, item @@ -8,6 +12,14 @@ class LineItemsController < Spree::BaseController respond_with(item) end + private + + # List all items the user already ordered in the current order cycle + def bought_items + return [] unless current_order_cycle && spree_current_user && current_distributor + current_order_cycle.items_bought_by_user(spree_current_user, current_distributor) + end + # Override default which just redirects # See Spree::BaseController and Spree::Core::ControllerHelpers::Auth def unauthorized diff --git a/app/helpers/enterprises_helper.rb b/app/helpers/enterprises_helper.rb index 441e8fd763..c20ac636cf 100644 --- a/app/helpers/enterprises_helper.rb +++ b/app/helpers/enterprises_helper.rb @@ -90,6 +90,6 @@ module EnterprisesHelper end def show_bought_items? - current_order.andand.distributor.andand.allow_order_changes? && current_order.finalised_line_items.present? + current_order.andand.distributor.andand.allow_order_changes? end end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 894cbac7f7..ed07eda927 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -250,6 +250,18 @@ class OrderCycle < ActiveRecord::Base OpenFoodNetwork::ProductsCache.order_cycle_changed self end + def items_bought_by_user(user, distributor) + orders = Spree::Order.complete.where(user_id: user, order_cycle_id: self) + items = [] + orders.each do |o| + items += o.line_items + end + scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) + items.each do |li| + scoper.scope(li.variant) + end + items + end private diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 7b57d2a678..f0b1a906ac 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -195,17 +195,8 @@ Spree::Order.class_eval do # Show already bought line items of this order cycle def finalised_line_items - return [] unless order_cycle && user - orders = self.class.complete.where(user_id: user, order_cycle_id: order_cycle) - items = [] - orders.each do |o| - items += o.line_items - end - scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) - items.each do |li| - scoper.scope(li.variant) - end - items + return [] unless order_cycle && user && distributor + order_cycle.items_bought_by_user(user, distributor) end def admin_and_handling_total diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index f37e32e728..b678c17152 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -49,10 +49,10 @@ %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t 'checkout' - if show_bought_items? - %h5{"ng-if" => "Cart.line_items_finalised().length", style: 'margin-top: 1em'} + %h5{"ng-if" => "Cart.line_items_finalised.length", style: 'margin-top: 1em'} = t '.already_ordered_products' %table - %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised()", + %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items_finalised", "id" => "cart-variant-{{ line_item.variant.id }}"} %td %small diff --git a/config/routes.rb b/config/routes.rb index 26a7b85df2..ad47a68149 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -42,7 +42,7 @@ Openfoodnetwork::Application.routes.draw do end end - resources :line_items, only: [:destroy] + resources :line_items, only: [:index, :destroy] resources :groups, only: [:index, :show] do collection do diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 4d5cfb1801..ae34c328b9 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -10,11 +10,17 @@ describe LineItemsController do item.order.save item end - let(:distributor) do - distributor = create(:distributor_enterprise) - item.order.distributor = distributor - item.order.save - distributor + + it "lists bought items" do + item.order.finalize! + controller.stub spree_current_user: item.order.user + controller.stub current_order_cycle: item_with_oc.order.order_cycle + controller.stub current_distributor: item_with_oc.order.distributor + get :index, { format: :json } + expect(response.status).to eq 200 + json_response = JSON.parse(response.body) + expect(json_response.length).to eq 1 + expect(json_response[0]['id']).to eq item.id end it "fails without line item id" do diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index e11f929f6a..6c9a78671a 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -137,6 +137,32 @@ feature "As a consumer I want to shop with a distributor", js: true do end end end + + context "when logged in" do + let!(:prev_order) { create(:completed_order_with_totals, order_cycle: oc1, distributor: distributor, user: order.user) } + + before do + distributor.allow_order_changes = true + distributor.save + quick_login_as order.user + visit shop_path + end + + it "shows previous orders if order cycle was selected already" do + select "frogs", from: "order_cycle_id" + expect(page).to have_content "Next order closing in 2 days" + visit shop_path + find("#cart").click + expect(page).to have_text(I18n.t("shared.menu.cart.already_ordered_products")) + end + + it "shows previous orders after selecting an order cycle" do + select "frogs", from: "order_cycle_id" + expect(page).to have_content "Next order closing in 2 days" + find("#cart").click + expect(page).to have_text(I18n.t("shared.menu.cart.already_ordered_products")) + end + end end end From bf05866f92f5dcbc574794d4dfcd04bf2a42a492 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 4 Nov 2016 16:23:49 +1100 Subject: [PATCH 023/104] Change headline of already ordered items --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 56555261cd..03832b9959 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1590,7 +1590,7 @@ Please follow the instructions there to make your enterprise visible on the Open zipcode: Postcode orders: bought: - item: "Already bought item" + item: "Already ordered in this order cycle" shipment_states: backorder: backorder partial: partial From 3bce2eb7b5fb734d2faeabb21d8f088cc4cfcb5f Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 9 Nov 2016 11:34:55 +1100 Subject: [PATCH 024/104] Rename translation key `checkout` to avoid conflicts A top-level translation key `checkout` can't co-exist with translation keys in the path `checkout`. Moving the old key to `shared.menu.cart.checkout` avoids conflicts. It also structures the locale better by view. --- app/views/shared/menu/_cart.html.haml | 4 ++-- config/locales/en.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index b678c17152..0cbe12b917 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -15,7 +15,7 @@ %a.button.secondary.tiny.add_to_cart{ href: cart_path, type: :submit, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }" } = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} - = t 'checkout' + = t '.checkout' %table %tr.product-cart{"ng-repeat" => "line_item in Cart.line_items", "id" => "cart-variant-{{ line_item.variant.id }}"} %td @@ -47,7 +47,7 @@ %a.button.secondary.tiny.add_to_cart{ href: cart_path, type: :submit, "ng-disabled" => "Cart.dirty || Cart.empty()", "ng-class" => "{ dirty: Cart.dirty }" } = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} - = t 'checkout' + = t '.checkout' - if show_bought_items? %h5{"ng-if" => "Cart.line_items_finalised.length", style: 'margin-top: 1em'} = t '.already_ordered_products' diff --git a/config/locales/en.yml b/config/locales/en.yml index 03832b9959..3a421a192d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -558,6 +558,7 @@ en: shared: menu: cart: + checkout: "Checkout now" already_ordered_products: "Already ordered in this order cycle" register_call: selling_on_ofn: "Interested in getting on the Open Food Network?" @@ -656,7 +657,6 @@ en: items: "items" cart_headline: "Your shopping cart" total: "Total" - checkout: "Checkout now" cart_updating: "Updating cart..." cart_empty: "Cart empty" cart_edit: "Edit your cart" From f3f67144723b5c730225584dcfca6041bba35d09 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 9 Nov 2016 12:50:53 +1100 Subject: [PATCH 025/104] Add message about previous orders on checkout page The message appears if the user ordered before within the same order cycle and the shop allows to change previous orders. --- app/helpers/enterprises_helper.rb | 6 +++++- app/views/checkout/_already_ordered.html.haml | 2 ++ app/views/checkout/_form.html.haml | 1 + app/views/shared/menu/_cart.html.haml | 2 +- config/locales/en.yml | 9 +++++++++ .../consumer/shopping/checkout_spec.rb | 18 ++++++++++++++++++ 6 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 app/views/checkout/_already_ordered.html.haml diff --git a/app/helpers/enterprises_helper.rb b/app/helpers/enterprises_helper.rb index c20ac636cf..5987b20475 100644 --- a/app/helpers/enterprises_helper.rb +++ b/app/helpers/enterprises_helper.rb @@ -89,7 +89,11 @@ module EnterprisesHelper distance_of_time_in_words(Time.zone.now, enterprise.shop_trial_start_date + Spree::Config[:shop_trial_length_days].days) end - def show_bought_items? + def order_changes_allowed? current_order.andand.distributor.andand.allow_order_changes? end + + def show_bought_items? + order_changes_allowed? && current_order.finalised_line_items.present? + end end diff --git a/app/views/checkout/_already_ordered.html.haml b/app/views/checkout/_already_ordered.html.haml new file mode 100644 index 0000000000..1327365a2f --- /dev/null +++ b/app/views/checkout/_already_ordered.html.haml @@ -0,0 +1,2 @@ +%p.alert-box.info + = t '.message_html', cart: link_to(t('.cart'), cart_path) diff --git a/app/views/checkout/_form.html.haml b/app/views/checkout/_form.html.haml index 65ed90b069..42f31f4a35 100644 --- a/app/views/checkout/_form.html.haml +++ b/app/views/checkout/_form.html.haml @@ -11,6 +11,7 @@ = render "checkout/billing", f: f = render "checkout/shipping", f: f = render "checkout/payment", f: f + = render "checkout/already_ordered", f: f if show_bought_items? %p %button.button.primary{type: :submit} = t :checkout_send diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index 0cbe12b917..37c67fd067 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -48,7 +48,7 @@ = "{{ Cart.dirty ? '#{t(:cart_updating)}' : (Cart.empty() ? '#{t(:cart_empty)}' : '#{t(:cart_edit)}' ) }}" %a.button.primary.tiny{href: checkout_path, "ng-disabled" => "Cart.dirty || Cart.empty()"} = t '.checkout' - - if show_bought_items? + - if order_changes_allowed? %h5{"ng-if" => "Cart.line_items_finalised.length", style: 'margin-top: 1em'} = t '.already_ordered_products' %table diff --git a/config/locales/en.yml b/config/locales/en.yml index 3a421a192d..92944c9298 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -550,6 +550,15 @@ en: invoice_style2?: Use the alternative invoice model that includes total tax breakdown per rate and tax rate info per item (not yet suitable for countries displaying prices excluding tax) enable_receipt_printing?: Show options for printing receipts using thermal printers in order dropdown? +# Frontend views +# +# These keys are referenced relatively like `t('.message')` in +# app/views/checkout/_already_ordered.html.haml. +# + checkout: + already_ordered: + cart: "cart" + message_html: "You have an order for this order cycle already. Check the %{cart} to see the items you ordered before. You can also cancel items as long as the order cycle is open." home: hubs: show_closed_shops: "Show closed shops" diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index 18360b806a..da846bae88 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -113,6 +113,24 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do user.reload.bill_address.address1.should eq '123 Your Head' user.reload.ship_address.address1.should eq '123 Your Head' end + + it "it doesn't tell about previous orders" do + expect(page).to_not have_content("You have an order for this order cycle already.") + end + + context "with previous orders" do + let!(:prev_order) { create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor, user: order.user) } + + before do + order.distributor.allow_order_changes = true + order.distributor.save + end + + it "informs about previous orders" do + visit checkout_path + expect(page).to have_content("You have an order for this order cycle already.") + end + end end context "on the checkout page" do From 936df71d0dd37273b1d76fd5ad4a52326cc2af94 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 7 Dec 2016 15:04:55 +1100 Subject: [PATCH 026/104] Link to bought products on cart page The checkout page was just linking to the cart page, but not scrolling down. --- app/views/checkout/_already_ordered.html.haml | 2 +- app/views/spree/orders/_bought.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/checkout/_already_ordered.html.haml b/app/views/checkout/_already_ordered.html.haml index 1327365a2f..01c4265252 100644 --- a/app/views/checkout/_already_ordered.html.haml +++ b/app/views/checkout/_already_ordered.html.haml @@ -1,2 +1,2 @@ %p.alert-box.info - = t '.message_html', cart: link_to(t('.cart'), cart_path) + = t '.message_html', cart: link_to(t('.cart'), "#{cart_path}#bought-products") diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml index 2cc33d52aa..b503c4e33f 100644 --- a/app/views/spree/orders/_bought.html.haml +++ b/app/views/spree/orders/_bought.html.haml @@ -1,4 +1,4 @@ -%div{ng: {controller: "EditOrderCtrl"}} +%div#bought-products{ng: {controller: "EditOrderCtrl"}} %div %div .row From 811671661ec651371625baba6e7687d21cf2cdbe Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 8 Dec 2016 13:03:12 +1100 Subject: [PATCH 027/104] Remove item from dropdown cart after deletion --- .../darkswarm/controllers/edit_order_controller.js.coffee | 1 + app/assets/javascripts/darkswarm/services/cart.js.coffee | 4 ++++ spec/features/consumer/shopping/cart_spec.rb | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee index e39b79c48b..84c5460300 100644 --- a/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee @@ -4,6 +4,7 @@ Darkswarm.controller "EditOrderCtrl", ($scope, $resource, Cart) -> params = {id: id} success = (response) -> $(".line-item-" + id).remove() + Cart.removeFinalisedLineItem(id) fail = (error) -> console.log error diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index 690f31deef..b80d9a14dd 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -120,6 +120,10 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo @line_items = [] localStorageService.clearAll() # One day this will have to be moar GRANULAR + removeFinalisedLineItem: (id) => + @line_items_finalised = @line_items_finalised.filter (item) -> + item.id != id + reloadFinalisedLineItems: => @line_items_finalised = [] $resource("/line_items").query (items) => diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index cc808d7116..6a213ddec6 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -110,6 +110,11 @@ feature "full-page cart", js: true do expect(page).to have_no_content item1.variant.name expect(page).to have_content item2.variant.name + # open the dropdown cart and check there as well + find('#cart').click + expect(page).to have_no_content item1.variant.name + expect(page).to have_content item2.variant.name + visit spree.cart_path expect(page).to have_no_content item1.variant.name expect(page).to have_content item2.variant.name From 1f08729df34b6b89da859502797655a52427b8d0 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 15 Dec 2016 14:50:06 +1100 Subject: [PATCH 028/104] Update shipping fees after removing item After removing an item from a completed order, update the shipping fees of all shipments that are pending or ready (not completed). --- app/controllers/line_items_controller.rb | 1 + app/models/spree/order_decorator.rb | 15 +++++++ .../controllers/line_items_controller_spec.rb | 23 +++++++++++ spec/factories.rb | 41 ++++++++++++++++++- spec/models/spree/order_spec.rb | 25 +++++++++++ 5 files changed, 104 insertions(+), 1 deletion(-) diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index c00d3380d5..004f511bb5 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -30,6 +30,7 @@ class LineItemsController < BaseController order = item.order order.with_lock do item.destroy + order.update_shipping_fees! order.update_distribution_charge! end end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index f0b1a906ac..e31745ba83 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -139,6 +139,21 @@ Spree::Order.class_eval do current_item end + # After changing line items of a completed order + def update_shipping_fees! + line_items(:reload) + shipments.each do |shipment| + next if shipment.shipped? + adjustment = shipment.adjustment + locked = adjustment.locked + adjustment.locked = false + adjustment.update! + adjustment.locked = locked + update_totals + save + end + end + def cap_quantity_at_stock! line_items.each &:cap_quantity_at_stock! end diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index ae34c328b9..5df2131d06 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -59,4 +59,27 @@ describe LineItemsController do expect(response.status).to eq 204 expect { item.reload }.to raise_error end + + it "updates fees" do + distributor = create(:distributor_enterprise, allow_order_changes: true) + shipping_fee = 3 + payment_fee = 5 + order = create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) + + # Sanity check fees + item_num = order.line_items.length + expected_fees = item_num * (shipping_fee + payment_fee) + expect(order.adjustment_total).to eq expected_fees + + # Delete the item + item = order.line_items.first + controller.stub spree_current_user: order.user + request = { format: :json, id: item } + delete :destroy, request + expect(response.status).to eq 204 + + # Check the fees again + order.reload + expect(order.adjustment_total).to eq expected_fees - shipping_fee + end end diff --git a/spec/factories.rb b/spec/factories.rb index d4193c11aa..5f1a0ae7b9 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,6 +1,20 @@ require 'ffaker' require 'spree/core/testing_support/factories' +# http://www.rubydoc.info/gems/factory_girl/file/GETTING_STARTED.md +# +# The spree_core gem defines factories in several files. For example: +# +# - lib/spree/core/testing_support/factories/calculator_factory.rb +# * calculator +# * no_amount_calculator +# +# - lib/spree/core/testing_support/factories/order_factory.rb +# * order +# * order_with_totals +# * order_with_inventory_unit_shipped +# * completed_order_with_totals +# FactoryGirl.define do factory :classification, class: Spree::Classification do end @@ -171,6 +185,10 @@ FactoryGirl.define do end sequence(:calculator_amount) + factory :calculator_per_item, class: Spree::Calculator::PerItem do + preferred_amount { generate(:calculator_amount) } + end + factory :enterprise_fee, :class => EnterpriseFee do ignore { amount nil } @@ -178,7 +196,7 @@ FactoryGirl.define do sequence(:fee_type) { |n| EnterpriseFee::FEE_TYPES[n % EnterpriseFee::FEE_TYPES.count] } enterprise { Enterprise.first || FactoryGirl.create(:supplier_enterprise) } - calculator { Spree::Calculator::PerItem.new(preferred_amount: amount || generate(:calculator_amount)) } + calculator { build(:calculator_per_item, preferred_amount: amount) } after(:create) { |ef| ef.calculator.save! } end @@ -237,6 +255,27 @@ FactoryGirl.define do end end + factory :completed_order_with_fees, parent: :order_with_totals_and_distribution do + ignore do + shipping_fee 3 + payment_fee 5 + end + + shipping_method do + shipping_calculator = build(:calculator_per_item, preferred_amount: shipping_fee) + create(:shipping_method, calculator: shipping_calculator, require_ship_address: false) + end + + after(:create) do |order, evaluator| + create(:line_item, order: order) + order.create_shipment! + payment_calculator = build(:calculator_per_item, preferred_amount: evaluator.payment_fee) + payment_method = create(:payment_method, calculator: payment_calculator) + create(:payment, order: order, amount: order.total, payment_method: payment_method, state: 'completed') + order.finalize! + end + end + factory :zone_with_member, :parent => :zone do default_tax true diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 1b81f6ba0b..74418c6642 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -651,6 +651,31 @@ describe Spree::Order do end end + describe "a completed order with shipping and transaction fees" do + let(:distributor) { create(:distributor_enterprise, allow_order_changes: true) } + let(:order) { create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) } + let(:shipping_fee) { 3 } + let(:payment_fee) { 5 } + + it "updates shipping fees" do + # Sanity check the fees + expect(order.adjustments.length).to eq 2 + item_num = order.line_items.length + expect(item_num).to eq 2 + expected_fees = item_num * (shipping_fee + payment_fee) + expect(order.adjustment_total).to eq expected_fees + + # Delete the item + order.line_items.first.destroy + order.update_shipping_fees! + + # Check if fees got updated + expect(order.adjustments.length).to eq 2 + expect(order.line_items.length).to eq item_num - 1 + expect(order.adjustment_total).to eq expected_fees - shipping_fee + end + end + describe "retrieving previously ordered items" do let(:distributor) { create(:distributor_enterprise) } let(:order_cycle) { create(:simple_order_cycle) } From 479c7ba24be05afd74a7d7f9827abe3a43831ea3 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 16 Dec 2016 15:33:49 +1100 Subject: [PATCH 029/104] Update transaction fees of completed orders The adjustments associated to incomplete payments are re-calculated when a line item is removed from a completed order. --- app/controllers/line_items_controller.rb | 1 + app/models/spree/order_decorator.rb | 29 ++++++++++++++----- .../controllers/line_items_controller_spec.rb | 6 ++-- spec/factories.rb | 2 +- spec/models/spree/order_spec.rb | 14 +++++++++ 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index 004f511bb5..0459ae9351 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -31,6 +31,7 @@ class LineItemsController < BaseController order.with_lock do item.destroy order.update_shipping_fees! + order.update_payment_fees! order.update_distribution_charge! end end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index e31745ba83..4a746cd856 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -144,14 +144,22 @@ Spree::Order.class_eval do line_items(:reload) shipments.each do |shipment| next if shipment.shipped? - adjustment = shipment.adjustment - locked = adjustment.locked - adjustment.locked = false - adjustment.update! - adjustment.locked = locked - update_totals - save + update_adjustment! shipment.adjustment end + update_totals + save + end + + # After changing line items of a completed order + def update_payment_fees! + payments(:reload) + line_items(:reload) + payments.each do |payment| + next if payment.completed? + update_adjustment! payment.adjustment + end + update_totals + save end def cap_quantity_at_stock! @@ -333,4 +341,11 @@ Spree::Order.class_eval do self.customer = Customer.create(enterprise: distributor, email: email_for_customer, user: user, name: customer_name, bill_address: bill_address.andand.clone, ship_address: ship_address.andand.clone) end end + + def update_adjustment!(adjustment) + locked = adjustment.locked + adjustment.locked = false + adjustment.update! + adjustment.locked = locked + end end diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 5df2131d06..dc566bbafa 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -68,8 +68,8 @@ describe LineItemsController do # Sanity check fees item_num = order.line_items.length - expected_fees = item_num * (shipping_fee + payment_fee) - expect(order.adjustment_total).to eq expected_fees + initial_fees = item_num * (shipping_fee + payment_fee) + expect(order.adjustment_total).to eq initial_fees # Delete the item item = order.line_items.first @@ -80,6 +80,6 @@ describe LineItemsController do # Check the fees again order.reload - expect(order.adjustment_total).to eq expected_fees - shipping_fee + expect(order.adjustment_total).to eq initial_fees - shipping_fee - payment_fee end end diff --git a/spec/factories.rb b/spec/factories.rb index 5f1a0ae7b9..4c3cc67ebd 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -271,7 +271,7 @@ FactoryGirl.define do order.create_shipment! payment_calculator = build(:calculator_per_item, preferred_amount: evaluator.payment_fee) payment_method = create(:payment_method, calculator: payment_calculator) - create(:payment, order: order, amount: order.total, payment_method: payment_method, state: 'completed') + create(:payment, order: order, amount: order.total, payment_method: payment_method, state: 'checkout') order.finalize! end end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 74418c6642..6a005362c1 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -674,6 +674,20 @@ describe Spree::Order do expect(order.line_items.length).to eq item_num - 1 expect(order.adjustment_total).to eq expected_fees - shipping_fee end + + it "updates transaction fees" do + item_num = order.line_items.length + initial_fees = item_num * (shipping_fee + payment_fee) + + # Delete the item + order.line_items.first.destroy + order.update_payment_fees! + + # Check if fees got updated + expect(order.adjustments.length).to eq 2 + expect(order.line_items.length).to eq item_num - 1 + expect(order.adjustment_total).to eq initial_fees - payment_fee + end end describe "retrieving previously ordered items" do From db4a528ba3edf26ba52399578db7ab7d55e6d3c4 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 22 Dec 2016 13:26:11 +1100 Subject: [PATCH 030/104] Update shipment to re-calculate included tax And re-create tax charges on the order. (untested) --- app/controllers/line_items_controller.rb | 1 + app/models/spree/order_decorator.rb | 1 + spec/controllers/line_items_controller_spec.rb | 7 ++++++- spec/models/spree/order_spec.rb | 9 ++++++++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index 0459ae9351..04fe14fc30 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -33,6 +33,7 @@ class LineItemsController < BaseController order.update_shipping_fees! order.update_payment_fees! order.update_distribution_charge! + order.create_tax_charge! end end end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 4a746cd856..a3fa3586d0 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -145,6 +145,7 @@ Spree::Order.class_eval do shipments.each do |shipment| next if shipment.shipped? update_adjustment! shipment.adjustment + shipment.save # updates included tax end update_totals save diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index dc566bbafa..2fcaf00d30 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -61,7 +61,9 @@ describe LineItemsController do end it "updates fees" do - distributor = create(:distributor_enterprise, allow_order_changes: true) + Spree::Config.shipment_inc_vat = true + Spree::Config.shipping_tax_rate = 0.25 + distributor = create(:distributor_enterprise, charges_sales_tax: true, allow_order_changes: true) shipping_fee = 3 payment_fee = 5 order = create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) @@ -70,6 +72,7 @@ describe LineItemsController do item_num = order.line_items.length initial_fees = item_num * (shipping_fee + payment_fee) expect(order.adjustment_total).to eq initial_fees + expect(order.shipment.adjustment.included_tax).to eq 1.2 # Delete the item item = order.line_items.first @@ -80,6 +83,8 @@ describe LineItemsController do # Check the fees again order.reload + order.shipment.reload expect(order.adjustment_total).to eq initial_fees - shipping_fee - payment_fee + expect(order.shipment.adjustment.included_tax).to eq 0.6 end end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 6a005362c1..763f7dd6c4 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -652,11 +652,16 @@ describe Spree::Order do end describe "a completed order with shipping and transaction fees" do - let(:distributor) { create(:distributor_enterprise, allow_order_changes: true) } + let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true, allow_order_changes: true) } let(:order) { create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) } let(:shipping_fee) { 3 } let(:payment_fee) { 5 } + before do + Spree::Config.shipment_inc_vat = true + Spree::Config.shipping_tax_rate = 0.25 + end + it "updates shipping fees" do # Sanity check the fees expect(order.adjustments.length).to eq 2 @@ -664,6 +669,7 @@ describe Spree::Order do expect(item_num).to eq 2 expected_fees = item_num * (shipping_fee + payment_fee) expect(order.adjustment_total).to eq expected_fees + expect(order.shipment.adjustment.included_tax).to eq 1.2 # Delete the item order.line_items.first.destroy @@ -673,6 +679,7 @@ describe Spree::Order do expect(order.adjustments.length).to eq 2 expect(order.line_items.length).to eq item_num - 1 expect(order.adjustment_total).to eq expected_fees - shipping_fee + expect(order.shipment.adjustment.included_tax).to eq 0.6 end it "updates transaction fees" do From 12a6f652ada947cf17324c4e6315a7c82c106856 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 6 Jan 2017 16:32:38 +1100 Subject: [PATCH 031/104] Warn when allowing guest orders and order changes --- .../stylesheets/admin/enterprises.css.scss | 3 +++ .../api/admin/enterprise_serializer.rb | 2 +- .../form/_shop_preferences.html.haml | 22 ++++++++++++------- config/locales/en.yml | 1 + 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 app/assets/stylesheets/admin/enterprises.css.scss diff --git a/app/assets/stylesheets/admin/enterprises.css.scss b/app/assets/stylesheets/admin/enterprises.css.scss new file mode 100644 index 0000000000..5768ebaf27 --- /dev/null +++ b/app/assets/stylesheets/admin/enterprises.css.scss @@ -0,0 +1,3 @@ +form[name="enterprise_form"] div.row.warning { + color: #DA7F52; +} diff --git a/app/serializers/api/admin/enterprise_serializer.rb b/app/serializers/api/admin/enterprise_serializer.rb index 9fd20c1d78..c9b4c50aa1 100644 --- a/app/serializers/api/admin/enterprise_serializer.rb +++ b/app/serializers/api/admin/enterprise_serializer.rb @@ -4,7 +4,7 @@ class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer attributes :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order attributes :preferred_product_selection_from_inventory_only attributes :owner, :users, :tag_groups, :default_tag_group - attributes :require_login + attributes :require_login, :allow_guest_orders, :allow_order_changes has_one :owner, serializer: Api::Admin::UserSerializer has_many :users, serializer: Api::Admin::UserSerializer diff --git a/app/views/admin/enterprises/form/_shop_preferences.html.haml b/app/views/admin/enterprises/form/_shop_preferences.html.haml index 066f8a5fe3..c34fbdfe54 100644 --- a/app/views/admin/enterprises/form/_shop_preferences.html.haml +++ b/app/views/admin/enterprises/form/_shop_preferences.html.haml @@ -51,12 +51,18 @@ %label= t '.allow_guest_orders' %div{'ofn-with-tip' => t('.allow_guest_orders_tip')} %a= t 'admin.whats_this' - .three.columns - = f.radio_button :allow_guest_orders, true - = f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true - .five.columns.omega - = f.radio_button :allow_guest_orders, false - = f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false + .eight.columns.omega + .row + .three.columns.alpha + = f.radio_button :allow_guest_orders, true, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "true" + = f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true + .five.columns.omega + = f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false" + = f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false + .row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}} + .eight.columns.alpha.omega + %i.icon-warning-sign + = t '.recommend_require_login' .row .alpha.eleven.columns .three.columns.alpha @@ -64,8 +70,8 @@ %div{'ofn-with-tip' => t('.allow_order_changes_tip')} %a= t 'admin.whats_this' .three.columns - = f.radio_button :allow_order_changes, false + = f.radio_button :allow_order_changes, false, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "false" = f.label :allow_order_changes, t('.allow_order_changes_false'), value: :false .five.columns.omega - = f.radio_button :allow_order_changes, true + = f.radio_button :allow_order_changes, true, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "true" = f.label :allow_order_changes, t('.allow_order_changes_true'), value: :true diff --git a/config/locales/en.yml b/config/locales/en.yml index 92944c9298..4abb72d108 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -391,6 +391,7 @@ en: shopfront_requires_login_tip: "Choose whether customers must login to view the shopfront or if it's visible to everybody." shopfront_requires_login_false: "Public" shopfront_requires_login_true: "Visible to registered customers only" + recommend_require_login: "We recommend to require users to login when orders can be changed." allow_guest_orders: "Guest orders" allow_guest_orders_tip: "Allow checkout as guest or require a registered user." allow_guest_orders_false: "Require login to order" From 630b8a257757b461811612483d512c31ada97f5c Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 29 Mar 2017 17:01:28 +1100 Subject: [PATCH 032/104] Add OrdersController#order_to_update method, to allow updating a complete order where appropriate --- .../spree/orders_controller_decorator.rb | 6 +++ .../spree/orders_controller_spec.rb | 52 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index dd4f2eba81..155e89ab5b 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -202,4 +202,10 @@ Spree::OrdersController.class_eval do def wrap_json_infinity(n) n == Float::INFINITY ? 2147483647 : n end + + def order_to_update + order = Spree::Order.complete.find_by_id(params[:order].andand[:id]) + return order if order.present? && can?(:update, order) + current_order + end end diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index 74e9efaaf9..a1bbe96b70 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -191,6 +191,58 @@ describe Spree::OrdersController do end end + describe "#order_to_update" do + let!(:current_order) { double(:current_order) } + let!(:order) { create(:order) } + let(:li) { order.line_items.first } + let(:params) { { order: {} } } + + before do + allow(controller).to receive(:current_order) { current_order } + allow(controller).to receive(:params) { params } + end + + context "when no order id is given in params" do + it "returns the current_order" do + expect(controller.send(:order_to_update)).to eq current_order + end + end + + context "when an order_id is given in params" do + before do + params[:order].merge!({id: order.id}) + end + + context "and the order is not complete" do + it "returns the current_order" do + expect(controller.send(:order_to_update)).to eq current_order + end + end + + context "and the order is complete" do + before do + allow(Spree::Order).to receive(:complete) { Spree::Order.where(id: order.id) } + end + + context "and the user doesn't have permisson to 'update' the order" do + before { allow(controller).to receive(:can?).with(:update, order) { false } } + + it "returns the current_order" do + expect(controller.send(:order_to_update)).to eq current_order + end + end + + context "and the user has permission to 'update' the order" do + before { allow(controller).to receive(:can?).with(:update, order) { true } } + + it "returns the order" do + expect(controller.send(:order_to_update)).to eq order + end + end + end + end + end + private From 5af86685608a744f8ea6acd38e227dd16122d6f4 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 30 Mar 2017 12:19:43 +1100 Subject: [PATCH 033/104] Rewriting Spree::Taxons.distributed_taxons for better performance --- app/models/spree/taxon_decorator.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/models/spree/taxon_decorator.rb b/app/models/spree/taxon_decorator.rb index 1878a20e49..fcc71a92dc 100644 --- a/app/models/spree/taxon_decorator.rb +++ b/app/models/spree/taxon_decorator.rb @@ -37,13 +37,14 @@ Spree::Taxon.class_eval do # # Format: {enterprise_id => [taxon_id, ...]} def self.distributed_taxons(which_taxons=:all) - # TODO: Why can't we merge(Spree::Product.with_order_cycles_inner) here? - taxons = Spree::Taxon. - joins(products: {variants_including_master: {exchanges: :order_cycle}}). - merge(Exchange.outgoing). - select('spree_taxons.*, exchanges.receiver_id AS enterprise_id') + ents_and_vars = ExchangeVariant.joins(exchange: :order_cycle).merge(Exchange.outgoing) + .select("DISTINCT variant_id, receiver_id AS enterprise_id") - taxons = taxons.merge(OrderCycle.active) if which_taxons == :current + ents_and_vars = ents_and_vars.merge(OrderCycle.active) if which_taxons == :current + + taxons = Spree::Taxon + .select("DISTINCT spree_taxons.id, ents_and_vars.enterprise_id").joins(products: :variants_including_master) + .joins("INNER JOIN (#{ents_and_vars.to_sql}) AS ents_and_vars ON spree_variants.id = ents_and_vars.variant_id") taxons.inject({}) do |ts, t| ts[t.enterprise_id.to_i] ||= Set.new From 768240a5ba45e3967dfbd5e3bf980a4ee50fd461 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 30 Mar 2017 15:23:09 +1100 Subject: [PATCH 034/104] Reorganising darkswarm order views into partials --- app/views/spree/orders/_form.html.haml | 13 +--- app/views/spree/orders/_summary.html.haml | 65 ++++++++++++++++++ app/views/spree/orders/edit.html.haml | 13 +--- .../orders/form/_cart_actions_row.html.haml | 10 +++ .../spree/orders/form/_cart_links.html.haml | 9 +++ .../orders/form/_update_buttons.html.haml | 5 ++ app/views/spree/orders/show.html.haml | 7 -- .../spree/shared/_order_details.html.haml | 67 +------------------ 8 files changed, 93 insertions(+), 96 deletions(-) create mode 100644 app/views/spree/orders/_summary.html.haml create mode 100644 app/views/spree/orders/form/_cart_actions_row.html.haml create mode 100644 app/views/spree/orders/form/_cart_links.html.haml create mode 100644 app/views/spree/orders/form/_update_buttons.html.haml diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index 68ba409aa0..a4feef8f84 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -21,18 +21,7 @@ = render :partial => 'line_item', :locals => { :variant => item_form.object.variant, :line_item => item_form.object, :item_form => item_form } %tfoot#edit-cart - %tr - %td{colspan:"2"} - %td - = button_tag :class => 'secondary radius expand small', :id => 'update-button' do - %i.ofn-i_023-refresh - = t(:update) - %td - %td#empty-cart.text-center - %span#clear_cart_link{"data-hook" => ""} - = link_to t(:orders_form_empty_cart), empty_cart_path, method: :put, :class => 'not-bold small' - -#= form_tag empty_cart_path, :method => :put do - -#= submit_tag t(:empty_cart), :class => 'button alert expand small' + = render 'spree/orders/form/cart_actions_row' / This is the fees row which we want to replace with the pop-over -# - unless @order.adjustments.eligible.blank? diff --git a/app/views/spree/orders/_summary.html.haml b/app/views/spree/orders/_summary.html.haml new file mode 100644 index 0000000000..8c904716c1 --- /dev/null +++ b/app/views/spree/orders/_summary.html.haml @@ -0,0 +1,65 @@ +%table#line-items{"data-hook" => "order_details"} + %col{valign: "middle"}/ + %col{halign: "center", valign: "middle", width: "5%"}/ + %col{halign: "center", valign: "middle", width: "5%"}/ + %col{halign: "center", valign: "middle", width: "5%"}/ + %thead{"data-hook" => ""} + %tr{"data-hook" => "order_details_line_items_headers"} + %th= t(:item) + %th.price= t(:price) + %th.text-center.qty= t(:qty) + %th.text-right.total + %span= t(:total) + %tbody{"data-hook" => ""} + - order.line_items.each do |item| + %tr{"data-hook" => "order_details_line_item_row"} + %td(data-hook = "order_item_description") + + %div.item-thumb-image{"data-hook" => "order_item_image"} + - if item.variant.images.length == 0 + = link_to mini_image(item.variant.product), item.variant.product + - else + = link_to image_tag(item.variant.images.first.attachment.url(:mini)), item.variant.product + + + = render 'spree/shared/line_item_name', line_item: item + + %td.text-right.price{"data-hook" => "order_item_price"} + %span= item.single_display_amount_with_adjustments.to_html + %td.text-center{"data-hook" => "order_item_qty"}= item.quantity + %td.text-right.total{"data-hook" => "order_item_total"} + %span= item.display_amount_with_adjustments.to_html + + %tfoot + #subtotal{"data-hook" => "order_details_subtotal"} + %tr#subtotal-row.total + %td.text-right{colspan: "3"} + %strong + = t :order_produce + %td.text-right.total + %span= display_checkout_subtotal(order) + + #order-charges{"data-hook" => "order_details_adjustments"} + - checkout_adjustments_for(order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment| + %tr.total + %td.text-right{:colspan => "3"} + %strong + = adjustment.label + %td.text-right.total + %span= adjustment.display_amount.to_html + + #order-total{"data-hook" => "order_details_total"} + %tr.total + %td.text-right{colspan: "3"} + %h5 + = t :order_total_price + %td.text-right.total + %h5#order_total= order.display_total.to_html + + - if order.total_tax > 0 + #tax{"data-hook" => "order_details_tax"} + %tr#tax-row.total + %td.text-right{colspan: "3"} + = t :order_includes_tax + %td.text-right.total + %span= display_checkout_tax_total(order) diff --git a/app/views/spree/orders/edit.html.haml b/app/views/spree/orders/edit.html.haml index 58124ffa71..8be16c9cec 100644 --- a/app/views/spree/orders/edit.html.haml +++ b/app/views/spree/orders/edit.html.haml @@ -31,18 +31,7 @@ .row = render :partial => 'form', :locals => { :order_form => order_form } - - .links{'data-hook' => "cart_buttons"} - .row - .columns.large-8{"data-hook" => ""} - - %a.button.large.secondary{href: main_app.shop_path} - %i.ofn-i_008-caret-left - = t :orders_edit_continue - .columns.large-4.text-right - %a#checkout-link.button.large.primary{href: main_app.checkout_path} - = t :orders_edit_checkout - %i.ofn-i_007-caret-right + = render "spree/orders/form/cart_links" = render 'bought' if show_bought_items? diff --git a/app/views/spree/orders/form/_cart_actions_row.html.haml b/app/views/spree/orders/form/_cart_actions_row.html.haml new file mode 100644 index 0000000000..5790f7f9e1 --- /dev/null +++ b/app/views/spree/orders/form/_cart_actions_row.html.haml @@ -0,0 +1,10 @@ +%tr + %td{colspan:"2"} + %td + = button_tag :class => 'secondary radius expand small', :id => 'update-button' do + %i.ofn-i_023-refresh + = t(:update) + %td + %td#empty-cart.text-center + %span#clear_cart_link{"data-hook" => ""} + = link_to t(:orders_form_empty_cart), empty_cart_path, method: :put, :class => 'not-bold small' diff --git a/app/views/spree/orders/form/_cart_links.html.haml b/app/views/spree/orders/form/_cart_links.html.haml new file mode 100644 index 0000000000..cec97a8a4d --- /dev/null +++ b/app/views/spree/orders/form/_cart_links.html.haml @@ -0,0 +1,9 @@ +.row.links{'data-hook' => "cart_buttons"} + .columns.large-8{"data-hook" => ""} + %a.button.large.secondary{href: main_app.shop_path} + %i.ofn-i_008-caret-left + = t :orders_edit_continue + .columns.large-4.text-right + %a#checkout-link.button.large.primary{href: main_app.checkout_path} + = t :orders_edit_checkout + %i.ofn-i_007-caret-right diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml new file mode 100644 index 0000000000..5c8f4fa972 --- /dev/null +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -0,0 +1,5 @@ +.row + .columns.small-12.medium-3 + = link_to main_app.shop_path, :class => "button expand" do + %i.ofn-i_008-caret-left + = t(:back_to_store) diff --git a/app/views/spree/orders/show.html.haml b/app/views/spree/orders/show.html.haml index e4cb3b1980..41b3682383 100644 --- a/app/views/spree/orders/show.html.haml +++ b/app/views/spree/orders/show.html.haml @@ -19,12 +19,5 @@ = render 'spree/shared/order_details', order: @order - .row - .columns.large-12 - = link_to t(:back_to_store), main_app.shop_path, :class => "button" - - unless params.has_key? :checkout_complete - - if try_spree_current_user && respond_to?(:spree_account_path) - = link_to t(:my_account), spree_account_path, :class => "button" - = render partial: "shared/footer" diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index d0a7e99ddf..6845c0905a 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -86,68 +86,5 @@ %br .row .columns.large-12 - %table#line-items{"data-hook" => "order_details"} - %col{valign: "middle"}/ - %col{halign: "center", valign: "middle", width: "5%"}/ - %col{halign: "center", valign: "middle", width: "5%"}/ - %col{halign: "center", valign: "middle", width: "5%"}/ - %thead{"data-hook" => ""} - %tr{"data-hook" => "order_details_line_items_headers"} - %th= t(:item) - %th.price= t(:price) - %th.text-center.qty= t(:qty) - %th.text-right.total - %span= t(:total) - %tbody{"data-hook" => ""} - - order.line_items.each do |item| - %tr{"data-hook" => "order_details_line_item_row"} - %td(data-hook = "order_item_description") - - %div.item-thumb-image{"data-hook" => "order_item_image"} - - if item.variant.images.length == 0 - = link_to mini_image(item.variant.product), item.variant.product - - else - = link_to image_tag(item.variant.images.first.attachment.url(:mini)), item.variant.product - - - = render 'spree/shared/line_item_name', line_item: item - - %td.text-right.price{"data-hook" => "order_item_price"} - %span= item.single_display_amount_with_adjustments.to_html - %td.text-center{"data-hook" => "order_item_qty"}= item.quantity - %td.text-right.total{"data-hook" => "order_item_total"} - %span= item.display_amount_with_adjustments.to_html - - %tfoot - #subtotal{"data-hook" => "order_details_subtotal"} - %tr#subtotal-row.total - %td.text-right{colspan: "3"} - %strong - = t :order_produce - %td.text-right.total - %span= display_checkout_subtotal(order) - - #order-charges{"data-hook" => "order_details_adjustments"} - - checkout_adjustments_for(order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment| - %tr.total - %td.text-right{:colspan => "3"} - %strong - = adjustment.label - %td.text-right.total - %span= adjustment.display_amount.to_html - - #order-total{"data-hook" => "order_details_total"} - %tr.total - %td.text-right{colspan: "3"} - %h5 - = t :order_total_price - %td.text-right.total - %h5#order_total= order.display_total.to_html - - - if order.total_tax > 0 - #tax{"data-hook" => "order_details_tax"} - %tr#tax-row.total - %td.text-right{colspan: "3"} - = t :order_includes_tax - %td.text-right.total - %span= display_checkout_tax_total(order) + = render partial: 'spree/orders/summary' + = render 'spree/orders/form/update_buttons' From eec3a21c892a03fee543c58e0bd2f0b60cdaa9f2 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 30 Mar 2017 17:34:39 +1100 Subject: [PATCH 035/104] Allow editing of completed orders from confirmation page where distributor allows it --- .../javascripts/darkswarm/cart.js.coffee | 8 +-- .../spree/orders_controller_decorator.rb | 8 ++- app/models/spree/order_decorator.rb | 4 ++ app/views/spree/orders/_form.html.haml | 2 +- app/views/spree/orders/_line_item.html.haml | 2 +- app/views/spree/orders/_summary.html.haml | 2 +- .../orders/form/_update_buttons.html.haml | 10 +++ .../spree/shared/_order_details.html.haml | 8 ++- .../spree/orders_controller_spec.rb | 24 +++++-- .../features/consumer/shopping/orders_spec.rb | 66 +++++++++++++++++++ 10 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 spec/features/consumer/shopping/orders_spec.rb diff --git a/app/assets/javascripts/darkswarm/cart.js.coffee b/app/assets/javascripts/darkswarm/cart.js.coffee index 1e971c8bb4..03419a2c87 100644 --- a/app/assets/javascripts/darkswarm/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/cart.js.coffee @@ -1,8 +1,8 @@ $ -> - if ($ 'form#update-cart').is('*') - ($ 'form#update-cart a.delete').show().one 'click', -> - ($ this).parents('.line-item').first().find('input.line_item_quantity').val 0 - ($ this).parents('form').first().submit() + if $('form#update-cart').is('*') || $('form#update-order').is('*') + $('form#update-cart a.delete, form#update-order a.delete').show().one 'click', -> + $(this).parents('.line-item').first().find('input.line_item_quantity').val 0 + $(this).parents('form').first().submit() false ($ 'form#update-cart').submit -> diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 155e89ab5b..0de7d0f8f0 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -32,7 +32,7 @@ Spree::OrdersController.class_eval do def update @insufficient_stock_lines = [] - @order = current_order + @order = order_to_update unless @order flash[:error] = t(:order_not_found) redirect_to root_path and return @@ -49,6 +49,8 @@ Spree::OrdersController.class_eval do if params.has_key?(:checkout) @order.next_transition.run_callbacks if @order.cart? redirect_to checkout_state_path(@order.checkout_steps.first) + elsif @order.complete? + redirect_to order_path(@order) else redirect_to cart_path end @@ -204,8 +206,8 @@ Spree::OrdersController.class_eval do end def order_to_update - order = Spree::Order.complete.find_by_id(params[:order].andand[:id]) - return order if order.present? && can?(:update, order) + order = Spree::Order.complete.find_by_number(params[:id]) + return order if order.andand.editable? && can?(:update, order) current_order end end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index a3fa3586d0..0060b5adf2 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -289,6 +289,10 @@ Spree::Order.class_eval do user_id == user.id && distributor.andand.allow_order_changes? && order_cycle.andand.open? end + def editable? + distributor.andand.allow_order_changes? && order_cycle.andand.open? + end + private def shipping_address_from_distributor diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index a4feef8f84..67fc663e7f 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -21,7 +21,7 @@ = render :partial => 'line_item', :locals => { :variant => item_form.object.variant, :line_item => item_form.object, :item_form => item_form } %tfoot#edit-cart - = render 'spree/orders/form/cart_actions_row' + = render 'spree/orders/form/cart_actions_row' unless @order.complete? / This is the fees row which we want to replace with the pop-over -# - unless @order.adjustments.eligible.blank? diff --git a/app/views/spree/orders/_line_item.html.haml b/app/views/spree/orders/_line_item.html.haml index 14219c4e73..7e200253be 100644 --- a/app/views/spree/orders/_line_item.html.haml +++ b/app/views/spree/orders/_line_item.html.haml @@ -17,7 +17,7 @@ = render 'spree/shared/line_item_name', line_item: line_item - - if @insufficient_stock_lines.include? line_item + - if @insufficient_stock_lines.andand.include? line_item %span.out-of-stock = variant.in_stock? ? t(:insufficient_stock, :on_hand => variant.on_hand) : t(:out_of_stock) %br/ diff --git a/app/views/spree/orders/_summary.html.haml b/app/views/spree/orders/_summary.html.haml index 8c904716c1..b3276faede 100644 --- a/app/views/spree/orders/_summary.html.haml +++ b/app/views/spree/orders/_summary.html.haml @@ -12,7 +12,7 @@ %span= t(:total) %tbody{"data-hook" => ""} - order.line_items.each do |item| - %tr{"data-hook" => "order_details_line_item_row"} + %tr.line_item{"data-hook" => "order_details_line_item_row", class: "variant-#{item.variant.id}" } %td(data-hook = "order_item_description") %div.item-thumb-image{"data-hook" => "order_item_image"} diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index 5c8f4fa972..a319f4ff67 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -3,3 +3,13 @@ = link_to main_app.shop_path, :class => "button expand" do %i.ofn-i_008-caret-left = t(:back_to_store) + - if order.editable? + .columns.show-for-medium-up.medium-6   + -# .columns.small-12.medium-3   + -# = link_to "#", method: :delete, :class => "button secondary expand" do + -# %i.ofn-i_009-close + -# =t(:cancel_order) + .columns.small-12.medium-3 + = button_tag :class => 'button primary radius expand', :id => 'update-button' do + %i.ofn-i_051-check-big + = t(:save_changes) diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index 6845c0905a..1c40254cb4 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -86,5 +86,9 @@ %br .row .columns.large-12 - = render partial: 'spree/orders/summary' - = render 'spree/orders/form/update_buttons' + = form_for order, html: {id: 'update-order'} do |order_form| + - if order.editable? + = render 'spree/orders/form', order_form: order_form + -else + = render 'spree/orders/summary', order: order + = render 'spree/orders/form/update_buttons', order: order diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index a1bbe96b70..e1396be3f6 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -195,7 +195,7 @@ describe Spree::OrdersController do let!(:current_order) { double(:current_order) } let!(:order) { create(:order) } let(:li) { order.line_items.first } - let(:params) { { order: {} } } + let(:params) { { } } before do allow(controller).to receive(:current_order) { current_order } @@ -210,7 +210,7 @@ describe Spree::OrdersController do context "when an order_id is given in params" do before do - params[:order].merge!({id: order.id}) + params.merge!({id: order.number}) end context "and the order is not complete" do @@ -235,8 +235,24 @@ describe Spree::OrdersController do context "and the user has permission to 'update' the order" do before { allow(controller).to receive(:can?).with(:update, order) { true } } - it "returns the order" do - expect(controller.send(:order_to_update)).to eq order + context "and the order is not editable" do + + it "returns the current_order" do + expect(controller.send(:order_to_update)).to eq current_order + end + end + + context "and the order is editable" do + let(:order_cycle) { create(:simple_order_cycle) } + let(:distributor) { create(:enterprise, allow_order_changes: true) } + + before do + order.update_attributes(order_cycle_id: order_cycle.id, distributor_id: distributor.id) + end + + it "returns the order" do + expect(controller.send(:order_to_update)).to eq order + end end end end diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb new file mode 100644 index 0000000000..11e65806fc --- /dev/null +++ b/spec/features/consumer/shopping/orders_spec.rb @@ -0,0 +1,66 @@ +require 'spec_helper' + +feature "Order Management", js: true do + include AuthenticationWorkflow + + describe "editing a completed order" do + let(:address) { create(:address) } + let(:user) { create(:user, bill_address: address, ship_address: address) } + let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true, charges_sales_tax: true) } + let(:order_cycle) { create(:order_cycle) } + let(:order) { create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor, user: user, bill_address: address, ship_address: address) } + let!(:item1) { order.reload.line_items.first } + let!(:item2) { create(:line_item, order: order) } + let!(:item3) { create(:line_item, order: order) } + + before do + order.update_attributes(shipping_method_id: distributor.shipping_methods.first.id) + order.reload.save + quick_login_as user + end + + context "when the distributor doesn't allow changes to be made to orders" do + before do + order.distributor.update_attributes(allow_order_changes: false) + end + + it "doesn't show form elements for editing the order" do + visit spree.order_path(order) + expect(find("tr.variant-#{item1.variant.id}")).to have_content item1.product.name + expect(find("tr.variant-#{item2.variant.id}")).to have_content item2.product.name + expect(find("tr.variant-#{item3.variant.id}")).to have_content item3.product.name + expect(page).to_not have_button I18n.t(:save_changes) + end + end + + context "when the distributor allows changes to be made to orders" do + before do + order.distributor.update_attributes(allow_order_changes: true) + end + + it "shows already ordered line items" do + visit spree.order_path(order) + within "tr.variant-#{item1.variant.id}" do + expect(page).to have_content item1.product.name + expect(page).to have_field 'order_line_items_attributes_0_quantity' + fill_in 'order_line_items_attributes_0_quantity', with: 2 + end + expect(find("tr.variant-#{item2.variant.id}")).to have_content item2.product.name + expect(find("tr.variant-#{item3.variant.id}")).to have_content item3.product.name + + click_button I18n.t(:save_changes) + + expect(find(".order-total.grand-total")).to have_content "$40.00" + expect(item1.reload.quantity).to eq 2 + + within "tr.variant-#{item2.variant.id}" do + click_link "delete_line_item_#{item2.id}" + end + + expect(find(".order-total.grand-total")).to have_content "$30.00" + + expect(Spree::LineItem.find_by_id(item2.id)).to be nil + end + end + end +end From c6afa1849cd5b3c131cf72f54e18f337f06cc1d6 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 5 Apr 2017 15:31:11 +1000 Subject: [PATCH 036/104] Basic routing for front-end OrdersController#cancel action --- .../spree/orders_controller_decorator.rb | 13 +++++++ app/models/spree/ability_decorator.rb | 3 ++ config/locales/en.yml | 2 ++ config/routes.rb | 1 + .../spree/orders_controller_spec.rb | 35 +++++++++++++++++++ 5 files changed, 54 insertions(+) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 0de7d0f8f0..64ae25df7e 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -12,6 +12,7 @@ Spree::OrdersController.class_eval do include OrderCyclesHelper layout 'darkswarm' + respond_to :json # Patching to redirect to shop if order is empty def edit @@ -164,6 +165,18 @@ Spree::OrdersController.class_eval do @order_cycle = OrderCycle.find session[:expired_order_cycle_id] end + def cancel + @order = Spree::Order.find_by_number!(params[:id]) + authorize! :cancel, @order + + if @order.cancel + flash[:success] = I18n.t(:orders_your_order_has_been_cancelled) + else + flash[:error] = I18n.t(:orders_could_not_cancel) + end + redirect_to request.referer || order_path(@order) + end + private diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index b2ceffd1b0..6c5cad6fb3 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -55,6 +55,9 @@ class AbilityDecorator can [:destroy], Spree::LineItem do |item| item.andand.order.andand.can_remove_items? user end + can [:cancel], Spree::Order do |order| + order.user == user + end end # New users can create an enterprise, and gain other permissions from doing this. diff --git a/config/locales/en.yml b/config/locales/en.yml index 4abb72d108..9484e0b291 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1048,6 +1048,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using orders_show_title: Order Confirmation orders_show_time: Order ready on orders_show_number: Order confirmation + orders_your_order_has_been_cancelled: "Your order has been cancelled" + orders_could_not_cancel: "Sorry, the order could not be cancelled" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." diff --git a/config/routes.rb b/config/routes.rb index ad47a68149..17986e2081 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -264,6 +264,7 @@ Spree::Core::Engine.routes.prepend do resources :orders do get :clear, :on => :collection get :order_cycle_expired, :on => :collection + put :cancel, on: :member end end diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index e1396be3f6..3707bd194d 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -259,6 +259,41 @@ describe Spree::OrdersController do end end + describe "cancelling an order" do + let(:user) { create(:user) } + let(:order) { create(:order, user: user) } + let(:params) { { id: order.number } } + + context "when the user does not have permission to cancel the order" do + it "responds with unauthorized" do + spree_put :cancel, params + expect(response).to render_template 'shared/unauthorized' + end + end + + context "when the user has permission to cancel the order" do + before { allow(controller).to receive(:spree_current_user) { user } } + + context "when the order is not yet complete" do + it "responds with forbidden" do + spree_put :cancel, params + expect(response.status).to redirect_to spree.order_path(order) + expect(flash[:error]).to eq I18n.t(:orders_could_not_cancel) + end + end + + context "when the order is complete" do + let(:order) { create(:completed_order_with_totals, user: user) } + + it "responds with success" do + spree_put :cancel, params + expect(response.status).to redirect_to spree.order_path(order) + expect(flash[:success]).to eq I18n.t(:orders_your_order_has_been_cancelled) + end + end + end + end + private From 5d9f92eaa7aadb6eef60cc15bfc2d231a28ffd7b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 6 Apr 2017 12:38:34 +1000 Subject: [PATCH 037/104] Adding 'Cancel Order' button to order confimation interface --- app/models/spree/order_decorator.rb | 2 +- app/views/spree/orders/form/_update_buttons.html.haml | 10 +++++----- app/views/spree/orders/show.html.haml | 11 +++++++++-- config/locales/en.yml | 4 +++- spec/features/consumer/shopping/orders_spec.rb | 11 +++++++++-- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 0060b5adf2..2c1fbcf45a 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -290,7 +290,7 @@ Spree::Order.class_eval do end def editable? - distributor.andand.allow_order_changes? && order_cycle.andand.open? + complete? && distributor.andand.allow_order_changes? && order_cycle.andand.open? end private diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index a319f4ff67..965fd1bde7 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -4,11 +4,11 @@ %i.ofn-i_008-caret-left = t(:back_to_store) - if order.editable? - .columns.show-for-medium-up.medium-6   - -# .columns.small-12.medium-3   - -# = link_to "#", method: :delete, :class => "button secondary expand" do - -# %i.ofn-i_009-close - -# =t(:cancel_order) + .columns.show-for-medium-up.medium-3   + .columns.small-12.medium-3 + = link_to spree.cancel_order_path(@order), method: :put, :class => "button secondary expand" do + %i.ofn-i_009-close + = t(:cancel_order) .columns.small-12.medium-3 = button_tag :class => 'button primary radius expand', :id => 'update-button' do %i.ofn-i_051-check-big diff --git a/app/views/spree/orders/show.html.haml b/app/views/spree/orders/show.html.haml index 41b3682383..24d058db49 100644 --- a/app/views/spree/orders/show.html.haml +++ b/app/views/spree/orders/show.html.haml @@ -10,8 +10,15 @@ .row .columns.large-12.text-center %h2 - = t :orders_show_number - = " #" + @order.number + = t(:orders_show_order_number, number: @order.number) + - if @order.canceled? + %span.brick + = t(:orders_show_cancelled) + %i.ofn-i_009-close + - elsif @order.complete? + %span.turquoise + = t(:orders_show_confirmed) + %i.ofn-i_051-check-big #order{"data-hook" => ""} - if params.has_key? :checkout_complete diff --git a/config/locales/en.yml b/config/locales/en.yml index 9484e0b291..9637a744a3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1047,7 +1047,9 @@ See the %{link} to find out more about %{sitename}'s features and to start using orders_oc_expired_phone: "Phone:" orders_show_title: Order Confirmation orders_show_time: Order ready on - orders_show_number: Order confirmation + orders_show_order_number: "Order #%{number}" + orders_show_cancelled: Cancelled + orders_show_confirmed: Confirmed orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb index 11e65806fc..8a55439441 100644 --- a/spec/features/consumer/shopping/orders_spec.rb +++ b/spec/features/consumer/shopping/orders_spec.rb @@ -38,8 +38,10 @@ feature "Order Management", js: true do order.distributor.update_attributes(allow_order_changes: true) end - it "shows already ordered line items" do + it "allows quantity to be changed, items to be removed and the order to be cancelled" do visit spree.order_path(order) + + # Changing the quantity of an item within "tr.variant-#{item1.variant.id}" do expect(page).to have_content item1.product.name expect(page).to have_field 'order_line_items_attributes_0_quantity' @@ -53,13 +55,18 @@ feature "Order Management", js: true do expect(find(".order-total.grand-total")).to have_content "$40.00" expect(item1.reload.quantity).to eq 2 + # Deleting an item within "tr.variant-#{item2.variant.id}" do click_link "delete_line_item_#{item2.id}" end expect(find(".order-total.grand-total")).to have_content "$30.00" - expect(Spree::LineItem.find_by_id(item2.id)).to be nil + + # Cancelling the order + click_link(I18n.t(:cancel_order)) + expect(page).to have_content I18n.t(:orders_show_cancelled) + expect(order.reload).to be_canceled end end end From cda43f075b09fcc8e8ce361856ff48a2099d22f6 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 6 Apr 2017 17:29:13 +1000 Subject: [PATCH 038/104] Moving bought items listing up into main section of cart --- ...=> edit_bought_order_controller.js.coffee} | 3 +- .../darkswarm/shopping-cart.css.scss | 30 +++++--- app/views/spree/orders/_bought.html.haml | 70 ++++++++----------- app/views/spree/orders/_form.html.haml | 4 +- app/views/spree/orders/edit.html.haml | 2 - config/locales/en.yml | 5 ++ spec/features/consumer/shopping/cart_spec.rb | 10 ++- 7 files changed, 72 insertions(+), 52 deletions(-) rename app/assets/javascripts/darkswarm/controllers/{edit_order_controller.js.coffee => edit_bought_order_controller.js.coffee} (71%) diff --git a/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/edit_bought_order_controller.js.coffee similarity index 71% rename from app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee rename to app/assets/javascripts/darkswarm/controllers/edit_bought_order_controller.js.coffee index 84c5460300..3ed9f9af38 100644 --- a/app/assets/javascripts/darkswarm/controllers/edit_order_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/edit_bought_order_controller.js.coffee @@ -1,4 +1,5 @@ -Darkswarm.controller "EditOrderCtrl", ($scope, $resource, Cart) -> +Darkswarm.controller "EditBoughtOrderController", ($scope, $resource, Cart) -> + $scope.showBought = false $scope.deleteLineItem = (id) -> params = {id: id} diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss index 25ed0ba930..eee3657704 100644 --- a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss +++ b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss @@ -72,11 +72,31 @@ // Shopping cart #cart-detail { - .cart-item-delete { - a.delete { + .cart-item-delete, .bought-item-delete { + a { font-size: 1.125em; } } + + button, .button { + margin: 0; + } + + .toggle-bought { + cursor: pointer; + } + + tr.bought td { + color: $med-grey; + + h5 { + color: $med-grey; + } + + .already-confirmed { + float: right; + } + } } .item-thumb-image { @@ -90,9 +110,3 @@ height: 36px; } } - -#edit-cart { - button, .button { - margin: 0; - } -} diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml index b503c4e33f..0f44ef4d22 100644 --- a/app/views/spree/orders/_bought.html.haml +++ b/app/views/spree/orders/_bought.html.haml @@ -1,43 +1,35 @@ -%div#bought-products{ng: {controller: "EditOrderCtrl"}} - %div - %div - .row - .row - .columns.large-12 - %table{style: "width: 100%; margin-top: 2em"} - %col{halign: "left", valign: "middle", width: "60%"}/ - %col{halign: "left", valign: "middle", width: "15%"}/ - %col{halign: "center", valign: "middle", width: "10%"}/ - %col{halign: "center", valign: "middle", width: "10%"}/ - %col{halign: "center", valign: "middle", width: "5%"}/ - %thead - %tr - %th.cart-item-description-header= t('.item') - %th.cart-item-price-header.text-right= t(:price) - %th.text-center.cart-item-quantity-header= t(:qty) - %th.cart-item-total-header.text-right= t(:total) - %th.cart-item-delete-header +%tbody{ ng: { controller: 'EditBoughtOrderController' } } + %tr + %td.toggle-bought{ colspan: 2, ng: { click: 'showBought=!showBought' } } + %h5.brick + %i{ ng: { class: "{ 'ofn-i_007-caret-right': !showBought, 'ofn-i_005-caret-down': showBought}"}} + = t(:orders_bought_items_notice, count: @order.finalised_line_items.count) + %td.text-right{ colspan: 3} + %a.edit-finalised.button.radius.expand.small{ href: 'javascript:void(0)', ng: { class: "{secondary: !showBought, primary: showBought}" } } + = t(:orders_bought_edit_button) + %i.ofn-i_007-caret-right - %tbody - - @order.finalised_line_items.each do |line_item| - - variant = line_item.variant - %tr.line-item{class: "line-item-#{line_item.id} variant-#{variant.id}"} - %td.cart-item-description - %div.item-thumb-image - - if variant.images.length == 0 - = link_to mini_image(variant.product), variant.product - - else - = link_to image_tag(variant.images.first.attachment.url(:mini)), variant.product + - @order.finalised_line_items.each do |line_item| + - variant = line_item.variant + %tr.bought.line-item{class: "line-item-#{line_item.id} variant-#{variant.id}", ng: { show: 'showBought'} } + %td.cart-item-description - = render 'spree/shared/line_item_name', line_item: line_item - %td.text-right.cart-item-price - = line_item.single_display_amount_with_adjustments.to_html - %td.text-center.cart-item-quantity - = line_item.quantity - %td.cart-item-total.text-right - = line_item.display_amount_with_adjustments.to_html unless line_item.quantity.nil? + %div.item-thumb-image + - if variant.images.length == 0 + = link_to mini_image(variant.product), variant.product + - else + = link_to image_tag(variant.images.first.attachment.url(:mini)), variant.product - %td.cart-item-delete.text-center - %a.delete{ng: {click: "deleteLineItem(#{line_item.id})"}} - %i.delete.ofn-i_026-trash + = render 'spree/shared/line_item_name', line_item: line_item + %span.already-confirmed= t(:orders_bought_already_confirmed) + %td.text-right.cart-item-price + = line_item.single_display_amount_with_adjustments.to_html + %td.text-center.cart-item-quantity + = line_item.quantity + %td.cart-item-total.text-right + = line_item.display_amount_with_adjustments.to_html unless line_item.quantity.nil? + + %td.bought-item-delete.text-center + %a{ng: {click: "deleteLineItem(#{line_item.id})"}} + %i.ofn-i_026-trash diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index 67fc663e7f..e7d5f69f72 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -20,8 +20,10 @@ = order_form.fields_for :line_items do |item_form| = render :partial => 'line_item', :locals => { :variant => item_form.object.variant, :line_item => item_form.object, :item_form => item_form } + = render 'bought' if show_bought_items? && @order.cart? + %tfoot#edit-cart - = render 'spree/orders/form/cart_actions_row' unless @order.complete? + = render 'spree/orders/form/cart_actions_row' if @order.cart? / This is the fees row which we want to replace with the pop-over -# - unless @order.adjustments.eligible.blank? diff --git a/app/views/spree/orders/edit.html.haml b/app/views/spree/orders/edit.html.haml index 8be16c9cec..a5afad1178 100644 --- a/app/views/spree/orders/edit.html.haml +++ b/app/views/spree/orders/edit.html.haml @@ -33,6 +33,4 @@ = render "spree/orders/form/cart_links" - = render 'bought' if show_bought_items? - = render partial: "shared/footer" diff --git a/config/locales/en.yml b/config/locales/en.yml index 9637a744a3..e9f7f6710b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1052,6 +1052,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using orders_show_confirmed: Confirmed orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" + orders_bought_items_notice: + one: An additional item is already confirmed for this order cycle + other: "%{count} additional items already confirmed for this order cycle" + orders_bought_edit_button: Edit confirmed items + orders_bought_already_confirmed: "* already confirmed" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index 6a213ddec6..19f2bc301e 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -104,9 +104,15 @@ feature "full-page cart", js: true do it "shows already ordered line items" do item1 = prev_order1.line_items.first item2 = prev_order2.line_items.first + + expect(page).to_not have_content item1.variant.name + expect(page).to_not have_content item2.variant.name + + find("td.toggle-bought").click + expect(page).to have_content item1.variant.name expect(page).to have_content item2.variant.name - page.find(".line-item-#{item1.id} a.delete").click + page.find(".line-item-#{item1.id} td.bought-item-delete a").click expect(page).to have_no_content item1.variant.name expect(page).to have_content item2.variant.name @@ -116,6 +122,8 @@ feature "full-page cart", js: true do expect(page).to have_content item2.variant.name visit spree.cart_path + + find("td.toggle-bought").click expect(page).to have_no_content item1.variant.name expect(page).to have_content item2.variant.name end From 493a537f2cf8029beecdf6b4d8784329063522c6 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 6 Apr 2017 18:04:34 +1000 Subject: [PATCH 039/104] Making out-of-stock products in the cart more visible --- app/assets/stylesheets/darkswarm/shopping-cart.css.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss index eee3657704..def151a63b 100644 --- a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss +++ b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss @@ -78,6 +78,10 @@ } } + .out-of-stock { + color: $clr-brick; + } + button, .button { margin: 0; } From b0ff7ca767c34db4325ec58b40bd258d2c38fa84 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 24 Mar 2017 10:39:35 +1100 Subject: [PATCH 040/104] Making accounts page orders listing full-width --- .../stylesheets/darkswarm/account.css.scss | 22 +++++++------ app/views/spree/users/_skinny.html.haml | 16 ++++------ app/views/spree/users/show.html.haml | 32 +++++++++---------- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/account.css.scss b/app/assets/stylesheets/darkswarm/account.css.scss index 0d44ea1eaa..cae99872d3 100644 --- a/app/assets/stylesheets/darkswarm/account.css.scss +++ b/app/assets/stylesheets/darkswarm/account.css.scss @@ -1,16 +1,14 @@ @import "branding"; @import "mixins"; +.account-summary { + color: #4a4a4a; +} + + .orders { - @include sidepaddingSm; - - @include panepadding; - - padding-top: 10px; - - h3 { - padding-top: 2em; - } + margin-top: 50px; + margin-bottom: 100px; a { color: $clr-brick; @@ -26,6 +24,12 @@ height: auto; } + .active_table_row { + h3 { + margin-top: 0.5em; + } + } + i.ofn-i_059-producer, i.ofn-i_060-producer-reversed { font-size: 3rem; display: inline-block; diff --git a/app/views/spree/users/_skinny.html.haml b/app/views/spree/users/_skinny.html.haml index 4894824296..70ba39d335 100644 --- a/app/views/spree/users/_skinny.html.haml +++ b/app/views/spree/users/_skinny.html.haml @@ -1,12 +1,10 @@ .row.active_table_row.skinny-head.margin-top{"ng-click" => "toggle($event)", "ng-class" => "{'closed' : !open()}"} .columns.small-2 - %span.margin-top - %img.account-logo{"logo-fallback" => true, "ng-src" => "{{distributor.logo}}"} - .columns.small-10.medium-5 - %span.margin-top - %strong{"ng-bind" => "::distributor.name"} - .columns.small-8.small-offset-2.medium-3.text-right - %span.margin-top.distributor-balance{"ng-bind" => "::distributor.balance | formatBalance", "ng-class" => "{'credit' : distributor.balance < 0, 'debit' : distributor.balance > 0, 'paid' : distributor.balance == 0}" } - .columns.small-2.medium-2.text-right - %span.margin-top + %img.margin-top.account-logo{"logo-fallback" => true, "ng-src" => "{{distributor.logo}}"} + .columns.small-5 + %h3.margin-top{"ng-bind" => "::distributor.name"} + .columns.small-4.text-right + %h3.margin-top.distributor-balance{"ng-bind" => "::distributor.balance | formatBalance", "ng-class" => "{'credit' : distributor.balance < 0, 'debit' : distributor.balance > 0, 'paid' : distributor.balance == 0}" } + .columns.small-1.text-right + %h3.margin-top %i{"ng-class" => "{'ofn-i_005-caret-down' : !open(), 'ofn-i_006-caret-up' : open()}"} diff --git a/app/views/spree/users/show.html.haml b/app/views/spree/users/show.html.haml index 0b4800f79e..f99f592459 100644 --- a/app/views/spree/users/show.html.haml +++ b/app/views/spree/users/show.html.haml @@ -3,22 +3,22 @@ .row.pad-top .small-12.columns.pad-top - %h2= accurate_title - .account-summary{"data-hook" => "account_summary"} - = @user.email - (#{link_to t(:edit), spree.edit_account_path}) - %h3= t(:my_orders) + %h2 + = accurate_title + %span.account-summary{"data-hook" => "account_summary"} + = @user.email + (#{link_to t(:edit), spree.edit_account_path}) + .orders{"ng-controller" => "OrdersCtrl", "ng-cloak" => true} - .row - .small-12.columns - .active_table - %distributor.active_table_node.row.animate-repeat{"ng-if" => "Orders.orders_by_distributor.length > 0", "ng-repeat" => "(key, distributor) in Orders.orders_by_distributor", - "ng-controller" => "DistributorNodeCtrl", - "ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !distributor.active}", - id: "{{distributor.hash}}"} - .small-12.columns - = render partial: "spree/users/skinny" - = render partial: "spree/users/fat" - .message{"ng-if" => "Orders.orders_by_distributor.length == 0", "ng-bind" => "::'you_have_no_orders_yet' | t"} + .active_table + %h3.my-orders= t(:my_orders) + %distributor.active_table_node.row.animate-repeat{"ng-if" => "Orders.orders_by_distributor.length > 0", "ng-repeat" => "(key, distributor) in Orders.orders_by_distributor", + "ng-controller" => "DistributorNodeCtrl", + "ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !distributor.active}", + id: "{{distributor.hash}}"} + .small-12.columns + = render partial: "spree/users/skinny" + = render partial: "spree/users/fat" + .message{"ng-if" => "Orders.orders_by_distributor.length == 0", "ng-bind" => "::'you_have_no_orders_yet' | t"} = render partial: "shared/footer" From b94bcd697f6dd4a11f82d39e69e31cf986c66ba7 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 09:43:45 +1000 Subject: [PATCH 041/104] Restructuring customer accounts spec --- spec/features/consumer/account_spec.rb | 84 +++++++++++++------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/spec/features/consumer/account_spec.rb b/spec/features/consumer/account_spec.rb index 58d4e1acc6..e79b19ca0c 100644 --- a/spec/features/consumer/account_spec.rb +++ b/spec/features/consumer/account_spec.rb @@ -7,57 +7,59 @@ feature %q{ }, js: true do include UIComponentHelper include AuthenticationWorkflow - let!(:user) { create(:user)} - let!(:user2) {create(:user)} + + let(:user) { create(:user)} let!(:distributor1) { create(:distributor_enterprise) } let!(:distributor2) { create(:distributor_enterprise) } let!(:distributor_credit) { create(:distributor_enterprise) } let!(:distributor_without_orders) { create(:distributor_enterprise) } let!(:accounts_distributor) {create :distributor_enterprise} let!(:order_account_invoice) { create(:order, distributor: accounts_distributor, state: 'complete', user: user) } - let!(:d1o1) { create(:completed_order_with_totals, distributor_id: distributor1.id, user_id: user.id, total: 10000)} - let!(:d1o2) { create(:order_without_full_payment, distributor_id: distributor1.id, user_id: user.id, total: 5000)} - let!(:d2o1) { create(:completed_order_with_totals, distributor_id: distributor2.id, user_id: user.id)} - let!(:credit_order) { create(:order_with_credit_payment, distributor_id: distributor_credit.id, user_id: user.id)} -# let!(:credit_payment) { create(:payment, amount: 12000.00, order_id: credit_order.id)} - - before do - Spree::Config.accounts_distributor_id = accounts_distributor.id - credit_order.update! - login_as user - visit "/account" - end - - it "shows all hubs that have been ordered from with balance or credit" do - # Single test to avoid re-rendering page - expect(page).to have_content distributor1.name - expect(page).to have_content distributor2.name - expect(page).not_to have_content distributor_without_orders.name - # Exclude the special Accounts & Billing distributor - expect(page).not_to have_content accounts_distributor.name - expect(page).to have_content distributor1.name + " " + "Balance due" - expect(page).to have_content distributor_credit.name + " Credit" - end - - - it "reveals table of orders for distributors when clicked" do - expand_active_table_node distributor1.name - expect(page).to have_link "Order " + d1o1.number, href:"/orders/#{d1o1.number}" - - expand_active_table_node distributor2.name - expect(page).not_to have_content "Order " + d1o1.number.to_s - end - - context "for a user without orders" do + context "as a logged in user" do before do - login_as user2 - visit "/account" + Spree::Config.accounts_distributor_id = accounts_distributor.id + login_as user end - it "displays an appropriate message" do - expect(page).to have_content {t :you_have_no_orders_yet} + context "with completed orders" do + let!(:d1o1) { create(:completed_order_with_totals, distributor_id: distributor1.id, user_id: user.id, total: 10000)} + let!(:d1o2) { create(:order_without_full_payment, distributor_id: distributor1.id, user_id: user.id, total: 5000)} + let!(:d2o1) { create(:completed_order_with_totals, distributor_id: distributor2.id, user_id: user.id)} + let!(:credit_order) { create(:order_with_credit_payment, distributor_id: distributor_credit.id, user_id: user.id)} + + before do + credit_order.update! + end + + it "shows all hubs that have been ordered from with balance or credit" do + # Single test to avoid re-rendering page + visit "/account" + + # It shows all hubs that have been ordered from with balance or credit + expect(page).to have_content distributor1.name + expect(page).to have_content distributor2.name + expect(page).not_to have_content distributor_without_orders.name + + # Exclude the special Accounts & Billing distributor + expect(page).not_to have_content accounts_distributor.name + expect(page).to have_content distributor1.name + " " + "Balance due" + expect(page).to have_content distributor_credit.name + " Credit" + + # It reveals table of orders for distributors when clicked + expand_active_table_node distributor1.name + expect(page).to have_link "Order " + d1o1.number, href:"/orders/#{d1o1.number}" + + expand_active_table_node distributor2.name + expect(page).not_to have_content "Order " + d1o1.number.to_s + end + end + + context "without any completed orders" do + it "displays an appropriate message" do + visit "/account" + expect(page).to have_content {t :you_have_no_orders_yet} + end end end - end From 893331c7bb7d83d8fff17025b306aac2d0c3e496 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 11:29:12 +1000 Subject: [PATCH 042/104] Adding 'Open Orders' section to the top of customer accounts page --- .../darkswarm/filters/dates.js.coffee | 6 ++++ .../darkswarm/services/orders.js.coffee | 8 +++++- .../stylesheets/darkswarm/account.css.scss | 1 + app/serializers/api/order_serializer.rb | 27 ++++++++++++++++-- app/views/spree/users/_open_orders.html.haml | 23 +++++++++++++++ app/views/spree/users/show.html.haml | 6 +++- config/locales/en.yml | 14 ++++++++++ spec/features/consumer/account_spec.rb | 28 ++++++++++++++++--- 8 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 app/views/spree/users/_open_orders.html.haml diff --git a/app/assets/javascripts/darkswarm/filters/dates.js.coffee b/app/assets/javascripts/darkswarm/filters/dates.js.coffee index 7b5dd861d5..0f5a36f3ee 100644 --- a/app/assets/javascripts/darkswarm/filters/dates.js.coffee +++ b/app/assets/javascripts/darkswarm/filters/dates.js.coffee @@ -8,3 +8,9 @@ Darkswarm.filter "sensible_timeframe", (date_in_wordsFilter)-> t 'orders_open' else t('closing') + date_in_wordsFilter(date) + +Darkswarm.filter "changesAllowed", -> + (date) -> + return t('say_no') unless date? + return t('spree.users.open_orders.closed') if date < moment() + t('spree.users.open_orders.until') + " " + moment(date).calendar() diff --git a/app/assets/javascripts/darkswarm/services/orders.js.coffee b/app/assets/javascripts/darkswarm/services/orders.js.coffee index 78ba65f79e..cd9a570a3a 100644 --- a/app/assets/javascripts/darkswarm/services/orders.js.coffee +++ b/app/assets/javascripts/darkswarm/services/orders.js.coffee @@ -3,10 +3,12 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub, constructor: -> # Populate Orders.orders from json in page. @orders_by_distributor = orders_by_distributor + @editable_orders = [] @currency_symbol = currencyConfig.symbol for distributor in @orders_by_distributor - @updateRunningBalance(distributor.distributed_orders) + @findEditableOrders(distributor.distributed_orders) + @updateRunningBalance(distributor.distributed_orders) updateRunningBalance: (orders) -> @@ -14,3 +16,7 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub, balances = orders.slice(i,orders.length).map (o) -> parseFloat(o.outstanding_balance) running_balance = balances.reduce (a,b) -> a+b order.running_balance = running_balance.toFixed(2) + + findEditableOrders: (orders) -> + for order in orders when order.editable + @editable_orders.push(order) diff --git a/app/assets/stylesheets/darkswarm/account.css.scss b/app/assets/stylesheets/darkswarm/account.css.scss index cae99872d3..4c60033a2a 100644 --- a/app/assets/stylesheets/darkswarm/account.css.scss +++ b/app/assets/stylesheets/darkswarm/account.css.scss @@ -65,6 +65,7 @@ .transaction-group {} table { + width: 100%; border-radius: 0.5em 0.5em 0 0; tr:nth-of-type(even) { diff --git a/app/serializers/api/order_serializer.rb b/app/serializers/api/order_serializer.rb index acbd0fdd01..57ae70170e 100644 --- a/app/serializers/api/order_serializer.rb +++ b/app/serializers/api/order_serializer.rb @@ -1,13 +1,27 @@ module Api class OrderSerializer < ActiveModel::Serializer - attributes :number, :completed_at, :total, :state, :shipment_state, :payment_state, :outstanding_balance, :payments, :path + attributes :number, :completed_at, :total, :state, :shipment_state, :payment_state + attributes :outstanding_balance, :payments, :path, :cancel_path, :editable, :editable_until + attributes :shop_name, :item_count has_many :payments, serializer: Api::PaymentSerializer + def shop_name + object.distributor.andand.name + end + + def item_count + object.line_items.sum(&:quantity) + end + def completed_at object.completed_at.blank? ? "" : I18n.l(object.completed_at, format: :long) end + def editable_until + object.order_cycle.andand.orders_close_at + end + def total object.total.to_money.to_s end @@ -25,7 +39,16 @@ module Api end def path - Spree::Core::Engine.routes_url_helpers.order_url(object.number, only_path: true) + Spree::Core::Engine.routes_url_helpers.order_path(object) + end + + def cancel_path + return nil unless object.editable? + Spree::Core::Engine.routes_url_helpers.cancel_order_path(object) + end + + def editable + object.editable? end end end diff --git a/app/views/spree/users/_open_orders.html.haml b/app/views/spree/users/_open_orders.html.haml new file mode 100644 index 0000000000..a8fa1070f6 --- /dev/null +++ b/app/views/spree/users/_open_orders.html.haml @@ -0,0 +1,23 @@ +.row + .small-12.columns + %table + %tr + %th.order1= t('.order') + %th.order2= t('.shop') + %th.order3.show-for-large-up= t('.changes_allowed') + %th.order4.show-for-large-up= t('.items') + %th.order5.text-right= t('.total') + %th.order6.text-right.show-for-large-up= t('.edit') + %th.order7.text-right= t('.cancel') + %tbody.transaction-group{"ng-repeat" => "order in Orders.editable_orders", "ng-class-odd"=>"'odd'", "ng-class-even"=>"'even'"} + %tr.order-row + %td.order1 + %a{"ng-href" => "{{::order.path}}", "ng-bind" => "::order.number"} + %td.order2{"ng-bind" => "::order.shop_name"} + %td.order3.show-for-large-up{"ng-bind" => "order.editable_until | changesAllowed"} + %td.order4.show-for-large-up{"ng-bind" => "::order.item_count"} + %td.order5.text-right{"ng-class" => "{'credit' : order.total < 0, 'debit' : order.total > 0, 'paid' : order.total == 0}","ng-bind" => "::order.total | localizeCurrency"} + %td.order6.text-right.show-for-large-up.brick + %a{"ng-href" => "{{::order.path}}" }= t('.edit') + %td.order7.text-right + = link_to t('.cancel'), "", method: :put, "ng-href" => "{{::order.cancel_path}}" diff --git a/app/views/spree/users/show.html.haml b/app/views/spree/users/show.html.haml index f99f592459..2206258830 100644 --- a/app/views/spree/users/show.html.haml +++ b/app/views/spree/users/show.html.haml @@ -10,8 +10,12 @@ (#{link_to t(:edit), spree.edit_account_path}) .orders{"ng-controller" => "OrdersCtrl", "ng-cloak" => true} + .my-open-orders{ ng: { show: 'Orders.editable_orders.length > 0' } } + %h3= t(:open_orders) + = render 'open_orders' + .active_table - %h3.my-orders= t(:my_orders) + %h3.my-orders= t(:transaction_history) %distributor.active_table_node.row.animate-repeat{"ng-if" => "Orders.orders_by_distributor.length > 0", "ng-repeat" => "(key, distributor) in Orders.orders_by_distributor", "ng-controller" => "DistributorNodeCtrl", "ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !distributor.active}", diff --git a/config/locales/en.yml b/config/locales/en.yml index e9f7f6710b..e247a3a4d1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1676,3 +1676,17 @@ Please follow the instructions there to make your enterprise visible on the Open If you continue to have problems please feel free to contact us. weight: Weight (per kg) zipcode: Postcode + users: + show: + open_orders: Open Orders + transaction_history: Transaction History + open_orders: + order: Order + shop: Shop + changes_allowed: Changes Allowed? + items: Items + total: Total + edit: Edit + cancel: Cancel + closed: Closed + until: Until diff --git a/spec/features/consumer/account_spec.rb b/spec/features/consumer/account_spec.rb index e79b19ca0c..07f8b3ddc6 100644 --- a/spec/features/consumer/account_spec.rb +++ b/spec/features/consumer/account_spec.rb @@ -23,10 +23,11 @@ feature %q{ end context "with completed orders" do - let!(:d1o1) { create(:completed_order_with_totals, distributor_id: distributor1.id, user_id: user.id, total: 10000)} - let!(:d1o2) { create(:order_without_full_payment, distributor_id: distributor1.id, user_id: user.id, total: 5000)} - let!(:d2o1) { create(:completed_order_with_totals, distributor_id: distributor2.id, user_id: user.id)} - let!(:credit_order) { create(:order_with_credit_payment, distributor_id: distributor_credit.id, user_id: user.id)} + let(:order_cycle) { create(:simple_order_cycle) } + let!(:d1o1) { create(:completed_order_with_totals, distributor: distributor1, user: user, total: 10000, order_cycle: order_cycle)} + let!(:d1o2) { create(:order_without_full_payment, distributor: distributor1, user: user, total: 5000, order_cycle: order_cycle)} + let!(:d2o1) { create(:completed_order_with_totals, distributor: distributor2, user: user)} + let!(:credit_order) { create(:order_with_credit_payment, distributor: distributor_credit, user: user)} before do credit_order.update! @@ -36,6 +37,9 @@ feature %q{ # Single test to avoid re-rendering page visit "/account" + # No distributors allow changes to orders + expect(page).to_not have_content I18n.t('spree.users.show.open_orders') + # It shows all hubs that have been ordered from with balance or credit expect(page).to have_content distributor1.name expect(page).to have_content distributor2.name @@ -53,6 +57,22 @@ feature %q{ expand_active_table_node distributor2.name expect(page).not_to have_content "Order " + d1o1.number.to_s end + + context "when there is at least one editable order" do + before do + distributor1.update_attributes(allow_order_changes: true) + end + + it "shows such orders in a section labelled 'Open Orders'" do + visit '/account' + expect(page).to have_content I18n.t('spree.users.show.open_orders') + + expect(page).to have_link d1o1.number, href: spree.order_path(d1o1) + expect(page).to have_link d1o2.number, href: spree.order_path(d1o2) + expect(page).to have_link I18n.t('spree.users.open_orders.cancel'), href: spree.cancel_order_path(d1o1) + expect(page).to have_link I18n.t('spree.users.open_orders.cancel'), href: spree.cancel_order_path(d1o2) + end + end end context "without any completed orders" do From e21bfd95f42b9c0953a110ab7593439d9a0125a9 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 11:48:31 +1000 Subject: [PATCH 043/104] Renaming order.editable? to order.changes_allowed? --- .../javascripts/darkswarm/services/orders.js.coffee | 10 +++++----- app/controllers/spree/orders_controller_decorator.rb | 2 +- app/models/spree/order_decorator.rb | 2 +- app/serializers/api/order_serializer.rb | 10 +++++----- app/views/spree/orders/form/_update_buttons.html.haml | 2 +- app/views/spree/shared/_order_details.html.haml | 2 +- app/views/spree/users/_open_orders.html.haml | 4 ++-- app/views/spree/users/show.html.haml | 2 +- spec/features/consumer/account_spec.rb | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/orders.js.coffee b/app/assets/javascripts/darkswarm/services/orders.js.coffee index cd9a570a3a..049c3baa5e 100644 --- a/app/assets/javascripts/darkswarm/services/orders.js.coffee +++ b/app/assets/javascripts/darkswarm/services/orders.js.coffee @@ -3,11 +3,11 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub, constructor: -> # Populate Orders.orders from json in page. @orders_by_distributor = orders_by_distributor - @editable_orders = [] + @changeable_orders = [] @currency_symbol = currencyConfig.symbol for distributor in @orders_by_distributor - @findEditableOrders(distributor.distributed_orders) + @findChangeableOrders(distributor.distributed_orders) @updateRunningBalance(distributor.distributed_orders) @@ -17,6 +17,6 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub, running_balance = balances.reduce (a,b) -> a+b order.running_balance = running_balance.toFixed(2) - findEditableOrders: (orders) -> - for order in orders when order.editable - @editable_orders.push(order) + findChangeableOrders: (orders) -> + for order in orders when order.changes_allowed + @changeable_orders.push(order) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 64ae25df7e..7f87d198e9 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -220,7 +220,7 @@ Spree::OrdersController.class_eval do def order_to_update order = Spree::Order.complete.find_by_number(params[:id]) - return order if order.andand.editable? && can?(:update, order) + return order if order.andand.changes_allowed? && can?(:update, order) current_order end end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 2c1fbcf45a..a1b2ee0b56 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -289,7 +289,7 @@ Spree::Order.class_eval do user_id == user.id && distributor.andand.allow_order_changes? && order_cycle.andand.open? end - def editable? + def changes_allowed? complete? && distributor.andand.allow_order_changes? && order_cycle.andand.open? end diff --git a/app/serializers/api/order_serializer.rb b/app/serializers/api/order_serializer.rb index 57ae70170e..354af5e878 100644 --- a/app/serializers/api/order_serializer.rb +++ b/app/serializers/api/order_serializer.rb @@ -1,7 +1,7 @@ module Api class OrderSerializer < ActiveModel::Serializer attributes :number, :completed_at, :total, :state, :shipment_state, :payment_state - attributes :outstanding_balance, :payments, :path, :cancel_path, :editable, :editable_until + attributes :outstanding_balance, :payments, :path, :cancel_path, :changes_allowed, :changes_allowed_until attributes :shop_name, :item_count has_many :payments, serializer: Api::PaymentSerializer @@ -18,7 +18,7 @@ module Api object.completed_at.blank? ? "" : I18n.l(object.completed_at, format: :long) end - def editable_until + def changes_allowed_until object.order_cycle.andand.orders_close_at end @@ -43,12 +43,12 @@ module Api end def cancel_path - return nil unless object.editable? + return nil unless object.changes_allowed? Spree::Core::Engine.routes_url_helpers.cancel_order_path(object) end - def editable - object.editable? + def changes_allowed + object.changes_allowed? end end end diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index 965fd1bde7..77f31ce418 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -3,7 +3,7 @@ = link_to main_app.shop_path, :class => "button expand" do %i.ofn-i_008-caret-left = t(:back_to_store) - - if order.editable? + - if order.changes_allowed? .columns.show-for-medium-up.medium-3   .columns.small-12.medium-3 = link_to spree.cancel_order_path(@order), method: :put, :class => "button secondary expand" do diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index 1c40254cb4..b9eeb26e77 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -87,7 +87,7 @@ .row .columns.large-12 = form_for order, html: {id: 'update-order'} do |order_form| - - if order.editable? + - if order.changes_allowed? = render 'spree/orders/form', order_form: order_form -else = render 'spree/orders/summary', order: order diff --git a/app/views/spree/users/_open_orders.html.haml b/app/views/spree/users/_open_orders.html.haml index a8fa1070f6..6447589dfc 100644 --- a/app/views/spree/users/_open_orders.html.haml +++ b/app/views/spree/users/_open_orders.html.haml @@ -9,12 +9,12 @@ %th.order5.text-right= t('.total') %th.order6.text-right.show-for-large-up= t('.edit') %th.order7.text-right= t('.cancel') - %tbody.transaction-group{"ng-repeat" => "order in Orders.editable_orders", "ng-class-odd"=>"'odd'", "ng-class-even"=>"'even'"} + %tbody.transaction-group{"ng-repeat" => "order in Orders.changeable_orders", "ng-class-odd"=>"'odd'", "ng-class-even"=>"'even'"} %tr.order-row %td.order1 %a{"ng-href" => "{{::order.path}}", "ng-bind" => "::order.number"} %td.order2{"ng-bind" => "::order.shop_name"} - %td.order3.show-for-large-up{"ng-bind" => "order.editable_until | changesAllowed"} + %td.order3.show-for-large-up{"ng-bind" => "order.changes_allowed_until | changesAllowed"} %td.order4.show-for-large-up{"ng-bind" => "::order.item_count"} %td.order5.text-right{"ng-class" => "{'credit' : order.total < 0, 'debit' : order.total > 0, 'paid' : order.total == 0}","ng-bind" => "::order.total | localizeCurrency"} %td.order6.text-right.show-for-large-up.brick diff --git a/app/views/spree/users/show.html.haml b/app/views/spree/users/show.html.haml index 2206258830..8272cc9eeb 100644 --- a/app/views/spree/users/show.html.haml +++ b/app/views/spree/users/show.html.haml @@ -10,7 +10,7 @@ (#{link_to t(:edit), spree.edit_account_path}) .orders{"ng-controller" => "OrdersCtrl", "ng-cloak" => true} - .my-open-orders{ ng: { show: 'Orders.editable_orders.length > 0' } } + .my-open-orders{ ng: { show: 'Orders.changeable_orders.length > 0' } } %h3= t(:open_orders) = render 'open_orders' diff --git a/spec/features/consumer/account_spec.rb b/spec/features/consumer/account_spec.rb index 07f8b3ddc6..d5c7236b72 100644 --- a/spec/features/consumer/account_spec.rb +++ b/spec/features/consumer/account_spec.rb @@ -58,7 +58,7 @@ feature %q{ expect(page).not_to have_content "Order " + d1o1.number.to_s end - context "when there is at least one editable order" do + context "when there is at least one changeable order" do before do distributor1.update_attributes(allow_order_changes: true) end From 316b0915e4cdcc4b5c11194a1099df6dd1656c1e Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 12:00:08 +1000 Subject: [PATCH 044/104] Just display the date that orders can be changed until No fancy moment.js stuff --- app/assets/javascripts/darkswarm/filters/dates.js.coffee | 6 ------ app/serializers/api/order_serializer.rb | 2 +- app/views/spree/users/_open_orders.html.haml | 4 ++-- config/locales/en.yml | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/darkswarm/filters/dates.js.coffee b/app/assets/javascripts/darkswarm/filters/dates.js.coffee index 0f5a36f3ee..7b5dd861d5 100644 --- a/app/assets/javascripts/darkswarm/filters/dates.js.coffee +++ b/app/assets/javascripts/darkswarm/filters/dates.js.coffee @@ -8,9 +8,3 @@ Darkswarm.filter "sensible_timeframe", (date_in_wordsFilter)-> t 'orders_open' else t('closing') + date_in_wordsFilter(date) - -Darkswarm.filter "changesAllowed", -> - (date) -> - return t('say_no') unless date? - return t('spree.users.open_orders.closed') if date < moment() - t('spree.users.open_orders.until') + " " + moment(date).calendar() diff --git a/app/serializers/api/order_serializer.rb b/app/serializers/api/order_serializer.rb index 354af5e878..4f07cdb962 100644 --- a/app/serializers/api/order_serializer.rb +++ b/app/serializers/api/order_serializer.rb @@ -19,7 +19,7 @@ module Api end def changes_allowed_until - object.order_cycle.andand.orders_close_at + I18n.l(object.order_cycle.andand.orders_close_at, format: :long) end def total diff --git a/app/views/spree/users/_open_orders.html.haml b/app/views/spree/users/_open_orders.html.haml index 6447589dfc..c8efbfb4f4 100644 --- a/app/views/spree/users/_open_orders.html.haml +++ b/app/views/spree/users/_open_orders.html.haml @@ -4,7 +4,7 @@ %tr %th.order1= t('.order') %th.order2= t('.shop') - %th.order3.show-for-large-up= t('.changes_allowed') + %th.order3.show-for-large-up= t('.changes_allowed_until') %th.order4.show-for-large-up= t('.items') %th.order5.text-right= t('.total') %th.order6.text-right.show-for-large-up= t('.edit') @@ -14,7 +14,7 @@ %td.order1 %a{"ng-href" => "{{::order.path}}", "ng-bind" => "::order.number"} %td.order2{"ng-bind" => "::order.shop_name"} - %td.order3.show-for-large-up{"ng-bind" => "order.changes_allowed_until | changesAllowed"} + %td.order3.show-for-large-up{"ng-bind" => "order.changes_allowed_until"} %td.order4.show-for-large-up{"ng-bind" => "::order.item_count"} %td.order5.text-right{"ng-class" => "{'credit' : order.total < 0, 'debit' : order.total > 0, 'paid' : order.total == 0}","ng-bind" => "::order.total | localizeCurrency"} %td.order6.text-right.show-for-large-up.brick diff --git a/config/locales/en.yml b/config/locales/en.yml index e247a3a4d1..712ab9706f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1683,7 +1683,7 @@ Please follow the instructions there to make your enterprise visible on the Open open_orders: order: Order shop: Shop - changes_allowed: Changes Allowed? + changes_allowed_until: Changes Allowed Until items: Items total: Total edit: Edit From 0dd8959bf7bb6ee523f453507602b9dcfcffccc8 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 12:17:00 +1000 Subject: [PATCH 045/104] Use an actual completed order for OrdersController#order_to_update spec --- spec/controllers/spree/orders_controller_spec.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index 3707bd194d..36e2182cd6 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -193,8 +193,6 @@ describe Spree::OrdersController do describe "#order_to_update" do let!(:current_order) { double(:current_order) } - let!(:order) { create(:order) } - let(:li) { order.line_items.first } let(:params) { { } } before do @@ -214,15 +212,15 @@ describe Spree::OrdersController do end context "and the order is not complete" do + let!(:order) { create(:order) } + it "returns the current_order" do expect(controller.send(:order_to_update)).to eq current_order end end context "and the order is complete" do - before do - allow(Spree::Order).to receive(:complete) { Spree::Order.where(id: order.id) } - end + let!(:order) { create(:completed_order_with_totals) } context "and the user doesn't have permisson to 'update' the order" do before { allow(controller).to receive(:can?).with(:update, order) { false } } From ae28d7a96b22eec182502269bc0edc7d754abd2b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 14:15:52 +1000 Subject: [PATCH 046/104] Adding a link in cart to allow user to edit existing + open orders for same OC --- app/helpers/spree/orders_helper.rb | 8 ++++++++ app/views/spree/orders/_bought.html.haml | 7 ++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index 5fd0f74fa8..a3183d8273 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -16,5 +16,13 @@ module Spree def cart_count current_order.andand.line_items.andand.count || 0 end + + def changeable_orders + return [] unless spree_current_user && current_distributor && current_order_cycle + Spree::Order.complete.where( + user_id: spree_current_user.id, + distributor_id: current_distributor.id, + order_cycle_id: current_order_cycle.id) + end end end diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml index 0f44ef4d22..6c31acd25c 100644 --- a/app/views/spree/orders/_bought.html.haml +++ b/app/views/spree/orders/_bought.html.haml @@ -2,10 +2,11 @@ %tr %td.toggle-bought{ colspan: 2, ng: { click: 'showBought=!showBought' } } %h5.brick - %i{ ng: { class: "{ 'ofn-i_007-caret-right': !showBought, 'ofn-i_005-caret-down': showBought}"}} + %i{ ng: { class: "{ 'ofn-i_007-caret-right': !showBought, 'ofn-i_005-caret-down': showBought}"} } = t(:orders_bought_items_notice, count: @order.finalised_line_items.count) - %td.text-right{ colspan: 3} - %a.edit-finalised.button.radius.expand.small{ href: 'javascript:void(0)', ng: { class: "{secondary: !showBought, primary: showBought}" } } + %td.text-right{ colspan: 3 } + - edit_path = changeable_orders.count > 1 ? spree.user_path : spree.order_path(changeable_orders.first) + %a.edit-finalised.button.radius.expand.small{ href: edit_path, ng: { class: "{secondary: !showBought, primary: showBought}" } } = t(:orders_bought_edit_button) %i.ofn-i_007-caret-right From 47011e11fffb21a37c481b76fd49690d6a03f343 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 14:21:51 +1000 Subject: [PATCH 047/104] order_cycle.items_bought_by_user actually scopes to the current distributor --- app/models/order_cycle.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index ed07eda927..4c23a8703f 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -251,7 +251,7 @@ class OrderCycle < ActiveRecord::Base end def items_bought_by_user(user, distributor) - orders = Spree::Order.complete.where(user_id: user, order_cycle_id: self) + orders = Spree::Order.complete.where(user_id: user, distributor_id: distributor, order_cycle_id: self) items = [] orders.each do |o| items += o.line_items From b55036e16556bbc643fca4bcddf662f1982819a9 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 15:50:01 +1000 Subject: [PATCH 048/104] Adding alert to shopfront to alert user to presence of orders open for editing --- app/helpers/spree/orders_helper.rb | 13 +++++++++++++ app/views/enterprises/shop.html.haml | 5 +++++ app/views/spree/orders/_bought.html.haml | 3 +-- config/locales/en.yml | 4 ++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index a3183d8273..eb10adecef 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -24,5 +24,18 @@ module Spree distributor_id: current_distributor.id, order_cycle_id: current_order_cycle.id) end + + def changeable_orders_link_path + changeable_orders.one? ? spree.order_path(changeable_orders.first) : spree.account_path + end + + def shop_changeable_orders_alert_html + t(:shop_changeable_orders_alert_html, + count: changeable_orders.count, + path: changeable_orders_link_path, + order: changeable_orders.first.number, + shop: current_distributor.name, + oc_close: l(current_order_cycle.orders_close_at, format: :long)) + end end end diff --git a/app/views/enterprises/shop.html.haml b/app/views/enterprises/shop.html.haml index 569009db09..23c31e69aa 100644 --- a/app/views/enterprises/shop.html.haml +++ b/app/views/enterprises/shop.html.haml @@ -8,6 +8,11 @@ = inject_shop_enterprises %shop.darkswarm + - if changeable_orders.any? + .alert-box.info{ "ofn-inline-alert" => true, ng: { show: "visible" } } + = shop_changeable_orders_alert_html + %a.close{ ng: { click: "close()" } } × + - content_for :order_cycle_form do %div{"ng-controller" => "OrderCycleChangeCtrl", "ng-cloak" => true} diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml index 6c31acd25c..2de33307e9 100644 --- a/app/views/spree/orders/_bought.html.haml +++ b/app/views/spree/orders/_bought.html.haml @@ -5,8 +5,7 @@ %i{ ng: { class: "{ 'ofn-i_007-caret-right': !showBought, 'ofn-i_005-caret-down': showBought}"} } = t(:orders_bought_items_notice, count: @order.finalised_line_items.count) %td.text-right{ colspan: 3 } - - edit_path = changeable_orders.count > 1 ? spree.user_path : spree.order_path(changeable_orders.first) - %a.edit-finalised.button.radius.expand.small{ href: edit_path, ng: { class: "{secondary: !showBought, primary: showBought}" } } + %a.edit-finalised.button.radius.expand.small{ href: changeable_orders_link_path, ng: { class: "{secondary: !showBought, primary: showBought}" } } = t(:orders_bought_edit_button) %i.ofn-i_007-caret-right diff --git a/config/locales/en.yml b/config/locales/en.yml index 712ab9706f..48b4916fd4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -892,6 +892,10 @@ See the %{link} to find out more about %{sitename}'s features and to start using hubs_distance: Closest to hubs_distance_filter: "Show me shops near %{location}" + shop_changeable_orders_alert_html: + one: Your order with %{shop} / %{order} is open for review. You can make changes until %{oc_close}. + other: You have %{count} orders with %{shop} currently open for review. + products_clear_all: Clear all products_showing: "Showing:" products_with: with From 7ea74ccf4a961fa6b24256dfa6dad6c401d0b0d5 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 16:02:28 +1000 Subject: [PATCH 049/104] Order confirmation redirects 'Back to Cart' if cart is non-empty --- app/views/spree/orders/form/_update_buttons.html.haml | 11 ++++++++--- config/locales/en.yml | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index 77f31ce418..46d36e0e5c 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -1,8 +1,13 @@ .row .columns.small-12.medium-3 - = link_to main_app.shop_path, :class => "button expand" do - %i.ofn-i_008-caret-left - = t(:back_to_store) + - if current_order.andand.line_items.present? + = link_to spree.cart_path, :class => "button expand" do + %i.ofn-i_008-caret-left + = t(:order_back_to_cart) + - else + = link_to main_app.shop_path, :class => "button expand" do + %i.ofn-i_008-caret-left + = t(:order_back_to_store) - if order.changes_allowed? .columns.show-for-medium-up.medium-3   .columns.small-12.medium-3 diff --git a/config/locales/en.yml b/config/locales/en.yml index 48b4916fd4..b5735d34f2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -783,6 +783,8 @@ en: order_includes_tax: (includes tax) order_payment_paypal_successful: Your payment via PayPal has been processed successfully. order_hub_info: Hub Info + order_back_to_store: Back To Store + order_back_to_cart: Back To Cart bom_tip: "Use this page to alter product quantities across multiple orders. Products may also be removed from orders entirely, if required." From 840c936a6f0ba4ed1a64a5f0c454c62ca06bbb0e Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 16:06:58 +1000 Subject: [PATCH 050/104] OrderSerializer#changes_allowed_until returns 'Not allowed' unless changes are allowed --- app/serializers/api/order_serializer.rb | 1 + config/locales/en.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/serializers/api/order_serializer.rb b/app/serializers/api/order_serializer.rb index 4f07cdb962..807811461b 100644 --- a/app/serializers/api/order_serializer.rb +++ b/app/serializers/api/order_serializer.rb @@ -19,6 +19,7 @@ module Api end def changes_allowed_until + return I18n.t(:not_allowed) unless object.changes_allowed? I18n.l(object.order_cycle.andand.orders_close_at, format: :long) end diff --git a/config/locales/en.yml b/config/locales/en.yml index b5735d34f2..7c3a1738bc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -645,6 +645,7 @@ en: terms_of_service: "Terms of service" on_demand: On demand none: None + not_allowed: Not allowed label_shops: "Shops" label_map: "Map" From 3d0ada803f323c65318c730d7cb4b0374be56a13 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 12 Apr 2017 16:24:03 +1000 Subject: [PATCH 051/104] Test presence of 'Edit' link for previous orders in cart --- spec/features/consumer/shopping/cart_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index 19f2bc301e..15de00deb3 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -108,6 +108,7 @@ feature "full-page cart", js: true do expect(page).to_not have_content item1.variant.name expect(page).to_not have_content item2.variant.name + expect(page).to have_link I18n.t(:orders_bought_edit_button), href: spree.account_path find("td.toggle-bought").click expect(page).to have_content item1.variant.name From bfcde728554e7871a00d981dc6058c54d4004e5b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 21 Apr 2017 14:03:47 +1000 Subject: [PATCH 052/104] Use explicit format for dates on front-end account page --- app/serializers/api/order_serializer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/serializers/api/order_serializer.rb b/app/serializers/api/order_serializer.rb index 807811461b..7aa53a0d6b 100644 --- a/app/serializers/api/order_serializer.rb +++ b/app/serializers/api/order_serializer.rb @@ -15,12 +15,12 @@ module Api end def completed_at - object.completed_at.blank? ? "" : I18n.l(object.completed_at, format: :long) + object.completed_at.blank? ? "" : I18n.l(object.completed_at, format: "%b %d, %Y %H:%M") end def changes_allowed_until return I18n.t(:not_allowed) unless object.changes_allowed? - I18n.l(object.order_cycle.andand.orders_close_at, format: :long) + I18n.l(object.order_cycle.andand.orders_close_at, format: "%b %d, %Y %H:%M") end def total From 0029a1b6cf38f9215e18b0f0d9eb20d03b07efe7 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 27 Apr 2017 12:41:12 +1000 Subject: [PATCH 053/104] Ensure order adjustments are displayed in edit form for customers --- app/views/spree/orders/_form.html.haml | 8 ++++++++ spec/features/consumer/shopping/orders_spec.rb | 10 +++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index e7d5f69f72..7cb5c0f9bf 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -43,6 +43,14 @@ %span.order-total.distribution-total= display_checkout_admin_and_handling_adjustments_total_for(@order) %td + - checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment| + %tr.order-adjustment + %td.text-right{:colspan => "3"} + = adjustment.label + %td.text-right.total + %span= adjustment.display_amount.to_html + %td + %tr %td.text-right{colspan:"3"} %h5 diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb index 8a55439441..f5962a232a 100644 --- a/spec/features/consumer/shopping/orders_spec.rb +++ b/spec/features/consumer/shopping/orders_spec.rb @@ -8,13 +8,15 @@ feature "Order Management", js: true do let(:user) { create(:user, bill_address: address, ship_address: address) } let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true, charges_sales_tax: true) } let(:order_cycle) { create(:order_cycle) } + let(:shipping_method) { distributor.shipping_methods.first } let(:order) { create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor, user: user, bill_address: address, ship_address: address) } let!(:item1) { order.reload.line_items.first } let!(:item2) { create(:line_item, order: order) } let!(:item3) { create(:line_item, order: order) } before do - order.update_attributes(shipping_method_id: distributor.shipping_methods.first.id) + shipping_method.calculator.update_attributes(preferred_amount: 5.0) + order.update_attributes(shipping_method_id: shipping_method.id) order.reload.save quick_login_as user end @@ -49,10 +51,12 @@ feature "Order Management", js: true do end expect(find("tr.variant-#{item2.variant.id}")).to have_content item2.product.name expect(find("tr.variant-#{item3.variant.id}")).to have_content item3.product.name + expect(find("tr.order-adjustment")).to have_content "Shipping" + expect(find("tr.order-adjustment")).to have_content "$5.00" click_button I18n.t(:save_changes) - expect(find(".order-total.grand-total")).to have_content "$40.00" + expect(find(".order-total.grand-total")).to have_content "$45.00" expect(item1.reload.quantity).to eq 2 # Deleting an item @@ -60,7 +64,7 @@ feature "Order Management", js: true do click_link "delete_line_item_#{item2.id}" end - expect(find(".order-total.grand-total")).to have_content "$30.00" + expect(find(".order-total.grand-total")).to have_content "$35.00" expect(Spree::LineItem.find_by_id(item2.id)).to be nil # Cancelling the order From 314e9a4f15433271fb3b9b210d35681ec206d68f Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 27 Apr 2017 13:16:06 +1000 Subject: [PATCH 054/104] Open shopfront existing orders flash link in a new window --- config/locales/en.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 7c3a1738bc..f5935d819f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -896,8 +896,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using hubs_distance_filter: "Show me shops near %{location}" shop_changeable_orders_alert_html: - one: Your order with %{shop} / %{order} is open for review. You can make changes until %{oc_close}. - other: You have %{count} orders with %{shop} currently open for review. + one: Your order with %{shop} / %{order} is open for review. You can make changes until %{oc_close}. + other: You have %{count} orders with %{shop} currently open for review. products_clear_all: Clear all products_showing: "Showing:" From 68c8759af1e0a15fa8b08a215c70836b97ef7c3a Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 27 Apr 2017 13:18:05 +1000 Subject: [PATCH 055/104] Count of items in cart form looks is consistent with rest of UI (ie. uses quantities) --- app/views/spree/orders/_bought.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/orders/_bought.html.haml b/app/views/spree/orders/_bought.html.haml index 2de33307e9..fb66cd1525 100644 --- a/app/views/spree/orders/_bought.html.haml +++ b/app/views/spree/orders/_bought.html.haml @@ -3,7 +3,7 @@ %td.toggle-bought{ colspan: 2, ng: { click: 'showBought=!showBought' } } %h5.brick %i{ ng: { class: "{ 'ofn-i_007-caret-right': !showBought, 'ofn-i_005-caret-down': showBought}"} } - = t(:orders_bought_items_notice, count: @order.finalised_line_items.count) + = t(:orders_bought_items_notice, count: @order.finalised_line_items.sum(&:quantity)) %td.text-right{ colspan: 3 } %a.edit-finalised.button.radius.expand.small{ href: changeable_orders_link_path, ng: { class: "{secondary: !showBought, primary: showBought}" } } = t(:orders_bought_edit_button) From 314ccc2f276452579508508cae6698ce4ed698f5 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 27 Apr 2017 14:39:36 +1000 Subject: [PATCH 056/104] Ensuring that #items_bought_by_user doesn't return items from cancelled orders --- app/models/order_cycle.rb | 13 ++++--------- spec/models/order_cycle_spec.rb | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 4c23a8703f..64fcce4baf 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -251,16 +251,11 @@ class OrderCycle < ActiveRecord::Base end def items_bought_by_user(user, distributor) - orders = Spree::Order.complete.where(user_id: user, distributor_id: distributor, order_cycle_id: self) - items = [] - orders.each do |o| - items += o.line_items - end + # The Spree::Order.complete scope only checks for completed_at date, does not ensure state is "complete" + orders = Spree::Order.complete.where(state: "complete", user_id: user, distributor_id: distributor, order_cycle_id: self) + items = orders.map(&:line_items).flatten scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) - items.each do |li| - scoper.scope(li.variant) - end - items + items.each { |li| scoper.scope(li.variant) } end private diff --git a/spec/models/order_cycle_spec.rb b/spec/models/order_cycle_spec.rb index ca2c8260cf..8715e1ef5c 100644 --- a/spec/models/order_cycle_spec.rb +++ b/spec/models/order_cycle_spec.rb @@ -505,4 +505,22 @@ describe OrderCycle do OrderCycle.earliest_closing_times[e2.id].should == time2 end end + + describe "finding all line items sold by to a user by a given shop" do + let(:shop) { create(:enterprise) } + let(:user) { create(:user) } + let(:oc) { create(:order_cycle) } + let!(:order1) { create(:completed_order_with_totals, distributor: shop, user: user, order_cycle: oc) } + let!(:order2) { create(:completed_order_with_totals, distributor: create(:enterprise), user: user, order_cycle: oc) } + let!(:order3) { create(:completed_order_with_totals, distributor: shop, user: create(:user), order_cycle: oc) } + let!(:order4) { create(:completed_order_with_totals, distributor: shop, user: user, order_cycle: create(:order_cycle)) } + let!(:order5) { create(:completed_order_with_totals, distributor: shop, user: user, order_cycle: oc) } + + before { order5.cancel } + + it "only returns items from non-cancelled orders in the OC, placed by the user at the shop" do + items = oc.items_bought_by_user(user, shop) + expect(items).to eq order1.reload.line_items + end + end end From e79a23a5542058ef5e6d241d12d97ba0fbfd88cd Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 28 Apr 2017 14:42:00 +1000 Subject: [PATCH 057/104] Disabling save button on order page until changes are made to the order --- .../javascripts/darkswarm/directives/on_hand.js.coffee | 6 +++++- app/views/spree/orders/form/_update_buttons.html.haml | 5 +++-- app/views/spree/shared/_order_details.html.haml | 2 +- config/locales/en.yml | 1 + spec/features/consumer/shopping/orders_spec.rb | 6 ++++++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/darkswarm/directives/on_hand.js.coffee b/app/assets/javascripts/darkswarm/directives/on_hand.js.coffee index 610b11d3ca..3c51f86c2f 100644 --- a/app/assets/javascripts/darkswarm/directives/on_hand.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/on_hand.js.coffee @@ -6,7 +6,11 @@ Darkswarm.directive "ofnOnHand", -> # In cases where this field gets its value from the HTML element rather than the model, # initialise the model with the HTML value. if scope.$eval(attr.ngModel) == undefined - ngModel.$setViewValue elem.val() + # Don't dirty the model when we do this + setDirty = ngModel.$setDirty + ngModel.$setDirty = angular.noop + ngModel.$setViewValue(elem.val()) + ngModel.$setDirty = setDirty ngModel.$parsers.push (viewValue) -> on_hand = parseInt(attr.ofnOnHand) diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index 46d36e0e5c..35debc535f 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -15,6 +15,7 @@ %i.ofn-i_009-close = t(:cancel_order) .columns.small-12.medium-3 - = button_tag :class => 'button primary radius expand', :id => 'update-button' do + = button_tag :class => 'button primary radius expand', :id => 'update-button', "ng-disabled" => 'update_order_form.$pristine' do %i.ofn-i_051-check-big - = t(:save_changes) + %span{ ng: { show: 'update_order_form.$dirty' } }= t(:save_changes) + %span{ ng: { hide: 'update_order_form.$dirty' } }= t(:order_saved) diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index b9eeb26e77..50d72f8304 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -86,7 +86,7 @@ %br .row .columns.large-12 - = form_for order, html: {id: 'update-order'} do |order_form| + = form_for order, html: {id: 'update-order', name: 'update_order_form' } do |order_form| - if order.changes_allowed? = render 'spree/orders/form', order_form: order_form -else diff --git a/config/locales/en.yml b/config/locales/en.yml index f5935d819f..501b614e5a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1332,6 +1332,7 @@ Please follow the instructions there to make your enterprise visible on the Open price: "Price" on_hand: "On hand" save_changes: "Save Changes" + order_saved: "Order Saved" spree_admin_overview_enterprises_header: "My Enterprises" spree_admin_overview_enterprises_footer: "MANAGE MY ENTERPRISES" spree_admin_enterprises_hubs_name: "Name" diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb index f5962a232a..379f1b5197 100644 --- a/spec/features/consumer/shopping/orders_spec.rb +++ b/spec/features/consumer/shopping/orders_spec.rb @@ -43,12 +43,18 @@ feature "Order Management", js: true do it "allows quantity to be changed, items to be removed and the order to be cancelled" do visit spree.order_path(order) + expect(page).to have_button I18n.t(:order_saved), disabled: true + expect(page).to_not have_button I18n.t(:save_changes) + # Changing the quantity of an item within "tr.variant-#{item1.variant.id}" do expect(page).to have_content item1.product.name expect(page).to have_field 'order_line_items_attributes_0_quantity' fill_in 'order_line_items_attributes_0_quantity', with: 2 end + + expect(page).to have_button I18n.t(:save_changes) + expect(find("tr.variant-#{item2.variant.id}")).to have_content item2.product.name expect(find("tr.variant-#{item3.variant.id}")).to have_content item3.product.name expect(find("tr.order-adjustment")).to have_content "Shipping" From 6c90b4e6d099c6c591b2c975a2ebce075d5282ca Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 28 Apr 2017 15:18:35 +1000 Subject: [PATCH 058/104] Adding alert to order summary, notifying user of remaining time to make changes --- .../stylesheets/darkswarm/checkout.css.sass | 29 ++++++++++--------- app/helpers/spree/orders_helper.rb | 2 +- .../spree/shared/_order_details.html.haml | 5 ++++ config/locales/en.yml | 1 + 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/checkout.css.sass b/app/assets/stylesheets/darkswarm/checkout.css.sass index d5a2cb8104..f13d2d1bc6 100644 --- a/app/assets/stylesheets/darkswarm/checkout.css.sass +++ b/app/assets/stylesheets/darkswarm/checkout.css.sass @@ -6,23 +6,25 @@ background-color: #e1f0f5 padding: 1em width: 100% + border: none + color: inherit checkout display: block - @media all and (max-width: 640px) - &.row .row + @media all and (max-width: 640px) + &.row .row margin-left: 0 margin-right: 0 - + orderdetails .button, table width: 100% - @media all and (max-width: 640px) + @media all and (max-width: 640px) form.edit_order border: 1px solid $disabled-bright margin-bottom: 2rem - + #details, #billing, #shipping, #payment border: 0 margin: 1em 0 @@ -34,20 +36,20 @@ checkout margin: 0 padding: 0.65em background: #f7f7f7 - - .label + + .label font-size: 1em padding: 0.3rem 0.35rem 0.275rem // Logic to turn on & off the alerts for success against each fieldset - label, label.alert, label.success, &.valid label.alert, &.dirty label.success + label, label.alert, label.success, &.valid label.alert, &.dirty label.success display: none - &.dirty label.alert + &.dirty label.alert display: inline - &.dirty.valid label.alert - display: none + &.dirty.valid label.alert + display: none &.valid label.success display: inline @@ -60,7 +62,7 @@ checkout text-align: left // Logic to swap out up / down accordion icons - //Foundation overrides + //Foundation overrides dd > a @include csstrans background: $disabled-light !important @@ -68,7 +70,7 @@ checkout dd > a:hover background: $disabled-v-dark !important color: white - + dd span.accordion-up display: none @@ -79,4 +81,3 @@ checkout display: inline span.accordion-down display: none - diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index eb10adecef..c2c4e788cc 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -35,7 +35,7 @@ module Spree path: changeable_orders_link_path, order: changeable_orders.first.number, shop: current_distributor.name, - oc_close: l(current_order_cycle.orders_close_at, format: :long)) + oc_close: l(current_order_cycle.orders_close_at, format: "%b %d, %Y %H:%M")) end end end diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index 50d72f8304..63e0f4450b 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -86,6 +86,11 @@ %br .row .columns.large-12 + - if order.changes_allowed? + .alert-box.order-summary{ "ofn-inline-alert" => true, "ng-show" => "visible" } + = t(:orders_changeable_orders_alert_html, oc_close: l(order.order_cycle.orders_close_at, format: "%b %d, %Y %H:%M")) + %a.close{ "ng-click" => "close()" } × + = form_for order, html: {id: 'update-order', name: 'update_order_form' } do |order_form| - if order.changes_allowed? = render 'spree/orders/form', order_form: order_form diff --git a/config/locales/en.yml b/config/locales/en.yml index 501b614e5a..5e5d067b31 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -898,6 +898,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using shop_changeable_orders_alert_html: one: Your order with %{shop} / %{order} is open for review. You can make changes until %{oc_close}. other: You have %{count} orders with %{shop} currently open for review. + orders_changeable_orders_alert_html: This order has been confirmed, but you can make changes until %{oc_close}. products_clear_all: Clear all products_showing: "Showing:" From c0445d46f3f34c42a6ae575ed03fcc434eda1b59 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 28 Apr 2017 15:26:37 +1000 Subject: [PATCH 059/104] Changeable orders ignores cancelled orders --- app/helpers/spree/orders_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index c2c4e788cc..2388cd3eea 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -20,6 +20,7 @@ module Spree def changeable_orders return [] unless spree_current_user && current_distributor && current_order_cycle Spree::Order.complete.where( + state: 'complete', user_id: spree_current_user.id, distributor_id: current_distributor.id, order_cycle_id: current_order_cycle.id) From 07b2f0a7c248749e32cce56ac93eb899a1ed6119 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 28 Apr 2017 15:44:41 +1000 Subject: [PATCH 060/104] Showing banner for distributor of order on order summary, regardless of current_distributor --- app/views/shopping_shared/_details.html.haml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/views/shopping_shared/_details.html.haml b/app/views/shopping_shared/_details.html.haml index d060c130ca..ec73b2f5af 100644 --- a/app/views/shopping_shared/_details.html.haml +++ b/app/views/shopping_shared/_details.html.haml @@ -1,14 +1,18 @@ +- distributor = @order.andand.distributor || current_distributor + %navigation %distributor.details.row .small-12.medium-6.large-6.columns #distributor_title - - if current_distributor.logo? - %img.left{src: current_distributor.logo.url(:thumb)} + - if distributor.logo? + %img.left{src: distributor.logo.url(:thumb)} %h3 - = current_distributor.name - %location= current_distributor.address.city + = distributor.name + %location= distributor.address.city / Will this needs to be a drop-down to choose either pick-up point or delivery once shipping methods are implemented + .small-12.medium-6.large-6.columns = render partial: "shopping_shared/order_cycles" -= render partial: "shopping_shared/tabs" + += render partial: "shopping_shared/tabs" if distributor == current_distributor From 3df629bc6e30692a14bc5e0bfbaf634086ff9668 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 3 May 2017 11:36:45 +1000 Subject: [PATCH 061/104] Prevent users from removing the final line item of an order, suggest cancelling instead --- .../spree/orders_controller_decorator.rb | 14 ++++++++ config/locales/en.yml | 1 + .../spree/orders_controller_spec.rb | 34 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 7f87d198e9..356691958e 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -8,6 +8,7 @@ Spree::OrdersController.class_eval do prepend_before_filter :require_order_cycle, only: :edit prepend_before_filter :require_distributor_chosen, only: :edit before_filter :check_hub_ready_for_checkout, only: :edit + before_filter :check_at_least_one_line_item, only: :update include OrderCyclesHelper layout 'darkswarm' @@ -223,4 +224,17 @@ Spree::OrdersController.class_eval do return order if order.andand.changes_allowed? && can?(:update, order) current_order end + + def check_at_least_one_line_item + order = order_to_update + return unless order.complete? + + items = params[:order][:line_items_attributes] + .andand.select{ |k,attrs| attrs["quantity"].to_i > 0 } + + if items.empty? + flash[:error] = I18n.t(:orders_cannot_remove_the_final_item) + redirect_to order_path(order) + end + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 5e5d067b31..9aa3a0de57 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1060,6 +1060,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using orders_show_confirmed: Confirmed orders_your_order_has_been_cancelled: "Your order has been cancelled" orders_could_not_cancel: "Sorry, the order could not be cancelled" + orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." orders_bought_items_notice: one: An additional item is already confirmed for this order cycle other: "%{count} additional items already confirmed for this order cycle" diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index 36e2182cd6..5008042c34 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -191,6 +191,40 @@ describe Spree::OrdersController do end end + describe "removing items from a completed order" do + let(:order) { create(:completed_order_with_totals) } + let!(:line_item) { order.reload.line_items.first } + let(:params) { { order: {} } } + + before { allow(subject).to receive(:order_to_update) { order } } + + context "when more than one item remains" do + before do + params[:order][:line_items_attributes] = { "0" => {quantity: "1", id: line_item.id} } + end + + it "does not remove the item, flash suggests cancellation" do + spree_post :update, params + expect(flash[:error]).to be nil + expect(response).to redirect_to spree.order_path(order) + expect(order.reload.line_items.count).to eq 1 + end + end + + context "when only one item remains" do + before do + params[:order][:line_items_attributes] = { "0" => {quantity: "0", id: line_item.id} } + end + + it "does not remove the item, flash suggests cancellation" do + spree_post :update, params + expect(flash[:error]).to eq I18n.t(:orders_cannot_remove_the_final_item) + expect(response).to redirect_to spree.order_path(order) + expect(order.reload.line_items.count).to eq 1 + end + end + end + describe "#order_to_update" do let!(:current_order) { double(:current_order) } let(:params) { { } } From 348ab81c423e1354ad07ef131230cb355e599aa0 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 3 May 2017 16:09:47 +1000 Subject: [PATCH 062/104] Overriding #increment! using variant overrides --- app/models/variant_override.rb | 8 ++++++++ lib/open_food_network/scope_variant_to_hub.rb | 8 ++++++++ spec/models/variant_override_spec.rb | 20 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index e96b56db56..07b2c78cc8 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -58,6 +58,14 @@ class VariantOverride < ActiveRecord::Base end end + def increment_stock!(quantity) + if stock_overridden? + increment! :count_on_hand, quantity + else + Bugsnag.notify RuntimeError.new "Attempting to decrement stock level on a VariantOverride without a count_on_hand specified." + end + end + def default_stock? default_stock.present? end diff --git a/lib/open_food_network/scope_variant_to_hub.rb b/lib/open_food_network/scope_variant_to_hub.rb index dadcfbd9a8..e70e7966e1 100644 --- a/lib/open_food_network/scope_variant_to_hub.rb +++ b/lib/open_food_network/scope_variant_to_hub.rb @@ -47,6 +47,14 @@ module OpenFoodNetwork end end + def increment!(attribute, by=1) + if attribute == :count_on_hand && @variant_override.andand.stock_overridden? + @variant_override.increment_stock! by + else + super + end + end + def sku @variant_override.andand.sku || super end diff --git a/spec/models/variant_override_spec.rb b/spec/models/variant_override_spec.rb index a24a921f43..91956a082c 100644 --- a/spec/models/variant_override_spec.rb +++ b/spec/models/variant_override_spec.rb @@ -97,6 +97,26 @@ describe VariantOverride do end end + describe "incrementing stock" do + let!(:vo) { create(:variant_override, variant: variant, hub: hub, count_on_hand: 8) } + + context "when the vo overrides stock" do + it "increments stock" do + vo.increment_stock! 2 + vo.reload.count_on_hand.should == 10 + end + end + + context "when the vo doesn't override stock" do + before { vo.update_attributes(count_on_hand: nil) } + + it "silently logs an error" do + Bugsnag.should_receive(:notify) + vo.increment_stock! 2 + end + end + end + describe "checking default stock value is present" do it "returns true when a default stock level has been set" do vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20) From 579f3bf90a9eb8d6b0919789c50aa93acc6d6f34 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 3 May 2017 16:11:39 +1000 Subject: [PATCH 063/104] Changing quantity and deleting line_items of completed orders works with inventory where present --- app/models/spree/line_item_decorator.rb | 33 ++++++++++++++++ spec/models/spree/line_item_spec.rb | 50 +++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 31d263761f..cdbae883fc 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -94,8 +94,41 @@ Spree::LineItem.class_eval do (final_weight_volume || 0) / 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 + private + def scoper + return @scoper unless @scoper.nil? + @scoper = OpenFoodNetwork::ScopeVariantToHub.new(order.distributor) + end + def calculate_final_weight_volume if final_weight_volume.present? && quantity_was > 0 self.final_weight_volume = final_weight_volume * quantity / quantity_was diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index 111108f7b4..d5ab83b59c 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -77,6 +77,56 @@ module Spree end end + describe "tracking stock when quantity is changed" do + context "when the order is already complete" do + let(:shop) { create(:distributor_enterprise)} + let(:order) { create(:completed_order_with_totals, distributor: shop) } + let!(:line_item) { order.reload.line_items.first } + let!(:variant) { line_item.variant } + + context "when a variant override applies" do + let!(:vo) { create(:variant_override, hub: shop, variant: variant, count_on_hand: 3 ) } + + it "draws stock from the variant override" do + expect(vo.reload.count_on_hand).to eq 3 + expect{line_item.increment!(:quantity)}.to_not change{Spree::Variant.find(variant.id).on_hand} + expect(vo.reload.count_on_hand).to eq 2 + end + end + + context "when a variant override does not apply" do + it "draws stock from the variant" do + expect{line_item.increment!(:quantity)}.to change{Spree::Variant.find(variant.id).on_hand}.by(-1) + end + end + end + end + + describe "tracking stock when a line item is destroyed" do + context "when the order is already complete" do + let(:shop) { create(:distributor_enterprise)} + let(:order) { create(:completed_order_with_totals, distributor: shop) } + let!(:line_item) { order.reload.line_items.first } + let!(:variant) { line_item.variant } + + context "when a variant override applies" do + let!(:vo) { create(:variant_override, hub: shop, variant: variant, count_on_hand: 3 ) } + + it "restores stock to the variant override" do + expect(vo.reload.count_on_hand).to eq 3 + expect{line_item.destroy}.to_not change{Spree::Variant.find(variant.id).on_hand} + expect(vo.reload.count_on_hand).to eq 4 + end + end + + context "when a variant override does not apply" do + it "restores stock to the variant" do + expect{line_item.destroy}.to change{Spree::Variant.find(variant.id).on_hand}.by(1) + end + end + end + end + describe "calculating price with adjustments" do it "does not return fractional cents" do li = LineItem.new From 217eda8362d30f64d5bd16e360a8361f3309be27 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 4 May 2017 18:26:07 +1000 Subject: [PATCH 064/104] Shipping and payment fees are updated for completed orders when the order changes --- app/models/spree/order_decorator.rb | 13 ++- .../controllers/line_items_controller_spec.rb | 82 +++++++++++++------ spec/factories.rb | 2 +- spec/models/spree/order_spec.rb | 63 ++++++++------ 4 files changed, 104 insertions(+), 56 deletions(-) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index a1b2ee0b56..2691b15798 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -21,6 +21,9 @@ Spree::Order.class_eval do 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 @@ -141,26 +144,20 @@ Spree::Order.class_eval do # After changing line items of a completed order def update_shipping_fees! - line_items(:reload) shipments.each do |shipment| next if shipment.shipped? update_adjustment! shipment.adjustment shipment.save # updates included tax end - update_totals - save end # After changing line items of a completed order def update_payment_fees! - payments(:reload) - line_items(:reload) payments.each do |payment| next if payment.completed? update_adjustment! payment.adjustment + payment.save end - update_totals - save end def cap_quantity_at_stock! @@ -350,7 +347,7 @@ Spree::Order.class_eval do def update_adjustment!(adjustment) locked = adjustment.locked adjustment.locked = false - adjustment.update! + adjustment.update!(self) adjustment.locked = locked end end diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 2fcaf00d30..3ee277f4fe 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -60,31 +60,67 @@ describe LineItemsController do expect { item.reload }.to raise_error end - it "updates fees" do - Spree::Config.shipment_inc_vat = true - Spree::Config.shipping_tax_rate = 0.25 - distributor = create(:distributor_enterprise, charges_sales_tax: true, allow_order_changes: true) - shipping_fee = 3 - payment_fee = 5 - order = create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) + describe "destroying a line item" do + context "where shipping and payment fees apply" do + let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true, allow_order_changes: true) } + let(:shipping_fee) { 3 } + let(:payment_fee) { 5 } + let(:order) { create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) } - # Sanity check fees - item_num = order.line_items.length - initial_fees = item_num * (shipping_fee + payment_fee) - expect(order.adjustment_total).to eq initial_fees - expect(order.shipment.adjustment.included_tax).to eq 1.2 + before do + Spree::Config.shipment_inc_vat = true + Spree::Config.shipping_tax_rate = 0.25 + end - # Delete the item - item = order.line_items.first - controller.stub spree_current_user: order.user - request = { format: :json, id: item } - delete :destroy, request - expect(response.status).to eq 204 + it "updates the fees" do + # Sanity check fees + item_num = order.line_items.length + initial_fees = item_num * (shipping_fee + payment_fee) + expect(order.adjustment_total).to eq initial_fees + expect(order.shipment.adjustment.included_tax).to eq 1.2 - # Check the fees again - order.reload - order.shipment.reload - expect(order.adjustment_total).to eq initial_fees - shipping_fee - payment_fee - expect(order.shipment.adjustment.included_tax).to eq 0.6 + # Delete the item + item = order.line_items.first + controller.stub spree_current_user: order.user + request = { format: :json, id: item } + delete :destroy, request + expect(response.status).to eq 204 + + # Check the fees again + order.reload + order.shipment.reload + expect(order.adjustment_total).to eq initial_fees - shipping_fee - payment_fee + expect(order.shipment.adjustment.amount).to eq shipping_fee + expect(order.payment.adjustment.amount).to eq payment_fee + expect(order.shipment.adjustment.included_tax).to eq 0.6 + end + end + + context "where enterprise fees apply" do + let(:user) { create(:user) } + let(:variant) { create(:variant) } + let(:distributor) { create(:distributor_enterprise, allow_order_changes: true) } + let(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) } + let(:enterprise_fee) { create(:enterprise_fee, calculator: Spree::Calculator::PerItem.new ) } + let!(:exchange) { create(:exchange, sender: variant.product.supplier, receiver: order_cycle.coordinator, variants: [variant], enterprise_fees: [enterprise_fee]) } + let!(:order) do + order = create(:order, distributor: distributor, order_cycle: order_cycle, user: user) + order.line_items << build(:line_item, variant: variant) + order.update_distribution_charge! + order.save! + order + end + let(:params) { { format: :json, id: order.line_items.first } } + + it "updates the fees" do + expect(order.adjustment_total).to eq enterprise_fee.calculator.preferred_amount + + controller.stub spree_current_user: user + delete :destroy, params + expect(response.status).to eq 204 + + expect(order.reload.adjustment_total).to eq 0 + end + end end end diff --git a/spec/factories.rb b/spec/factories.rb index 4c3cc67ebd..14f08ca619 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -272,7 +272,7 @@ FactoryGirl.define do payment_calculator = build(:calculator_per_item, preferred_amount: evaluator.payment_fee) payment_method = create(:payment_method, calculator: payment_calculator) create(:payment, order: order, amount: order.total, payment_method: payment_method, state: 'checkout') - order.finalize! + while !order.completed? do break unless order.next! end end end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 763f7dd6c4..e7c46c27cb 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -656,44 +656,59 @@ describe Spree::Order do let(:order) { create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) } let(:shipping_fee) { 3 } let(:payment_fee) { 5 } + let(:item_num) { order.line_items.length } + let(:expected_fees) { item_num * (shipping_fee + payment_fee) } before do Spree::Config.shipment_inc_vat = true Spree::Config.shipping_tax_rate = 0.25 - end - it "updates shipping fees" do # Sanity check the fees expect(order.adjustments.length).to eq 2 - item_num = order.line_items.length expect(item_num).to eq 2 - expected_fees = item_num * (shipping_fee + payment_fee) expect(order.adjustment_total).to eq expected_fees expect(order.shipment.adjustment.included_tax).to eq 1.2 - - # Delete the item - order.line_items.first.destroy - order.update_shipping_fees! - - # Check if fees got updated - expect(order.adjustments.length).to eq 2 - expect(order.line_items.length).to eq item_num - 1 - expect(order.adjustment_total).to eq expected_fees - shipping_fee - expect(order.shipment.adjustment.included_tax).to eq 0.6 end - it "updates transaction fees" do - item_num = order.line_items.length - initial_fees = item_num * (shipping_fee + payment_fee) + context "removing line_items" do + it "updates shipping and transaction fees" do + # Setting quantity of an item to zero + order.update_attributes(line_items_attributes: [{id: order.line_items.first.id, quantity: 0}]) - # Delete the item - order.line_items.first.destroy - order.update_payment_fees! + # Check if fees got updated + order.reload + expect(order.adjustment_total).to eq expected_fees - shipping_fee - payment_fee + expect(order.shipment.adjustment.included_tax).to eq 0.6 + end + end - # Check if fees got updated - expect(order.adjustments.length).to eq 2 - expect(order.line_items.length).to eq item_num - 1 - expect(order.adjustment_total).to eq initial_fees - payment_fee + context "changing the shipping method to one without fees" do + let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 0)) } + + it "updates shipping fees" do + # Change the shipping method + order.shipment.update_attributes(shipping_method_id: shipping_method.id) + order.save + + # Check if fees got updated + order.reload + expect(order.adjustment_total).to eq expected_fees - (item_num * shipping_fee) + expect(order.shipment.adjustment.included_tax).to eq 0 + end + end + + context "changing the payment method to one without fees" do + let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 0)) } + + it "removes transaction fees" do + # Change the payment method + order.payment.update_attributes(payment_method_id: payment_method.id) + order.save + + # Check if fees got updated + order.reload + expect(order.adjustment_total).to eq expected_fees - (item_num * payment_fee) + end end end From f977a05b081fb04f6fcc8dce45aa821ec66f3a6d Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 5 May 2017 08:50:45 +1000 Subject: [PATCH 065/104] Fixing broken spec for fetching list of bought items as json --- .../controllers/line_items_controller_spec.rb | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 3ee277f4fe..2b7ee1c247 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -2,25 +2,31 @@ require 'spec_helper' describe LineItemsController do let(:item) { create(:line_item) } + let(:user) { create(:user) } + let(:distributor) { create(:distributor_enterprise) } + let(:order_cycle) { create(:simple_order_cycle) } + let(:completed_order) do + order = create(:completed_order_with_totals, user: user, distributor: distributor, order_cycle: order_cycle) + while !order.completed? do break unless order.next! end + order + end let(:item_with_oc) do - order_cycle = create(:simple_order_cycle) - distributor = create(:distributor_enterprise) + item.order.user = user item.order.order_cycle = order_cycle item.order.distributor = distributor item.order.save item end - it "lists bought items" do - item.order.finalize! - controller.stub spree_current_user: item.order.user + it "lists items bought by the user from the same shop in the same order_cycle" do + controller.stub spree_current_user: completed_order.user controller.stub current_order_cycle: item_with_oc.order.order_cycle controller.stub current_distributor: item_with_oc.order.distributor get :index, { format: :json } expect(response.status).to eq 200 json_response = JSON.parse(response.body) - expect(json_response.length).to eq 1 - expect(json_response[0]['id']).to eq item.id + expect(json_response.length).to eq completed_order.line_items(:reload).count + expect(json_response[0]['id']).to eq completed_order.line_items.first.id end it "fails without line item id" do From 5eadb33db94475f4895f31e188de5096a5b40cad Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 5 May 2017 11:44:05 +1000 Subject: [PATCH 066/104] Using changes_allowed? to authorize cancellation of line_items --- app/models/spree/ability_decorator.rb | 3 +- app/models/spree/order_decorator.rb | 4 - .../controllers/line_items_controller_spec.rb | 155 +++++++++++------- spec/factories.rb | 2 +- 4 files changed, 97 insertions(+), 67 deletions(-) diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 6c5cad6fb3..2b3843bb6e 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -53,7 +53,8 @@ class AbilityDecorator def add_shopping_abilities(user) can [:destroy], Spree::LineItem do |item| - item.andand.order.andand.can_remove_items? user + user == item.order.user && + item.order.changes_allowed? end can [:cancel], Spree::Order do |order| order.user == user diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 2691b15798..4ed49728ff 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -282,10 +282,6 @@ Spree::Order.class_eval do Delayed::Job.enqueue ConfirmOrderJob.new(id) unless account_invoice? end - def can_remove_items?(user) - user_id == user.id && distributor.andand.allow_order_changes? && order_cycle.andand.open? - end - def changes_allowed? complete? && distributor.andand.allow_order_changes? && order_cycle.andand.open? end diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 2b7ee1c247..ba78537fd7 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -1,72 +1,105 @@ require 'spec_helper' describe LineItemsController do - let(:item) { create(:line_item) } let(:user) { create(:user) } let(:distributor) { create(:distributor_enterprise) } let(:order_cycle) { create(:simple_order_cycle) } - let(:completed_order) do - order = create(:completed_order_with_totals, user: user, distributor: distributor, order_cycle: order_cycle) - while !order.completed? do break unless order.next! end - order - end - let(:item_with_oc) do - item.order.user = user - item.order.order_cycle = order_cycle - item.order.distributor = distributor - item.order.save - item + + context "listing bought items" do + let!(:completed_order) do + order = create(:completed_order_with_totals, user: user, distributor: distributor, order_cycle: order_cycle) + while !order.completed? do break unless order.next! end + order + end + + before do + controller.stub spree_current_user: user + controller.stub current_order_cycle: order_cycle + controller.stub current_distributor: distributor + end + + it "lists items bought by the user from the same shop in the same order_cycle" do + get :index, { format: :json } + expect(response.status).to eq 200 + json_response = JSON.parse(response.body) + expect(json_response.length).to eq completed_order.line_items(:reload).count + expect(json_response[0]['id']).to eq completed_order.line_items.first.id + end end - it "lists items bought by the user from the same shop in the same order_cycle" do - controller.stub spree_current_user: completed_order.user - controller.stub current_order_cycle: item_with_oc.order.order_cycle - controller.stub current_distributor: item_with_oc.order.distributor - get :index, { format: :json } - expect(response.status).to eq 200 - json_response = JSON.parse(response.body) - expect(json_response.length).to eq completed_order.line_items(:reload).count - expect(json_response[0]['id']).to eq completed_order.line_items.first.id - end + describe "destroying a line item on a completed order" do + let(:item) do + order = create(:completed_order_with_totals) + item = create(:line_item, order: order) + while !order.completed? do break unless order.next! end + item + end - it "fails without line item id" do - expect { delete :destroy }.to raise_error - end + before { controller.stub spree_current_user: item.order.user } - it "denies deletion without order cycle" do - request = { format: :json, id: item } - delete :destroy, request - expect(response.status).to eq 403 - expect { item.reload }.to_not raise_error - end + context "without a line item id" do + it "fails and raises an error" do + expect { delete :destroy }.to raise_error + end + end - it "denies deletion without user" do - request = { format: :json, id: item_with_oc } - delete :destroy, request - expect(response.status).to eq 403 - expect { item.reload }.to_not raise_error - end + context "with a line item id" do + let(:params) { { format: :json, id: item } } - it "denies deletion if editing is not allowed" do - controller.stub spree_current_user: item.order.user - request = { format: :json, id: item_with_oc } - delete :destroy, request - expect(response.status).to eq 403 - expect { item.reload }.to_not raise_error - end + context "without a user" do + it "denies deletion" do + delete :destroy, params + expect(response.status).to eq 403 + expect { item.reload }.to_not raise_error + end + end - it "deletes the line item if allowed" do - controller.stub spree_current_user: item.order.user - distributor = item_with_oc.order.distributor - distributor.allow_order_changes = true - distributor.save - request = { format: :json, id: item_with_oc } - delete :destroy, request - expect(response.status).to eq 204 - expect { item.reload }.to raise_error - end + context "where the item's order is associated with the current user" do + before { item.order.update_attributes(user_id: user.id) } + + context "without an order cycle" do + it "denies deletion" do + delete :destroy, params + expect(response.status).to eq 403 + expect { item.reload }.to_not raise_error + end + end + + context "with an order cycle" do + before { item.order.update_attributes(order_cycle_id: order_cycle.id) } + + context "without a distributor" do + it "denies deletion" do + delete :destroy, params + expect(response.status).to eq 403 + expect { item.reload }.to_not raise_error + end + end + + context "where the item's order has a distributor" do + before { item.order.update_attributes(distributor_id: distributor.id) } + context "where changes are not allowed" do + it "denies deletion" do + delete :destroy, params + expect(response.status).to eq 403 + expect { item.reload }.to_not raise_error + end + end + + context "where changes are allowed" do + before { distributor.update_attributes(allow_order_changes: true) } + + it "deletes the line item" do + delete :destroy, params + expect(response.status).to eq 204 + expect { item.reload }.to raise_error + end + end + end + end + end + end - describe "destroying a line item" do context "where shipping and payment fees apply" do let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true, allow_order_changes: true) } let(:shipping_fee) { 3 } @@ -107,19 +140,19 @@ describe LineItemsController do let(:variant) { create(:variant) } let(:distributor) { create(:distributor_enterprise, allow_order_changes: true) } let(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) } - let(:enterprise_fee) { create(:enterprise_fee, calculator: Spree::Calculator::PerItem.new ) } - let!(:exchange) { create(:exchange, sender: variant.product.supplier, receiver: order_cycle.coordinator, variants: [variant], enterprise_fees: [enterprise_fee]) } + let(:enterprise_fee) { create(:enterprise_fee, calculator: build(:calculator_per_item) ) } + let!(:exchange) { create(:exchange, incoming: true, sender: variant.product.supplier, receiver: order_cycle.coordinator, variants: [variant], enterprise_fees: [enterprise_fee]) } let!(:order) do - order = create(:order, distributor: distributor, order_cycle: order_cycle, user: user) - order.line_items << build(:line_item, variant: variant) + order = create(:completed_order_with_totals, user: user, distributor: distributor, order_cycle: order_cycle) + order.reload.line_items.first.update_attributes(variant_id: variant.id) + while !order.completed? do break unless order.next! end order.update_distribution_charge! - order.save! order end let(:params) { { format: :json, id: order.line_items.first } } it "updates the fees" do - expect(order.adjustment_total).to eq enterprise_fee.calculator.preferred_amount + expect(order.reload.adjustment_total).to eq enterprise_fee.calculator.preferred_amount controller.stub spree_current_user: user delete :destroy, params diff --git a/spec/factories.rb b/spec/factories.rb index 14f08ca619..5b4df5cf38 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -263,7 +263,7 @@ FactoryGirl.define do shipping_method do shipping_calculator = build(:calculator_per_item, preferred_amount: shipping_fee) - create(:shipping_method, calculator: shipping_calculator, require_ship_address: false) + create(:shipping_method, calculator: shipping_calculator, require_ship_address: false, distributors: [distributor]) end after(:create) do |order, evaluator| From c3eda435eb03b6f8490b0ba0638ee6e86eec4aeb Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 5 May 2017 12:05:57 +1000 Subject: [PATCH 067/104] Hiding 'Back to Cart' and 'Back to Store' buttons on completed orders when distributor does not match cart --- .../spree/orders/form/_update_buttons.html.haml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index 35debc535f..9d62b720d8 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -1,13 +1,16 @@ .row .columns.small-12.medium-3 - - if current_order.andand.line_items.present? - = link_to spree.cart_path, :class => "button expand" do - %i.ofn-i_008-caret-left - = t(:order_back_to_cart) + - if current_order.andand.distributor == @order.distributor + - if current_order.line_items.present? + = link_to spree.cart_path, :class => "button expand" do + %i.ofn-i_008-caret-left + = t(:order_back_to_cart) + - else + = link_to main_app.shop_path, :class => "button expand" do + %i.ofn-i_008-caret-left + = t(:order_back_to_store) - else - = link_to main_app.shop_path, :class => "button expand" do - %i.ofn-i_008-caret-left - = t(:order_back_to_store) +   - if order.changes_allowed? .columns.show-for-medium-up.medium-3   .columns.small-12.medium-3 From 8c8b40c5a846dbd4b7e676d1f68390cbc9db5fdf Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 5 May 2017 12:20:00 +1000 Subject: [PATCH 068/104] Showing order cycle close time on banner when multiple open orders are present --- app/helpers/spree/orders_helper.rb | 3 ++- config/locales/en.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index 2388cd3eea..790ff1b155 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -18,6 +18,7 @@ module Spree end def changeable_orders + # Only returns open order for the current user + shop + oc combo return [] unless spree_current_user && current_distributor && current_order_cycle Spree::Order.complete.where( state: 'complete', @@ -36,7 +37,7 @@ module Spree path: changeable_orders_link_path, order: changeable_orders.first.number, shop: current_distributor.name, - oc_close: l(current_order_cycle.orders_close_at, format: "%b %d, %Y %H:%M")) + oc_close: l(current_order_cycle.orders_close_at, format: "%A, %b %d, %Y @ %H:%M")) end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 9aa3a0de57..7ffb769534 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -897,7 +897,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using shop_changeable_orders_alert_html: one: Your order with %{shop} / %{order} is open for review. You can make changes until %{oc_close}. - other: You have %{count} orders with %{shop} currently open for review. + other: You have %{count} orders with %{shop} currently open for review. You can make changes until %{oc_close}. orders_changeable_orders_alert_html: This order has been confirmed, but you can make changes until %{oc_close}. products_clear_all: Clear all From 08e391856c7feff75d137463c615ca5ce0e7880e Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 5 May 2017 15:17:14 +1000 Subject: [PATCH 069/104] Ask user to confirm cancellation of order --- .../darkswarm/directives/confirm_link_click.js.coffee | 9 +++++++++ app/views/spree/orders/form/_update_buttons.html.haml | 2 +- app/views/spree/users/_open_orders.html.haml | 2 +- config/locales/en.yml | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/directives/confirm_link_click.js.coffee diff --git a/app/assets/javascripts/darkswarm/directives/confirm_link_click.js.coffee b/app/assets/javascripts/darkswarm/directives/confirm_link_click.js.coffee new file mode 100644 index 0000000000..b5da68d4dc --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/confirm_link_click.js.coffee @@ -0,0 +1,9 @@ +Darkswarm.directive "confirmLinkClick", ($window) -> + restrict: 'A' + scope: + confirmMsg: '@confirmLinkClick' + link: (scope, elem, attr) -> + elem.bind 'click', (event) -> + unless confirm(scope.confirmMsg) + event.preventDefault() + event.stopPropagation() diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index 9d62b720d8..7a89ab25b4 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -14,7 +14,7 @@ - if order.changes_allowed? .columns.show-for-medium-up.medium-3   .columns.small-12.medium-3 - = link_to spree.cancel_order_path(@order), method: :put, :class => "button secondary expand" do + = link_to spree.cancel_order_path(@order), method: :put, :class => "button secondary expand", "confirm-link-click" => t('orders_confirm_cancel') do %i.ofn-i_009-close = t(:cancel_order) .columns.small-12.medium-3 diff --git a/app/views/spree/users/_open_orders.html.haml b/app/views/spree/users/_open_orders.html.haml index c8efbfb4f4..5f78738e34 100644 --- a/app/views/spree/users/_open_orders.html.haml +++ b/app/views/spree/users/_open_orders.html.haml @@ -20,4 +20,4 @@ %td.order6.text-right.show-for-large-up.brick %a{"ng-href" => "{{::order.path}}" }= t('.edit') %td.order7.text-right - = link_to t('.cancel'), "", method: :put, "ng-href" => "{{::order.cancel_path}}" + = link_to t('.cancel'), "", method: :put, "ng-href" => "{{::order.cancel_path}}", "confirm-link-click" => t('orders_confirm_cancel') diff --git a/config/locales/en.yml b/config/locales/en.yml index 7ffb769534..ab882e9527 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1066,6 +1066,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using other: "%{count} additional items already confirmed for this order cycle" orders_bought_edit_button: Edit confirmed items orders_bought_already_confirmed: "* already confirmed" + orders_confirm_cancel: Are you sure you want to cancel this order? products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." From c4fbcb19d066523d934501e82b1fde017fea59cc Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 5 May 2017 15:28:01 +1000 Subject: [PATCH 070/104] Only show Admin & Handling fees once on completed order form --- app/helpers/checkout_helper.rb | 2 +- app/views/spree/orders/_form.html.haml | 2 +- config/locales/en.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb index eb4cb1fb65..193c4cef4d 100644 --- a/app/helpers/checkout_helper.rb +++ b/app/helpers/checkout_helper.rb @@ -16,7 +16,7 @@ module CheckoutHelper enterprise_fee_adjustments = adjustments.select { |a| a.originator_type == 'EnterpriseFee' && a.source_type != 'Spree::LineItem' } adjustments.reject! { |a| a.originator_type == 'EnterpriseFee' && a.source_type != 'Spree::LineItem' } unless exclude.include? :admin_and_handling - adjustments << Spree::Adjustment.new(label: 'Admin & Handling', amount: enterprise_fee_adjustments.sum(&:amount)) + adjustments << Spree::Adjustment.new(label: I18n.t(:orders_form_admin), amount: enterprise_fee_adjustments.sum(&:amount)) end adjustments diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index 7cb5c0f9bf..9813ff8642 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -43,7 +43,7 @@ %span.order-total.distribution-total= display_checkout_admin_and_handling_adjustments_total_for(@order) %td - - checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment| + - checkout_adjustments_for(@order, exclude: [:line_item, :admin_and_handling]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment| %tr.order-adjustment %td.text-right{:colspan => "3"} = adjustment.label diff --git a/config/locales/en.yml b/config/locales/en.yml index ab882e9527..0863fcef0f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1045,7 +1045,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using orders_edit_checkout: Checkout orders_form_empty_cart: "Empty cart" orders_form_subtotal: Produce subtotal - orders_form_admin: Admin and handling + orders_form_admin: Admin & Handling orders_form_total: Total orders_oc_expired_headline: Orders have closed for this order cycle orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." From 56c2350d36b761a35797f671420ccc4ddd67ae62 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 10 May 2017 12:04:32 +1000 Subject: [PATCH 071/104] Updating enterprise fees on completed order from OrdersController#update --- .../spree/orders_controller_decorator.rb | 7 +- .../spree/orders_controller_spec.rb | 77 ++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 356691958e..54b08aed8b 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -45,7 +45,12 @@ Spree::OrdersController.class_eval do render :edit and return unless apply_coupon_code - fire_event('spree.order.contents_changed') + if @order == current_order + fire_event('spree.order.contents_changed') + else + @order.update_distribution_charge! + end + respond_with(@order) do |format| format.html do if params.has_key?(:checkout) diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index 5008042c34..4ec0c63eed 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -191,6 +191,81 @@ describe Spree::OrdersController do end end + describe "removing items from a completed order" do + context "with shipping and transaction fees" do + let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true, allow_order_changes: true) } + let(:order) { create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee, payment_fee: payment_fee) } + let(:line_item1) { order.line_items.first } + let(:line_item2) { order.line_items.second } + let(:shipping_fee) { 3 } + let(:payment_fee) { 5 } + let(:item_num) { order.line_items.length } + let(:expected_fees) { item_num * (shipping_fee + payment_fee) } + let(:params) { { order: { line_items_attributes: { + "0" => {id: line_item1.id, quantity: 1}, + "1" => {id: line_item2.id, quantity: 0} + } } } } + + before do + Spree::Config.shipment_inc_vat = true + Spree::Config.shipping_tax_rate = 0.25 + + # Sanity check the fees + expect(order.adjustments.length).to eq 2 + expect(item_num).to eq 2 + expect(order.adjustment_total).to eq expected_fees + expect(order.shipment.adjustment.included_tax).to eq 1.2 + + allow(subject).to receive(:spree_current_user) { order.user } + allow(subject).to receive(:order_to_update) { order } + end + + it "updates the fees" do + # Setting quantity of an item to zero + spree_post :update, params + + # Check if fees got updated + order.reload + expect(order.line_items.count).to eq 1 + expect(order.adjustment_total).to eq expected_fees - shipping_fee - payment_fee + expect(order.shipment.adjustment.included_tax).to eq 0.6 + end + end + + context "with enterprise fees" do + let(:user) { create(:user) } + let(:variant) { create(:variant) } + let(:distributor) { create(:distributor_enterprise, allow_order_changes: true) } + let(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) } + let(:enterprise_fee) { create(:enterprise_fee, calculator: build(:calculator_per_item) ) } + let!(:exchange) { create(:exchange, incoming: true, sender: variant.product.supplier, receiver: order_cycle.coordinator, variants: [variant], enterprise_fees: [enterprise_fee]) } + let!(:order) do + order = create(:completed_order_with_totals, user: user, distributor: distributor, order_cycle: order_cycle) + order.reload.line_items.first.update_attributes(variant_id: variant.id) + while !order.completed? do break unless order.next! end + order.update_distribution_charge! + order + end + let(:params) { { order: { line_items_attributes: { + "0" => { id: order.line_items.first.id, quantity: 2 } + } } } } + + before do + allow(subject).to receive(:spree_current_user) { order.user } + allow(subject).to receive(:order_to_update) { order } + end + + it "updates the fees" do + expect(order.reload.adjustment_total).to eq enterprise_fee.calculator.preferred_amount + + controller.stub spree_current_user: user + spree_post :update, params + + expect(order.reload.adjustment_total).to eq enterprise_fee.calculator.preferred_amount * 2 + end + end + end + describe "removing items from a completed order" do let(:order) { create(:completed_order_with_totals) } let!(:line_item) { order.reload.line_items.first } @@ -203,7 +278,7 @@ describe Spree::OrdersController do params[:order][:line_items_attributes] = { "0" => {quantity: "1", id: line_item.id} } end - it "does not remove the item, flash suggests cancellation" do + it "removes the item" do spree_post :update, params expect(flash[:error]).to be nil expect(response).to redirect_to spree.order_path(order) From 958666624813210c65372589514e5b29f098aa69 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 12 May 2017 10:45:59 +1000 Subject: [PATCH 072/104] Updating translation for allow_changes option --- config/locales/en.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 0863fcef0f..ba8edf6bc2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -398,8 +398,8 @@ en: allow_guest_orders_true: "Allow guest checkout" allow_order_changes: "Change orders" allow_order_changes_tip: "Allow customers to change their order as long the order cycle is open." - allow_order_changes_false: "Placed orders cannot be changed" - allow_order_changes_true: "Customers can remove items from an order of an open order cycle" + allow_order_changes_false: "Placed orders cannot be changed / cancelled" + allow_order_changes_true: "Customers can change / cancel orders while order cycle is open" shopfront_message: Shopfront Message shopfront_message_placeholder: > An optional explanation for customers detailing how your shopfront works, From fab6d70832ed656ad9c4a68a850b8265c3458b98 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 12 May 2017 11:22:33 +1000 Subject: [PATCH 073/104] Changeable orders only returns orders if the shop allows changes --- app/helpers/spree/orders_helper.rb | 1 + spec/helpers/spree/orders_helper_spec.rb | 52 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 spec/helpers/spree/orders_helper_spec.rb diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index 790ff1b155..05644815b7 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -20,6 +20,7 @@ module Spree def changeable_orders # Only returns open order for the current user + shop + oc combo return [] unless spree_current_user && current_distributor && current_order_cycle + return [] unless current_distributor.allow_order_changes? Spree::Order.complete.where( state: 'complete', user_id: spree_current_user.id, diff --git a/spec/helpers/spree/orders_helper_spec.rb b/spec/helpers/spree/orders_helper_spec.rb new file mode 100644 index 0000000000..9c1787f16e --- /dev/null +++ b/spec/helpers/spree/orders_helper_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe Spree::OrdersHelper, type: :helper do + + describe "#changeable_orders" do + let(:complete_orders) { double(:complete_orders, where: "some_orders") } + + before do + allow(Spree::Order).to receive(:complete) { complete_orders } + allow(helper).to receive(:spree_current_user) { spree_current_user } + allow(helper).to receive(:current_distributor) { current_distributor } + allow(helper).to receive(:current_order_cycle) { current_order_cycle } + end + + context "when a current_user is defined" do + let(:spree_current_user) { double(:spree_current_user, id: 1) } + + context "when a current_distributor is defined" do + let(:current_distributor) { double(:current_distributor, id: 1) } + + context "when a current_order_cycle is defined" do + let(:current_order_cycle) { double(:current_order_cycle, id: 1) } + + context "when the current_distributor allows order changes" do + before { allow(current_distributor).to receive(:allow_order_changes?) { true} } + it { expect(helper.changeable_orders).to eq "some_orders" } + end + + context "when the current_distributor does not allow order changes" do + before { allow(current_distributor).to receive(:allow_order_changes?) { false } } + it { expect(helper.changeable_orders).to eq [] } + end + end + + context "when a current_order_cycle is not defined" do + let(:current_order_cycle) { nil } + it { expect(helper.changeable_orders).to eq [] } + end + end + + context "when a current_distributor is not defined" do + let(:current_distributor) { nil } + it { expect(helper.changeable_orders).to eq [] } + end + end + + context "when spree_current_user is not defined" do + let(:spree_current_user) { nil } + it { expect(helper.changeable_orders).to eq [] } + end + end +end From 77c8c85775803201e7fefc121d0030f282282db7 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 12 May 2017 12:18:05 +1000 Subject: [PATCH 074/104] Memoizing the result of OrdersController#order_to_update --- .../spree/orders_controller_decorator.rb | 17 +++++++++++------ .../controllers/spree/orders_controller_spec.rb | 12 ++++++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 54b08aed8b..7d221ddbeb 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -224,22 +224,27 @@ Spree::OrdersController.class_eval do n == Float::INFINITY ? 2147483647 : n end + # If a specific order is mentioned, check that it is COMPLETE, that changes + # are allowed and that the user has access. Return nil if not. def order_to_update - order = Spree::Order.complete.find_by_number(params[:id]) - return order if order.andand.changes_allowed? && can?(:update, order) - current_order + return @order_to_update if defined? @order_to_update + return @order_to_update = current_order unless params[:id] + @order_to_update = begin + order = Spree::Order.complete.find_by_number(params[:id]) + order = nil unless order.andand.changes_allowed? && can?(:update, order) + order + end end def check_at_least_one_line_item - order = order_to_update - return unless order.complete? + return unless order_to_update.andand.complete? items = params[:order][:line_items_attributes] .andand.select{ |k,attrs| attrs["quantity"].to_i > 0 } if items.empty? flash[:error] = I18n.t(:orders_cannot_remove_the_final_item) - redirect_to order_path(order) + redirect_to order_path(order_to_update) end end end diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index 4ec0c63eed..e7b5a7e12a 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -323,8 +323,8 @@ describe Spree::OrdersController do context "and the order is not complete" do let!(:order) { create(:order) } - it "returns the current_order" do - expect(controller.send(:order_to_update)).to eq current_order + it "returns nil" do + expect(controller.send(:order_to_update)).to eq nil end end @@ -334,8 +334,8 @@ describe Spree::OrdersController do context "and the user doesn't have permisson to 'update' the order" do before { allow(controller).to receive(:can?).with(:update, order) { false } } - it "returns the current_order" do - expect(controller.send(:order_to_update)).to eq current_order + it "returns nil" do + expect(controller.send(:order_to_update)).to eq nil end end @@ -344,8 +344,8 @@ describe Spree::OrdersController do context "and the order is not editable" do - it "returns the current_order" do - expect(controller.send(:order_to_update)).to eq current_order + it "returns nil" do + expect(controller.send(:order_to_update)).to eq nil end end From e47e10d267289e6bc5b349f3263b42f326a5463b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 12 May 2017 12:39:36 +1000 Subject: [PATCH 075/104] Removing n+1 query from #items_bought_by_user --- app/models/order_cycle.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 64fcce4baf..6a21b9309e 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -253,8 +253,8 @@ class OrderCycle < ActiveRecord::Base def items_bought_by_user(user, distributor) # The Spree::Order.complete scope only checks for completed_at date, does not ensure state is "complete" orders = Spree::Order.complete.where(state: "complete", user_id: user, distributor_id: distributor, order_cycle_id: self) - items = orders.map(&:line_items).flatten scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) + items = Spree::LineItem.joins(:order).merge(orders) items.each { |li| scoper.scope(li.variant) } end From 38d3b446cc171a34b9d939fd3402f810a7c8477b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 12 May 2017 12:45:42 +1000 Subject: [PATCH 076/104] Removing unused #tag_list method on VariantSerializer --- app/serializers/api/variant_serializer.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/serializers/api/variant_serializer.rb b/app/serializers/api/variant_serializer.rb index c1fa8d213b..0d060798d3 100644 --- a/app/serializers/api/variant_serializer.rb +++ b/app/serializers/api/variant_serializer.rb @@ -22,8 +22,4 @@ class Api::VariantSerializer < ActiveModel::Serializer def product_name object.product.name end - - def tag_list - object.tag_list if object.is_a? VariantOverride - end end From 61cb78fc93695236cfe3852b0969582f58e42253 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 12 May 2017 16:10:43 +1000 Subject: [PATCH 077/104] Tweaks to LineItemsController, renaming #index to #bought --- .../darkswarm/services/cart.js.coffee | 2 +- app/controllers/line_items_controller.rb | 13 +++++++---- config/routes.rb | 4 +++- .../controllers/line_items_controller_spec.rb | 23 ++++++++++--------- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index b80d9a14dd..b797390e73 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -126,7 +126,7 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo reloadFinalisedLineItems: => @line_items_finalised = [] - $resource("/line_items").query (items) => + $resource("/line_items/bought").query (items) => for line_item in items line_item.variant.line_item = line_item Variants.extend line_item.variant diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index 04fe14fc30..7ae5cb7251 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -1,7 +1,10 @@ class LineItemsController < BaseController respond_to :json - def index + # Taken from Spree::Api::BaseController + rescue_from ActiveRecord::RecordNotFound, :with => :not_found + + def bought respond_with bought_items, each_serializer: Api::LineItemSerializer end @@ -20,10 +23,12 @@ class LineItemsController < BaseController current_order_cycle.items_bought_by_user(spree_current_user, current_distributor) end - # Override default which just redirects - # See Spree::BaseController and Spree::Core::ControllerHelpers::Auth def unauthorized - render text: '', status: 403 + render nothing: true, status: 401 and return + end + + def not_found + render nothing: true, status: 404 and return end def destroy_with_lock(item) diff --git a/config/routes.rb b/config/routes.rb index 17986e2081..a38fb8a55c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -42,7 +42,9 @@ Openfoodnetwork::Application.routes.draw do end end - resources :line_items, only: [:index, :destroy] + resources :line_items, only: [:destroy] do + get :bought, on: :collection + end resources :groups, only: [:index, :show] do collection do diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index ba78537fd7..9eff3982a2 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -19,7 +19,7 @@ describe LineItemsController do end it "lists items bought by the user from the same shop in the same order_cycle" do - get :index, { format: :json } + get :bought, { format: :json } expect(response.status).to eq 200 json_response = JSON.parse(response.body) expect(json_response.length).to eq completed_order.line_items(:reload).count @@ -39,7 +39,8 @@ describe LineItemsController do context "without a line item id" do it "fails and raises an error" do - expect { delete :destroy }.to raise_error + delete :destroy + expect(response.status).to eq 404 end end @@ -49,8 +50,8 @@ describe LineItemsController do context "without a user" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 403 - expect { item.reload }.to_not raise_error + expect(response.status).to eq 401 + expect(item.reload).to be_a Spree::LineItem end end @@ -60,8 +61,8 @@ describe LineItemsController do context "without an order cycle" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 403 - expect { item.reload }.to_not raise_error + expect(response.status).to eq 401 + expect(item.reload).to be_a Spree::LineItem end end @@ -71,8 +72,8 @@ describe LineItemsController do context "without a distributor" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 403 - expect { item.reload }.to_not raise_error + expect(response.status).to eq 401 + expect(item.reload).to be_a Spree::LineItem end end @@ -81,8 +82,8 @@ describe LineItemsController do context "where changes are not allowed" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 403 - expect { item.reload }.to_not raise_error + expect(response.status).to eq 401 + expect(item.reload).to be_a Spree::LineItem end end @@ -92,7 +93,7 @@ describe LineItemsController do it "deletes the line item" do delete :destroy, params expect(response.status).to eq 204 - expect { item.reload }.to raise_error + expect { item.reload }.to raise_error ActiveRecord::RecordNotFound end end end From 22b5dafad251c6321ca707a7ad53d93e18181f0b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 17 May 2017 12:27:29 +1000 Subject: [PATCH 078/104] Further tweaks to LineItemsController --- app/controllers/line_items_controller.rb | 18 +++++++++++------- spec/controllers/line_items_controller_spec.rb | 14 +++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index 7ae5cb7251..45f0d497f2 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -1,22 +1,25 @@ class LineItemsController < BaseController respond_to :json - # Taken from Spree::Api::BaseController - rescue_from ActiveRecord::RecordNotFound, :with => :not_found + before_filter :load_line_item, only: :destroy def bought respond_with bought_items, each_serializer: Api::LineItemSerializer end def destroy - item = Spree::LineItem.find(params[:id]) - authorize! :destroy, item - destroy_with_lock item - respond_with(item) + authorize! :destroy, @line_item + destroy_with_lock @line_item + respond_with(@line_item) end private + def load_line_item + @line_item = Spree::LineItem.find_by_id(params[:id]) + not_found unless @line_item + end + # List all items the user already ordered in the current order cycle def bought_items return [] unless current_order_cycle && spree_current_user && current_distributor @@ -24,7 +27,8 @@ class LineItemsController < BaseController end def unauthorized - render nothing: true, status: 401 and return + status = spree_current_user ? 403 : 401 + render nothing: true, status: status and return end def not_found diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 9eff3982a2..1db2d96dea 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -47,11 +47,10 @@ describe LineItemsController do context "with a line item id" do let(:params) { { format: :json, id: item } } - context "without a user" do + context "where the item's order is not associated with the user" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 401 - expect(item.reload).to be_a Spree::LineItem + expect(response.status).to eq 403 end end @@ -61,8 +60,7 @@ describe LineItemsController do context "without an order cycle" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 401 - expect(item.reload).to be_a Spree::LineItem + expect(response.status).to eq 403 end end @@ -72,8 +70,7 @@ describe LineItemsController do context "without a distributor" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 401 - expect(item.reload).to be_a Spree::LineItem + expect(response.status).to eq 403 end end @@ -82,8 +79,7 @@ describe LineItemsController do context "where changes are not allowed" do it "denies deletion" do delete :destroy, params - expect(response.status).to eq 401 - expect(item.reload).to be_a Spree::LineItem + expect(response.status).to eq 403 end end From daab0dfd7a8690126b05611ffc0b4a4bbba7ee03 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 17 May 2017 12:38:17 +1000 Subject: [PATCH 079/104] Refactor: Splitting changeable_order_from_number out into separate method --- .../spree/orders_controller_decorator.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 7d221ddbeb..22791661fb 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -224,16 +224,18 @@ Spree::OrdersController.class_eval do n == Float::INFINITY ? 2147483647 : n end - # If a specific order is mentioned, check that it is COMPLETE, that changes - # are allowed and that the user has access. Return nil if not. def order_to_update return @order_to_update if defined? @order_to_update return @order_to_update = current_order unless params[:id] - @order_to_update = begin - order = Spree::Order.complete.find_by_number(params[:id]) - order = nil unless order.andand.changes_allowed? && can?(:update, order) - order - end + @order_to_update = changeable_order_from_number + end + + # If a specific order is requested, return it if it is COMPLETE and + # changes are allowed and the user has access. Return nil if not. + def changeable_order_from_number + order = Spree::Order.complete.find_by_number(params[:id]) + return nil unless order.andand.changes_allowed? && can?(:update, order) + order end def check_at_least_one_line_item From c9f186f48fdd2e09fd2106ef131b9489413d6089 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 18 May 2017 15:33:14 +1000 Subject: [PATCH 080/104] Fixing SlideOutUp animation for darkswarm --- app/assets/stylesheets/darkswarm/animations.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/animations.scss b/app/assets/stylesheets/darkswarm/animations.scss index f9c7c1967f..7601da02dc 100644 --- a/app/assets/stylesheets/darkswarm/animations.scss +++ b/app/assets/stylesheets/darkswarm/animations.scss @@ -33,7 +33,9 @@ @-webkit-keyframes slideOutUp { 0% { + opacity: 1; -webkit-transform: translateY(0); + -ms-transform: translateY(0); transform: translateY(0); } @@ -46,10 +48,18 @@ @keyframes slideOutUp { 0% { + opacity: 1; -webkit-transform: translateY(0); -ms-transform: translateY(0); transform: translateY(0); } + + 100% { + opacity: 0; + -webkit-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } } @-webkit-keyframes fadeIn { From b6f4ce373ef4f4548bca64fcea801cd51720dfd3 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 18 May 2017 15:34:22 +1000 Subject: [PATCH 081/104] Preloading variants for VariantOverride.indexed --- app/models/variant_override.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index 07b2c78cc8..226c614998 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -19,7 +19,7 @@ class VariantOverride < ActiveRecord::Base def self.indexed(hub) Hash[ - for_hubs(hub).map { |vo| [vo.variant, vo] } + for_hubs(hub).preload(:variant).map { |vo| [vo.variant, vo] } ] end From 74d8dc48b4698ddd10f46aef6265f273acafbaf1 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 18 May 2017 15:35:07 +1000 Subject: [PATCH 082/104] Rewriting shopfront alert regarding changeable orders to be dynamic --- .../controllers/order_cycle_controller.js.coffee | 3 ++- .../directives/changeable_order_alert.js.coffee | 5 +++++ .../services/changeable_orders_alert.js.coffee | 14 ++++++++++++++ app/assets/stylesheets/darkswarm/shop.css.scss | 4 ++++ app/controllers/shop_controller.rb | 4 ++++ app/helpers/spree/orders_helper.rb | 8 +++++--- app/views/enterprises/shop.html.haml | 7 +++---- app/views/shop/changeable_orders_alert.html.haml | 1 + config/routes.rb | 1 + 9 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/directives/changeable_order_alert.js.coffee create mode 100644 app/assets/javascripts/darkswarm/services/changeable_orders_alert.js.coffee create mode 100644 app/views/shop/changeable_orders_alert.html.haml diff --git a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee index 79c826165c..d900fd0a27 100644 --- a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee @@ -10,7 +10,7 @@ Darkswarm.controller "OrderCycleCtrl", ($scope, $timeout, OrderCycle) -> $("#order_cycle_id").trigger("openTrigger") -Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Products, Variants, Cart) -> +Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Products, Variants, Cart, ChangeableOrdersAlert) -> # Track previous order cycle id for use with revertOrderCycle() $scope.previous_order_cycle_id = OrderCycle.order_cycle.order_cycle_id $scope.$watch 'order_cycle.order_cycle_id', (newValue, oldValue)-> @@ -31,3 +31,4 @@ Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Prod Cart.clear() Products.update() Cart.reloadFinalisedLineItems() + ChangeableOrdersAlert.reload() diff --git a/app/assets/javascripts/darkswarm/directives/changeable_order_alert.js.coffee b/app/assets/javascripts/darkswarm/directives/changeable_order_alert.js.coffee new file mode 100644 index 0000000000..7fec779ce1 --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/changeable_order_alert.js.coffee @@ -0,0 +1,5 @@ +Darkswarm.directive "changeableOrdersAlert", (ChangeableOrdersAlert) -> + restrict: "C" + scope: true + link: (scope, element, attrs) -> + scope.alert = ChangeableOrdersAlert diff --git a/app/assets/javascripts/darkswarm/services/changeable_orders_alert.js.coffee b/app/assets/javascripts/darkswarm/services/changeable_orders_alert.js.coffee new file mode 100644 index 0000000000..e4b597c57b --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/changeable_orders_alert.js.coffee @@ -0,0 +1,14 @@ +Darkswarm.factory 'ChangeableOrdersAlert', ($http) -> + new class ChangeableOrdersAlert + html: '' + visible: true + + constructor: -> + @reload() + + reload: -> + $http.get('/shop/changeable_orders_alert').then (response) => + @html = response.data.trim() + + close: => + @visible = false diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss index 33ccbb31e7..eb738fd6ba 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.scss +++ b/app/assets/stylesheets/darkswarm/shop.css.scss @@ -110,6 +110,10 @@ } } + .alert-box.changeable-orders-alert { + margin-bottom: 0px; + } + .alert-box.shopfront-message { border: 2px solid $clr-turquoise; border-radius: 5px; diff --git a/app/controllers/shop_controller.rb b/app/controllers/shop_controller.rb index 091a501ca5..6ad6f56e56 100644 --- a/app/controllers/shop_controller.rb +++ b/app/controllers/shop_controller.rb @@ -37,6 +37,10 @@ class ShopController < BaseController end end + def changeable_orders_alert + render layout: false + end + private def filtered_json(products_json) diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index 05644815b7..99540f6ed4 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -19,9 +19,10 @@ module Spree def changeable_orders # Only returns open order for the current user + shop + oc combo - return [] unless spree_current_user && current_distributor && current_order_cycle - return [] unless current_distributor.allow_order_changes? - Spree::Order.complete.where( + return @changeable_orders unless @changeable_orders.nil? + return @changeable_orders = [] unless spree_current_user && current_distributor && current_order_cycle + return @changeable_orders = [] unless current_distributor.allow_order_changes? + @changeable_orders = Spree::Order.complete.where( state: 'complete', user_id: spree_current_user.id, distributor_id: current_distributor.id, @@ -33,6 +34,7 @@ module Spree end def shop_changeable_orders_alert_html + return "" unless changeable_orders.any? t(:shop_changeable_orders_alert_html, count: changeable_orders.count, path: changeable_orders_link_path, diff --git a/app/views/enterprises/shop.html.haml b/app/views/enterprises/shop.html.haml index 23c31e69aa..2dd7b63b09 100644 --- a/app/views/enterprises/shop.html.haml +++ b/app/views/enterprises/shop.html.haml @@ -8,10 +8,9 @@ = inject_shop_enterprises %shop.darkswarm - - if changeable_orders.any? - .alert-box.info{ "ofn-inline-alert" => true, ng: { show: "visible" } } - = shop_changeable_orders_alert_html - %a.close{ ng: { click: "close()" } } × + .alert-box.changeable-orders-alert.info.animate-show{ ng: { show: "alert.visible && alert.html" } } + %span{ ng: { bind: { html: "alert.html" } } } + %a.close{ ng: { click: "alert.close()" } } × - content_for :order_cycle_form do diff --git a/app/views/shop/changeable_orders_alert.html.haml b/app/views/shop/changeable_orders_alert.html.haml new file mode 100644 index 0000000000..2fc8f1b551 --- /dev/null +++ b/app/views/shop/changeable_orders_alert.html.haml @@ -0,0 +1 @@ += shop_changeable_orders_alert_html diff --git a/config/routes.rb b/config/routes.rb index a38fb8a55c..ca5a8d5ade 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,6 +28,7 @@ Openfoodnetwork::Application.routes.draw do get :products post :order_cycle get :order_cycle + get :changeable_orders_alert end resources :producers, only: [:index] do From 6fc4a297a043b4c383da9fb0ec1564d90687de0d Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 May 2017 13:15:30 +1000 Subject: [PATCH 083/104] Fixing race condition on link click in spec/features/consumer/shopping/products_spec.rb --- app/views/shop/products/_summary.html.haml | 2 +- spec/features/consumer/registration_spec.rb | 13 ------------- spec/features/consumer/shopping/products_spec.rb | 6 +++--- spec/support/request/web_helper.rb | 13 +++++++++++++ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index 09f9aa15d5..628ae5a161 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -6,7 +6,7 @@ .row.summary .small-10.medium-10.large-11.columns.summary-header %h3 - %a{"ng-click" => "triggerProductModal()"} + %a{"ng-click" => "triggerProductModal()", href: 'javascript:void(0)'} %span{"ng-bind" => "::product.name"} %i.ofn-i_057-expand %small diff --git a/spec/features/consumer/registration_spec.rb b/spec/features/consumer/registration_spec.rb index c4e7af36ee..4a7b815737 100644 --- a/spec/features/consumer/registration_spec.rb +++ b/spec/features/consumer/registration_spec.rb @@ -172,17 +172,4 @@ feature "Registration", js: true do end expect(page).to have_content content end - - def perform_and_ensure(action, *args, assertion) - # Buttons/Links/Checkboxes appear to be unresponsive for a while - # so keep clicking them until assertion is satified - using_wait_time 0.5 do - 10.times do - send(action, *args) - return if assertion.call - end - # Only make it here if we have tried 10 times - expect(assertion.call).to be true - end - end end diff --git a/spec/features/consumer/shopping/products_spec.rb b/spec/features/consumer/shopping/products_spec.rb index d8b0c2b792..c53027b12d 100644 --- a/spec/features/consumer/shopping/products_spec.rb +++ b/spec/features/consumer/shopping/products_spec.rb @@ -32,7 +32,7 @@ feature "As a consumer I want to view products", js: true do visit shop_path select "monday", :from => "order_cycle_id" - open_product_modal product + perform_and_ensure(:click_link, product.name, lambda{ page.has_selector?('.reveal-modal')}) modal_should_be_open_for product within(".reveal-modal") do @@ -47,7 +47,7 @@ feature "As a consumer I want to view products", js: true do visit shop_path select "monday", :from => "order_cycle_id" - open_product_modal product + perform_and_ensure(:click_link, product.name, lambda{ page.has_selector?('.reveal-modal')}) modal_should_be_open_for product within(".reveal-modal") do @@ -57,4 +57,4 @@ feature "As a consumer I want to view products", js: true do end end end -end \ No newline at end of file +end diff --git a/spec/support/request/web_helper.rb b/spec/support/request/web_helper.rb index bca12c46ab..e3460b935d 100644 --- a/spec/support/request/web_helper.rb +++ b/spec/support/request/web_helper.rb @@ -170,6 +170,19 @@ module WebHelper page.evaluate_script "jQuery('#{selector}').select2('close');" end + def perform_and_ensure(action, *args, assertion) + # Buttons/Links/Checkboxes can be unresponsive for a while + # so keep clicking them until assertion is satified + using_wait_time 0.5 do + 10.times do + send(action, *args) + return if assertion.call + end + # Only make it here if we have tried 10 times + expect(assertion.call).to be true + end + end + private def wait_for_ajax wait_until { page.evaluate_script("$.active") == 0 } From 15ee62aaa81012149013a3a7be3e45f05c8e11e3 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 May 2017 13:29:47 +1000 Subject: [PATCH 084/104] Fixing race condition on link click in spec/features/consumer/shops_spec.rb --- spec/features/consumer/shops_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/consumer/shops_spec.rb b/spec/features/consumer/shops_spec.rb index 082bf57d79..fa9aa909fc 100644 --- a/spec/features/consumer/shops_spec.rb +++ b/spec/features/consumer/shops_spec.rb @@ -125,7 +125,7 @@ feature 'Shops', js: true do describe "closed shops" do it "shows taxons for any order cycle" do visit shops_path - click_link 'Show Closed Shops' + click_link_and_ensure('Show Closed Shops', -> { page.has_selector? '.active_table_node'}) expand_active_table_node shop.name expect(page).to have_selector '.fat-taxons', text: 'Closed' end From 1766da9d60c0affcf6381d3f4aa5982cefca8c42 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 May 2017 15:23:37 +1000 Subject: [PATCH 085/104] Adding ng-cloak directive to changeable orders banner --- app/views/enterprises/shop.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/enterprises/shop.html.haml b/app/views/enterprises/shop.html.haml index 2dd7b63b09..10677b1bfe 100644 --- a/app/views/enterprises/shop.html.haml +++ b/app/views/enterprises/shop.html.haml @@ -8,7 +8,7 @@ = inject_shop_enterprises %shop.darkswarm - .alert-box.changeable-orders-alert.info.animate-show{ ng: { show: "alert.visible && alert.html" } } + .alert-box.changeable-orders-alert.info.animate-show{ ng: { show: "alert.visible && alert.html", cloak: true } } %span{ ng: { bind: { html: "alert.html" } } } %a.close{ ng: { click: "alert.close()" } } × From 1f9698f7a252518d625fbad5d3a1f3cfc2d2660b Mon Sep 17 00:00:00 2001 From: stveep Date: Mon, 13 Feb 2017 23:14:04 +0000 Subject: [PATCH 086/104] Test to reproduce bug with overridden price not being displayed when an order is added manually --- spec/factories.rb | 8 +++++++ spec/features/admin/variant_overrides_spec.rb | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/spec/factories.rb b/spec/factories.rb index 5b4df5cf38..cc582f7f69 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -71,6 +71,14 @@ FactoryGirl.define do end end + factory :order_cycle_with_overrides, parent: :order_cycle do + after (:create) do |oc| + oc.variants.each do |variant| + create(:variant_override, variant: variant, hub: oc.coordinator, price: variant.price + 100) + end + end + end + factory :simple_order_cycle, :class => OrderCycle do sequence(:name) { |n| "Order Cycle #{n}" } diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index d21c0998e5..3bb6789211 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -315,6 +315,29 @@ feature %q{ end end end + + end + + describe "when manually placing an order" do + let!(:order_cycle) { create(:order_cycle_with_overrides, name: "Overidden") } + + before do + dist = order_cycle.distributors.first + login_to_admin_section + visit 'admin/orders/new' + select2_select dist.name, from: 'order_distributor_id' + page.should have_select2 'order_order_cycle_id', with_options: ['Overidden (open)'] + select2_select order_cycle.name, from: 'order_order_cycle_id' + end + + # Reproducing a bug, issue #1446 + it "shows the overridden price" do + product = order_cycle.products.first + targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + click_link 'Add' + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + page.should have_content product.variants.first.variant_overrides.first.price + end end describe "when inventory_items do not exist for variants" do From fcce858ea445b4f2214a35d35ae6434cc3128a4f Mon Sep 17 00:00:00 2001 From: stveep Date: Sat, 25 Feb 2017 12:18:59 +0000 Subject: [PATCH 087/104] Fix OC with override factory --- spec/factories.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/factories.rb b/spec/factories.rb index cc582f7f69..3a46afa718 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -74,7 +74,7 @@ FactoryGirl.define do factory :order_cycle_with_overrides, parent: :order_cycle do after (:create) do |oc| oc.variants.each do |variant| - create(:variant_override, variant: variant, hub: oc.coordinator, price: variant.price + 100) + create(:variant_override, variant: variant, hub: oc.distributor, price: variant.price + 100) end end end From 220693f4e35221f03f17c853f13f02b16309963a Mon Sep 17 00:00:00 2001 From: stveep Date: Sun, 19 Mar 2017 19:24:31 +0000 Subject: [PATCH 088/104] Starting alternative flow for new manual order --- .../admin/orders_controller_decorator.rb | 9 +++++ .../spree/orders_controller_decorator.rb | 6 +++ .../add_distribution_fields.html.haml.deface | 37 +------------------ .../_form/_distribution_fields.html.haml | 36 ++++++++++++++++++ .../admin/orders/set_distribution.html.haml | 20 ++++++++++ 5 files changed, 72 insertions(+), 36 deletions(-) create mode 100644 app/views/spree/admin/orders/_form/_distribution_fields.html.haml create mode 100644 app/views/spree/admin/orders/set_distribution.html.haml diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 129d4c3308..f1aa48f95c 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -5,6 +5,9 @@ Spree::Admin::OrdersController.class_eval do helper CheckoutHelper before_filter :load_spree_api_key, :only => :bulk_management + # Ensure that the distributor is set for an order when + before_filter :ensure_distribution, only: :new + # We need to add expections for collection actions other than :index here # because spree_auth_devise causes load_order to be called, which results # in an auth failure as the @order object is nil for collection actions @@ -131,4 +134,10 @@ Spree::Admin::OrdersController.class_eval do ocs.closed + ocs.undated end + + def ensure_distribution + unless @order.distribution_set? + render 'set_distribution' + end + end end diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 22791661fb..4ed822396a 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -186,6 +186,12 @@ Spree::OrdersController.class_eval do private + def ensure_distributor + unless @order.distributor_id + render 'set_distribution' + end + end + def populate_variant_attributes order = current_order.reload diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index a6c51d517c..f8b9e769f7 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -1,38 +1,3 @@ / insert_before "[data-hook='admin_order_form_buttons']" -%fieldset.no-border-bottom - %legend{align: 'center'} Distribution - - - if @order.complete? - .alpha.six.columns - %p - %b Distributor: - = f.object.distributor.andand.name || "None" - = f.hidden_field :distributor_id - .omega.six.columns - %p - %b Order cycle: - = f.object.order_cycle.andand.name || "None" - = f.hidden_field :order_cycle_id - - - else - .alpha.six.columns - .field - %label{for: "order_distributor_id"} Distributor - %input.ofn-select2.fullwidth{id: "order_distributor_id", - type: 'number', - name: "order[distributor_id]", - "ng-model" => 'distributor_id', - data: "shops" } - - .omega.six.columns - .field - %label{ for: "order_order_cycle_id"} Order Cycle - %input.ofn-select2.fullwidth{id: "order_order_cycle_id", - type: 'number', - name: "order[order_cycle_id]", - "ng-model" => 'order_cycle_id', - "ng-disabled" => "!distributor_id", - data: "orderCycles", - text: "name_and_status", - filter: "validOrderCycle" } += render partial: 'distribution_fields' diff --git a/app/views/spree/admin/orders/_form/_distribution_fields.html.haml b/app/views/spree/admin/orders/_form/_distribution_fields.html.haml new file mode 100644 index 0000000000..1657fcaf71 --- /dev/null +++ b/app/views/spree/admin/orders/_form/_distribution_fields.html.haml @@ -0,0 +1,36 @@ +%fieldset.no-border-bottom + %legend{align: 'center'} Distribution + + - if @order.complete? + .alpha.six.columns + %p + %b Distributor: + = f.object.distributor.andand.name || "None" + = f.hidden_field :distributor_id + .omega.six.columns + %p + %b Order cycle: + = f.object.order_cycle.andand.name || "None" + = f.hidden_field :order_cycle_id + + - else + .alpha.six.columns + .field + %label{for: "order_distributor_id"} Distributor + %input.ofn-select2.fullwidth{id: "order_distributor_id", + type: 'number', + name: "order[distributor_id]", + "ng-model" => 'distributor_id', + data: "shops" } + + .omega.six.columns + .field + %label{ for: "order_order_cycle_id"} Order Cycle + %input.ofn-select2.fullwidth{id: "order_order_cycle_id", + type: 'number', + name: "order[order_cycle_id]", + "ng-model" => 'order_cycle_id', + "ng-disabled" => "!distributor_id", + data: "orderCycles", + text: "name_and_status", + filter: "validOrderCycle" } diff --git a/app/views/spree/admin/orders/set_distribution.html.haml b/app/views/spree/admin/orders/set_distribution.html.haml new file mode 100644 index 0000000000..f867ad4cb1 --- /dev/null +++ b/app/views/spree/admin/orders/set_distribution.html.haml @@ -0,0 +1,20 @@ +- content_for :page_title do + = t(:new) + +- content_for :page_actions do + %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' + += admin_inject_shops 'admin.orders' += admin_inject_order_cycles + += render 'spree/admin/shared/order_tabs', :current => 'Order Details' + += csrf_meta_tags + +%div{"data-hook" => "admin_order_new_header"} + = render 'spree/shared/error_messages', :target => @order + +%div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl"} + = form_for @order, url: admin_order_url(@order), method: :put do |f| + = render '_form/_distribution_fields.html.haml' + # ...... From c1c5d00f45b67bac39598d05e525e3d784a6b8c8 Mon Sep 17 00:00:00 2001 From: stveep Date: Sat, 8 Apr 2017 11:58:23 +0100 Subject: [PATCH 089/104] Add new view to set distribution, ensure the scoped variant single item price is used. --- .../spree/admin/orders_controller_decorator.rb | 16 ++++++++++++---- app/models/spree/order_decorator.rb | 4 ++++ .../add_distribution_fields.html.haml.deface | 2 +- .../replace_variant_price.html.haml.deface | 3 +++ .../admin/orders/set_distribution.html.haml | 6 ++++-- config/routes.rb | 2 ++ 6 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 app/overrides/spree/admin/orders/_line_item/replace_variant_price.html.haml.deface diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index f1aa48f95c..8754ae00c2 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -5,9 +5,6 @@ Spree::Admin::OrdersController.class_eval do helper CheckoutHelper before_filter :load_spree_api_key, :only => :bulk_management - # Ensure that the distributor is set for an order when - before_filter :ensure_distribution, only: :new - # We need to add expections for collection actions other than :index here # because spree_auth_devise causes load_order to be called, which results # in an auth failure as the @order object is nil for collection actions @@ -15,6 +12,11 @@ Spree::Admin::OrdersController.class_eval do before_filter :load_distribution_choices, only: [:new, :edit, :update] + # Ensure that the distributor is set for an order when + before_filter :ensure_distribution, only: :new + +# before_filter :clear_errors, only: :update + # After updating an order, the fees should be updated as well # Currently, adding or deleting line items does not trigger updating the # fees! This is a quick fix for that. @@ -136,8 +138,14 @@ Spree::Admin::OrdersController.class_eval do end def ensure_distribution + unless @order + @order = Spree::Order.new + @order.generate_order_number + @order.save! + end unless @order.distribution_set? - render 'set_distribution' + render 'set_distribution', locals: { order: @order } end end + end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 4ed49728ff..273848ad9c 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -177,6 +177,10 @@ Spree::Order.class_eval do save! end + def distribution_set? + distributor && order_cycle + end + def update_distribution_charge! with_lock do EnterpriseFee.clear_all_adjustments_on_order self diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index f8b9e769f7..af07be1d23 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -1,3 +1,3 @@ / insert_before "[data-hook='admin_order_form_buttons']" -= render partial: 'distribution_fields' += render partial: 'spree/admin/orders/_form/distribution_fields' diff --git a/app/overrides/spree/admin/orders/_line_item/replace_variant_price.html.haml.deface b/app/overrides/spree/admin/orders/_line_item/replace_variant_price.html.haml.deface new file mode 100644 index 0000000000..605f645996 --- /dev/null +++ b/app/overrides/spree/admin/orders/_line_item/replace_variant_price.html.haml.deface @@ -0,0 +1,3 @@ +/ replace 'code[erb-loud]:contains(\'f.object.variant.display_amount\')' + += f.object.single_money diff --git a/app/views/spree/admin/orders/set_distribution.html.haml b/app/views/spree/admin/orders/set_distribution.html.haml index f867ad4cb1..85096a612c 100644 --- a/app/views/spree/admin/orders/set_distribution.html.haml +++ b/app/views/spree/admin/orders/set_distribution.html.haml @@ -16,5 +16,7 @@ %div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl"} = form_for @order, url: admin_order_url(@order), method: :put do |f| - = render '_form/_distribution_fields.html.haml' - # ...... + = render 'spree/admin/orders/_form/distribution_fields' + = button_tag :class => 'secondary radius expand small', :id => 'update-button' do + %i.icon-arrow-right + = t(:next) diff --git a/config/routes.rb b/config/routes.rb index ca5a8d5ade..137249efd3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -156,6 +156,8 @@ Openfoodnetwork::Application.routes.draw do end resource :invoice_settings, only: [:edit, :update] + + post '/order/:id/update', to: :update, controller: 'orders' end namespace :api do From 4699c654fce7ca9c2d8396ebe2e4b99de4bb2126 Mon Sep 17 00:00:00 2001 From: stveep Date: Sat, 8 Apr 2017 22:36:43 +0100 Subject: [PATCH 090/104] Fix feature specs for new 'new admin order' flow --- .../_form/_distribution_fields.html.haml | 9 ++--- spec/factories.rb | 2 +- spec/features/admin/orders_spec.rb | 39 +++++++++++++------ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/app/views/spree/admin/orders/_form/_distribution_fields.html.haml b/app/views/spree/admin/orders/_form/_distribution_fields.html.haml index 1657fcaf71..01cb19ed83 100644 --- a/app/views/spree/admin/orders/_form/_distribution_fields.html.haml +++ b/app/views/spree/admin/orders/_form/_distribution_fields.html.haml @@ -5,14 +5,13 @@ .alpha.six.columns %p %b Distributor: - = f.object.distributor.andand.name || "None" - = f.hidden_field :distributor_id + = @order.distributor.andand.name || "None" + %input{type: "hidden", id: "order_distributor_id", value: @order.distributor.andand.id} .omega.six.columns %p %b Order cycle: - = f.object.order_cycle.andand.name || "None" - = f.hidden_field :order_cycle_id - + = @order.order_cycle.andand.name || "None" + %input{type: "hidden", id: "order_order_cycle_id", value: @order.order_cycle.andand.id} - else .alpha.six.columns .field diff --git a/spec/factories.rb b/spec/factories.rb index 3a46afa718..73e62744ba 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -74,7 +74,7 @@ FactoryGirl.define do factory :order_cycle_with_overrides, parent: :order_cycle do after (:create) do |oc| oc.variants.each do |variant| - create(:variant_override, variant: variant, hub: oc.distributor, price: variant.price + 100) + create(:variant_override, variant: variant, hub: oc.distributors.first, price: variant.price + 100) end end end diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index cf1598f3fe..576b14b69b 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -12,6 +12,7 @@ feature %q{ @product = create(:simple_product) @distributor = create(:distributor_enterprise, owner: @user, charges_sales_tax: true) @order_cycle = create(:simple_order_cycle, name: 'One', distributors: [@distributor], variants: [@product.variants.first]) + @oc_overrides = create(:order_cycle_with_overrides) @order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due') @customer = create(:customer, enterprise: @distributor, email: @user.email, user: @user, ship_address: create(:address)) @@ -22,6 +23,14 @@ feature %q{ create :check_payment, order: @order, amount: @order.total end + def new_order_with_distribution(distributor, order_cycle) + visit 'admin/orders/new' + page.should have_selector('#s2id_order_distributor_id') + select2_select distributor.name, from: 'order_distributor_id' + select2_select order_cycle.name, from: 'order_order_cycle_id' + click_button 'Next' + end + scenario "creating an order with distributor and order cycle" do distributor_disabled = create(:distributor_enterprise) create(:simple_order_cycle, name: 'Two') @@ -43,6 +52,7 @@ feature %q{ select2_select @distributor.name, from: 'order_distributor_id' page.should have_select2 'order_order_cycle_id', options: ['One (open)'] select2_select @order_cycle.name, from: 'order_order_cycle_id' + click_button 'Next' page.should have_content 'ADD PRODUCT' targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' @@ -127,12 +137,11 @@ feature %q{ # When I create a new order quick_login_as @user - visit spree.admin_path - - visit '/admin/orders' - click_link 'New Order' - select2_select @distributor.name, from: 'order_distributor_id' - select2_select @order_cycle.name, from: 'order_order_cycle_id' + new_order_with_distribution(@distributor, @order_cycle) + # visit '/admin/orders' + # click_link 'New Order' + # select2_select @distributor.name, from: 'order_distributor_id' + # select2_select @order_cycle.name, from: 'order_order_cycle_id' targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' click_link 'Add' page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS @@ -212,11 +221,7 @@ feature %q{ end scenario "creating an order with distributor and order cycle" do - visit '/admin/orders' - click_link 'New Order' - - select2_select distributor1.name, from: 'order_distributor_id' - select2_select order_cycle1.name, from: 'order_order_cycle_id' + new_order_with_distribution(distributor1, order_cycle1) expect(page).to have_content 'ADD PRODUCT' targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' @@ -241,6 +246,18 @@ feature %q{ end + scenario "with overrides it uses the overriden price" do + login_to_admin_section + new_order_with_distribution(@oc_overrides.distributors.first, @oc_overrides) + product = @oc_overrides.products.first + targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + click_link 'Add' + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + page.should have_selector 'td', text: "119.99" + + end + + # Working around intermittent click failing # Possible causes of failure: # - the link moves From 3b4ffe1f70bfef7cd766f7dcfdc55e2a6e1a35cc Mon Sep 17 00:00:00 2001 From: stveep Date: Sat, 8 Apr 2017 23:37:07 +0100 Subject: [PATCH 091/104] Suppress line item validation error for newly-created orders --- .../admin/orders/edit/suppress_errors.html.haml.deface | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface diff --git a/app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface b/app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface new file mode 100644 index 0000000000..404a73003a --- /dev/null +++ b/app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface @@ -0,0 +1,6 @@ +/ replace "code[erb-loud]:contains(\'error_messages\')" + +-# Suppress errors when manually creating a new order - needs to proceed to edit page +-# without having line items (which otherwise gives a validation error) +- unless @order.created_at > 20.seconds.ago + = render partial: "spree/shared/error_messages", :locals => { :target => @order } From 38c25c412f5e09015d2f5a3c35b28a5a5a5320bb Mon Sep 17 00:00:00 2001 From: stveep Date: Sun, 9 Apr 2017 18:44:05 +0100 Subject: [PATCH 092/104] Remove duplicated spec, better error message suppression, fix shipping test to wait correctly --- .../admin/orders_controller_decorator.rb | 2 -- .../edit/suppress_errors.html.haml.deface | 2 +- .../admin/orders/set_distribution.html.haml | 2 ++ config/routes.rb | 2 -- spec/features/admin/orders_spec.rb | 19 +++++-------------- spec/features/admin/variant_overrides_spec.rb | 1 + 6 files changed, 9 insertions(+), 19 deletions(-) diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 8754ae00c2..b9798c8ca1 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -15,8 +15,6 @@ Spree::Admin::OrdersController.class_eval do # Ensure that the distributor is set for an order when before_filter :ensure_distribution, only: :new -# before_filter :clear_errors, only: :update - # After updating an order, the fees should be updated as well # Currently, adding or deleting line items does not trigger updating the # fees! This is a quick fix for that. diff --git a/app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface b/app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface index 404a73003a..31a8c961e8 100644 --- a/app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface +++ b/app/overrides/spree/admin/orders/edit/suppress_errors.html.haml.deface @@ -2,5 +2,5 @@ -# Suppress errors when manually creating a new order - needs to proceed to edit page -# without having line items (which otherwise gives a validation error) -- unless @order.created_at > 20.seconds.ago +- unless params["suppress_error_msg"] = render partial: "spree/shared/error_messages", :locals => { :target => @order } diff --git a/app/views/spree/admin/orders/set_distribution.html.haml b/app/views/spree/admin/orders/set_distribution.html.haml index 85096a612c..b4874751d4 100644 --- a/app/views/spree/admin/orders/set_distribution.html.haml +++ b/app/views/spree/admin/orders/set_distribution.html.haml @@ -17,6 +17,8 @@ %div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl"} = form_for @order, url: admin_order_url(@order), method: :put do |f| = render 'spree/admin/orders/_form/distribution_fields' + -# This param passed to stop validation error in next page due to no line items in order yet: + = hidden_field_tag 'suppress_error_msg', "true" = button_tag :class => 'secondary radius expand small', :id => 'update-button' do %i.icon-arrow-right = t(:next) diff --git a/config/routes.rb b/config/routes.rb index 137249efd3..ca5a8d5ade 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -156,8 +156,6 @@ Openfoodnetwork::Application.routes.draw do end resource :invoice_settings, only: [:edit, :update] - - post '/order/:id/update', to: :update, controller: 'orders' end namespace :api do diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 576b14b69b..5b0a215dd8 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -12,7 +12,6 @@ feature %q{ @product = create(:simple_product) @distributor = create(:distributor_enterprise, owner: @user, charges_sales_tax: true) @order_cycle = create(:simple_order_cycle, name: 'One', distributors: [@distributor], variants: [@product.variants.first]) - @oc_overrides = create(:order_cycle_with_overrides) @order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due') @customer = create(:customer, enterprise: @distributor, email: @user.email, user: @user, ship_address: create(:address)) @@ -54,6 +53,8 @@ feature %q{ select2_select @order_cycle.name, from: 'order_order_cycle_id' click_button 'Next' + # it suppresses validation errors when setting distribution + page.should_not have_selector '#errorExplanation' page.should have_content 'ADD PRODUCT' targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' click_link 'Add' @@ -85,6 +86,8 @@ feature %q{ scenario "displays error when incorrect distribution for products is chosen" do d = create(:distributor_enterprise) oc = create(:simple_order_cycle, distributors: [d]) + puts d.name + puts @distributor.name @order.state = 'cart'; @order.completed_at = nil; @order.save @@ -99,7 +102,6 @@ feature %q{ select2_select oc.name, from: 'order_order_cycle_id' click_button 'Update And Recalculate Fees' - page.should have_content "Distributor or order cycle cannot supply the products in your cart" end @@ -151,7 +153,7 @@ feature %q{ # And I select that customer's email address and save the order targetted_select2_search @customer.email, from: '#customer_search_override', dropdown_css: '.select2-drop' click_button 'Continue' - within('h1.page-title') { page.should have_content "Shipments" } + page.should have_selector "h1.page-title", text: "Shipments" # Then their addresses should be associated with the order order = Spree::Order.last @@ -246,17 +248,6 @@ feature %q{ end - scenario "with overrides it uses the overriden price" do - login_to_admin_section - new_order_with_distribution(@oc_overrides.distributors.first, @oc_overrides) - product = @oc_overrides.products.first - targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' - click_link 'Add' - page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS - page.should have_selector 'td', text: "119.99" - - end - # Working around intermittent click failing # Possible causes of failure: diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 3bb6789211..44fa258eb3 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -328,6 +328,7 @@ feature %q{ select2_select dist.name, from: 'order_distributor_id' page.should have_select2 'order_order_cycle_id', with_options: ['Overidden (open)'] select2_select order_cycle.name, from: 'order_order_cycle_id' + click_button 'Next' end # Reproducing a bug, issue #1446 From 570f0344da700cae90dbcdf971452ad749a5867b Mon Sep 17 00:00:00 2001 From: stveep Date: Mon, 10 Apr 2017 21:07:44 +0100 Subject: [PATCH 093/104] Remove unused method in wrong controller ^_^ --- app/controllers/spree/orders_controller_decorator.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index 4ed822396a..22791661fb 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -186,12 +186,6 @@ Spree::OrdersController.class_eval do private - def ensure_distributor - unless @order.distributor_id - render 'set_distribution' - end - end - def populate_variant_attributes order = current_order.reload From 848193434bc7f62de28f8d592af816d5d5f01490 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 May 2017 17:26:55 +1000 Subject: [PATCH 094/104] Show item single_display_amount instead of variant price in order details table Also has the effect of taking the inventory price into account (since it is stored against the line item price) --- .../shared/_order_details/replace_item_price.html.haml.deface | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/overrides/spree/admin/shared/_order_details/replace_item_price.html.haml.deface diff --git a/app/overrides/spree/admin/shared/_order_details/replace_item_price.html.haml.deface b/app/overrides/spree/admin/shared/_order_details/replace_item_price.html.haml.deface new file mode 100644 index 0000000000..6da1bc542d --- /dev/null +++ b/app/overrides/spree/admin/shared/_order_details/replace_item_price.html.haml.deface @@ -0,0 +1,3 @@ +/ replace_contents 'tr[data-hook="order_details_line_item_row"] td.price' + += item.single_display_amount From db63f30a76499c40975e095f0ea2357da80507fb Mon Sep 17 00:00:00 2001 From: Pierre de Lacroix Date: Mon, 17 Apr 2017 22:09:25 +0200 Subject: [PATCH 095/104] cosmetic fixes to the ticket view --- app/views/spree/admin/orders/ticket.html.haml | 20 +++++++++---------- config/locales/fr.yml | 4 ++-- lib/spree/money_decorator.rb | 3 +++ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/views/spree/admin/orders/ticket.html.haml b/app/views/spree/admin/orders/ticket.html.haml index 53f224cff1..ea0dc2c913 100644 --- a/app/views/spree/admin/orders/ticket.html.haml +++ b/app/views/spree/admin/orders/ticket.html.haml @@ -26,7 +26,7 @@ '\x1B' + '\x61' + '\x30', // left align '\x0A', '\x1B' + '\x4D' + '\x31', // small text - "#{'%6s %-23s%12s%12s' % + "#{'%6s %-26s%10s%10s' % [t(:ticket_column_qty), t(:ticket_column_item), t(:ticket_column_unit_price), @@ -39,8 +39,8 @@ .map { |line_item| '%5d %-19.19s%8.8s%8.8s' % [line_item.quantity, line_item.product.name, - line_item.single_display_amount_with_adjustments.money.format(symbol: false), - line_item.display_amount_with_adjustments.money.format(symbol: false)] } + line_item.single_display_amount_with_adjustments.format(symbol: false, with_currency: false), + line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] } .join('" + \'\x0A\' + "')}", '\x0A', "#{checkout_adjustments_for(@order, exclude: [:line_item]) @@ -48,26 +48,24 @@ .reverse.map { |adjustment| '%5s %-27.27s%8.8s' % ["", raw(adjustment.label), - display_adjustment_amount(adjustment).money.format(symbol: false)] } - .join('" + \'\x0A\' + "')}", - '\x0A', + display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] + + '" + \'\x0A\' + "'}.join }", '__________________________________________' + '\x0A', '\x0A', '\x1B' + '\x45' + '\x0D', // bold on "#{'%31s%10s' % [t(:total_incl_tax), - @order.display_total]}", + @order.display_total.format(with_currency: false)]}", '\x1B' + '\x45' + '\x0A', // bold off '\x0A', "#{display_checkout_taxes_hash(@order).map { |tax_rate, tax_value| '%31s%10s' % [t(:tax_total, rate: tax_rate), - tax_value] } - .join('" + \'\x0A\' + "')}", - '\x0A', + tax_value.format(with_currency: false)] + + '" + \'\x0A\' + "'}.join }", "#{'%31s%10s' % [t(:total_excl_tax), - display_checkout_total_less_tax(@order)]}", + display_checkout_total_less_tax(@order).format(with_currency: false)]}", '\x0A', '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A', '\x1B' + '\x69', // cut paper diff --git a/config/locales/fr.yml b/config/locales/fr.yml index fc7c6c3111..088acf1481 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -513,8 +513,8 @@ fr: date_of_transaction: "Date de la transaction :" ticket_column_qty: "Qté" ticket_column_item: "Produit" - ticket_column_unit_price: "Prix unitaire" - ticket_column_total_price: "Prix total" + ticket_column_unit_price: "Px unit" + ticket_column_total_price: "Px total" logo: "Logo (640x130)" logo_mobile: "Logo smartphone (75x26)" logo_mobile_svg: "Logo smartphone (SVG)" diff --git a/lib/spree/money_decorator.rb b/lib/spree/money_decorator.rb index 755041df0e..0194925d4e 100644 --- a/lib/spree/money_decorator.rb +++ b/lib/spree/money_decorator.rb @@ -20,4 +20,7 @@ Spree::Money.class_eval do output end + def format(options={}) + @money.format(@options.merge!(options)) + end end From 6972822c4929f3931a76bd8079277f85cf1141a0 Mon Sep 17 00:00:00 2001 From: Pierre de Lacroix Date: Thu, 27 Apr 2017 16:00:28 +0200 Subject: [PATCH 096/104] fix escaping problems on ticket view --- app/views/spree/admin/orders/ticket.html.haml | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/app/views/spree/admin/orders/ticket.html.haml b/app/views/spree/admin/orders/ticket.html.haml index ea0dc2c913..22e9799754 100644 --- a/app/views/spree/admin/orders/ticket.html.haml +++ b/app/views/spree/admin/orders/ticket.html.haml @@ -13,24 +13,24 @@ '\x1B' + '\x74' + '\x10', '\x1B' + '\x61' + '\x31', // center align '\x1B' + '\x21' + '\x30', // em mode on - '#{@order.distributor.name}' + '\x0A', + '#{j(@order.distributor.name)}' + '\x0A', '\x1B' + '\x21' + '\x0A' + '\x1B' + '\x45' + '\x0A', // em mode off '\x0A', - '#{@order.distributor.address.address_part1}' + '\x0A', // text and line break - '#{@order.distributor.address.address_part2}' + '\x0A', - '#{@order.distributor.email}' + '\x0A', + '#{j(@order.distributor.address.address_part1)}' + '\x0A', // text and line break + '#{j(@order.distributor.address.address_part2)}' + '\x0A', + '#{j(@order.distributor.email)}' + '\x0A', '\x0A', // line break '\x1B' + '\x61' + '\x32', // right align - '#{l Time.zone.now.to_date}' + '\x0A', - '#{@order.number}' + '\x0A', + '#{j(l(Time.zone.now.to_date))}' + '\x0A', + '#{j(@order.number)}' + '\x0A', '\x1B' + '\x61' + '\x30', // left align '\x0A', '\x1B' + '\x4D' + '\x31', // small text "#{'%6s %-26s%10s%10s' % - [t(:ticket_column_qty), - t(:ticket_column_item), - t(:ticket_column_unit_price), - t(:ticket_column_total_price)]}", + [j(t(:ticket_column_qty)), + j(t(:ticket_column_item)), + j(t(:ticket_column_unit_price)), + j(t(:ticket_column_total_price))]}", '\x0A', '\x1B' + '\x4D' + '\x30', // normal text '__________________________________________' + '\x0A', @@ -38,34 +38,34 @@ .sort_by{ |line_item| line_item.product.name } .map { |line_item| '%5d %-19.19s%8.8s%8.8s' % [line_item.quantity, - line_item.product.name, - line_item.single_display_amount_with_adjustments.format(symbol: false, with_currency: false), - line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] } + j(line_item.product.name), + j(line_item.single_display_amount_with_adjustments.format(symbol: false, with_currency: false)), + j(line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false))] } .join('" + \'\x0A\' + "')}", '\x0A', "#{checkout_adjustments_for(@order, exclude: [:line_item]) .reject{ |a| a.amount == 0 } .reverse.map { |adjustment| '%5s %-27.27s%8.8s' % ["", - raw(adjustment.label), - display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] + + j(raw(adjustment.label)), + j(display_adjustment_amount(adjustment).format(symbol: false, with_currency: false))] + '" + \'\x0A\' + "'}.join }", '__________________________________________' + '\x0A', '\x0A', '\x1B' + '\x45' + '\x0D', // bold on "#{'%31s%10s' % - [t(:total_incl_tax), - @order.display_total.format(with_currency: false)]}", + [j(t(:total_incl_tax)), + j(@order.display_total.format(with_currency: false))]}", '\x1B' + '\x45' + '\x0A', // bold off '\x0A', "#{display_checkout_taxes_hash(@order).map { |tax_rate, tax_value| '%31s%10s' % - [t(:tax_total, rate: tax_rate), - tax_value.format(with_currency: false)] + + [j(t(:tax_total, rate: tax_rate)), + j(tax_value.format(with_currency: false))] + '" + \'\x0A\' + "'}.join }", "#{'%31s%10s' % - [t(:total_excl_tax), - display_checkout_total_less_tax(@order).format(with_currency: false)]}", + [j(t(:total_excl_tax)), + j(display_checkout_total_less_tax(@order).format(with_currency: false))]}", '\x0A', '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A', '\x1B' + '\x69', // cut paper From a6ed4a2c6aaf20671f622afe9bc7f61cab8aac63 Mon Sep 17 00:00:00 2001 From: Pierre de Lacroix Date: Sat, 29 Apr 2017 06:16:05 +0200 Subject: [PATCH 097/104] fix bad return value in method Spree::Adjustment#find_closest_tax_rates_from_included_tax --- app/helpers/checkout_helper.rb | 1 - app/models/spree/adjustment_decorator.rb | 8 ++++---- spec/models/spree/adjustment_spec.rb | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb index 193c4cef4d..7397ce812e 100644 --- a/app/helpers/checkout_helper.rb +++ b/app/helpers/checkout_helper.rb @@ -55,7 +55,6 @@ module CheckoutHelper def display_adjustment_tax_rates(adjustment) tax_rates = adjustment.tax_rates - return "" if adjustment.amount == adjustment.included_tax tax_rates.map { |tr| number_to_percentage(tr.amount * 100, :precision => 1) }.join(", ") end diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index 4ad456ba12..255f3de51a 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -47,14 +47,14 @@ module Spree return originator.tax_category ? originator.tax_category.tax_rates.match(source) : [] end else - [find_closest_tax_rate_from_included_tax] + find_closest_tax_rates_from_included_tax end end - def find_closest_tax_rate_from_included_tax + def find_closest_tax_rates_from_included_tax approximation = (included_tax / (amount - included_tax)) - return nil if approximation.infinite? or approximation.zero? - Spree::TaxRate.order("ABS(amount - #{approximation})").first + return [] if approximation.infinite? or approximation.zero? + [Spree::TaxRate.order("ABS(amount - #{approximation})").first] end diff --git a/spec/models/spree/adjustment_spec.rb b/spec/models/spree/adjustment_spec.rb index 64113c6290..2292381009 100644 --- a/spec/models/spree/adjustment_spec.rb +++ b/spec/models/spree/adjustment_spec.rb @@ -288,12 +288,12 @@ module Spree let!(:tax_rate) { create(:tax_rate, calculator: Spree::Calculator::DefaultTax.new, amount: 0.25) } let!(:other_tax_rate) { create(:tax_rate, calculator: Spree::Calculator::DefaultTax.new, amount: 0.3) } - it "returns nil if there is no included tax" do - adjustment_without_tax.find_closest_tax_rate_from_included_tax.should == nil + it "returns [] if there is no included tax" do + adjustment_without_tax.find_closest_tax_rates_from_included_tax.should == [] end it "returns the most accurate tax rate" do - adjustment_with_tax.find_closest_tax_rate_from_included_tax.should == tax_rate + adjustment_with_tax.find_closest_tax_rates_from_included_tax.should == [tax_rate] end end end From b879ea5a968d1bf0e3c31e0fa2d9f85354d69959 Mon Sep 17 00:00:00 2001 From: Pierre de Lacroix Date: Mon, 15 May 2017 09:03:59 +0200 Subject: [PATCH 098/104] add comments --- app/models/spree/adjustment_decorator.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index 255f3de51a..035398d332 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -34,6 +34,7 @@ module Spree included_tax > 0 end + # @return [Array] def tax_rates case originator when Spree::TaxRate @@ -51,6 +52,9 @@ module Spree end end + # shipping fees and adjustments created from the admin panel have + # taxes set at creation in the included_tax field without relation + # to the corresponding TaxRate, so we look for the closest one def find_closest_tax_rates_from_included_tax approximation = (included_tax / (amount - included_tax)) return [] if approximation.infinite? or approximation.zero? From 6c36c269c806683653a6b853d50fa552438519c5 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley Date: Tue, 11 Apr 2017 10:34:21 +0100 Subject: [PATCH 099/104] Product Edit UX adjustments --- .../edit_units_controller.js.coffee | 28 +++++++++++++++++++ .../variant_units_controller.js.coffee | 16 +++++++++++ .../_form/add_units_form.html.haml.deface | 25 +++++++++-------- .../new/replace_form.html.haml.deface | 2 +- ...nit_value_and_description.html.haml.deface | 9 ++++-- .../_form/replace_weight.html.haml.deface | 14 ++++++++++ config/locales/en.yml | 4 +++ 7 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee create mode 100644 app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee create mode 100644 app/overrides/spree/admin/variants/_form/replace_weight.html.haml.deface diff --git a/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee b/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee new file mode 100644 index 0000000000..d990e3778c --- /dev/null +++ b/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee @@ -0,0 +1,28 @@ +angular.module("admin.products").controller "editUnitsCtrl", ($scope, VariantUnitManager) -> + + $scope.product = { + variant_unit: angular.element('#variant_unit').val() + variant_unit_scale: angular.element('#variant_unit_scale').val() + } + + $scope.variant_unit_options = VariantUnitManager.variantUnitOptions() + + $scope.setDropdown = () -> + if $scope.product.variant_unit == 'items' + $scope.variant_unit_with_scale = 'items' + else + $scope.variant_unit_with_scale = $scope.product.variant_unit + '_' + $scope.product.variant_unit_scale + + $scope.setFields = () -> + if $scope.variant_unit_with_scale == 'items' + variant_unit = 'items' + variant_unit_scale = null + else + options = $scope.variant_unit_with_scale.split('_') + variant_unit = options[0] + variant_unit_scale = options[1] + + $scope.product.variant_unit = variant_unit + $scope.product.variant_unit_scale = variant_unit_scale + + diff --git a/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee b/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee new file mode 100644 index 0000000000..7d8b5a1324 --- /dev/null +++ b/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee @@ -0,0 +1,16 @@ +angular.module("admin.products").controller "variantUnitsCtrl", ($scope, VariantUnitManager, $timeout) -> + + $scope.unitName = (scale, type) -> + VariantUnitManager.getUnitName(scale, type) + + $scope.scale = angular.element('#product_variant_unit_scale').val() + + $scope.setInitialValues = () -> + variant_unit_value = angular.element('#variant_unit_value').val() + $scope.unit_value_human = variant_unit_value / $scope.scale + $timeout -> + $scope.updateValue() + + $scope.updateValue = () -> + unit_value_human = angular.element('#unit_value_human').val() + $scope.unit_value = unit_value_human * $scope.scale \ No newline at end of file diff --git a/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface b/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface index 9a5b6a87d6..8169e8b81c 100644 --- a/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface +++ b/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface @@ -1,16 +1,17 @@ / insert_top "[data-hook='admin_product_form_right']" -= f.field_container :variant_unit do - = f.label :variant_unit, 'Variant unit' - = f.select :variant_unit, product_variant_unit_options, {:include_blank => true}, {:class => "select2 fullwidth"} - = f.error_message_on :variant_unit +.variant_units_form{'ng-app' => 'admin.products', 'ng-controller' => 'editUnitsCtrl', 'ng-init' => 'setDropdown()'} -= f.field_container :variant_unit_scale do - = f.label :variant_unit_scale, 'Variant unit scale' - = f.text_field :variant_unit_scale - = f.error_message_on :variant_unit_scale + = f.field_container :units do + = f.label :variant_unit_with_scale, :units + %select.select2.fullwidth{ id: 'product_variant_unit_with_scale', 'ng-model' => 'variant_unit_with_scale', 'ng-change' => 'setFields()', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' } + %option{'value' => ''} -= f.field_container :variant_unit_name do - = f.label :variant_unit_name, 'Variant unit name' - = f.text_field :variant_unit_name - = f.error_message_on :variant_unit_name + = f.text_field :variant_unit, {'id' => 'variant_unit', 'ng-value' => 'product.variant_unit', 'hidden' => true} + = f.text_field :variant_unit_scale, {'id' => 'variant_unit_scale', 'ng-value' => 'product.variant_unit_scale', 'hidden' => true} + + .variant_unit_name{'ng-show' => 'product.variant_unit == "items"'} + = f.field_container :variant_unit_name do + = f.label :variant_unit_name, 'Variant unit name' + = f.text_field :variant_unit_name, {placeholder: t('admin.products.unit_name_placeholder')} + = f.error_message_on :variant_unit_name diff --git a/app/overrides/spree/admin/products/new/replace_form.html.haml.deface b/app/overrides/spree/admin/products/new/replace_form.html.haml.deface index 01894a8965..e9dc6f13c5 100644 --- a/app/overrides/spree/admin/products/new/replace_form.html.haml.deface +++ b/app/overrides/spree/admin/products/new/replace_form.html.haml.deface @@ -34,7 +34,7 @@ .three.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" } = f.field_container :unit_name do = f.label :product_variant_unit_name, t(:unit_name) - %input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => 'eg. bunches', :type => 'text' } + %input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => t('admin.products.unit_name_placeholder'), :type => 'text' } .twelve.columns.alpha .six.columns.alpha = render 'spree/admin/products/primary_taxon_form', f: f diff --git a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface index 8696134177..c459ca21cc 100644 --- a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface +++ b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface @@ -1,9 +1,12 @@ / insert_top "[data-hook='admin_variant_form_fields']" - if product_has_variant_unit_option_type?(@product) - .field{"data-hook" => "unit_value"} - = f.label :unit_value, "Unit Value" - = f.text_field :unit_value, class: "fullwidth" + - if @product.variant_unit != 'items' + .field{"data-hook" => "unit_value", 'ng-controller' => 'variantUnitsCtrl', 'ng-init' => 'setInitialValues()'} + = f.label :unit_value, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})" + = hidden_field_tag 'product_variant_unit_scale', @product.variant_unit_scale + = text_field_tag :unit_value_human, nil, {class: "fullwidth", 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'} + = f.text_field :unit_value, {hidden: true, 'ng-value' => 'unit_value'} .field{"data-hook" => "unit_description"} = f.label :unit_description, "Unit Description" diff --git a/app/overrides/spree/admin/variants/_form/replace_weight.html.haml.deface b/app/overrides/spree/admin/variants/_form/replace_weight.html.haml.deface new file mode 100644 index 0000000000..0618c3bab5 --- /dev/null +++ b/app/overrides/spree/admin/variants/_form/replace_weight.html.haml.deface @@ -0,0 +1,14 @@ +/ replace "[data-hook='admin_variant_form_additional_fields']" + +.right.six.columns.omega.label-block{"data-hook" => "admin_variant_form_additional_fields"} + - if @product.variant_unit != 'weight' + .field{"data-hook" => 'weight'} + = f.label 'weight', t('weight')+' (kg)' + - value = number_with_precision(@variant.weight, :precision => 2) + = f.text_field 'weight', :value => value, :class => 'fullwidth' + + - [:height, :width, :depth].each do |field| + .field{"data-hook" => field} + = f.label field, t(field) + - value = number_with_precision(@variant.send(field), :precision => 2) + = f.text_field field, :value => value, :class => 'fullwidth' diff --git a/config/locales/en.yml b/config/locales/en.yml index ba8edf6bc2..9d71f18bdb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -114,6 +114,9 @@ en: sku: SKU tags: Tags variant: Variant + weight: Weight + volume: Volume + items: Items # General form elements quick_search: Quick Search @@ -236,6 +239,7 @@ en: new_button: New Enterprise Group products: + unit_name_placeholder: 'eg. bunches' bulk_edit: unit: Unit display_as: Display As From b6955cb98c034f4b424bd66f917c185dac1c179a Mon Sep 17 00:00:00 2001 From: Matt-Yorkley Date: Tue, 11 Apr 2017 11:29:22 +0100 Subject: [PATCH 100/104] Updated variant feature spec --- spec/features/admin/variants_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/admin/variants_spec.rb b/spec/features/admin/variants_spec.rb index 7303e81766..67123f222b 100644 --- a/spec/features/admin/variants_spec.rb +++ b/spec/features/admin/variants_spec.rb @@ -16,7 +16,7 @@ feature %q{ visit spree.admin_product_variants_path p click_link 'New Variant' - fill_in 'variant_unit_value', with: '1' + fill_in 'unit_value_human', with: '1' fill_in 'variant_unit_description', with: 'foo' click_button 'Create' @@ -43,11 +43,11 @@ feature %q{ expect(page).to_not have_selector "div[data-hook='presentation'] input" # And I should see unit value and description fields for the unit-related option value - page.should have_field "variant_unit_value", with: "1" + page.should have_field "unit_value_human", with: "1" page.should have_field "variant_unit_description", with: "foo" # When I update the fields and save the variant - fill_in "variant_unit_value", with: "123" + fill_in "unit_value_human", with: "123" fill_in "variant_unit_description", with: "bar" click_button 'Update' page.should have_content %Q(Variant "#{p.name}" has been successfully updated!) From 41b5cf10dd9fee8cc4e8709eccd26015880b9fa9 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley Date: Wed, 12 Apr 2017 20:13:46 +0100 Subject: [PATCH 101/104] Quick testing update --- .../_form/add_unit_value_and_description.html.haml.deface | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface index c459ca21cc..84e4b5bbdf 100644 --- a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface +++ b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface @@ -8,6 +8,6 @@ = text_field_tag :unit_value_human, nil, {class: "fullwidth", 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'} = f.text_field :unit_value, {hidden: true, 'ng-value' => 'unit_value'} - .field{"data-hook" => "unit_description"} - = f.label :unit_description, "Unit Description" - = f.text_field :unit_description, class: "fullwidth" + .field{"data-hook" => "unit_description"} + = f.label :unit_description, "Unit Description" + = f.text_field :unit_description, class: "fullwidth" From 7974ac45f29c01933c7c1609bb9821bf9e5ae7d4 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley Date: Fri, 14 Apr 2017 17:25:11 +0100 Subject: [PATCH 102/104] Add unit description placeholder --- .../_form/add_unit_value_and_description.html.haml.deface | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface index 84e4b5bbdf..f6c955ed00 100644 --- a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface +++ b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface @@ -10,4 +10,4 @@ .field{"data-hook" => "unit_description"} = f.label :unit_description, "Unit Description" - = f.text_field :unit_description, class: "fullwidth" + = f.text_field :unit_description, class: "fullwidth", placeholder: t('admin.products.unit_name_placeholder') From 8b560e6cee23800d5cd9b163c185638065ba3384 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 24 May 2017 11:16:47 +1000 Subject: [PATCH 103/104] Cleaning up angular variant units controllers a little bit --- .../controllers/edit_units_controller.js.coffee | 16 ++++++---------- .../variant_units_controller.js.coffee | 14 ++++++-------- .../_form/add_units_form.html.haml.deface | 2 +- ...d_unit_value_and_description.html.haml.deface | 2 +- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee b/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee index d990e3778c..b5ef2847b4 100644 --- a/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee +++ b/app/assets/javascripts/admin/products/controllers/edit_units_controller.js.coffee @@ -1,19 +1,17 @@ angular.module("admin.products").controller "editUnitsCtrl", ($scope, VariantUnitManager) -> - $scope.product = { + $scope.product = variant_unit: angular.element('#variant_unit').val() variant_unit_scale: angular.element('#variant_unit_scale').val() - } $scope.variant_unit_options = VariantUnitManager.variantUnitOptions() - $scope.setDropdown = () -> - if $scope.product.variant_unit == 'items' - $scope.variant_unit_with_scale = 'items' - else - $scope.variant_unit_with_scale = $scope.product.variant_unit + '_' + $scope.product.variant_unit_scale + if $scope.product.variant_unit == 'items' + $scope.variant_unit_with_scale = 'items' + else + $scope.variant_unit_with_scale = $scope.product.variant_unit + '_' + $scope.product.variant_unit_scale - $scope.setFields = () -> + $scope.setFields = -> if $scope.variant_unit_with_scale == 'items' variant_unit = 'items' variant_unit_scale = null @@ -24,5 +22,3 @@ angular.module("admin.products").controller "editUnitsCtrl", ($scope, VariantUni $scope.product.variant_unit = variant_unit $scope.product.variant_unit_scale = variant_unit_scale - - diff --git a/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee b/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee index 7d8b5a1324..2cceef9f1d 100644 --- a/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee +++ b/app/assets/javascripts/admin/products/controllers/variant_units_controller.js.coffee @@ -5,12 +5,10 @@ angular.module("admin.products").controller "variantUnitsCtrl", ($scope, Variant $scope.scale = angular.element('#product_variant_unit_scale').val() - $scope.setInitialValues = () -> - variant_unit_value = angular.element('#variant_unit_value').val() - $scope.unit_value_human = variant_unit_value / $scope.scale - $timeout -> - $scope.updateValue() - - $scope.updateValue = () -> + $scope.updateValue = -> unit_value_human = angular.element('#unit_value_human').val() - $scope.unit_value = unit_value_human * $scope.scale \ No newline at end of file + $scope.unit_value = unit_value_human * $scope.scale + + variant_unit_value = angular.element('#variant_unit_value').val() + $scope.unit_value_human = variant_unit_value / $scope.scale + $timeout -> $scope.updateValue() diff --git a/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface b/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface index 8169e8b81c..c7e4e2feb3 100644 --- a/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface +++ b/app/overrides/spree/admin/products/_form/add_units_form.html.haml.deface @@ -1,6 +1,6 @@ / insert_top "[data-hook='admin_product_form_right']" -.variant_units_form{'ng-app' => 'admin.products', 'ng-controller' => 'editUnitsCtrl', 'ng-init' => 'setDropdown()'} +.variant_units_form{ 'ng-app' => 'admin.products', 'ng-controller' => 'editUnitsCtrl' } = f.field_container :units do = f.label :variant_unit_with_scale, :units diff --git a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface index f6c955ed00..649b210799 100644 --- a/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface +++ b/app/overrides/spree/admin/variants/_form/add_unit_value_and_description.html.haml.deface @@ -2,7 +2,7 @@ - if product_has_variant_unit_option_type?(@product) - if @product.variant_unit != 'items' - .field{"data-hook" => "unit_value", 'ng-controller' => 'variantUnitsCtrl', 'ng-init' => 'setInitialValues()'} + .field{"data-hook" => "unit_value", 'ng-controller' => 'variantUnitsCtrl'} = f.label :unit_value, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})" = hidden_field_tag 'product_variant_unit_scale', @product.variant_unit_scale = text_field_tag :unit_value_human, nil, {class: "fullwidth", 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'} From 18c7b03f3d06259e8c926ab07de4544ee97347eb Mon Sep 17 00:00:00 2001 From: sseerrggii Date: Fri, 12 May 2017 12:24:51 +0200 Subject: [PATCH 104/104] Add plurals --- config/locales/en.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 9d71f18bdb..73173f9c2e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1382,6 +1382,8 @@ Please follow the instructions there to make your enterprise visible on the Open edit_profile_details: "Edit profile details" edit_profile_details_etc: "Change your profile description, images, etc." order_cycle: "Order Cycle" + order_cycles: "Order Cycles" + enterprises: "Enterprises" remove_tax: "Remove tax" enterprise_terms_of_service: "Enterprise Terms of Service" enterprises_require_tos: "Enterprises must accept Terms of Service"