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