diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee index a8047d9199..19d1810f38 100644 --- a/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee @@ -1,6 +1,7 @@ -Darkswarm.controller "CheckoutCtrl", ($scope, storage, CheckoutFormState, Order, CurrentUser) -> +Darkswarm.controller "CheckoutCtrl", ($scope, storage, Order, CurrentUser) -> $scope.Order = Order - storage.bind $scope, "Order.order", {storeName: "order_#{Order.order.id}#{Order.order.user_id}"} + Order.bindFieldsToLocalStorage($scope) + $scope.order = Order.order # Ordering is important $scope.secrets = Order.secrets @@ -9,6 +10,3 @@ Darkswarm.controller "CheckoutCtrl", ($scope, storage, CheckoutFormState, Order, $scope.purchase = (event)-> event.preventDefault() $scope.Order.submit() - - $scope.CheckoutFormState = CheckoutFormState - storage.bind $scope, "CheckoutFormState.ship_address_same_as_billing", { defaultValue: true} diff --git a/app/assets/javascripts/darkswarm/services/checkout_form_state.js.coffee b/app/assets/javascripts/darkswarm/services/checkout_form_state.js.coffee deleted file mode 100644 index 6fedb6b3c6..0000000000 --- a/app/assets/javascripts/darkswarm/services/checkout_form_state.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -Darkswarm.factory 'CheckoutFormState', ()-> - # Just a singleton place to store data about the form state - new class CheckoutFormState diff --git a/app/assets/javascripts/darkswarm/services/order.js.coffee b/app/assets/javascripts/darkswarm/services/order.js.coffee index bde2373aec..cea0f54d23 100644 --- a/app/assets/javascripts/darkswarm/services/order.js.coffee +++ b/app/assets/javascripts/darkswarm/services/order.js.coffee @@ -1,10 +1,23 @@ -Darkswarm.factory 'Order', ($resource, order, $http, CheckoutFormState, flash, Navigation)-> +Darkswarm.factory 'Order', ($resource, order, $http, flash, Navigation, storage)-> new class Order errors: {} secrets: {} + order: order + ship_address_same_as_billing: true - constructor: -> - @order = order + #Whitelist of fields from Order.order to bind into localStorage + fieldsToBind: ["bill_address", "email", "payment_method_id", "shipping_method_id", "ship_address"] + + # Bind all the fields from fieldsToBind, + anything on the Order class + bindFieldsToLocalStorage: (scope)=> + prefix = "order_#{@order.id}#{@order.user_id}" + for field in @fieldsToBind + storage.bind scope, "Order.order.#{field}", + storeName: "#{prefix}_#{field}" + + storage.bind scope, "Order.ship_address_same_as_billing", + storeName: "#{prefix}_sameasbilling" + defaultValue: true submit: -> $http.put('/checkout', {order: @preprocess()}).success (data, status)=> @@ -25,11 +38,12 @@ Darkswarm.factory 'Order', ($resource, order, $http, CheckoutFormState, flash, N munged_order["ship_address_attributes"] = value when "payment_method_id" munged_order["payments_attributes"] = [{payment_method_id: value}] + when "form_state" # don't keep this shit else munged_order[name] = value - if CheckoutFormState.ship_address_same_as_billing + if @ship_address_same_as_billing munged_order.ship_address_attributes = munged_order.bill_address_attributes if @paymentMethod()?.method_type == 'gateway' @@ -52,7 +66,7 @@ Darkswarm.factory 'Order', ($resource, order, $http, CheckoutFormState, flash, N @shippingMethod()?.require_ship_address shippingPrice: -> - @shippingMethod()?.price + @shippingMethod()?.price || 0.0 paymentMethod: -> @order.payment_methods[@order.payment_method_id] diff --git a/app/views/checkout/_order.rabl b/app/views/checkout/_order.rabl index f18c2e0173..af37d2edf1 100644 --- a/app/views/checkout/_order.rabl +++ b/app/views/checkout/_order.rabl @@ -1,3 +1,6 @@ +#NOTE: when adding new fields for user input, it may want to be cached in localStorage +# If so, make sure to add it to Order.attributes_to_cache + object current_order attributes :id, :email, :shipping_method_id, :user_id @@ -18,7 +21,7 @@ child current_order.ship_address => :ship_address do end node :shipping_methods do - Hash[current_order.available_shipping_methods("front_end").collect { |method| + Hash[current_distributor.shipping_methods.uniq.collect { |method| [method.id, { require_ship_address: method.require_ship_address, price: method.compute_amount(current_order).to_f, diff --git a/app/views/checkout/_shipping.html.haml b/app/views/checkout/_shipping.html.haml index 215ea8ed61..67172ce392 100644 --- a/app/views/checkout/_shipping.html.haml +++ b/app/views/checkout/_shipping.html.haml @@ -42,10 +42,10 @@ = f.fields_for :ship_address, @order.ship_address do |sa| #ship_address{"ng-if" => "Order.requireShipAddress()"} %label - %input{type: :checkbox, "ng-model" => "CheckoutFormState.ship_address_same_as_billing"} + %input{type: :checkbox, "ng-model" => "Order.ship_address_same_as_billing"} Shipping address same as billing address? - %div.visible{"ng-if" => "!CheckoutFormState.ship_address_same_as_billing"} + %div.visible{"ng-if" => "!Order.ship_address_same_as_billing"} .row .small-12.columns = validated_input "Address", "order.ship_address.address1", "ofn-focus" => "accordion['shipping']" diff --git a/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee index ea9c28a82d..0cb8e8d678 100644 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee @@ -10,6 +10,7 @@ describe "CheckoutCtrl", -> Order = submit: -> navigate: -> + bindFieldsToLocalStorage: -> order: id: 1 public: "public" @@ -20,6 +21,7 @@ describe "CheckoutCtrl", -> beforeEach -> inject ($controller, $rootScope) -> scope = $rootScope.$new() + spyOn(Order, "bindFieldsToLocalStorage") ctrl = $controller 'CheckoutCtrl', {$scope: scope, Order: Order, CurrentUser: {}} it "delegates to the service on submit", -> @@ -32,6 +34,9 @@ describe "CheckoutCtrl", -> it "is enabled", -> expect(scope.enabled).toEqual true + it "triggers localStorage binding", -> + expect(Order.bindFieldsToLocalStorage).toHaveBeenCalled() + describe "without user", -> beforeEach -> inject ($controller, $rootScope) -> diff --git a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee index d7233dae22..4dd50b2575 100644 --- a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee @@ -2,9 +2,9 @@ describe 'Order service', -> Order = null orderData = null $httpBackend = null - CheckoutFormState = null Navigation = null flash = null + storage = null beforeEach -> orderData = @@ -15,6 +15,7 @@ describe 'Order service', -> firstname: "Robert" lastname: "Harrington" ship_address: {test: "bar"} + user_id: 901 shipping_methods: 7: require_ship_address: true @@ -34,18 +35,29 @@ describe 'Order service', -> angular.module('Darkswarm').value('order', orderData) module 'Darkswarm' - inject ($injector, _$httpBackend_)-> + inject ($injector, _$httpBackend_, _storage_)-> $httpBackend = _$httpBackend_ + storage = _storage_ Order = $injector.get("Order") Navigation = $injector.get("Navigation") flash = $injector.get("flash") - CheckoutFormState = $injector.get("CheckoutFormState") spyOn(Navigation, "go") # Stubbing out writes to window.location it "defaults to no shipping method", -> expect(Order.order.shipping_method_id).toEqual null expect(Order.shippingMethod()).toEqual undefined + it "has a shipping price of zero with no shipping method", -> + expect(Order.shippingPrice()).toEqual 0.0 + + it "binds to localStorage when given a scope", -> + spyOn(storage, "bind") + Order.fieldsToBind = ["testy"] + Order.bindFieldsToLocalStorage({}) + prefix = "order_#{Order.order.id}#{Order.order.user_id}" + expect(storage.bind).toHaveBeenCalledWith({}, "Order.order.testy", {storeName: "#{prefix}_testy"}) + expect(storage.bind).toHaveBeenCalledWith({}, "Order.ship_address_same_as_billing", {storeName: "#{prefix}_sameasbilling", defaultValue: true}) + describe "with shipping method", -> beforeEach -> @@ -100,9 +112,9 @@ describe 'Order service', -> expect(Order.preprocess().ship_address).toBe(undefined) it "munges the order attributes to clone ship address from bill address", -> - CheckoutFormState.ship_address_same_as_billing = false + Order.ship_address_same_as_billing = false expect(Order.preprocess().ship_address_attributes).toEqual(orderData.ship_address) - CheckoutFormState.ship_address_same_as_billing = true + Order.ship_address_same_as_billing = true expect(Order.preprocess().ship_address_attributes).toEqual(orderData.bill_address) it "creates attributes for card fields", ->