From dcf64464504f490b25885f76bf30d938afecdd24 Mon Sep 17 00:00:00 2001 From: Rob H Date: Sat, 8 Jun 2013 19:52:51 +0530 Subject: [PATCH] BPUR: can delete variants --- .../javascripts/admin/bulk_product_update.js | 36 ++++++++++++++----- .../spree/admin/products/bulk_index.html.haml | 6 ++-- .../admin/bulk_product_update_spec.rb | 22 +++++++++++- .../unit/bulk_product_update_spec.js | 35 +++++++++++++++--- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_product_update.js b/app/assets/javascripts/admin/bulk_product_update.js index ef3598a7a6..0003926fbf 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js +++ b/app/assets/javascripts/admin/bulk_product_update.js @@ -103,12 +103,27 @@ productsApp.controller('AdminBulkProductsCtrl', function($scope, $timeout, $http method: 'DELETE', url: '/admin/products/'+product.permalink_live+".js" }) - .success(function(data,status,headers,config){ + .success(function(data){ delete $scope.products[product.id] - delete $scope.dirtyProducts[product.id] + if ($scope.dirtyProducts.hasOwnProperty(product.id)) delete $scope.dirtyProducts[product.id] }) } + $scope.deleteVariant = function(product,variant){ + $http({ + method: 'DELETE', + url: '/admin/products/'+product.permalink_live+"/variants/"+variant.id+".js" + }) + .success(function(data){ + delete $scope.products[product.id].variants[variant.id] + if ($scope.dirtyProducts.hasOwnProperty(product.id) && $scope.dirtyProducts[product.id].hasOwnProperty("variants") && $scope.dirtyProducts[product.id].variants.hasOwnProperty(variant.id)) delete $scope.dirtyProducts[product.id].variants[variant.id] + }) + } + + $scope.hasVariants = function(product){ + return !angular.equals(product.variants,{}); + } + $scope.updateProducts = function(productsToSubmit){ $scope.displayUpdating(); $http({ @@ -177,7 +192,7 @@ productsApp.factory('dataFetcher', function($http,$q){ function onHand(product){ var onHand = 0; - if(product.hasOwnProperty('variants') && product.variants instanceof Array){ + if(product.hasOwnProperty('variants') && product.variants instanceof Object){ angular.forEach(product.variants, function(variant) { onHand = parseInt( onHand ) + parseInt( variant.on_hand > 0 ? variant.on_hand : 0 ); }); @@ -240,17 +255,20 @@ function addDirtyProperty(dirtyObjects, objectID, propertyName, propertyValue){ function removeCleanProperty(dirtyObjects, objectID, propertyName){ if (dirtyObjects.hasOwnProperty(objectID) && dirtyObjects[objectID].hasOwnProperty(propertyName)) delete dirtyObjects[objectID][propertyName]; - if (dirtyObjects.hasOwnProperty(objectID) && Object.keys(dirtyObjects[objectID]).length <= 1) delete dirtyObjects[objectID]; + if (dirtyObjects.hasOwnProperty(objectID) && Object.keys(dirtyObjects[objectID]).length <= 1) delete dirtyObjects[objectID]; } function toObjectWithIDKeys(array){ - object = {}; - if (array instanceof Array){ + var object = {}; + //if (array instanceof Array){ for (i in array){ - if (array[i].hasOwnProperty("id")){ - object[array[i].id] = array[i]; + if (array[i] instanceof Object && array[i].hasOwnProperty("id")){ + object[array[i].id] = angular.copy(array[i]); + if (array[i].hasOwnProperty("variants") && array[i].variants instanceof Array){ + object[array[i].id].variants = toObjectWithIDKeys(array[i].variants); + } } } - } + //} return object; } \ No newline at end of file diff --git a/app/views/spree/admin/products/bulk_index.html.haml b/app/views/spree/admin/products/bulk_index.html.haml index f4e1547859..d9b0a6d1d1 100644 --- a/app/views/spree/admin/products/bulk_index.html.haml +++ b/app/views/spree/admin/products/bulk_index.html.haml @@ -30,8 +30,8 @@ %td %input{ 'ng-model' => 'product.price', 'ng-decimal' => :true, :name => 'price', 'ng-track-product' => 'price', :type => 'text' } %td - %span{ 'ng-bind' => 'product.on_hand', :name => 'on_hand', 'ng-show' => 'product.variants.length > 0' } - %input.field{ 'ng-model' => 'product.on_hand', :name => 'on_hand', 'ng-track-product' => 'on_hand', 'ng-show' => 'product.variants.length == 0', :type => 'number' } + %span{ 'ng-bind' => 'product.on_hand', :name => 'on_hand', 'ng-show' => 'hasVariants(product)' } + %input.field{ 'ng-model' => 'product.on_hand', :name => 'on_hand', 'ng-track-product' => 'on_hand', 'ng-show' => '!hasVariants(product)', :type => 'number' } %td %input{ 'ng-model' => 'product.available_on', :name => 'available_on', 'ng-track-product' => 'available_on', :type => 'text' } %td.actions @@ -45,6 +45,8 @@ %td %input.field{ 'ng-model' => 'variant.on_hand', 'ng-change' => 'updateOnHand(product)', :name => 'variant_on_hand', 'ng-track-variant' => 'on_hand', :type => 'number' } %td + %td.actions + %a{ 'ng-click' => 'deleteVariant(product,variant)', :class => "delete-variant icon-trash no-text" } %input{:type => 'button', :value => 'Update', 'ng-click' => 'prepareProductsForSubmit()'} %span{ id: "update-status-message", 'ng-style' => 'updateStatusMessage.style' } {{ updateStatusMessage.text }} \ No newline at end of file diff --git a/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb index 84a3564d1e..54ee9acbcb 100644 --- a/spec/features/admin/bulk_product_update_spec.rb +++ b/spec/features/admin/bulk_product_update_spec.rb @@ -276,7 +276,27 @@ feature %q{ visit '/admin/products/bulk_index' page.should have_selector "a.delete-product", :count => 2 - end + end + + it "shows a delete button for variants, which deletes the appropriate variant when clicked" do + v1 = FactoryGirl.create(:variant) + v2 = FactoryGirl.create(:variant) + v3 = FactoryGirl.create(:variant) + login_to_admin_section + + visit '/admin/products/bulk_index' + + page.should have_selector "a.delete-variant", :count => 3 + + first("a.delete-variant").click + + page.should have_selector "a.delete-variant", :count => 2 + #page.should have_selector "div.flash.notice", text: "Product has been deleted." + + visit '/admin/products/bulk_index' + + page.should have_selector "a.delete-variant", :count => 2 + end end end end \ No newline at end of file diff --git a/spec/javascripts/unit/bulk_product_update_spec.js b/spec/javascripts/unit/bulk_product_update_spec.js index 6e958e5f42..a46e64464e 100644 --- a/spec/javascripts/unit/bulk_product_update_spec.js +++ b/spec/javascripts/unit/bulk_product_update_spec.js @@ -218,9 +218,9 @@ describe("AdminBulkProductsCtrl", function(){ describe("getting on_hand counts when products have variants", function(){ var p1, p2, p3; beforeEach(function(){ - p1 = { variants: [ { on_hand: 1 }, { on_hand: 2 }, { on_hand: 3 } ] }; - p2 = { variants: [ { not_on_hand: 1 }, { on_hand: 2 }, { on_hand: 3 } ] }; - p3 = { not_variants: [ { on_hand: 1 }, { on_hand: 2 } ], variants: [ { on_hand: 3 } ] }; + p1 = { variants: { 1: { id: 1, on_hand: 1 }, 2: { id: 2, on_hand: 2 }, 3: { id: 3, on_hand: 3 } } }; + p2 = { variants: { 4: { id: 4, not_on_hand: 1 }, 5: { id: 5, on_hand: 2 }, 6: { id: 6, on_hand: 3 } } }; + p3 = { not_variants: { 7: { id: 7, on_hand: 1 }, 8: { id: 8, on_hand: 2 } }, variants: { 9: { id: 9, on_hand: 3 } } }; }); it("sums variant on_hand properties", function(){ @@ -235,10 +235,9 @@ describe("AdminBulkProductsCtrl", function(){ expect(onHand(p3)).toEqual(3); }); - it("returns 'error' if not given an object with a variants property that is an array", function(){ + it("returns 'error' if not given an object with a variants property that is an object", function(){ expect( onHand([]) ).toEqual('error'); expect( onHand( { not_variants: [] } ) ).toEqual('error'); - expect( onHand( { variants: {} } ) ).toEqual('error'); }); }); @@ -341,4 +340,30 @@ describe("AdminBulkProductsCtrl", function(){ expect(field.text()).toBe("123"); }); });*/ +}); + +describe("converting arrays of objects with ids to an object with ids as keys", function(){ + it("returns an object", function(){ + var array = []; + expect(toObjectWithIDKeys(array)).toEqual({}); + }); + + it("adds each object in the array provided with an id to the returned object with the id as its key", function(){ + var array = [ { id: 1 }, { id: 3 } ]; + expect(toObjectWithIDKeys(array)).toEqual({ 1: { id: 1 }, 3: { id: 3 } } ); + }); + + it("ignores items which are not objects and those which do not possess ids", function(){ + var array = [ { id: 1 }, "not an object", { notanid: 3 } ]; + expect(toObjectWithIDKeys(array)).toEqual({ 1: { id: 1 } } ); + }); + + it("sends arrays with the key 'variants' to itself", function(){ + spyOn(window, "toObjectWithIDKeys").andCallThrough(); + var array = [ { id: 1, variants: [ { id: 17 } ] }, { id: 2, variants: { 12: { id: 12 } } } ]; + var products = toObjectWithIDKeys(array); + expect(products["1"].variants).toEqual( { 17: { id: 17 } } ); + expect(toObjectWithIDKeys).toHaveBeenCalledWith( [ { id: 17 } ] ); + expect(toObjectWithIDKeys).not.toHaveBeenCalledWith( { 12: { id: 12 } } ); + }); }); \ No newline at end of file