From d3ab2c3a0bcbd25f3d20a592c982a343df7c3c69 Mon Sep 17 00:00:00 2001 From: Peter Berkenbosch Date: Thu, 2 Oct 2014 23:17:50 +0200 Subject: [PATCH] make sure we can handle the shopify JSON order --- .../spree/wombat/order_serializer.rb | 12 +- .../spree/wombat/product_serializer.rb | 6 +- lib/spree/wombat/handler/add_order_handler.rb | 32 +++- .../wombat/handler/add_shipment_handler.rb | 6 +- .../wombat/handler/order_handler_base.rb | 2 +- .../wombat/handler/update_shipment_handler.rb | 4 +- .../add_order_handler_shopify_json_spec.rb | 174 ++++++++++++++++++ .../spree/wombat/order_serializer_spec.rb | 15 +- 8 files changed, 240 insertions(+), 11 deletions(-) create mode 100644 spec/lib/spree/wombat/handler/add_order_handler_shopify_json_spec.rb diff --git a/app/serializers/spree/wombat/order_serializer.rb b/app/serializers/spree/wombat/order_serializer.rb index 8b3c0b7..2943a77 100644 --- a/app/serializers/spree/wombat/order_serializer.rb +++ b/app/serializers/spree/wombat/order_serializer.rb @@ -54,7 +54,7 @@ def totals def adjustments [ - { name: 'discount', value: adjustment_total }, + { name: 'discount', value: object.promo_total.to_f }, { name: 'tax', value: tax_total }, { name: 'shipping', value: shipping_total } ] @@ -71,7 +71,15 @@ def shipping_total end def tax_total - (object.included_tax_total + object.additional_tax_total).to_f + tax = 0.0 + tax_rate_taxes = (object.included_tax_total + object.additional_tax_total).to_f + manual_import_adjustment_tax_adjustments = object.adjustments.select{|adjustment| adjustment.label.downcase == "tax" && adjustment.source_id == nil && adjustment.source_type == nil} + if(tax_rate_taxes == 0.0 && manual_import_adjustment_tax_adjustments.present?) + tax = manual_import_adjustment_tax_adjustments.sum(&:amount).to_f + else + tax = tax_rate_taxes + end + tax end end diff --git a/app/serializers/spree/wombat/product_serializer.rb b/app/serializers/spree/wombat/product_serializer.rb index cf815fc..c88af81 100644 --- a/app/serializers/spree/wombat/product_serializer.rb +++ b/app/serializers/spree/wombat/product_serializer.rb @@ -46,7 +46,11 @@ def variants if object.variants.empty? [Spree::Wombat::VariantSerializer.new(object.master, root:false)] else - object.variants + ActiveModel::ArraySerializer.new( + object.variants, + each_serializer: Spree::Wombat::VariantSerializer, + root: false + ) end end diff --git a/lib/spree/wombat/handler/add_order_handler.rb b/lib/spree/wombat/handler/add_order_handler.rb index e044a53..14eb66d 100644 --- a/lib/spree/wombat/handler/add_order_handler.rb +++ b/lib/spree/wombat/handler/add_order_handler.rb @@ -4,9 +4,37 @@ module Handler class AddOrderHandler < OrderHandlerBase def process - order_params = OrderHandlerBase.order_params(@payload[:order]) + payload = @payload[:order] + order_params = OrderHandlerBase.order_params(payload) + + + adjustment_attrs = [] + + shipping_adjustment = nil + tax_adjustment = nil + + unless order_params["shipments_attributes"].present? + # remove possible shipment adjustment here + order_params["adjustments_attributes"].each do |adjustment| + adjustment_attrs << adjustment unless adjustment["label"].downcase == "shipping" + shipping_adjustment = adjustment if adjustment["label"].downcase == "shipping" + end + end + + order_params["adjustments_attributes"] = adjustment_attrs if adjustment_attrs.present? order = Spree::Core::Importer::Order.import(find_spree_user,order_params) - response "Order number #{order.number} was added", 200, Base.wombat_objects_for(order) + order.reload + + number_of_shipments_created = order.shipments.count + shipping_cost = payload["totals"]["shipping"] + order.shipments.each do |shipment| + cost_per_shipment = BigDecimal.new(shipping_cost.to_s) / number_of_shipments_created + shipment.update_columns(cost: cost_per_shipment) + end + order.updater.update_shipment_total + order.updater.update_payment_state + order.updater.persist_totals + response "Order number #{order.number} was added", 200, Base.wombat_objects_for(order.reload) end private diff --git a/lib/spree/wombat/handler/add_shipment_handler.rb b/lib/spree/wombat/handler/add_shipment_handler.rb index 55b0236..4117f59 100644 --- a/lib/spree/wombat/handler/add_shipment_handler.rb +++ b/lib/spree/wombat/handler/add_shipment_handler.rb @@ -16,7 +16,7 @@ def process external_id = shipment.delete(:id) existing_shipment = Spree::Shipment.find_by_number(external_id) - return response("Already have a shipment for order #{order_number} associated with shipment number #{external_id}", 500) if existing_shipment + return response("Already have a shipment for order #{order_number} associated with shipment number #{external_id}", 200) if existing_shipment address_attributes = shipment.delete(:shipping_address) @@ -99,6 +99,10 @@ def process order.updater.update_shipment_state order.updater.update + #make sure we set the provided cost, since the order updater is refreshing the shipment rates + # based on the shipping method. + shipment.update_columns(cost: shipment_attributes[:cost]) if shipment_attributes[:cost].present? + shipments_payload = [] shipment.order.reload.shipments.each do |shipment| shipments_payload << ShipmentSerializer.new(shipment.reload, root: false).serializable_hash diff --git a/lib/spree/wombat/handler/order_handler_base.rb b/lib/spree/wombat/handler/order_handler_base.rb index 40cc48a..0bed7e6 100644 --- a/lib/spree/wombat/handler/order_handler_base.rb +++ b/lib/spree/wombat/handler/order_handler_base.rb @@ -25,7 +25,7 @@ def self.order_params(order) order['line_items_attributes'] = line_items_hash order['adjustments_attributes'] = adjustments_attributes_hash - + payments_attributes.map {|payment| payment.delete("id")} order['payments_attributes'] = payments_attributes order['completed_at'] = placed_on order diff --git a/lib/spree/wombat/handler/update_shipment_handler.rb b/lib/spree/wombat/handler/update_shipment_handler.rb index e915f97..501f31a 100644 --- a/lib/spree/wombat/handler/update_shipment_handler.rb +++ b/lib/spree/wombat/handler/update_shipment_handler.rb @@ -122,9 +122,7 @@ def process #make sure we set the provided cost, since the order updater is refreshing the shipment rates # based on the shipping method. shipment.update_columns(cost: shipment_attributes[:cost]) if shipment_attributes[:cost].present? - - - + return response("Updated shipment #{shipment_number}", 200, Base.wombat_objects_for(shipment)) end diff --git a/spec/lib/spree/wombat/handler/add_order_handler_shopify_json_spec.rb b/spec/lib/spree/wombat/handler/add_order_handler_shopify_json_spec.rb new file mode 100644 index 0000000..24fd05d --- /dev/null +++ b/spec/lib/spree/wombat/handler/add_order_handler_shopify_json_spec.rb @@ -0,0 +1,174 @@ +require 'spec_helper' + +module Spree + module Wombat + describe Handler::AddOrderHandler do + let!(:country) { create(:country) } + let!(:state) { country.states.first || create(:state, :country => country) } + + let!(:user) do + user = Spree.user_class.new(:email => "spree@example.com") + user.generate_spree_api_key! + user + end + + let!(:variant) { create(:variant, :id => 73) } + let!(:payment_method) { create(:credit_card_payment_method, name: 'bogus') } + + context "#process" do + context "with shopify order data" do + let!(:message) do + msg = ::Hub::Samples::Order.request + msg["order"] = { + "id"=> "schoftech_1018", + "shopify_id"=> "342660281", + "source"=> "schoftech.myshopify.com", + "channel"=> "schoftech.myshopify.com", + "status"=> "complete", + "email"=> "sameer@spreecommerce.com", + "currency"=> "USD", + "placed_on"=> "2014-10-01T13=>38=>28Z", + "totals"=> { + "item"=> 38, + "tax"=> 0, + "shipping"=> 10, + "payment"=> 49.9, + "order"=> 49.9, + "adjustment"=> 11.9 + }, + "line_items"=> [ + { + "id"=> 235, + "product_id"=> "SPR-00001-Variant", + "name"=> "Spree Baseball Jersey", + "quantity"=> 2, + "price"=> 19 + } + ], + "adjustments"=> [ + { + "name"=> "discount", + "value"=> 11.9 + }, + { + "name"=> "tax", + "value"=> 0 + }, + { + "name"=> "shipping", + "value"=> 10 + } + ], + "shipping_address"=> { + "firstname"=> "Sameer", + "lastname"=> "Gulati", + "address1"=> "3627 Ordway Street NW", + "address2"=> "", + "zipcode"=> "20814", + "city"=> "Bethesda", + "state"=> "MD", + "country"=> "US", + "phone"=> "4084552962" + }, + "billing_address"=> { + "firstname"=> "Sameer", + "lastname"=> "Gulati", + "address1"=> "3627 Ordway Street NW", + "address2"=> "", + "zipcode"=> "20814", + "city"=> "Bethesda", + "state"=> "MD", + "country"=> "US", + "phone"=> "4084552962" + }, + "payments"=> [ + { + "id"=> 45, + "number"=> "AKJSKJHD", + "status"=> "completed", + "amount"=> 49.9, + "payment_method"=> "bogus" + } + ], + "updated_at"=> "2014-10-01T13=>40=>55Z", + "token"=> "36a7b988b2e068e5", + "shipping_instructions"=> nil + } + msg + end + let(:handler) { Handler::AddOrderHandler.new(message.to_json) } + + let(:line_item) { message['order']['line_items'].first } + + before { create(:variant, sku: line_item['product_id']) } + + it "imports a new order in the storefront" do + expect{handler.process}.to change{Spree::Order.count}.by(1) + end + + it "sets number from order payload id" do + handler.process + expect(Order.last.number).to eq message['order']['id'] + end + + it "creates line items properly" do + handler.process + expect(LineItem.last.variant.sku).to eq line_item['product_id'] + end + + it "returns a Hub::Responder" do + responder = handler.process + expect(responder.class.name).to eql "Spree::Wombat::Responder" + expect(responder.request_id).to eql message["request_id"] + expect(responder.summary).to match /Order number schoftech_1018 was added/ + end + + it "adding the payment" do + expect{handler.process}.to change{Spree::Payment.count}.by(1) + end + + it "generating proposed shipments" do + expect{handler.process}.to change{Spree::Shipment.count}.by(1) + end + + context "payment" do + before do + handler.process + order = Spree::Order.find_by_number("schoftech_1018") + @payment = order.payments.first + end + + it "amount is set correctly" do + expect(@payment.amount).to eql 49.9 + end + + end + + context "shipments" do + before do + handler.process + order = Spree::Order.find_by_number("schoftech_1018") + @shipment = order.shipments.first + end + + it "cost is set correctly" do + expect(@shipment.cost).to eql 10 + end + end + + context "adjustments" do + before do + handler.process + @order = Spree::Order.find_by_number("schoftech_1018") + end + + it "shipment total" do + expect(@order.shipment_total).to eql 10.0 + end + end + + end + end + end + end +end diff --git a/spec/serializers/spree/wombat/order_serializer_spec.rb b/spec/serializers/spree/wombat/order_serializer_spec.rb index fcfe1ad..b630ce7 100644 --- a/spec/serializers/spree/wombat/order_serializer_spec.rb +++ b/spec/serializers/spree/wombat/order_serializer_spec.rb @@ -64,14 +64,27 @@ module Wombat create(:adjustment, adjustable: order, source_type: 'Spree::PromotionAction', amount: -10) create(:adjustment, adjustable: order.line_items.first, source_type: 'Spree::PromotionAction', amount: -10) create(:adjustment, adjustable: order.shipments.first, source_type: 'Spree::PromotionAction', amount: -10) + #create(:adjustment, adjustable: order, source_type: nil, source_id: nil, amount: -10, label: 'Manual discount') order.update_totals end it "discount matches order promo total value" do discount_hash = serialized_order["adjustments"].select { |a| a["name"] == "discount" }.first - expect(discount_hash["value"]).to eq order.adjustment_total.to_f + expect(discount_hash["value"]).to eq -30.0 end end + + context 'manual tax from import' do + before do + create(:adjustment, adjustable: order, source_type: nil, source_id: nil, amount: 1.14, label: 'Tax') + order.update_totals + end + + it "tax_total matches the manual value" do + expect(serialized_order["totals"]["tax"]).to eql 1.14 + end + end + end end end