From 48a76fe7905c65b77856d2b192608c8c169360af Mon Sep 17 00:00:00 2001 From: Paul Mackay Date: Wed, 26 Mar 2014 19:37:55 +0000 Subject: [PATCH 01/29] Add Code Climate badge. --- README.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.markdown b/README.markdown index 77b56784e6..716a970532 100644 --- a/README.markdown +++ b/README.markdown @@ -1,3 +1,5 @@ +[![Code Climate](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork.png)](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork) + # Open Food Network Connect suppliers (ie. farmers), distributors (ie. co-ops) and From cc8e3537d1bcbffffad75b2b30e8d472e50a3665 Mon Sep 17 00:00:00 2001 From: Paul Mackay Date: Wed, 26 Mar 2014 19:42:03 +0000 Subject: [PATCH 02/29] Add Travis badge. --- README.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/README.markdown b/README.markdown index 716a970532..aabbe8f897 100644 --- a/README.markdown +++ b/README.markdown @@ -1,3 +1,4 @@ +[![Build Status](https://travis-ci.org/openfoodfoundation/openfoodnetwork.svg?branch=master)](https://travis-ci.org/openfoodfoundation/openfoodnetwork) [![Code Climate](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork.png)](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork) # Open Food Network From da2b424c4538e654fae9ec1ecf4f2b1617de2da9 Mon Sep 17 00:00:00 2001 From: Paul Mackay Date: Thu, 27 Mar 2014 09:17:13 +0000 Subject: [PATCH 03/29] #227: Replace Travis with Jenkins badge. --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index aabbe8f897..38055186a3 100644 --- a/README.markdown +++ b/README.markdown @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/openfoodfoundation/openfoodnetwork.svg?branch=master)](https://travis-ci.org/openfoodfoundation/openfoodnetwork) +[![Build Status](http://198.199.107.16:8080/buildStatus/icon?job=openfoodweb - tests)](http://198.199.107.16:8080/job/openfoodweb%20-%20tests/) [![Code Climate](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork.png)](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork) # Open Food Network From 00df441bc20d71eee46cf5b7911c6cd7ed4bb003 Mon Sep 17 00:00:00 2001 From: Rob H Date: Fri, 28 Mar 2014 16:47:52 +1100 Subject: [PATCH 04/29] Re-add changes to variant bulk show to fix 'I'm a teapot' fails --- app/assets/javascripts/admin/bulk_product_update.js.coffee | 3 +-- app/views/spree/api/variants/bulk_show.v1.rabl | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index 30d3a18f09..c2641615e2 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -259,11 +259,11 @@ productEditModule.controller "AdminProductEditCtrl", [ $scope.addVariant = (product) -> product.variants.push id: $scope.nextVariantId() - price: null unit_value: null unit_description: null on_demand: false on_hand: null + price: null $scope.displayProperties[product.id].showVariants = true @@ -358,7 +358,6 @@ productEditModule.controller "AdminProductEditCtrl", [ # conflicted with some changes I made before merging my work, so for now I've reverted to the old way of # doing things. TODO: Review together and decide on strategy here. -- Rohan, 14-1-2014 #if subset($scope.productsWithoutDerivedAttributes(), data) - if $scope.productListsMatch $scope.products, data $scope.resetProducts data $timeout -> $scope.displaySuccess() diff --git a/app/views/spree/api/variants/bulk_show.v1.rabl b/app/views/spree/api/variants/bulk_show.v1.rabl index 458d79e89b..52e293a890 100644 --- a/app/views/spree/api/variants/bulk_show.v1.rabl +++ b/app/views/spree/api/variants/bulk_show.v1.rabl @@ -1,6 +1,7 @@ object @variant -attributes :id, :price, :options_text, :unit_value, :unit_description, :on_demand +attributes :id, :options_text, :unit_value, :unit_description, :on_demand # Infinity is not a valid JSON object, but Rails encodes it anyway -node( :on_hand ) { |v| v.on_hand.to_f.finite? ? v.on_hand : "On demand" } \ No newline at end of file +node( :on_hand ) { |v| v.on_hand.nil? ? 0 : ( v.on_hand.to_f.finite? ? v.on_hand : "On demand" ) } +node( :price ) { |v| v.price.nil? ? 0.to_f : v.price } \ No newline at end of file From 8e54bf1e2ec0a234d0f777cbadf8ff4b50de585c Mon Sep 17 00:00:00 2001 From: Rob H Date: Fri, 4 Apr 2014 09:11:56 +1100 Subject: [PATCH 05/29] Enterprise users are aurthorised to view BOM --- .../admin/bulk_order_management.js.coffee | 2 +- .../admin/orders_controller_decorator.rb | 5 ++++ .../spree/api/orders_controller_decorator.rb | 13 ++++++++++ app/models/spree/ability_decorator.rb | 2 +- config/routes.rb | 4 +++ .../admin/bulk_order_management_spec.rb | 26 +++++++++++++++++++ .../unit/bulk_order_management_spec.js.coffee | 2 +- 7 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 app/controllers/spree/api/orders_controller_decorator.rb diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 22cc1660cf..dbd1015f83 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -167,7 +167,7 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ $scope.fetchOrders = -> $scope.loading = true - dataFetcher("/api/orders?template=bulk_index&q[completed_at_not_null]=true&q[completed_at_gt]=#{$scope.startDate}&q[completed_at_lt]=#{$scope.endDate}").then (data) -> + dataFetcher("/api/orders/managed?template=bulk_index&q[completed_at_not_null]=true&q[completed_at_gt]=#{$scope.startDate}&q[completed_at_lt]=#{$scope.endDate}").then (data) -> $scope.resetOrders data $scope.loading = false diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 089614e7c9..51c7acba09 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -1,6 +1,11 @@ Spree::Admin::OrdersController.class_eval do before_filter :load_spree_api_key, :only => :bulk_management + # 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 + before_filter :check_authorization, :except => :bulk_management + respond_override :index => { :html => { :success => lambda { # Filter orders to only show those distributed by current user (or all for admin user) diff --git a/app/controllers/spree/api/orders_controller_decorator.rb b/app/controllers/spree/api/orders_controller_decorator.rb new file mode 100644 index 0000000000..4f3c5c8c77 --- /dev/null +++ b/app/controllers/spree/api/orders_controller_decorator.rb @@ -0,0 +1,13 @@ +Spree::Api::OrdersController.class_eval do + + # We need to add expections for collection actions other than :index here + # because Spree's API controller causes authorize_read! to be called, which + # results in an ActiveRecord::NotFound Exception as the order object is not + # defined for collection actions + before_filter :authorize_read!, :except => [:managed] + + def managed + @orders = Spree::Order.ransack(params[:q]).result.managed_by(current_api_user).page(params[:page]).per(params[:per_page]) + respond_with(@orders, default_template: :index) + end +end \ No newline at end of file diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 83a4e5e0aa..75c89d8664 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -23,7 +23,7 @@ class AbilityDecorator # Enterprise User can only access orders that they are a distributor for can [:index, :create], Spree::Order - can [:admin, :read, :update, :fire, :resend], Spree::Order do |order| + can [:admin, :read, :update, :bulk_management, :fire, :resend], Spree::Order do |order| # We allow editing orders with a nil distributor as this state occurs # during the order creation process from the admin backend order.distributor.nil? || user.enterprises.include?(order.distributor) diff --git a/config/routes.rb b/config/routes.rb index 0e3db0bd35..a218fb145e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -104,6 +104,10 @@ Spree::Core::Engine.routes.prepend do get :managed, on: :collection end + resources :orders do + get :managed, on: :collection + end + resources :enterprises do get :managed, on: :collection end diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 48493130a6..0624d5fa97 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -575,4 +575,30 @@ feature %q{ end end end + + context "as an enterprise manager" do + let(:s1) { create(:supplier_enterprise, name: 'First Supplier') } + let(:s2) { create(:supplier_enterprise, name: 'Another Supplier') } + let(:d1) { create(:distributor_enterprise, name: 'First Distributor') } + let(:d2) { create(:distributor_enterprise, name: 'Another Distributor') } + let!(:o1) { FactoryGirl.create(:order, state: 'complete', completed_at: Time.now, distributor: d1 ) } + let!(:o2) { FactoryGirl.create(:order, state: 'complete', completed_at: Time.now, distributor: d2 ) } + let!(:line_item_distributed) { FactoryGirl.create(:line_item, order: o1 ) } + let!(:line_item_not_distributed) { FactoryGirl.create(:line_item, order: o2 ) } + + before(:each) do + @enterprise_user = create_enterprise_user + @enterprise_user.enterprise_roles.build(enterprise: s1).save + @enterprise_user.enterprise_roles.build(enterprise: d1).save + + login_to_admin_as @enterprise_user + end + + it "shows only line item from orders that I supply" do + visit '/admin/orders/bulk_management' + + page.should have_selector "tr#li_#{line_item_distributed.id}", :visible => true + page.should_not have_selector "tr#li_#{line_item_not_distributed.id}", :visible => true + end + end end diff --git a/spec/javascripts/unit/bulk_order_management_spec.js.coffee b/spec/javascripts/unit/bulk_order_management_spec.js.coffee index 9bd31401e7..12c4d77cd7 100644 --- a/spec/javascripts/unit/bulk_order_management_spec.js.coffee +++ b/spec/javascripts/unit/bulk_order_management_spec.js.coffee @@ -41,7 +41,7 @@ describe "AdminOrderMgmtCtrl", -> describe "fetching orders", -> beforeEach -> scope.initialiseVariables() - httpBackend.expectGET("/api/orders?template=bulk_index&q[completed_at_not_null]=true&q[completed_at_gt]=SomeDate&q[completed_at_lt]=SomeDate").respond "list of orders" + httpBackend.expectGET("/api/orders/managed?template=bulk_index&q[completed_at_not_null]=true&q[completed_at_gt]=SomeDate&q[completed_at_lt]=SomeDate").respond "list of orders" it "makes a call to dataFetcher, with current start and end date parameters", -> scope.fetchOrders() From 980797493de6abcf24bdd0f168d1333249fd5b94 Mon Sep 17 00:00:00 2001 From: Rob H Date: Fri, 4 Apr 2014 19:36:06 +1100 Subject: [PATCH 06/29] Create dropdown list for toggling columns --- .../admin/bulk_order_management.js.coffee | 2 +- .../javascripts/admin/dropdown.js.coffee | 18 +++++++ .../admin/shared_directives.js.coffee | 6 +-- .../admin/openfoodnetwork.css.scss | 52 +++++++++++++++++++ .../stylesheets/admin/products.css.scss | 14 ++--- .../admin/orders/bulk_management.html.haml | 8 +++ 6 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 app/assets/javascripts/admin/dropdown.js.coffee diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index dbd1015f83..18407061aa 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -1,4 +1,4 @@ -orderManagementModule = angular.module("ofn.bulk_order_management", ["ofn.shared_services", "ofn.shared_directives"]) +orderManagementModule = angular.module("ofn.bulk_order_management", ["ofn.shared_services", "ofn.shared_directives", "ofn.dropdown"]) orderManagementModule.config [ "$httpProvider" diff --git a/app/assets/javascripts/admin/dropdown.js.coffee b/app/assets/javascripts/admin/dropdown.js.coffee new file mode 100644 index 0000000000..9297ba52b4 --- /dev/null +++ b/app/assets/javascripts/admin/dropdown.js.coffee @@ -0,0 +1,18 @@ +dropDownModule = angular.module("ofn.dropdown", []) + +dropDownModule.directive "ofnDropDown", -> + link: (scope, element, attrs) -> + element.click -> + scope.$apply -> + if scope.expanded + unless $(event.target).parents("div.ofn_drop_down div.menu").length > 0 + scope.expanded = false + element.removeClass "expanded" + else + scope.expanded = true + element.addClass "expanded" + + + +dropDownModule.controller "DropDownCtrl", -> + $scope.expanded = false diff --git a/app/assets/javascripts/admin/shared_directives.js.coffee b/app/assets/javascripts/admin/shared_directives.js.coffee index e498482709..bb0a1067ce 100644 --- a/app/assets/javascripts/admin/shared_directives.js.coffee +++ b/app/assets/javascripts/admin/shared_directives.js.coffee @@ -28,12 +28,12 @@ sharedDirectivesModule.directive "ofnSelect2MinSearch", [ sharedDirectivesModule.directive "ofnToggleColumn", -> link: (scope, element, attrs) -> - element.addClass "unselected" unless scope.column.visible + element.addClass "selected" if scope.column.visible element.click "click", -> scope.$apply -> if scope.column.visible scope.column.visible = false - element.addClass "unselected" + element.removeClass "selected" else scope.column.visible = true - element.removeClass "unselected" \ No newline at end of file + element.addClass "selected" \ No newline at end of file diff --git a/app/assets/stylesheets/admin/openfoodnetwork.css.scss b/app/assets/stylesheets/admin/openfoodnetwork.css.scss index 14feebae0d..8c8ddeb6b7 100644 --- a/app/assets/stylesheets/admin/openfoodnetwork.css.scss +++ b/app/assets/stylesheets/admin/openfoodnetwork.css.scss @@ -133,3 +133,55 @@ table#listing_enterprise_groups { } } +.ofn_drop_down { + padding: 7px 15px; + border-radius: 3px; + border: 1px solid #d4d4d4; + background-color: #f5f5f5; + position: relative; + display: block; + float: left; + color: #828282; + cursor: pointer; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + text-align: center; + + > span { + text-transform: uppercase; + font-size: 85%; + font-weight: 600; + } + + .menu { + margin-top: 1px; + position: absolute; + float: none; + top:100%; + left: 0px; + padding: 5px 0px; + border: 1px solid #adadad; + background-color: #ffffff; + box-shadow: 1px 3px 10px #888888; + + .menu_item { + margin: 0px; + padding: 2px 0px; + color: #454545; + text-align: left; + } + + .menu_item:hover { + background-color: #ededed; + } + } +} + +.ofn_drop_down:hover, .ofn_drop_down.expanded { + border: 1px solid #adadad; + color: #575757; +} + diff --git a/app/assets/stylesheets/admin/products.css.scss b/app/assets/stylesheets/admin/products.css.scss index 20f9c49a84..c8ceaaaac2 100644 --- a/app/assets/stylesheets/admin/products.css.scss +++ b/app/assets/stylesheets/admin/products.css.scss @@ -80,9 +80,9 @@ li.column-list-item { border-radius: 3px; padding: 2px 20px; margin: 2px 1px; - border: 2px solid #5498da; - background-color: #5498da; - color: white; + background-color: white; + border: 2px solid lightgray; + color: darkgray; font-size: 100%; cursor: default; text-align: center; @@ -94,10 +94,10 @@ li.column-list-item { user-select: none; } -li.column-list-item.unselected { - background-color: white; - border: 2px solid lightgray; - color: darkgray; +li.column-list-item.selected { + border: 2px solid #5498da; + background-color: #5498da; + color: white; font-size: 100%; } diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index a3372434d0..236bf6f28e 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -77,6 +77,14 @@ %select{ :class => "three columns alpha", :id => 'bulk_actions', 'ofn-select2-min-search' => 10, 'ng-model' => 'selectedBulkAction', 'ng-options' => 'a as a.name for a in bulkActions' } %div{ :class => "three columns alpha" } %input{ :class => "three columns alpha", :value => "Run", :type => "button", :id => 'bulk_execute', 'ng-click' => 'selectedBulkAction.callback(filteredLineItems)' } + %div{ :class => "five columns omega" }   + %div.ofn_drop_down{ :class => "two columns omega", 'ofn-drop-down' => true } + %span Columns + %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } + %div.menu{ 'ng-show' => "expanded" } + %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } + %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} + %span{ :class => 'two columns omega' } {{column.name }} %table.index#listing_orders.bulk %thead %tr From b1c7f06779c615a9e8323e107e4fada6b69a31c6 Mon Sep 17 00:00:00 2001 From: Rob H Date: Sat, 5 Apr 2014 10:06:58 +1100 Subject: [PATCH 07/29] Add dropdown.js.coffee to karma config to stop tests failing --- config/ng-test.conf.js | 1 + 1 file changed, 1 insertion(+) diff --git a/config/ng-test.conf.js b/config/ng-test.conf.js index b1bddd6532..98357b4cac 100644 --- a/config/ng-test.conf.js +++ b/config/ng-test.conf.js @@ -13,6 +13,7 @@ module.exports = function(config) { 'app/assets/javascripts/admin/shared_directives.js.coffee', 'app/assets/javascripts/admin/shared_services.js.coffee', + 'app/assets/javascripts/admin/dropdown.js.coffee', 'app/assets/javascripts/admin/order_cycle.js.erb.coffee', 'app/assets/javascripts/admin/bulk_order_management.js.coffee', 'app/assets/javascripts/admin/bulk_product_update.js.coffee', From 366555d9a7e5deb0aca1f7460c51b74b6c89b675 Mon Sep 17 00:00:00 2001 From: Rob H Date: Sat, 5 Apr 2014 10:08:37 +1100 Subject: [PATCH 08/29] Remove old column toggle from BOM --- .../admin/bulk_order_management.js.coffee | 1 - .../admin/orders/bulk_management.html.haml | 6 +---- .../admin/bulk_order_management_spec.rb | 24 +++++++------------ 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 18407061aa..198d94a890 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -126,7 +126,6 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ $scope.reverse = false $scope.optionTabs = filters: { title: "Filter Line Items", visible: false } - column_toggle: { title: "Toggle Columns", visible: false } $scope.columns = order_no: { name: "Order No.", visible: false } full_name: { name: "Name", visible: true } diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 236bf6f28e..35b13dbe00 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -32,10 +32,6 @@ %label{ :for => 'order_cycle_filter' }Order Cycle %br %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.name for oc in orderCycles'} - .column_toggle{ :class => "nine columns alpha", "ng-show" => 'optionTabs.column_toggle.visible' } - %ul.column-list{ :class => "nine columns alpha" } - %li.column-list-item{ :class => "three columns alpha", 'ofn-toggle-column' => 'column', 'ng-repeat' => 'column in columns' } - {{ column.name }} %div{ :class => "nine columns alpha", 'ng-show' => '!optionTabs.filters.visible && !optionTabs.column_toggle.visible && unitsVariantSelected()' }  . %div#group_buy_calculation{ :class => "seven columns alpha", 'ng-show' => 'unitsVariantSelected()' } %div{ :class => "seven columns alpha" } @@ -78,7 +74,7 @@ %div{ :class => "three columns alpha" } %input{ :class => "three columns alpha", :value => "Run", :type => "button", :id => 'bulk_execute', 'ng-click' => 'selectedBulkAction.callback(filteredLineItems)' } %div{ :class => "five columns omega" }   - %div.ofn_drop_down{ :class => "two columns omega", 'ofn-drop-down' => true } + %div.ofn_drop_down{ :class => "two columns omega", :id => "columns_dropdown", 'ofn-drop-down' => true } %span Columns %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } %div.menu{ 'ng-show' => "expanded" } diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 0624d5fa97..9572dd33b6 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -165,30 +165,28 @@ feature %q{ it "shows a column display toggle button, which shows a list of columns when clicked" do visit '/admin/orders/bulk_management' - page.should have_selector "div.column_toggle", :visible => false + page.should_not have_selector "div#columns_dropdown.expanded" + page.should have_selector "div#columns_dropdown div.menu", :visible => false - page.should have_selector "div.option_tab_titles h6.unselected", :text => "Toggle Columns" - first("div.option_tab_titles h6", :text => "Toggle Columns").click + page.should have_selector "div#columns_dropdown", :text => "COLUMNS" + first("div#columns_dropdown", :text => "COLUMNS").click - page.should have_selector "div.option_tab_titles h6.selected", :text => "Toggle Columns" - page.should have_selector "div.column_toggle", :visible => true - page.should have_selector "li.column-list-item", text: "Producer" + page.should have_selector "div#columns_dropdown.expanded" + page.should have_selector "div#columns_dropdown div.menu", :visible => true + page.should have_selector "div#columns_dropdown div.menu div.menu_item", text: "Producer" page.should have_selector "div.filters", :visible => false page.should have_selector "div.option_tab_titles h6.unselected", :text => "Filter Line Items" first("div.option_tab_titles h6", :text => "Filter Line Items").click - page.should have_selector "div.option_tab_titles h6.unselected", :text => "Toggle Columns" page.should have_selector "div.option_tab_titles h6.selected", :text => "Filter Line Items" page.should have_selector "div.filters", :visible => true first("div.option_tab_titles h6", :text => "Filter Line Items").click page.should have_selector "div.option_tab_titles h6.unselected", :text => "Filter Line Items" - page.should have_selector "div.option_tab_titles h6.unselected", :text => "Toggle Columns" page.should have_selector "div.filters", :visible => false - page.should have_selector "div.column_toggle", :visible => false end end @@ -196,8 +194,6 @@ feature %q{ it "shows a column display toggle button, which shows a list of columns when clicked" do visit '/admin/orders/bulk_management' - first("div.option_tab_titles h6", :text => "Toggle Columns").click - page.should have_selector "th", :text => "NAME" page.should have_selector "th", :text => "ORDER DATE" page.should have_selector "th", :text => "PRODUCER" @@ -205,10 +201,8 @@ feature %q{ page.should have_selector "th", :text => "QUANTITY" page.should have_selector "th", :text => "MAX" - page.should have_selector "div.option_tab_titles h6", :text => "Toggle Columns" - - page.should have_selector "div ul.column-list li.column-list-item", text: "Producer" - first("li.column-list-item", text: "Producer").click + first("div#columns_dropdown", :text => "COLUMNS").click + first("div#columns_dropdown div.menu div.menu_item", text: "Producer").click page.should_not have_selector "th", :text => "PRODUCER" page.should have_selector "th", :text => "NAME" From 5cec4feb7e16a7e336cfec50296dc12bab273e29 Mon Sep 17 00:00:00 2001 From: Rob H Date: Sat, 5 Apr 2014 10:17:21 +1100 Subject: [PATCH 09/29] Remove search boxes from filter BPE filter boxes --- app/views/spree/admin/products/bulk_edit.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/spree/admin/products/bulk_edit.html.haml b/app/views/spree/admin/products/bulk_edit.html.haml index d90b5a8013..cedcc5df60 100644 --- a/app/views/spree/admin/products/bulk_edit.html.haml +++ b/app/views/spree/admin/products/bulk_edit.html.haml @@ -24,11 +24,11 @@ %div{ :class => "four columns alpha" } Column: %br.clear - %select.select2.fullwidth{ 'ng-model' => 'filterProperty', :id => "filter_property", 'ng-options' => 'fc.name for fc in filterableColumns' } + %select.fullwidth{ 'ng-model' => 'filterProperty', :id => "filter_property", 'ng-options' => 'fc.name for fc in filterableColumns', 'ofn-select2-min-search' => 10 } %div{ :class => "four columns omega" } Filter Type: %br.clear - %select.select2.fullwidth{ 'ng-model' => 'filterPredicate', :id => "filter_predicate", 'ng-options' => 'ft.name for ft in filterTypes' } + %select.fullwidth{ 'ng-model' => 'filterPredicate', :id => "filter_predicate", 'ng-options' => 'ft.name for ft in filterTypes', 'ofn-select2-min-search' => 10 } %div{ :class => "six columns omega" } Value: %br.clear From 0a6230088d4d836d39bad668a6a6a7f0aea6463b Mon Sep 17 00:00:00 2001 From: Rob H Date: Sun, 6 Apr 2014 17:39:53 +1000 Subject: [PATCH 10/29] Make BOM bulk action dropdown pretty --- .../admin/bulk_order_management.js.coffee | 15 +++++++--- .../javascripts/admin/dropdown.js.coffee | 29 ++++++++++++++----- .../admin/orders/bulk_management.html.haml | 16 +++++----- .../admin/bulk_order_management_spec.rb | 22 +++++++------- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 198d94a890..caf159cbbe 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -107,9 +107,8 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ ($scope, $http, dataFetcher, blankOption, pendingChanges) -> $scope.initialiseVariables = -> - now = new Date - start = new Date( now.getTime() - ( 7 * (1440 * 60 * 1000) ) - (now.getTime() - now.getTimezoneOffset() * 60 * 1000) % (1440 * 60 * 1000) ) - end = new Date( now.getTime() - (now.getTime() - now.getTimezoneOffset() * 60 * 1000) % (1440 * 60 * 1000) + ( 1 * ( 1440 * 60 * 1000 ) ) ) + start = daysFromToday -7 + end = daysFromToday 1 $scope.lineItems = [] $scope.filteredLineItems = [] $scope.confirmDelete = true @@ -117,7 +116,7 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ $scope.endDate = formatDate end $scope.pendingChanges = pendingChanges $scope.quickSearch = "" - $scope.bulkActions = [ { name: "Delete", callback: $scope.deleteLineItems } ] + $scope.bulkActions = [ { name: "Delete Selected", callback: $scope.deleteLineItems } ] $scope.selectedBulkAction = $scope.bulkActions[0] $scope.selectedUnitsProduct = {}; $scope.selectedUnitsVariant = {}; @@ -325,6 +324,14 @@ orderManagementModule.factory "switchClass", [ , timeout, true) ] +daysFromToday = (days) -> + now = new Date + now.setHours(0) + now.setMinutes(0) + now.setSeconds(0) + now.setDate( now.getDate() + days ) + now + formatDate = (date) -> year = date.getFullYear() month = twoDigitNumber date.getMonth() + 1 diff --git a/app/assets/javascripts/admin/dropdown.js.coffee b/app/assets/javascripts/admin/dropdown.js.coffee index 9297ba52b4..d36bdc81f2 100644 --- a/app/assets/javascripts/admin/dropdown.js.coffee +++ b/app/assets/javascripts/admin/dropdown.js.coffee @@ -1,18 +1,31 @@ dropDownModule = angular.module("ofn.dropdown", []) -dropDownModule.directive "ofnDropDown", -> +dropDownModule.directive "ofnDropDown", ($document) -> link: (scope, element, attrs) -> + outsideClickListener = -> + unless $(event.target).is("div.ofn_drop_down##{attrs.id} div.menu") || + $(event.target).parents("div.ofn_drop_down##{attrs.id} div.menu").length > 0 + scope.$emit "offClick" + element.click -> - scope.$apply -> - if scope.expanded - unless $(event.target).parents("div.ofn_drop_down div.menu").length > 0 + if !scope.expanded + event.stopPropagation() + scope.deregistrationCallback = scope.$on "offClick", -> + $document.off "click", outsideClickListener + scope.$apply -> scope.expanded = false element.removeClass "expanded" - else + scope.deregistrationCallback() + $document.on "click", outsideClickListener + scope.$apply -> scope.expanded = true element.addClass "expanded" +dropDownModule.directive "ofnCloseOnClick", ($document) -> + link: (scope, element, attrs) -> + element.click -> + event.stopPropagation() + scope.$emit "offClick" - -dropDownModule.controller "DropDownCtrl", -> - $scope.expanded = false +dropDownModule.controller "DropDownCtrl", ($scope) -> + $scope.expanded = false \ No newline at end of file diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 35b13dbe00..c07873c92e 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -68,13 +68,15 @@ %h4{ :style => 'color:red;' } No matching line items found. %div{ 'ng-hide' => 'loading || lineItems.length == 0' } .controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" } - %input{ :class => "three columns alpha", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } - %div{ :class => "three columns alpha" } - %select{ :class => "three columns alpha", :id => 'bulk_actions', 'ofn-select2-min-search' => 10, 'ng-model' => 'selectedBulkAction', 'ng-options' => 'a as a.name for a in bulkActions' } - %div{ :class => "three columns alpha" } - %input{ :class => "three columns alpha", :value => "Run", :type => "button", :id => 'bulk_execute', 'ng-click' => 'selectedBulkAction.callback(filteredLineItems)' } - %div{ :class => "five columns omega" }   - %div.ofn_drop_down{ :class => "two columns omega", :id => "columns_dropdown", 'ofn-drop-down' => true } + %input{ :class => "two columns alpha", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } + %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :class => "two columns omega", :id => "bulk_actions_dropdown", 'ofn-drop-down' => true } + %span Actions + %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } + %div.menu{ 'ng-show' => "expanded" } + %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredLineItems)", 'ofn-close-on-click' => true } + %span{ :class => 'three columns omega' } {{action.name }} + %div{ :class => "ten columns omega" }   + %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :class => "two columns omega", :id => "columns_dropdown", 'ofn-drop-down' => true } %span Columns %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } %div.menu{ 'ng-show' => "expanded" } diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 9572dd33b6..008955efce 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -357,7 +357,7 @@ feature %q{ end it "displays date fields for filtering orders, with default values set" do - one_week_ago = (Date.today - 7).strftime("%F %T") + one_week_ago = Date.today.prev_day(7).strftime("%F %T") tonight = Date.tomorrow.strftime("%F %T") page.should have_field "start_date_filter", with: one_week_ago page.should have_field "end_date_filter", with: tonight @@ -441,13 +441,11 @@ feature %q{ end it "displays a bulk action select box with a list of actions" do - list_of_actions = ['Delete'] - find("div.select2-container#s2id_bulk_actions").click - list_of_actions.each { |a| page.should have_selector "div.select2-drop-active ul.select2-results li", text: a } - end - - it "displays a bulk action button" do - page.should have_button "bulk_execute" + list_of_actions = ['Delete Selected'] + find("div#bulk_actions_dropdown").click + within("div#bulk_actions_dropdown") do + list_of_actions.each { |action_name| page.should have_selector "div.menu_item", text: action_name } + end end context "performing actions" do @@ -457,8 +455,8 @@ feature %q{ within("tr#li_#{li2.id} td.bulk") do check "bulk" end - select2_select "Delete", :from => "bulk_actions" - click_button "bulk_execute" + find("div#bulk_actions_dropdown").click + find("div#bulk_actions_dropdown div.menu_item", :text => "Delete Selected" ).click page.should have_selector "tr#li_#{li1.id}", visible: true page.should_not have_selector "tr#li_#{li2.id}", visible: true end @@ -477,8 +475,8 @@ feature %q{ it "only applies the delete action to filteredLineItems" do check "toggle_bulk" fill_in "quick_search", with: o1.number - select2_select "Delete", :from => "bulk_actions" - click_button "bulk_execute" + find("div#bulk_actions_dropdown").click + find("div#bulk_actions_dropdown div.menu_item", :text => "Delete Selected" ).click fill_in "quick_search", with: '' page.should_not have_selector "tr#li_#{li1.id}", visible: true page.should have_selector "tr#li_#{li2.id}", visible: true From aad5ad4bc07eef169a90a2cf97a484e0b6b1d852 Mon Sep 17 00:00:00 2001 From: Rob H Date: Sun, 6 Apr 2014 19:22:17 +1000 Subject: [PATCH 11/29] BOM interface cleanup --- .../javascripts/admin/dropdown.js.coffee | 6 +- .../admin/orders/bulk_management.html.haml | 88 +++++++++---------- .../admin/bulk_order_management_spec.rb | 31 ------- 3 files changed, 46 insertions(+), 79 deletions(-) diff --git a/app/assets/javascripts/admin/dropdown.js.coffee b/app/assets/javascripts/admin/dropdown.js.coffee index d36bdc81f2..e18407abcc 100644 --- a/app/assets/javascripts/admin/dropdown.js.coffee +++ b/app/assets/javascripts/admin/dropdown.js.coffee @@ -2,12 +2,12 @@ dropDownModule = angular.module("ofn.dropdown", []) dropDownModule.directive "ofnDropDown", ($document) -> link: (scope, element, attrs) -> - outsideClickListener = -> + outsideClickListener = (event) -> unless $(event.target).is("div.ofn_drop_down##{attrs.id} div.menu") || $(event.target).parents("div.ofn_drop_down##{attrs.id} div.menu").length > 0 scope.$emit "offClick" - element.click -> + element.click (event) -> if !scope.expanded event.stopPropagation() scope.deregistrationCallback = scope.$on "offClick", -> @@ -23,7 +23,7 @@ dropDownModule.directive "ofnDropDown", ($document) -> dropDownModule.directive "ofnCloseOnClick", ($document) -> link: (scope, element, attrs) -> - element.click -> + element.click (event) -> event.stopPropagation() scope.$emit "offClick" diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index c07873c92e..ff6162754d 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -6,34 +6,29 @@ %div{ 'ng-app' => 'ofn.bulk_order_management', 'ng-controller' => 'AdminOrderMgmtCtrl', 'ng-init' => "initialise('#{@spree_api_key}');loading=true;" } %div{ 'ng-show' => '!spree_api_key_ok' } {{ api_error_msg }} - .option_tab_titles{ :class => "sixteen columns alpha" } - %h6{ :class => "three columns alpha", 'ng-repeat' => "tab in optionTabs", "ng-click" => "shiftTab(tab)", "ng-class" => "tab.visible && 'selected' || !tab.visible && 'unselected'"} - {{ tab.title }} - .filters{ :class => "nine columns alpha", 'ng-show' => 'optionTabs.filters.visible' } - .row{ :class => "six columns alpha" } - .date_filter{ :class => "three columns alpha" } - %label{ :for => 'start_date_filter' }Start Date - %br - %input{ :class => "three columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datetimepicker' => "startDate", 'ofn-confirm-change' => "startDate" } - .date_filter{ :class => "three columns alpha" } - %label{ :for => 'end_date_filter' }End Date - %br - %input{ :class => "three columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datetimepicker' => "endDate", 'ofn-confirm-change' => "endDate" } - .row{ :class => "nine columns alpha" } - .filter_select{ :class => "three columns alpha" } - %label{ :for => 'supplier_filter' }Producer - %br - %select{ :class => "three columns alpha", :id => 'supplier_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'supplierFilter', 'ng-options' => 's.name for s in suppliers' } - .filter_select{ :class => "three columns alpha" } - %label{ :for => 'distributor_filter' }Hub - %br - %select{ :class => "three columns alpha", :id => 'distributor_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.name for d in distributors'} - .filter_select{ :class => "three columns alpha" } - %label{ :for => 'order_cycle_filter' }Order Cycle - %br - %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.name for oc in orderCycles'} - %div{ :class => "nine columns alpha", 'ng-show' => '!optionTabs.filters.visible && !optionTabs.column_toggle.visible && unitsVariantSelected()' }  . - %div#group_buy_calculation{ :class => "seven columns alpha", 'ng-show' => 'unitsVariantSelected()' } + .filters{ :class => "sixteen columns alpha" } + .date_filter{ :class => "three columns alpha" } + %label{ :for => 'start_date_filter' }Start Date + %br + %input{ :class => "three columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datetimepicker' => "startDate", 'ofn-confirm-change' => "startDate" } + .date_filter{ :class => "three columns omega" } + %label{ :for => 'end_date_filter' }End Date + %br + %input{ :class => "three columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datetimepicker' => "endDate", 'ofn-confirm-change' => "endDate" } + .one.column.omega   + .filter_select{ :class => "three columns omega" } + %label{ :for => 'supplier_filter' }Producer + %br + %select{ :class => "three columns alpha", :id => 'supplier_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'supplierFilter', 'ng-options' => 's.name for s in suppliers' } + .filter_select{ :class => "three columns omega" } + %label{ :for => 'distributor_filter' }Hub + %br + %select{ :class => "three columns alpha", :id => 'distributor_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.name for d in distributors'} + .filter_select{ :class => "three columns omega" } + %label{ :for => 'order_cycle_filter' }Order Cycle + %br + %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.name for oc in orderCycles'} + %div#group_buy_calculation{ :class => "sixteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } %div{ :class => "seven columns alpha" } %h6{ :class => "five columns alpha", 'ng-show' => 'sharedResource' } {{ selectedUnitsProduct.name + ": ALL" }} %h6{ :class => "five columns alpha", 'ng-hide' => 'sharedResource' } {{ selectedUnitsVariant.unit_text }} @@ -64,26 +59,29 @@ %hr{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px" } %div.loading{ :class => "sixteen columns alpha", 'ng-show' => 'loading' } %h4 Loading Line Items... - %div{ :class => "sixteen columns alpha", 'ng-show' => '!loading && lineItems.length == 0'} + %div{ :class => "sixteen columns alpha", 'ng-show' => '!loading && filteredLineItems.length == 0'} %h4{ :style => 'color:red;' } No matching line items found. %div{ 'ng-hide' => 'loading || lineItems.length == 0' } .controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" } - %input{ :class => "two columns alpha", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } - %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :class => "two columns omega", :id => "bulk_actions_dropdown", 'ofn-drop-down' => true } - %span Actions - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredLineItems)", 'ofn-close-on-click' => true } - %span{ :class => 'three columns omega' } {{action.name }} - %div{ :class => "ten columns omega" }   - %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :class => "two columns omega", :id => "columns_dropdown", 'ofn-drop-down' => true } - %span Columns - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } - %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} - %span{ :class => 'two columns omega' } {{column.name }} - %table.index#listing_orders.bulk + %div{ :class => "three columns alpha" } + %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } + %div{ :class => "three columns omega" } + %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "bulk_actions_dropdown", 'ofn-drop-down' => true } + %span{ :class => 'icon-check' }   Actions + %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } + %div.menu{ 'ng-show' => "expanded" } + %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredLineItems)", 'ofn-close-on-click' => true } + %span{ :class => 'three columns omega' } {{action.name }} + %div{ :class => "seven columns omega" }   + %div{ :class => "three columns omega" } + %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "columns_dropdown", 'ofn-drop-down' => true } + %span{ :class => 'icon-reorder' }   Columns + %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } + %div.menu{ 'ng-show' => "expanded" } + %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } + %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} + %span{ :class => 'two columns omega' } {{column.name }} + %table.index#listing_orders.bulk{ :class => "sixteen columns alpha" } %thead %tr %th.bulk diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 008955efce..fbc4710541 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -161,35 +161,6 @@ feature %q{ let!(:o1) { FactoryGirl.create(:order, state: 'complete', completed_at: Time.now ) } let!(:li1) { FactoryGirl.create(:line_item, order: o1, :quantity => 5 ) } - context "using tabs to hide and display page controls" do - it "shows a column display toggle button, which shows a list of columns when clicked" do - visit '/admin/orders/bulk_management' - - page.should_not have_selector "div#columns_dropdown.expanded" - page.should have_selector "div#columns_dropdown div.menu", :visible => false - - page.should have_selector "div#columns_dropdown", :text => "COLUMNS" - first("div#columns_dropdown", :text => "COLUMNS").click - - page.should have_selector "div#columns_dropdown.expanded" - page.should have_selector "div#columns_dropdown div.menu", :visible => true - page.should have_selector "div#columns_dropdown div.menu div.menu_item", text: "Producer" - - page.should have_selector "div.filters", :visible => false - - page.should have_selector "div.option_tab_titles h6.unselected", :text => "Filter Line Items" - first("div.option_tab_titles h6", :text => "Filter Line Items").click - - page.should have_selector "div.option_tab_titles h6.selected", :text => "Filter Line Items" - page.should have_selector "div.filters", :visible => true - - first("div.option_tab_titles h6", :text => "Filter Line Items").click - - page.should have_selector "div.option_tab_titles h6.unselected", :text => "Filter Line Items" - page.should have_selector "div.filters", :visible => false - end - end - context "using column display toggle" do it "shows a column display toggle button, which shows a list of columns when clicked" do visit '/admin/orders/bulk_management' @@ -229,7 +200,6 @@ feature %q{ before :each do visit '/admin/orders/bulk_management' - first("div.option_tab_titles h6", :text => "Filter Line Items").click end it "displays a select box for producers, which filters line items by the selected supplier" do @@ -353,7 +323,6 @@ feature %q{ before :each do visit '/admin/orders/bulk_management' - first("div.option_tab_titles h6", :text => "Filter Line Items").click end it "displays date fields for filtering orders, with default values set" do From fcb04481c4b8446bb60812d6302ccf101e3ee5ff Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 8 Apr 2014 17:55:09 +1000 Subject: [PATCH 12/29] Fixing a nil chain bug --- app/views/spree/order_mailer/confirm_email.text.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/order_mailer/confirm_email.text.erb b/app/views/spree/order_mailer/confirm_email.text.erb index 3ebeb233fd..12208bb8a4 100644 --- a/app/views/spree/order_mailer/confirm_email.text.erb +++ b/app/views/spree/order_mailer/confirm_email.text.erb @@ -24,7 +24,7 @@ Payment Details <% end %> -<%- if @order.shipping_method.require_ship_address %> +<%- if @order.shipping_method.andand.require_ship_address %> ============================================================ Shipping Details ============================================================ From 87a43fc36e35bb26c00d7aa5f07bd403c29aeeb5 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 9 Apr 2014 12:17:23 +1000 Subject: [PATCH 13/29] Fixing the build! Some minor bugs due to mailer changes --- .../enterprises_distributor_info_rich_text_feature_spec.rb | 5 +++-- spec/mailers/order_mailer_spec.rb | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb b/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb index 46385cee0f..10214d69dc 100644 --- a/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb +++ b/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb @@ -58,7 +58,6 @@ feature "enterprises distributor info as rich text" do end scenario "viewing distributor info with product distribution", js: true do - ActionMailer::Base.deliveries.clear d = create(:distributor_enterprise, distributor_info: 'Chu ge sai yubi dan bisento tobi ashi yubi ge omote.', next_collection_at: 'Thursday 2nd May') p = create(:product, :distributors => [d]) @@ -67,6 +66,7 @@ feature "enterprises distributor info as rich text" do login_to_consumer_section visit spree.select_distributor_order_path(d) + ActionMailer::Base.deliveries.clear # -- Product details page visit spree.product_path p @@ -110,6 +110,7 @@ feature "enterprises distributor info as rich text" do setup_shipping_details d login_to_consumer_section + ActionMailer::Base.deliveries.clear click_link 'Green Grass' visit enterprise_path d @@ -146,7 +147,7 @@ feature "enterprises distributor info as rich text" do zone = create(:zone) c = Spree::Country.find_by_name('Australia') Spree::ZoneMember.create(:zoneable => c, :zone => zone) - create(:shipping_method, zone: zone) + create(:shipping_method, zone: zone, require_ship_address: false) create(:payment_method, :description => 'Cheque payment method', distributors: [distributor]) end diff --git a/spec/mailers/order_mailer_spec.rb b/spec/mailers/order_mailer_spec.rb index f0535d88a7..0fae742ef9 100644 --- a/spec/mailers/order_mailer_spec.rb +++ b/spec/mailers/order_mailer_spec.rb @@ -17,6 +17,7 @@ describe Spree::OrderMailer do product_distribution = create(:product_distribution, :product => product, :distributor => @distributor) @shipping_instructions = "pick up on thursday please!" @order1 = create(:order, :distributor => @distributor, :bill_address => @bill_address, :special_instructions => @shipping_instructions) + ActionMailer::Base.deliveries = [] end it "should send an email when given an order" do From 19ca8e142aa631558dded637f00dcb1f7968a3c0 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 2 Apr 2014 14:13:06 +1100 Subject: [PATCH 14/29] Do not show deleted products on shopfront --- app/controllers/shop/shop_controller.rb | 2 +- spec/features/consumer/shopping/shopping_spec.rb | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/controllers/shop/shop_controller.rb b/app/controllers/shop/shop_controller.rb index 1af6ceec87..9db927cece 100644 --- a/app/controllers/shop/shop_controller.rb +++ b/app/controllers/shop/shop_controller.rb @@ -10,7 +10,7 @@ class Shop::ShopController < BaseController def products unless @products = current_order_cycle.andand .valid_products_distributed_by(current_distributor).andand - .select { |p| p.has_stock_for_distribution?(current_order_cycle, current_distributor) }.andand + .select { |p| !p.deleted? && p.has_stock_for_distribution?(current_order_cycle, current_distributor) }.andand .sort_by {|p| p.name } render json: "", status: 404 diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 89aa78eb5c..cb6816f69f 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -143,13 +143,14 @@ feature "As a consumer I want to shop with a distributor", js: true do end end - describe "filtering on hand and on demand products" do + describe "filtering products" do let(:oc) { create(:simple_order_cycle, distributors: [distributor]) } let(:p1) { create(:simple_product, on_demand: false) } let(:p2) { create(:simple_product, on_demand: true) } let(:p3) { create(:simple_product, on_demand: false) } let(:p4) { create(:simple_product, on_demand: false) } let(:p5) { create(:simple_product, on_demand: false) } + let(:p6) { create(:simple_product, on_demand: false) } let(:v1) { create(:variant, product: p4, unit_value: 2) } let(:v2) { create(:variant, product: p4, unit_value: 3, on_demand: false) } let(:v3) { create(:variant, product: p4, unit_value: 4, on_demand: true) } @@ -162,6 +163,8 @@ feature "As a consumer I want to shop with a distributor", js: true do p1.master.update_attribute(:count_on_hand, 1) p2.master.update_attribute(:count_on_hand, 0) p3.master.update_attribute(:count_on_hand, 0) + p6.master.update_attribute(:count_on_hand, 1) + p6.delete v1.update_attribute(:count_on_hand, 1) v2.update_attribute(:count_on_hand, 0) v3.update_attribute(:count_on_hand, 0) @@ -172,6 +175,7 @@ feature "As a consumer I want to shop with a distributor", js: true do exchange.variants << p1.master exchange.variants << p2.master exchange.variants << p3.master + exchange.variants << p6.master exchange.variants << v1 exchange.variants << v2 exchange.variants << v3 @@ -203,6 +207,9 @@ feature "As a consumer I want to shop with a distributor", js: true do # It does not show products that have no available variants in this distribution page.should_not have_content p5.name + + # It does not show deleted products + page.should_not have_content p6.name end end From e792107d7b0a74a05fee91baed9f706a13f0605b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 3 Apr 2014 11:18:46 +1100 Subject: [PATCH 15/29] Make order cycle specs more robust --- app/views/admin/order_cycles/show.rep | 2 +- spec/features/admin/order_cycles_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/admin/order_cycles/show.rep b/app/views/admin/order_cycles/show.rep index e5ccd66226..1f91cbe3e9 100644 --- a/app/views/admin/order_cycles/show.rep +++ b/app/views/admin/order_cycles/show.rep @@ -9,7 +9,7 @@ r.element :order_cycle, @order_cycle do r.element :id end - r.list_of :exchanges do |exchange| + r.list_of :exchanges, @order_cycle.exchanges.order('id ASC') do |exchange| r.element :id r.element :sender_id r.element :receiver_id diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 20e728a09d..25eaeb69dd 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -141,9 +141,9 @@ feature %q{ page.should have_selector 'td.distributors', text: 'My distributor' # And it should have some fees - OrderCycle.last.exchanges.first.enterprise_fees.should == [supplier_fee] - OrderCycle.last.coordinator_fees.should == [coordinator_fee] - OrderCycle.last.exchanges.last.enterprise_fees.should == [distributor_fee] + OrderCycle.last.exchanges.incoming.first.enterprise_fees.should == [supplier_fee] + OrderCycle.last.coordinator_fees.should == [coordinator_fee] + OrderCycle.last.exchanges.outgoing.first.enterprise_fees.should == [distributor_fee] # And it should have some variants selected OrderCycle.last.exchanges.first.variants.count.should == 2 From a91ea933cc8b0cfcb09c8954630ad80d97cb58e7 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 3 Apr 2014 11:19:05 +1100 Subject: [PATCH 16/29] Destroy adjustment metadata when adjustment is destroyed --- app/models/spree/adjustment_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index 5c4748b227..2c5bb0be0a 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -1,6 +1,6 @@ module Spree Adjustment.class_eval do - has_one :metadata, class_name: 'AdjustmentMetadata' + has_one :metadata, class_name: 'AdjustmentMetadata', dependent: :destroy scope :enterprise_fee, where(originator_type: 'EnterpriseFee') end From 3d0b24cc97bc83f4b4c7087db0f452f161a3871f Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 3 Apr 2014 11:23:54 +1100 Subject: [PATCH 17/29] Add missing foreign key indexes --- .../20140402032034_add_missing_indexes.rb | 38 +++++++++++++++++++ db/schema.rb | 36 +++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20140402032034_add_missing_indexes.rb diff --git a/db/migrate/20140402032034_add_missing_indexes.rb b/db/migrate/20140402032034_add_missing_indexes.rb new file mode 100644 index 0000000000..5c7713d3b6 --- /dev/null +++ b/db/migrate/20140402032034_add_missing_indexes.rb @@ -0,0 +1,38 @@ +class AddMissingIndexes < ActiveRecord::Migration + def change + add_index :adjustment_metadata, :enterprise_id + + add_index :carts, :user_id + + add_index :coordinator_fees, :order_cycle_id + add_index :coordinator_fees, :enterprise_fee_id + + add_index :distributors_payment_methods, :distributor_id + add_index :distributors_payment_methods, :payment_method_id + + add_index :enterprise_fees, :enterprise_id + + add_index :enterprise_groups_enterprises, :enterprise_group_id + add_index :enterprise_groups_enterprises, :enterprise_id + + add_index :enterprise_roles, :user_id + add_index :enterprise_roles, :enterprise_id + + add_index :enterprises, :address_id + + add_index :exchange_fees, :exchange_id + add_index :exchange_fees, :enterprise_fee_id + + add_index :exchange_variants, :exchange_id + add_index :exchange_variants, :variant_id + + add_index :exchanges, :order_cycle_id + add_index :exchanges, :sender_id + add_index :exchanges, :receiver_id + add_index :exchanges, :payment_enterprise_id + + add_index :product_distributions, :product_id + add_index :product_distributions, :distributor_id + add_index :product_distributions, :enterprise_fee_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 892382d1d7..83688ff525 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140324025840) do +ActiveRecord::Schema.define(:version => 20140402032034) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -22,11 +22,14 @@ ActiveRecord::Schema.define(:version => 20140324025840) do end add_index "adjustment_metadata", ["adjustment_id"], :name => "index_adjustment_metadata_on_adjustment_id" + add_index "adjustment_metadata", ["enterprise_id"], :name => "index_adjustment_metadata_on_enterprise_id" create_table "carts", :force => true do |t| t.integer "user_id" end + add_index "carts", ["user_id"], :name => "index_carts_on_user_id" + create_table "cms_blocks", :force => true do |t| t.integer "page_id", :null => false t.string "identifier", :null => false @@ -149,11 +152,17 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.integer "enterprise_fee_id" end + add_index "coordinator_fees", ["enterprise_fee_id"], :name => "index_coordinator_fees_on_enterprise_fee_id" + add_index "coordinator_fees", ["order_cycle_id"], :name => "index_coordinator_fees_on_order_cycle_id" + create_table "distributors_payment_methods", :id => false, :force => true do |t| t.integer "distributor_id" t.integer "payment_method_id" end + add_index "distributors_payment_methods", ["distributor_id"], :name => "index_distributors_payment_methods_on_distributor_id" + add_index "distributors_payment_methods", ["payment_method_id"], :name => "index_distributors_payment_methods_on_payment_method_id" + create_table "distributors_shipping_methods", :id => false, :force => true do |t| t.integer "distributor_id" t.integer "shipping_method_id" @@ -170,6 +179,8 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.datetime "updated_at", :null => false end + add_index "enterprise_fees", ["enterprise_id"], :name => "index_enterprise_fees_on_enterprise_id" + create_table "enterprise_groups", :force => true do |t| t.string "name" t.boolean "on_front_page" @@ -181,11 +192,17 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.integer "enterprise_id" end + add_index "enterprise_groups_enterprises", ["enterprise_group_id"], :name => "index_enterprise_groups_enterprises_on_enterprise_group_id" + add_index "enterprise_groups_enterprises", ["enterprise_id"], :name => "index_enterprise_groups_enterprises_on_enterprise_id" + create_table "enterprise_roles", :force => true do |t| t.integer "user_id" t.integer "enterprise_id" end + add_index "enterprise_roles", ["enterprise_id"], :name => "index_enterprise_roles_on_enterprise_id" + add_index "enterprise_roles", ["user_id"], :name => "index_enterprise_roles_on_user_id" + create_table "enterprises", :force => true do |t| t.string "name" t.string "description" @@ -215,6 +232,8 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.datetime "promo_image_updated_at" end + add_index "enterprises", ["address_id"], :name => "index_enterprises_on_address_id" + create_table "exchange_fees", :force => true do |t| t.integer "exchange_id" t.integer "enterprise_fee_id" @@ -222,6 +241,9 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.datetime "updated_at", :null => false end + add_index "exchange_fees", ["enterprise_fee_id"], :name => "index_exchange_fees_on_enterprise_fee_id" + add_index "exchange_fees", ["exchange_id"], :name => "index_exchange_fees_on_exchange_id" + create_table "exchange_variants", :force => true do |t| t.integer "exchange_id" t.integer "variant_id" @@ -229,6 +251,9 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.datetime "updated_at", :null => false end + add_index "exchange_variants", ["exchange_id"], :name => "index_exchange_variants_on_exchange_id" + add_index "exchange_variants", ["variant_id"], :name => "index_exchange_variants_on_variant_id" + create_table "exchanges", :force => true do |t| t.integer "order_cycle_id" t.integer "sender_id" @@ -241,6 +266,11 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.boolean "incoming", :default => false, :null => false end + add_index "exchanges", ["order_cycle_id"], :name => "index_exchanges_on_order_cycle_id" + add_index "exchanges", ["payment_enterprise_id"], :name => "index_exchanges_on_payment_enterprise_id" + add_index "exchanges", ["receiver_id"], :name => "index_exchanges_on_receiver_id" + add_index "exchanges", ["sender_id"], :name => "index_exchanges_on_sender_id" + create_table "landing_page_images", :force => true do |t| t.datetime "created_at", :null => false t.datetime "updated_at", :null => false @@ -267,6 +297,10 @@ ActiveRecord::Schema.define(:version => 20140324025840) do t.integer "enterprise_fee_id" end + add_index "product_distributions", ["distributor_id"], :name => "index_product_distributions_on_distributor_id" + add_index "product_distributions", ["enterprise_fee_id"], :name => "index_product_distributions_on_enterprise_fee_id" + add_index "product_distributions", ["product_id"], :name => "index_product_distributions_on_product_id" + create_table "spree_activators", :force => true do |t| t.string "description" t.datetime "expires_at" From 2bfbce65d85822ef601411d4cfd37e1483a9fb7b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 9 Apr 2014 12:01:43 +1000 Subject: [PATCH 18/29] Use domain instead of IP for Jenkins badge in README --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 38055186a3..4f6013a317 100644 --- a/README.markdown +++ b/README.markdown @@ -1,4 +1,4 @@ -[![Build Status](http://198.199.107.16:8080/buildStatus/icon?job=openfoodweb - tests)](http://198.199.107.16:8080/job/openfoodweb%20-%20tests/) +[![Build Status](http://ci.openfood.com.au:8080/buildStatus/icon?job=openfoodweb - tests)](http://ci.openfood.com.au:8080/job/openfoodweb%20-%20tests/) [![Code Climate](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork.png)](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork) # Open Food Network From 093004a460f418d1cc03e338e68f41bb6c60aa9a Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 9 Apr 2014 15:40:02 +1000 Subject: [PATCH 19/29] Clearing the cart when order cycle is changed --- app/models/spree/order_decorator.rb | 1 + spec/models/spree/order_spec.rb | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 40c06c3132..ccc827ec57 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -85,6 +85,7 @@ Spree::Order.class_eval do def set_order_cycle!(order_cycle) self.order_cycle = order_cycle self.distributor = nil unless order_cycle.nil? || order_cycle.has_distributor?(distributor) + self.empty! save! end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 18ad347dc2..bbdb6e22b9 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -181,14 +181,19 @@ describe Spree::Order do end describe "setting the order cycle" do + let(:oc) { create(:simple_order_cycle) } + + it "empties the cart when changing the order cycle" do + subject.should_receive(:empty!) + subject.set_order_cycle! oc + end + it "sets the order cycle when no distributor is set" do - oc = create(:simple_order_cycle) subject.set_order_cycle! oc subject.order_cycle.should == oc end it "keeps the distributor when it is available in the new order cycle" do - oc = create(:simple_order_cycle) d = create(:distributor_enterprise) create(:exchange, order_cycle: oc, sender: oc.coordinator, receiver: d, incoming: false) @@ -200,7 +205,6 @@ describe Spree::Order do end it "clears the distributor if it is not available at that order cycle" do - oc = create(:simple_order_cycle) d = create(:distributor_enterprise) subject.distributor = d @@ -211,7 +215,6 @@ describe Spree::Order do end it "clears the order cycle when setting to nil" do - oc = create(:simple_order_cycle) d = create(:distributor_enterprise) subject.set_order_cycle! oc subject.distributor = d From 35d590c9269e6b4ffd74085a63ea96278f31e299 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 9 Apr 2014 15:53:39 +1000 Subject: [PATCH 20/29] Fixing a bug uploading promo images --- app/views/admin/enterprises/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/enterprises/_form.html.haml b/app/views/admin/enterprises/_form.html.haml index 2d3c728bf0..1cb9707ecf 100644 --- a/app/views/admin/enterprises/_form.html.haml +++ b/app/views/admin/enterprises/_form.html.haml @@ -155,4 +155,4 @@ .omega.four.columns = image_tag @object.promo_image.url if @object.promo_image.present? - = f.file_field :pro_image + = f.file_field :promo_image From c5d5f5a9e69695d60c19c238bafd0da57bdccc7a Mon Sep 17 00:00:00 2001 From: Rob H Date: Thu, 10 Apr 2014 10:33:57 +1000 Subject: [PATCH 21/29] BOM: view information about max quantities ordered --- .../admin/bulk_order_management.js.coffee | 9 ++- .../admin/shared_directives.js.coffee | 27 ++++---- app/assets/stylesheets/admin/orders.css.scss | 9 +++ .../admin/orders/bulk_management.html.haml | 63 +++++++++++-------- .../admin/bulk_order_management_spec.rb | 14 +++-- .../unit/bulk_order_management_spec.js.coffee | 16 ++++- 6 files changed, 85 insertions(+), 53 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index caf159cbbe..e38aba47aa 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -230,6 +230,11 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ sum = sum + lineItem.quantity * lineItem.units_variant.unit_value , 0 + $scope.sumMaxUnitValues = -> + sum = $scope.filteredLineItems.reduce (sum,lineItem) -> + sum = sum + Math.max(lineItem.max_quantity,lineItem.quantity) * lineItem.units_variant.unit_value + , 0 + $scope.allUnitValuesPresent = -> for i,lineItem of $scope.filteredLineItems return false if !lineItem.units_variant.hasOwnProperty('unit_value') || !(lineItem.units_variant.unit_value > 0) @@ -262,12 +267,12 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ else '' - $scope.fulfilled = -> + $scope.fulfilled = (sumOfUnitValues) -> # A Units Variant is an API object which holds unit properies of a variant if $scope.selectedUnitsProduct.hasOwnProperty("group_buy_unit_size") && $scope.selectedUnitsProduct.group_buy_unit_size > 0 && $scope.selectedUnitsProduct.hasOwnProperty("variant_unit") && ( $scope.selectedUnitsProduct.variant_unit == "weight" || $scope.selectedUnitsProduct.variant_unit == "volume" ) - Math.round( $scope.sumUnitValues() / $scope.selectedUnitsProduct.group_buy_unit_size * 1000)/1000 + Math.round( sumOfUnitValues / $scope.selectedUnitsProduct.group_buy_unit_size * 1000)/1000 else '' diff --git a/app/assets/javascripts/admin/shared_directives.js.coffee b/app/assets/javascripts/admin/shared_directives.js.coffee index bb0a1067ce..1596abd0f0 100644 --- a/app/assets/javascripts/admin/shared_directives.js.coffee +++ b/app/assets/javascripts/admin/shared_directives.js.coffee @@ -1,21 +1,16 @@ sharedDirectivesModule = angular.module("ofn.shared_directives", []) -sharedDirectivesModule.directive "datetimepicker", [ - "$parse" - ($parse) -> - return ( - require: "ngModel" - link: (scope, element, attrs, ngModel) -> - element.datetimepicker - dateFormat: "yy-mm-dd" - timeFormat: "HH:mm:ss" - stepMinute: 15 - onSelect: (dateText, inst) -> - scope.$apply (scope) -> - # Fires ngModel.$parsers - ngModel.$setViewValue dateText - ) -] +sharedDirectivesModule.directive "datetimepicker", -> + require: "ngModel" + link: (scope, element, attrs, ngModel) -> + element.datetimepicker + dateFormat: "yy-mm-dd" + timeFormat: "HH:mm:ss" + stepMinute: 15 + onSelect: (dateText, inst) -> + scope.$apply (scope) -> + # Fires ngModel.$parsers + ngModel.$setViewValue dateText sharedDirectivesModule.directive "ofnSelect2MinSearch", [ -> diff --git a/app/assets/stylesheets/admin/orders.css.scss b/app/assets/stylesheets/admin/orders.css.scss index 7b4544e9a5..3098c7839c 100644 --- a/app/assets/stylesheets/admin/orders.css.scss +++ b/app/assets/stylesheets/admin/orders.css.scss @@ -28,4 +28,13 @@ div#group_buy_calculation { padding: 5px; } } + + hr { + width: 95%; + margin: 0 auto; + } + + .row span { + text-align: center; + } } \ No newline at end of file diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index ff6162754d..0eace6d1e2 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -28,33 +28,42 @@ %label{ :for => 'order_cycle_filter' }Order Cycle %br %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.name for oc in orderCycles'} - %div#group_buy_calculation{ :class => "sixteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } - %div{ :class => "seven columns alpha" } - %h6{ :class => "five columns alpha", 'ng-show' => 'sharedResource' } {{ selectedUnitsProduct.name + ": ALL" }} - %h6{ :class => "five columns alpha", 'ng-hide' => 'sharedResource' } {{ selectedUnitsVariant.unit_text }} - %h6{ :class => "two column omega" } - %a{ 'ng-click' => 'selectedUnitsVariant = {};selectedUnitsProduct = {}' } Clear - %div{ :class => "seven columns alpha" } - %span{ :class => "five columns alpha" } - Group Buy Unit Size - %span{ :class => "two columns omega" } - {{ formattedValueWithUnitName( selectedUnitsProduct.group_buy_unit_size, selectedUnitsProduct, selectedUnitsVariant ) }} - %div{ :class => "seven columns alpha" } - %span{ :class => "five columns alpha" } - Fulfilled Units - %span{ :class => "two columns omega" } - {{ fulfilled() }} - %div{ :class => "seven columns alpha" } - %span{ :class => "five columns alpha" } - Total Units Ordered - %span{ :class => "two columns omega" } - {{ formattedValueWithUnitName( sumUnitValues(), selectedUnitsProduct, selectedUnitsVariant ) }} - %div.shared_resource{ :class => "seven columns alpha" } - %span{ :class => "five columns alpha" } Shared Resource? - %span{ :class => 'two columns omega' } + %div#group_buy_calculation{ :class => "fifteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } + %div.shared_resource{ :class => "four columns alpha" } + %span{ :class => 'three columns omega' } %input{ type: 'checkbox', :id => 'shared_resource', 'ng-model' => 'sharedResource'} - %div{ :class => "seven columns alpha", 'ng-hide' => 'allUnitValuesPresent()' } - %span{ :class => "seven columns alpha", style: 'color:red' } + Shared Resource? + %div{ :class => "seven columns omega" } + %h6{ :class => "seven columns alpha", 'ng-show' => 'sharedResource', style: 'text-align: center;' } {{ selectedUnitsProduct.name + ": ALL" }} + %h6{ :class => "seven columns alpha", 'ng-hide' => 'sharedResource', style: 'text-align: center;' } {{ selectedUnitsVariant.unit_text }} + %div{ :class => "four columns alpha" } + %h6{ :class => "four columns alpha", :style => 'text-align: right;' } + %a{ 'ng-click' => 'selectedUnitsVariant = {};selectedUnitsProduct = {};sharedResource=false;' } Clear + %hr + .row{ :style => 'font-weight: bold'} + %span{ :class => "three columns omega" } + Group Buy Unit Size + %span{ :class => "three columns omega" } + Total Quantity Ordered + %span{ :class => "three columns omega" } + Max Quantity Ordered + %span{ :class => "three columns omega" } + Fulfilled Units + %span{ :class => "three columns alpha" } + Max Fulfilled Units + .row + %span{ :class => "three columns omega" } + {{ formattedValueWithUnitName( selectedUnitsProduct.group_buy_unit_size, selectedUnitsProduct, selectedUnitsVariant ) }} + %span{ :class => "three columns omega" } + {{ formattedValueWithUnitName( sumUnitValues(), selectedUnitsProduct, selectedUnitsVariant ) }} + %span{ :class => "three columns omega" } + {{ formattedValueWithUnitName( sumMaxUnitValues(), selectedUnitsProduct, selectedUnitsVariant ) }} + %span{ :class => "three columns omega" } + {{ fulfilled(sumUnitValues()) }} + %span{ :class => "three columns alpha" } + {{ fulfilled(sumMaxUnitValues()) }} + %div{ :class => "eight columns alpha", 'ng-hide' => 'allUnitValuesPresent()' } + %span{ :class => "eight columns alpha", style: 'color:red' } WARNING: Some variants do not have a unit value %hr{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px" } %div.loading{ :class => "sixteen columns alpha", 'ng-show' => 'loading' } @@ -121,7 +130,7 @@ %a{ 'ng-click' => "setSelectedUnitsVariant(line_item.units_product,line_item.units_variant)" } {{ line_item.units_variant.unit_text }} %td.quantity{ 'ng-show' => 'columns.quantity.visible' } %input{ :type => 'number', :name => 'quantity', 'ng-model' => "line_item.quantity", 'ofn-line-item-upd-attr' => "quantity" } - %td.max{ 'ng-show' => 'columns.max.visible' } {{ line_item.max }} + %td.max{ 'ng-show' => 'columns.max.visible' } {{ line_item.max_quantity }} %td.actions %a{ 'ng-click' => "deleteLineItem(line_item)", :class => "delete-line-item icon-trash no-text" } %input{ :type => "button", 'value' => 'Update', 'ng-click' => 'pendingChanges.submitAll()' } \ No newline at end of file diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index fbc4710541..86e0a337e4 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -486,8 +486,8 @@ feature %q{ let!(:p3) { FactoryGirl.create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000, variant_unit: "weight", variants: [FactoryGirl.create(:variant, unit_value: 1000)] ) } let!(:v3) { p3.variants.first } let!(:o3) { FactoryGirl.create(:order, state: 'complete', completed_at: Time.now ) } - let!(:li3) { FactoryGirl.create(:line_item, order: o3, variant: v3, quantity: 3 ) } - let!(:li4) { FactoryGirl.create(:line_item, order: o2, variant: v3, quantity: 1 ) } + let!(:li3) { FactoryGirl.create(:line_item, order: o3, variant: v3, quantity: 3, max_quantity: 6 ) } + let!(:li4) { FactoryGirl.create(:line_item, order: o2, variant: v3, quantity: 1, max_quantity: 3 ) } before :each do visit '/admin/orders/bulk_management' @@ -500,12 +500,16 @@ feature %q{ page.should have_selector "div#group_buy_calculation", :visible => true within "div#group_buy_calculation" do - page.should have_text "Group Buy Unit" + page.should have_text "Group Buy Unit Size" page.should have_text "5 kg" + page.should have_text "Total Quantity Ordered" + page.should have_text "4 kg" + page.should have_text "Max Quantity Ordered" + page.should have_text "9 kg" page.should have_text "Fulfilled Units" page.should have_text "0.8" - page.should have_text "Total Units Ordered" - page.should have_text "4 kg" + page.should have_text "Max Fulfilled Units" + page.should have_text "1.8" page.should have_selector "div.shared_resource", :visible => true within "div.shared_resource" do page.should have_selector "span", :text => "Shared Resource?" diff --git a/spec/javascripts/unit/bulk_order_management_spec.js.coffee b/spec/javascripts/unit/bulk_order_management_spec.js.coffee index 12c4d77cd7..c5adf09bd2 100644 --- a/spec/javascripts/unit/bulk_order_management_spec.js.coffee +++ b/spec/javascripts/unit/bulk_order_management_spec.js.coffee @@ -257,9 +257,7 @@ describe "AdminOrderMgmtCtrl", -> it "returns the quantity of fulfilled group buy units", -> scope.selectedUnitsProduct = { variant_unit: "weight", group_buy_unit_size: 1000 } - spyOn(scope,"sumUnitValues").andReturn 1500 - expect(scope.fulfilled()).toEqual 1.5 - expect(scope.sumUnitValues).toHaveBeenCalled() + expect(scope.fulfilled(1500)).toEqual 1.5 describe "allUnitValuesPresent()", -> it "returns false if the unit_value of any item in filteredLineItems does not exist", -> @@ -304,6 +302,18 @@ describe "AdminOrderMgmtCtrl", -> sp2 = scope.filteredLineItems[2].units_variant.unit_value * scope.filteredLineItems[2].quantity expect(scope.sumUnitValues()).toEqual (sp0 + sp1 + sp2) + describe "sumMaxUnitValues()", -> + it "returns the sum of the product of unit_value and maxOf(max_quantity,quantity) for specified line_items", -> + scope.filteredLineItems = [ + { units_variant: { unit_value: 1 }, quantity: 2, max_quantity: 5 } + { units_variant: { unit_value: 2 }, quantity: 3, max_quantity: 1 } + { units_variant: { unit_value: 3 }, quantity: 7, max_quantity: 10 } + ] + sp0 = scope.filteredLineItems[0].units_variant.unit_value * Math.max(scope.filteredLineItems[0].quantity, scope.filteredLineItems[0].max_quantity) + sp1 = scope.filteredLineItems[1].units_variant.unit_value * Math.max(scope.filteredLineItems[1].quantity, scope.filteredLineItems[1].max_quantity) + sp2 = scope.filteredLineItems[2].units_variant.unit_value * Math.max(scope.filteredLineItems[2].quantity, scope.filteredLineItems[2].max_quantity) + expect(scope.sumMaxUnitValues()).toEqual (sp0 + sp1 + sp2) + describe "formatting a value based upon the properties of a specified Units Variant", -> # A Units Variant is an API object which holds unit properies of a variant From 645b6d5a8f749cefa60bad6acbad32d7b38dff2e Mon Sep 17 00:00:00 2001 From: Rob H Date: Thu, 10 Apr 2014 10:51:55 +1000 Subject: [PATCH 22/29] BOM: change datetimepickers to datepickers --- .../admin/bulk_order_management.js.coffee | 5 ++++- .../javascripts/admin/shared_directives.js.coffee | 10 ++++++++++ .../spree/admin/orders/bulk_management.html.haml | 8 ++++---- spec/features/admin/bulk_order_management_spec.rb | 8 ++++---- .../unit/bulk_order_management_spec.js.coffee | 13 ++++++++++--- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index e38aba47aa..bdfb8d89e6 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -341,10 +341,13 @@ formatDate = (date) -> year = date.getFullYear() month = twoDigitNumber date.getMonth() + 1 day = twoDigitNumber date.getDate() + return year + "-" + month + "-" + day + +formatTime = (date) -> hours = twoDigitNumber date.getHours() mins = twoDigitNumber date.getMinutes() secs = twoDigitNumber date.getSeconds() - return year + "-" + month + "-" + day + " " + hours + ":" + mins + ":" + secs + return hours + ":" + mins + ":" + secs twoDigitNumber = (number) -> twoDigits = "" + number diff --git a/app/assets/javascripts/admin/shared_directives.js.coffee b/app/assets/javascripts/admin/shared_directives.js.coffee index 1596abd0f0..f5be794481 100644 --- a/app/assets/javascripts/admin/shared_directives.js.coffee +++ b/app/assets/javascripts/admin/shared_directives.js.coffee @@ -12,6 +12,16 @@ sharedDirectivesModule.directive "datetimepicker", -> # Fires ngModel.$parsers ngModel.$setViewValue dateText +sharedDirectivesModule.directive "datepicker", -> + require: "ngModel" + link: (scope, element, attrs, ngModel) -> + element.datepicker + dateFormat: "yy-mm-dd" + onSelect: (dateText, inst) -> + scope.$apply (scope) -> + # Fires ngModel.$parsers + ngModel.$setViewValue dateText + sharedDirectivesModule.directive "ofnSelect2MinSearch", [ -> return ( diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 0eace6d1e2..91813d6b35 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -7,14 +7,14 @@ %div{ 'ng-show' => '!spree_api_key_ok' } {{ api_error_msg }} .filters{ :class => "sixteen columns alpha" } - .date_filter{ :class => "three columns alpha" } + .date_filter{ :class => "two columns alpha" } %label{ :for => 'start_date_filter' }Start Date %br - %input{ :class => "three columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datetimepicker' => "startDate", 'ofn-confirm-change' => "startDate" } - .date_filter{ :class => "three columns omega" } + %input{ :class => "two columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'ofn-confirm-change' => "startDate" } + .date_filter{ :class => "two columns omega" } %label{ :for => 'end_date_filter' }End Date %br - %input{ :class => "three columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datetimepicker' => "endDate", 'ofn-confirm-change' => "endDate" } + %input{ :class => "two columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'ofn-confirm-change' => "endDate" } .one.column.omega   .filter_select{ :class => "three columns omega" } %label{ :for => 'supplier_filter' }Producer diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 86e0a337e4..0075b5e65a 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -326,8 +326,8 @@ feature %q{ end it "displays date fields for filtering orders, with default values set" do - one_week_ago = Date.today.prev_day(7).strftime("%F %T") - tonight = Date.tomorrow.strftime("%F %T") + one_week_ago = Date.today.prev_day(7).strftime("%F") + tonight = Date.tomorrow.strftime("%F") page.should have_field "start_date_filter", with: one_week_ago page.should have_field "end_date_filter", with: tonight end @@ -339,12 +339,12 @@ feature %q{ end it "displays only line items whose orders meet the date restriction criteria, when changed" do - fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") + fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F") page.should have_selector "tr#li_#{li1.id}", visible: true page.should have_selector "tr#li_#{li2.id}", visible: true page.should_not have_selector "tr#li_#{li3.id}", visible: true - fill_in "end_date_filter", :with => (Date.today + 3).strftime("%F %T") + fill_in "end_date_filter", :with => (Date.today + 3).strftime("%F") page.should have_selector "tr#li_#{li1.id}", visible: true page.should have_selector "tr#li_#{li2.id}", visible: true page.should have_selector "tr#li_#{li3.id}", visible: true diff --git a/spec/javascripts/unit/bulk_order_management_spec.js.coffee b/spec/javascripts/unit/bulk_order_management_spec.js.coffee index c5adf09bd2..1f6ec2a0da 100644 --- a/spec/javascripts/unit/bulk_order_management_spec.js.coffee +++ b/spec/javascripts/unit/bulk_order_management_spec.js.coffee @@ -609,8 +609,10 @@ describe "Auxiliary functions", -> expect(twoDigitNumber(1)).toEqual "01" expect(twoDigitNumber(9)).toEqual "09" - describe "formatting a date", -> - it "returns a date formatted as yyyy-mm-dd hh-MM:ss", -> + describe "formatting dates and times", -> + date = null + + beforeEach -> date = new Date date.setYear(2010) date.setMonth(5) # Zero indexed, so 5 is June @@ -618,4 +620,9 @@ describe "Auxiliary functions", -> date.setHours(5) date.setMinutes(10) date.setSeconds(30) - expect(formatDate(date)).toEqual "2010-06-15 05:10:30" \ No newline at end of file + + it "returns a date formatted as yyyy-mm-dd", -> + expect(formatDate(date)).toEqual "2010-06-15" + + it "returns a time formatted as hh-MM:ss", -> + expect(formatTime(date)).toEqual "05:10:30" \ No newline at end of file From 5c7d36ba9b7e0b18e0c59067091780f4970ecadf Mon Sep 17 00:00:00 2001 From: Rob H Date: Thu, 10 Apr 2014 15:29:09 +1000 Subject: [PATCH 23/29] BOM: interface cleanup and adding 'Clear All' button for filters --- .../admin/bulk_order_management.js.coffee | 26 +++--- .../admin/shared_directives.js.coffee | 17 ++-- app/assets/stylesheets/admin/orders.css.scss | 7 +- .../admin/orders/bulk_management.html.haml | 90 ++++++++++--------- .../admin/bulk_order_management_spec.rb | 17 +++- 5 files changed, 91 insertions(+), 66 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index bdfb8d89e6..9bd06d01bc 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -7,7 +7,7 @@ orderManagementModule.config [ ] orderManagementModule.value "blankOption", -> - { id: "", name: "All" } + { id: "0", name: "All" } orderManagementModule.directive "ofnLineItemUpdAttr", [ "switchClass", "pendingChanges" @@ -123,8 +123,6 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ $scope.sharedResource = false $scope.predicate = "" $scope.reverse = false - $scope.optionTabs = - filters: { title: "Filter Line Items", visible: false } $scope.columns = order_no: { name: "Order No.", visible: false } full_name: { name: "Name", visible: true } @@ -148,16 +146,15 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ dataFetcher("/api/enterprises/managed?template=bulk_index&q[is_primary_producer_eq]=true").then (data) -> $scope.suppliers = data $scope.suppliers.unshift blankOption() - $scope.supplierFilter = $scope.suppliers[0] dataFetcher("/api/enterprises/managed?template=bulk_index&q[is_distributor_eq]=true").then (data) -> $scope.distributors = data $scope.distributors.unshift blankOption() - $scope.distributorFilter = $scope.distributors[0] - dataFetcher("/api/order_cycles/managed").then (data) -> + ocFetcher = dataFetcher("/api/order_cycles/managed").then (data) -> $scope.orderCycles = data $scope.orderCycles.unshift blankOption() - $scope.orderCycleFilter = $scope.orderCycles[0] $scope.fetchOrders() + ocFetcher.then -> + $scope.resetSelectFilters() else if authorise_api_reponse.hasOwnProperty("error") $scope.api_error_msg = authorise_api_reponse("error") else @@ -279,18 +276,19 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ $scope.unitsVariantSelected = -> !angular.equals($scope.selectedUnitsVariant,{}) - $scope.shiftTab = (tab) -> - $scope.visibleTab.visible = false unless $scope.visibleTab == tab || $scope.visibleTab == undefined - tab.visible = !tab.visible - $scope.visibleTab = tab + $scope.resetSelectFilters = -> + $scope.distributorFilter = $scope.distributors[0].id + $scope.supplierFilter = $scope.suppliers[0].id + $scope.orderCycleFilter = $scope.orderCycles[0].id + $scope.quickSearch = "" ] orderManagementModule.filter "selectFilter", (blankOption) -> return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) -> filtered = [] - filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,blankOption()) || lineItem.supplier.id == selectedSupplier.id) && - (angular.equals(selectedDistributor,blankOption()) || lineItem.order.distributor.id == selectedDistributor.id) && - (angular.equals(selectedOrderCycle,blankOption()) || lineItem.order.order_cycle.id == selectedOrderCycle.id) + filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) && + (angular.equals(selectedDistributor,"0") || lineItem.order.distributor.id == selectedDistributor) && + (angular.equals(selectedOrderCycle,"0") || lineItem.order.order_cycle.id == selectedOrderCycle) filtered orderManagementModule.filter "variantFilter", -> diff --git a/app/assets/javascripts/admin/shared_directives.js.coffee b/app/assets/javascripts/admin/shared_directives.js.coffee index f5be794481..0a8a899a6f 100644 --- a/app/assets/javascripts/admin/shared_directives.js.coffee +++ b/app/assets/javascripts/admin/shared_directives.js.coffee @@ -22,14 +22,15 @@ sharedDirectivesModule.directive "datepicker", -> # Fires ngModel.$parsers ngModel.$setViewValue dateText -sharedDirectivesModule.directive "ofnSelect2MinSearch", [ - -> - return ( - link: (scope, element, attrs) -> - element.select2 - minimumResultsForSearch: attrs.ofnSelect2MinSearch - ) -] +sharedDirectivesModule.directive "ofnSelect2MinSearch", -> + require: 'ngModel' + link: (scope, element, attrs, ngModel) -> + element.select2 + minimumResultsForSearch: attrs.ofnSelect2MinSearch + + ngModel.$formatters.push (value) -> + if (value) + element.select2('val', value); sharedDirectivesModule.directive "ofnToggleColumn", -> link: (scope, element, attrs) -> diff --git a/app/assets/stylesheets/admin/orders.css.scss b/app/assets/stylesheets/admin/orders.css.scss index 3098c7839c..c0c1dac86b 100644 --- a/app/assets/stylesheets/admin/orders.css.scss +++ b/app/assets/stylesheets/admin/orders.css.scss @@ -2,6 +2,12 @@ margin-bottom: 10px; } +.filter_clear { + input { + background-color: #DA5354; + } +} + input.update-pending { border: solid 1px orange; } @@ -20,7 +26,6 @@ input.update-success { div#group_buy_calculation { border-radius: 3px; - border:1px solid #5498da; background-color: #eff5fc; div { margin-bottom: 5px; diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 91813d6b35..b689ed7b73 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -11,85 +11,91 @@ %label{ :for => 'start_date_filter' }Start Date %br %input{ :class => "two columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'ofn-confirm-change' => "startDate" } - .date_filter{ :class => "two columns omega" } + .date_filter{ :class => "two columns" } %label{ :for => 'end_date_filter' }End Date %br %input{ :class => "two columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'ofn-confirm-change' => "endDate" } - .one.column.omega   - .filter_select{ :class => "three columns omega" } + .one.column   + .filter_select{ :class => "three columns" } %label{ :for => 'supplier_filter' }Producer %br - %select{ :class => "three columns alpha", :id => 'supplier_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'supplierFilter', 'ng-options' => 's.name for s in suppliers' } - .filter_select{ :class => "three columns omega" } + %select{ :class => "three columns alpha", :id => 'supplier_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'supplierFilter', 'ng-options' => 's.id as s.name for s in suppliers' } + .filter_select{ :class => "three columns" } %label{ :for => 'distributor_filter' }Hub %br - %select{ :class => "three columns alpha", :id => 'distributor_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.name for d in distributors'} - .filter_select{ :class => "three columns omega" } + %select{ :class => "three columns alpha", :id => 'distributor_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.id as d.name for d in distributors'} + .filter_select{ :class => "three columns" } %label{ :for => 'order_cycle_filter' }Order Cycle %br - %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.name for oc in orderCycles'} - %div#group_buy_calculation{ :class => "fifteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } + %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.id as oc.name for oc in orderCycles'} + .filter_clear{ :class => "two columns omega" } + %label{ :for => 'clear_all_filters' } + %br + %input.fullwidth{ :type => 'button', :id => 'clear_all_filters', :value => "Clear All", 'ng-click' => "resetSelectFilters()" } + %hr{ :class => "sixteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } + %div#group_buy_calculation{ :class => "sixteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } %div.shared_resource{ :class => "four columns alpha" } - %span{ :class => 'three columns omega' } + %span{ :class => 'three columns alpha' } %input{ type: 'checkbox', :id => 'shared_resource', 'ng-model' => 'sharedResource'} Shared Resource? - %div{ :class => "seven columns omega" } - %h6{ :class => "seven columns alpha", 'ng-show' => 'sharedResource', style: 'text-align: center;' } {{ selectedUnitsProduct.name + ": ALL" }} - %h6{ :class => "seven columns alpha", 'ng-hide' => 'sharedResource', style: 'text-align: center;' } {{ selectedUnitsVariant.unit_text }} - %div{ :class => "four columns alpha" } + %div{ :class => "eight columns" } + %h6{ :class => "eight columns alpha", 'ng-show' => 'sharedResource', style: 'text-align: center;' } {{ selectedUnitsProduct.name + ": ALL" }} + %h6{ :class => "eight columns alpha", 'ng-hide' => 'sharedResource', style: 'text-align: center;' } {{ selectedUnitsVariant.unit_text }} + %div{ :class => "four columns omega" } %h6{ :class => "four columns alpha", :style => 'text-align: right;' } %a{ 'ng-click' => 'selectedUnitsVariant = {};selectedUnitsProduct = {};sharedResource=false;' } Clear %hr - .row{ :style => 'font-weight: bold'} - %span{ :class => "three columns omega" } - Group Buy Unit Size - %span{ :class => "three columns omega" } - Total Quantity Ordered - %span{ :class => "three columns omega" } - Max Quantity Ordered - %span{ :class => "three columns omega" } - Fulfilled Units - %span{ :class => "three columns alpha" } - Max Fulfilled Units .row - %span{ :class => "three columns omega" } - {{ formattedValueWithUnitName( selectedUnitsProduct.group_buy_unit_size, selectedUnitsProduct, selectedUnitsVariant ) }} - %span{ :class => "three columns omega" } - {{ formattedValueWithUnitName( sumUnitValues(), selectedUnitsProduct, selectedUnitsVariant ) }} - %span{ :class => "three columns omega" } - {{ formattedValueWithUnitName( sumMaxUnitValues(), selectedUnitsProduct, selectedUnitsVariant ) }} - %span{ :class => "three columns omega" } - {{ fulfilled(sumUnitValues()) }} - %span{ :class => "three columns alpha" } - {{ fulfilled(sumMaxUnitValues()) }} + .one.column.alpha   + .two.columns + %span.two.columns Group Buy Unit Size + %span.two.columns {{ formattedValueWithUnitName( selectedUnitsProduct.group_buy_unit_size, selectedUnitsProduct, selectedUnitsVariant ) }} + .one.column   + .two.columns + %span.two.columns Total Quantity Ordered + %span.two.columns {{ formattedValueWithUnitName( sumUnitValues(), selectedUnitsProduct, selectedUnitsVariant ) }} + .one.column   + .two.columns + %span.two.columns Max Quantity Ordered + %span.two.columns {{ formattedValueWithUnitName( sumMaxUnitValues(), selectedUnitsProduct, selectedUnitsVariant ) }} + .one.column   + .two.columns + %span.two.columns Current Fulfilled Units + %span.two.columns {{ fulfilled(sumUnitValues()) }} + .one.column   + .two.columns + %span.two.columns Max Fulfilled Units + %span.two.columns {{ fulfilled(sumMaxUnitValues()) }} + .one.column.omega   %div{ :class => "eight columns alpha", 'ng-hide' => 'allUnitValuesPresent()' } %span{ :class => "eight columns alpha", style: 'color:red' } WARNING: Some variants do not have a unit value %hr{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px" } - %div.loading{ :class => "sixteen columns alpha", 'ng-show' => 'loading' } - %h4 Loading Line Items... - %div{ :class => "sixteen columns alpha", 'ng-show' => '!loading && filteredLineItems.length == 0'} - %h4{ :style => 'color:red;' } No matching line items found. %div{ 'ng-hide' => 'loading || lineItems.length == 0' } .controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" } %div{ :class => "three columns alpha" } %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } - %div{ :class => "three columns omega" } + %div{ :class => "three columns" } %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "bulk_actions_dropdown", 'ofn-drop-down' => true } %span{ :class => 'icon-check' }   Actions %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } %div.menu{ 'ng-show' => "expanded" } %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredLineItems)", 'ofn-close-on-click' => true } %span{ :class => 'three columns omega' } {{action.name }} - %div{ :class => "seven columns omega" }   + %div{ :class => "seven columns" }   %div{ :class => "three columns omega" } - %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "columns_dropdown", 'ofn-drop-down' => true } + %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "columns_dropdown", 'ofn-drop-down' => true, :style => 'float:right;' } %span{ :class => 'icon-reorder' }   Columns %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } %div.menu{ 'ng-show' => "expanded" } %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} %span{ :class => 'two columns omega' } {{column.name }} + %div.loading{ :class => "sixteen columns alpha", 'ng-show' => 'loading' } + %h4 Loading Line Items... + %div{ :class => "sixteen columns alpha", 'ng-show' => '!loading && filteredLineItems.length == 0'} + %h4{ :style => 'color:red;' } No matching line items found. + %div{ 'ng-hide' => 'loading || filteredLineItems.length == 0' } %table.index#listing_orders.bulk{ :class => "sixteen columns alpha" } %thead %tr diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 0075b5e65a..9b5ac1dabe 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -284,6 +284,21 @@ feature %q{ page.should_not have_selector "tr#li_#{li1.id}", visible: true page.should have_selector "tr#li_#{li2.id}", visible: true end + + it "displays a 'Clear All' button which sets all select filters to 'All'" do + select2_select oc1.name, from: "order_cycle_filter" + select2_select d1.name, from: "distributor_filter" + select2_select s1.name, from: "supplier_filter" + page.should have_selector "tr#li_#{li1.id}", visible: true + page.should_not have_selector "tr#li_#{li2.id}", visible: true + page.should have_button "Clear All" + click_button "Clear All" + page.should have_selector "div#s2id_order_cycle_filter a.select2-choice", text: "All" + page.should have_selector "div#s2id_supplier_filter a.select2-choice", text: "All" + page.should have_selector "div#s2id_distributor_filter a.select2-choice", text: "All" + page.should have_selector "tr#li_#{li1.id}", visible: true + page.should have_selector "tr#li_#{li2.id}", visible: true + end end context "using quick search" do @@ -506,7 +521,7 @@ feature %q{ page.should have_text "4 kg" page.should have_text "Max Quantity Ordered" page.should have_text "9 kg" - page.should have_text "Fulfilled Units" + page.should have_text "Current Fulfilled Units" page.should have_text "0.8" page.should have_text "Max Fulfilled Units" page.should have_text "1.8" From 6228cc0c550f891808536cd48aada10aef5f9a35 Mon Sep 17 00:00:00 2001 From: Rob H Date: Thu, 10 Apr 2014 15:34:23 +1000 Subject: [PATCH 24/29] BOM: Add order cycle column --- app/assets/javascripts/admin/bulk_order_management.js.coffee | 1 + app/views/spree/admin/orders/bulk_management.html.haml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 9bd06d01bc..02ac040d99 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -130,6 +130,7 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ phone: { name: "Phone", visible: false } order_date: { name: "Order Date", visible: true } producer: { name: "Producer", visible: true } + order_cycle: { name: "Order Cycle", visible: false } hub: { name: "Hub", visible: false } variant: { name: "Variant", visible: true } quantity: { name: "Quantity", visible: true } diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index b689ed7b73..00c615effd 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -113,6 +113,8 @@ %a{ :href => '', 'ng-click' => "predicate = 'order.completed_at'; reverse = !reverse" } Order Date %th.producer{ 'ng-show' => 'columns.producer.visible' } %a{ :href => '', 'ng-click' => "predicate = 'supplier.name'; reverse = !reverse" } Producer + %th.order_cycle{ 'ng-show' => 'columns.order_cycle.visible' } + %a{ :href => '', 'ng-click' => "predicate = 'order.order_cycle.name'; reverse = !reverse" } Order Cycle %th.hub{ 'ng-show' => 'columns.hub.visible' } %a{ :href => '', 'ng-click' => "predicate = 'order.distributor.name'; reverse = !reverse" } Hub %th.variant{ 'ng-show' => 'columns.variant.visible' } @@ -131,6 +133,7 @@ %td.phone{ 'ng-show' => 'columns.phone.visible' } {{ line_item.order.phone }} %td.date{ 'ng-show' => 'columns.order_date.visible' } {{ line_item.order.completed_at }} %td.producer{ 'ng-show' => 'columns.producer.visible' } {{ line_item.supplier.name }} + %td.order_cycle{ 'ng-show' => 'columns.order_cycle.visible' } {{ line_item.order.order_cycle.name }} %td.hub{ 'ng-show' => 'columns.hub.visible' } {{ line_item.order.distributor.name }} %td.variant{ 'ng-show' => 'columns.variant.visible' } %a{ 'ng-click' => "setSelectedUnitsVariant(line_item.units_product,line_item.units_variant)" } {{ line_item.units_variant.unit_text }} From e64bfe8ba3b9b64a1fcd015818a8f3b38ff5f102 Mon Sep 17 00:00:00 2001 From: Rob H Date: Thu, 10 Apr 2014 16:26:24 +1000 Subject: [PATCH 25/29] Fix failing API Orders spec --- spec/controllers/spree/api/orders_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/spree/api/orders_controller_spec.rb b/spec/controllers/spree/api/orders_controller_spec.rb index 8de9dfabfa..99b218a009 100644 --- a/spec/controllers/spree/api/orders_controller_spec.rb +++ b/spec/controllers/spree/api/orders_controller_spec.rb @@ -24,7 +24,7 @@ module Spree context "as a normal user" do before :each do - spree_get :index, { :template => 'bulk_index', :format => :json } + spree_get :managed, { :template => 'bulk_index', :format => :json } end it "retrieves a list of orders with appropriate attributes, including line items with appropriate attributes" do From cf3681b93489350ddbb9ed3c3ec55e91dfbb2b73 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 11 Apr 2014 12:26:36 +1000 Subject: [PATCH 26/29] Moving over the new checkout authentication --- .../authentication_actions_controller.js.coffee | 12 ++++++++++++ app/views/shared/_menu.html.haml | 2 +- .../shop/checkout/_authentication.html.haml | 9 +++++++++ app/views/shop/checkout/edit.html.haml | 16 ++++------------ 4 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/controllers/authentication_actions_controller.js.coffee create mode 100644 app/views/shop/checkout/_authentication.html.haml diff --git a/app/assets/javascripts/darkswarm/controllers/authentication_actions_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/authentication_actions_controller.js.coffee new file mode 100644 index 0000000000..188867d7da --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/authentication_actions_controller.js.coffee @@ -0,0 +1,12 @@ +window.AuthenticationActionsCtrl = Darkswarm.controller "AuthenticationActionsCtrl", ($scope, Navigation, storage) -> + $scope.toggleLogin = -> + Navigation.navigate "/login" + + $scope.toggleSignup = -> + Navigation.navigate "/signup" + + $scope.toggleSignup = -> + Navigation.navigate "/signup" + + $scope.toggle = (path = null)-> + Navigation.navigate(path) diff --git a/app/views/shared/_menu.html.haml b/app/views/shared/_menu.html.haml index 3ece58cf4d..f5aee8cc17 100644 --- a/app/views/shared/_menu.html.haml +++ b/app/views/shared/_menu.html.haml @@ -1,6 +1,6 @@ %nav.top-bar %section.top-bar-section - %ul.left{"ng-controller" => "MenuCtrl"} + %ul.left{"ng-controller" => "AuthenticationActionsCtrl"} %li %a.icon{"ng-click" => "toggle()"} %i.fi-list diff --git a/app/views/shop/checkout/_authentication.html.haml b/app/views/shop/checkout/_authentication.html.haml new file mode 100644 index 0000000000..891958de25 --- /dev/null +++ b/app/views/shop/checkout/_authentication.html.haml @@ -0,0 +1,9 @@ +%fieldset + %accordion-group{heading: "User", "is-open" => "accordion.user"} + .row + .large-4.columns.text-center{"ng-controller" => "AuthenticationActionsCtrl"} + %button{"ng-click" => "toggle('/login')"} Login + .large-4.columns.text-center{"ng-controller" => "AuthenticationActionsCtrl"} + %button{"ng-click" => "toggle('/signup')"} Signup + .large-4.columns.text-center + %button{"ng-click" => "show('details')"} Checkout as guest diff --git a/app/views/shop/checkout/edit.html.haml b/app/views/shop/checkout/edit.html.haml index 98cead9b9f..c3db3fddf6 100644 --- a/app/views/shop/checkout/edit.html.haml +++ b/app/views/shop/checkout/edit.html.haml @@ -6,21 +6,13 @@ = render partial: "shop/details" - %checkout - .row + %accordion.row{"close-others" => "true"} + %checkout{"ng-controller" => "CheckoutCtrl"} .large-9.columns - unless spree_current_user - .row - %section#checkout_login - .large-6.columns - = render partial: "shop/checkout/login" - %section#checkout_signup - .large-6.columns - = render partial: "shop/checkout/signup" + = render partial: "shop/checkout/authentication" .row = render partial: "shop/checkout/form" - .large-3.columns - .row - = render partial: "shop/checkout/summary" + = render partial: "shop/checkout/summary" From 33cf05ab8381534046665dfbd4831de134f73eed Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 11 Apr 2014 12:37:32 +1000 Subject: [PATCH 27/29] Manually bringing over the login links for checkout --- .../javascripts/darkswarm/all.js.coffee | 2 + .../controllers/checkout_controller.js.coffee | 8 +- .../controllers/menu_controller.js.coffee | 13 -- .../javascripts/darkswarm/darkswarm.js.coffee | 3 +- .../shared/angular-local-storage.js | 171 ++++++++++++++++++ .../shop/checkout/_authentication.html.haml | 4 +- app/views/shop/checkout/_form.html.haml | 2 +- app/views/shop/shop/show.html.haml | 2 +- 8 files changed, 186 insertions(+), 19 deletions(-) delete mode 100644 app/assets/javascripts/darkswarm/controllers/menu_controller.js.coffee create mode 100644 app/assets/javascripts/shared/angular-local-storage.js diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index ea8c47eed8..7f09206ea3 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -4,8 +4,10 @@ #= require spin # #= require angular +#= require angular-cookies #= require angular-resource #= require ../shared/mm-foundation-tpls-0.2.0-SNAPSHOT +#= require ../shared/angular-local-storage.js # #= require ../shared/jquery.timeago #= require foundation diff --git a/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee index 1d0604d76c..1bb7692239 100644 --- a/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee @@ -1,6 +1,7 @@ -Darkswarm.controller "CheckoutCtrl", ($scope, $rootScope, order) -> +Darkswarm.controller "CheckoutCtrl", ($scope, $rootScope, order, $location, $anchorScroll) -> $scope.require_ship_address = false $scope.order = order + $scope.userOpen = true $scope.initialize = -> # Our shipping_methods comes through as a hash like so: {id: requires_shipping_address} @@ -25,5 +26,10 @@ Darkswarm.controller "CheckoutCtrl", ($scope, $rootScope, order) -> event.preventDefault() checkout.submit() + $scope.scrollTo = (name)-> + $location.hash(name); + $anchorScroll(); + $scope.userOpen = false + $scope.initialize() diff --git a/app/assets/javascripts/darkswarm/controllers/menu_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/menu_controller.js.coffee deleted file mode 100644 index 889c8fa8f4..0000000000 --- a/app/assets/javascripts/darkswarm/controllers/menu_controller.js.coffee +++ /dev/null @@ -1,13 +0,0 @@ -window.MenuCtrl = Darkswarm.controller "MenuCtrl", ($scope, Navigation) -> - - $scope.toggleLogin = -> - Navigation.navigate "/login" - - $scope.toggleSignup = -> - Navigation.navigate "/signup" - - $scope.toggleSignup = -> - Navigation.navigate "/signup" - - $scope.toggle = (path = null)-> - Navigation.navigate(path) diff --git a/app/assets/javascripts/darkswarm/darkswarm.js.coffee b/app/assets/javascripts/darkswarm/darkswarm.js.coffee index 6be3a4a155..d2ce7b6758 100644 --- a/app/assets/javascripts/darkswarm/darkswarm.js.coffee +++ b/app/assets/javascripts/darkswarm/darkswarm.js.coffee @@ -1,5 +1,6 @@ -window.Darkswarm = angular.module("Darkswarm", ["ngResource", "filters", 'mm.foundation']).config ($httpProvider, $tooltipProvider) -> +window.Darkswarm = angular.module("Darkswarm", ["ngResource", "filters", 'mm.foundation', 'angularLocalStorage']).config ($httpProvider, $tooltipProvider) -> $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-Requested-With'] = 'XMLHttpRequest' $httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*" diff --git a/app/assets/javascripts/shared/angular-local-storage.js b/app/assets/javascripts/shared/angular-local-storage.js new file mode 100644 index 0000000000..2ac18eba9e --- /dev/null +++ b/app/assets/javascripts/shared/angular-local-storage.js @@ -0,0 +1,171 @@ +/* + * Angular.js localStorage module + * https://github.com/agrublev/angularLocalStorage + */ + +(function (window, angular, undefined) { + 'use strict'; + + angular.module('angularLocalStorage', ['ngCookies']).factory('storage', ['$parse', '$cookieStore', '$window', '$log', function ($parse, $cookieStore, $window, $log) { + /** + * Global Vars + */ + var storage = (typeof $window.localStorage === 'undefined') ? undefined : $window.localStorage; + var supported = typeof storage !== 'undefined'; + + var privateMethods = { + /** + * Pass any type of a string from the localStorage to be parsed so it returns a usable version (like an Object) + * @param res - a string that will be parsed for type + * @returns {*} - whatever the real type of stored value was + */ + parseValue: function (res) { + var val; + try { + val = angular.fromJson(res); + if (typeof val === 'undefined') { + val = res; + } + if (val === 'true') { + val = true; + } + if (val === 'false') { + val = false; + } + if ($window.parseFloat(val) === val && !angular.isObject(val)) { + val = $window.parseFloat(val); + } + } catch (e) { + val = res; + } + return val; + } + }; + + var publicMethods = { + /** + * Set - let's you set a new localStorage key pair set + * @param key - a string that will be used as the accessor for the pair + * @param value - the value of the localStorage item + * @returns {*} - will return whatever it is you've stored in the local storage + */ + set: function (key, value) { + if (!supported) { + try { + $cookieStore.put(key, value); + return value; + } catch(e) { + $log.log('Local Storage not supported, make sure you have angular-cookies enabled.'); + } + } + var saver = angular.toJson(value); + storage.setItem(key, saver); + return privateMethods.parseValue(saver); + }, + + /** + * Get - let's you get the value of any pair you've stored + * @param key - the string that you set as accessor for the pair + * @returns {*} - Object,String,Float,Boolean depending on what you stored + */ + get: function (key) { + if (!supported) { + try { + return privateMethods.parseValue($.cookie(key)); + } catch (e) { + return null; + } + } + var item = storage.getItem(key); + return privateMethods.parseValue(item); + }, + + /** + * Remove - let's you nuke a value from localStorage + * @param key - the accessor value + * @returns {boolean} - if everything went as planned + */ + remove: function (key) { + if (!supported) { + try { + $cookieStore.remove(key); + return true; + } catch (e) { + return false; + } + } + storage.removeItem(key); + return true; + }, + + /** + * Bind - let's you directly bind a localStorage value to a $scope variable + * @param {Angular $scope} $scope - the current scope you want the variable available in + * @param {String} key - the name of the variable you are binding + * @param {Object} opts - (optional) custom options like default value or unique store name + * Here are the available options you can set: + * * defaultValue: the default value + * * storeName: add a custom store key value instead of using the scope variable name + * @returns {*} - returns whatever the stored value is + */ + bind: function ($scope, key, opts) { + var defaultOpts = { + defaultValue: '', + storeName: '' + }; + // Backwards compatibility with old defaultValue string + if (angular.isString(opts)) { + opts = angular.extend({},defaultOpts,{defaultValue:opts}); + } else { + // If no defined options we use defaults otherwise extend defaults + opts = (angular.isUndefined(opts)) ? defaultOpts : angular.extend(defaultOpts,opts); + } + + // Set the storeName key for the localStorage entry + // use user defined in specified + var storeName = opts.storeName || key; + + // If a value doesn't already exist store it as is + if (!publicMethods.get(storeName)) { + publicMethods.set(storeName, $parse(key)($scope) || opts.defaultValue); + } else { + // If it does exist assign it to the $scope value + $parse(key).assign($scope, publicMethods.get(storeName)); + } + + + // Register a listener for changes on the $scope value + // to update the localStorage value + $scope.$watch(key, function (val) { + if (angular.isDefined(val)) { + publicMethods.set(storeName, val); + } + }, true); + + return publicMethods.get(storeName); + }, + /** + * Unbind - let's you unbind a variable from localStorage while removing the value from both + * the localStorage and the local variable and sets it to null + * @param $scope - the scope the variable was initially set in + * @param key - the name of the variable you are unbinding + * @param storeName - (optional) if you used a custom storeName you will have to specify it here as well + */ + unbind: function($scope,key,storeName) { + storeName = storeName || key; + $parse(key).assign($scope, null); + $scope.$watch(key, function () { }); + publicMethods.remove(storeName); + }, + /** + * Clear All - let's you clear out ALL localStorage variables, use this carefully! + */ + clearAll: function() { + storage.clear(); + } + }; + + return publicMethods; + }]); + +})(window, window.angular); diff --git a/app/views/shop/checkout/_authentication.html.haml b/app/views/shop/checkout/_authentication.html.haml index 891958de25..62aba59509 100644 --- a/app/views/shop/checkout/_authentication.html.haml +++ b/app/views/shop/checkout/_authentication.html.haml @@ -1,9 +1,9 @@ %fieldset - %accordion-group{heading: "User", "is-open" => "accordion.user"} + %accordion-group{heading: "User", "is-open" => "userOpen"} .row .large-4.columns.text-center{"ng-controller" => "AuthenticationActionsCtrl"} %button{"ng-click" => "toggle('/login')"} Login .large-4.columns.text-center{"ng-controller" => "AuthenticationActionsCtrl"} %button{"ng-click" => "toggle('/signup')"} Signup .large-4.columns.text-center - %button{"ng-click" => "show('details')"} Checkout as guest + %button{"ng-click" => "scrollTo('details')"} Checkout as guest diff --git a/app/views/shop/checkout/_form.html.haml b/app/views/shop/checkout/_form.html.haml index 8ac9f67c90..cd3b277dbb 100644 --- a/app/views/shop/checkout/_form.html.haml +++ b/app/views/shop/checkout/_form.html.haml @@ -9,7 +9,7 @@ -#{{ order | json }} .large-12.columns - %fieldset#details + %fieldset#details{name: "details"} %legend Customer Details .row .large-6.columns diff --git a/app/views/shop/shop/show.html.haml b/app/views/shop/shop/show.html.haml index f8380c6c39..08f8ff448e 100644 --- a/app/views/shop/shop/show.html.haml +++ b/app/views/shop/shop/show.html.haml @@ -5,7 +5,7 @@ %select.avenir#order_cycle_id{"ng-model" => "order_cycle.order_cycle_id", "ng-change" => "changeOrderCycle()", "ng-options" => "oc.id as oc.time for oc in #{@order_cycles.map {|oc| {time: pickup_time(oc), id: oc.id}}.to_json}", - "popover-placement" => "bottom", "popover" => "testy", "popover-trigger" => "openTrigger"} + "popover-placement" => "bottom", "popover" => "Select an order cycle", "popover-trigger" => "openTrigger"} %closing{"ng-if" => "OrderCycle.selected()"} Orders close From 2e5425d931a351605a197ad9c94304ca4ec0b56e Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 11 Apr 2014 12:48:28 +1000 Subject: [PATCH 28/29] Pulling over some test changes --- .../consumer/shopping/checkout_auth_spec.rb | 67 +++++-------------- spec/support/request/shop_workflow.rb | 4 ++ 2 files changed, 21 insertions(+), 50 deletions(-) diff --git a/spec/features/consumer/shopping/checkout_auth_spec.rb b/spec/features/consumer/shopping/checkout_auth_spec.rb index 6ad1ab89d4..7a770cf9ee 100644 --- a/spec/features/consumer/shopping/checkout_auth_spec.rb +++ b/spec/features/consumer/shopping/checkout_auth_spec.rb @@ -23,61 +23,28 @@ feature "As a consumer I want to check out my cart", js: true do add_product_to_cart end - it "renders the login form if user is logged out" do - visit "/shop/checkout" - within "section[role='main']" do - page.should have_content "I HAVE AN OFN ACCOUNT" + context "logged in" do + before do + login_to_consumer_section + visit "/shop/checkout" + end + it "does not not render the login form" do + within "section[role='main']" do + page.should_not have_content "USER" + end end end - it "does not not render the login form if user is logged in" do - login_to_consumer_section - visit "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "I HAVE AN OFN ACCOUNT" - end - end - - it "renders the signup link if user is logged out" do - visit "/shop/checkout" - within "section[role='main']" do - page.should have_content "NEW TO OFN" - end - end - - it "does not not render the signup form if user is logged in" do - login_to_consumer_section - visit "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "NEW TO OFN" - end - end - - it "redirects to the checkout page when logging in from the checkout page" do - visit "/shop/checkout" - within "#checkout_login" do - fill_in "spree_user[email]", with: user.email - fill_in "spree_user[password]", with: user.password - click_button "Login" + context "logged out" do + before do + visit "/shop/checkout" + toggle_accordion "User" end - current_path.should == "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "I have an OFN Account" - end - end - - it "redirects to the checkout page when signing up from the checkout page" do - visit "/shop/checkout" - within "#checkout_signup" do - fill_in "spree_user[email]", with: "test@gmail.com" - fill_in "spree_user[password]", with: "password" - fill_in "spree_user[password_confirmation]", with: "password" - click_button "Sign Up" - end - current_path.should == "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "Sign Up" + it "renders the login form if user is logged out" do + within "section[role='main']" do + page.should have_content "USER" + end end end end diff --git a/spec/support/request/shop_workflow.rb b/spec/support/request/shop_workflow.rb index 414c7a4fa1..1473afe477 100644 --- a/spec/support/request/shop_workflow.rb +++ b/spec/support/request/shop_workflow.rb @@ -16,4 +16,8 @@ module ShopWorkflow def add_product_to_cart create(:line_item, variant: product.master, order: order) end + + def toggle_accordion(name) + find("dd a", text: name.upcase).click + end end From 9f3bf0b8f15b498bab744d01d7037f2ca86333d4 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 11 Apr 2014 12:50:06 +1000 Subject: [PATCH 29/29] Pending the checkout auth tests, since they're testing a monkeypatch --- spec/features/consumer/shopping/checkout_auth_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/features/consumer/shopping/checkout_auth_spec.rb b/spec/features/consumer/shopping/checkout_auth_spec.rb index 7a770cf9ee..605df207a9 100644 --- a/spec/features/consumer/shopping/checkout_auth_spec.rb +++ b/spec/features/consumer/shopping/checkout_auth_spec.rb @@ -15,7 +15,10 @@ feature "As a consumer I want to check out my cart", js: true do create_enterprise_group_for distributor end - describe "Login behaviour" do + # This was refactored in the new checkout + # We have monkey-patched in some of the new features + # Test suite works in that branch + pending "Login behaviour" do let(:user) { create_enterprise_user } before do select_distributor