diff --git a/app/models/customer.rb b/app/models/customer.rb index d1e44b1d71af..5ea0e18d66bc 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -128,6 +128,17 @@ def shipping_address } end + def same_billing_and_shipping_address? + return true if shipping_address.values.all?(&:blank?) + + address_line1 == shipping_address_line1 && + address_line2 == shipping_address_line2 && + city == shipping_city && + zipcode == shipping_zipcode && + state == shipping_state && + country == shipping_country + end + private def ensure_slug diff --git a/app/services/integrations/aggregator/contacts/payloads/netsuite.rb b/app/services/integrations/aggregator/contacts/payloads/netsuite.rb index f667ed35d09b..f3d4372d81bd 100644 --- a/app/services/integrations/aggregator/contacts/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/contacts/payloads/netsuite.rb @@ -8,7 +8,7 @@ class Netsuite < BasePayload def create_body { 'type' => 'customer', # Fixed value - 'isDynamic' => false, # Fixed value + 'isDynamic' => true, # Fixed value 'columns' => { 'companyname' => customer.name, 'subsidiary' => subsidiary_id, @@ -21,7 +21,8 @@ def create_body }, 'options' => { 'ignoreMandatoryFields' => false # Fixed value - } + }, + 'lines' => lines } end @@ -46,6 +47,65 @@ def update_body private + def lines + if customer.same_billing_and_shipping_address? + [ + { + 'lineItems' => [ + { + 'defaultshipping' => true, + 'defaultbilling' => true, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.address_line1, + 'addr2' => customer.address_line2, + 'city' => customer.city, + 'zip' => customer.zipcode, + 'state' => customer.state, + 'country' => customer.country + } + } + ], + 'sublistId' => 'addressbook' + } + ] + else + [ + { + 'lineItems' => [ + { + 'defaultshipping' => false, + 'defaultbilling' => true, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.address_line1, + 'addr2' => customer.address_line2, + 'city' => customer.city, + 'zip' => customer.zipcode, + 'state' => customer.state, + 'country' => customer.country + } + }, + { + 'defaultshipping' => true, + 'defaultbilling' => false, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.shipping_address_line1, + 'addr2' => customer.shipping_address_line2, + 'city' => customer.shipping_city, + 'zip' => customer.shipping_zipcode, + 'state' => customer.shipping_state, + 'country' => customer.shipping_country + } + } + ], + 'sublistId' => 'addressbook' + } + ] + end + end + def customer_url url = ENV["LAGO_FRONT_URL"].presence || "https://app.getlago.com" diff --git a/spec/factories/customers.rb b/spec/factories/customers.rb index 01988f9abdf7..c5f341b38cc8 100644 --- a/spec/factories/customers.rb +++ b/spec/factories/customers.rb @@ -18,5 +18,23 @@ legal_name { Faker::Company.name } legal_number { Faker::Company.duns_number } currency { 'EUR' } + + trait :with_shipping_address do + shipping_address_line1 { Faker::Address.street_address } + shipping_address_line2 { Faker::Address.secondary_address } + shipping_city { Faker::Address.city } + shipping_zipcode { Faker::Address.zip_code } + shipping_state { Faker::Address.state } + shipping_country { Faker::Address.country_code } + end + + trait :with_same_billing_and_shipping_address do + shipping_address_line1 { address_line1 } + shipping_address_line2 { address_line2 } + shipping_city { city } + shipping_zipcode { zipcode } + shipping_state { state } + shipping_country { country } + end end end diff --git a/spec/models/customer_spec.rb b/spec/models/customer_spec.rb index 3a2738b4863c..3e74b2eabf67 100644 --- a/spec/models/customer_spec.rb +++ b/spec/models/customer_spec.rb @@ -290,4 +290,34 @@ end end end + + describe '#same_billing_and_shipping_address?' do + subject(:method_call) { customer.same_billing_and_shipping_address? } + + context 'when shipping address is present' do + context 'when shipping address is not the same as billing address' do + let(:customer) { build_stubbed(:customer, :with_shipping_address) } + + it 'returns false' do + expect(subject).to eq(false) + end + end + + context 'when shipping address is the same as billing address' do + let(:customer) { build_stubbed(:customer, :with_same_billing_and_shipping_address) } + + it 'returns true' do + expect(subject).to eq(true) + end + end + end + + context 'when shipping address is not present' do + let(:customer) { build_stubbed(:customer) } + + it 'returns true' do + expect(subject).to eq(true) + end + end + end end diff --git a/spec/services/integrations/aggregator/contacts/create_service_spec.rb b/spec/services/integrations/aggregator/contacts/create_service_spec.rb index 4d184f4d9366..54da602d54cd 100644 --- a/spec/services/integrations/aggregator/contacts/create_service_spec.rb +++ b/spec/services/integrations/aggregator/contacts/create_service_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Integrations::Aggregator::Contacts::CreateService do subject(:service_call) { described_class.call(integration:, customer:, subsidiary_id:) } - let(:customer) { create(:customer, organization:) } + let(:customer) { create(:customer, :with_same_billing_and_shipping_address, organization:) } let(:subsidiary_id) { '1' } let(:organization) { create(:organization) } let(:lago_client) { instance_double(LagoHttpClient::Client) } @@ -46,7 +46,7 @@ let(:params) do { 'type' => 'customer', - 'isDynamic' => false, + 'isDynamic' => true, 'columns' => { 'companyname' => customer.name, 'subsidiary' => subsidiary_id, @@ -59,7 +59,27 @@ }, 'options' => { 'ignoreMandatoryFields' => false - } + }, + 'lines' => [ + { + 'lineItems' => [ + { + 'defaultshipping' => true, + 'defaultbilling' => true, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.address_line1, + 'addr2' => customer.address_line2, + 'city' => customer.city, + 'zip' => customer.zipcode, + 'state' => customer.state, + 'country' => customer.country + } + } + ], + 'sublistId' => 'addressbook' + } + ] } end @@ -159,7 +179,7 @@ let(:params) do { 'type' => 'customer', - 'isDynamic' => false, + 'isDynamic' => true, 'columns' => { 'companyname' => customer.name, 'subsidiary' => subsidiary_id, @@ -172,7 +192,27 @@ }, 'options' => { 'ignoreMandatoryFields' => false - } + }, + 'lines' => [ + { + 'lineItems' => [ + { + 'defaultshipping' => true, + 'defaultbilling' => true, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.address_line1, + 'addr2' => customer.address_line2, + 'city' => customer.city, + 'zip' => customer.zipcode, + 'state' => customer.state, + 'country' => customer.country + } + } + ], + 'sublistId' => 'addressbook' + } + ] } end diff --git a/spec/services/integrations/aggregator/contacts/payloads/netsuite_spec.rb b/spec/services/integrations/aggregator/contacts/payloads/netsuite_spec.rb index 741a11af2588..2d736c7dfc53 100644 --- a/spec/services/integrations/aggregator/contacts/payloads/netsuite_spec.rb +++ b/spec/services/integrations/aggregator/contacts/payloads/netsuite_spec.rb @@ -4,8 +4,8 @@ RSpec.describe Integrations::Aggregator::Contacts::Payloads::Netsuite do let(:integration) { integration_customer.integration } - let(:customer) { integration_customer.customer } - let(:integration_customer) { FactoryBot.create(:netsuite_customer) } + let(:integration_customer) { FactoryBot.create(:netsuite_customer, customer:) } + let(:customer) { create(:customer) } let(:subsidiary_id) { Faker::Number.number(digits: 2) } let(:payload) { described_class.new(integration:, customer:, integration_customer:, subsidiary_id:) } let(:customer_link) { payload.__send__(:customer_url) } @@ -16,7 +16,7 @@ let(:payload_body) do { 'type' => 'customer', - 'isDynamic' => false, + 'isDynamic' => true, 'columns' => { 'companyname' => customer.name, 'subsidiary' => subsidiary_id, @@ -29,12 +29,117 @@ }, 'options' => { 'ignoreMandatoryFields' => false - } + }, + 'lines' => lines } end - it "returns the payload body" do - expect(subject).to eq payload_body + context 'when shipping address is present' do + context 'when shipping address is not the same as billing address' do + let(:customer) { create(:customer, :with_shipping_address) } + + let(:lines) do + [ + { + 'lineItems' => [ + { + 'defaultshipping' => false, + 'defaultbilling' => true, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.address_line1, + 'addr2' => customer.address_line2, + 'city' => customer.city, + 'zip' => customer.zipcode, + 'state' => customer.state, + 'country' => customer.country + } + }, + { + 'defaultshipping' => true, + 'defaultbilling' => false, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.shipping_address_line1, + 'addr2' => customer.shipping_address_line2, + 'city' => customer.shipping_city, + 'zip' => customer.shipping_zipcode, + 'state' => customer.shipping_state, + 'country' => customer.shipping_country + } + } + ], + 'sublistId' => 'addressbook' + } + ] + end + + it 'returns the payload body' do + expect(subject).to eq payload_body + end + end + + context 'when shipping address is the same as billing address' do + let(:customer) { create(:customer, :with_same_billing_and_shipping_address) } + + let(:lines) do + [ + { + 'lineItems' => [ + { + 'defaultshipping' => true, + 'defaultbilling' => true, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.address_line1, + 'addr2' => customer.address_line2, + 'city' => customer.city, + 'zip' => customer.zipcode, + 'state' => customer.state, + 'country' => customer.country + } + } + ], + 'sublistId' => 'addressbook' + } + ] + end + + it 'returns the payload body' do + expect(subject).to eq payload_body + end + end + end + + context 'when shipping address is not present' do + let(:customer) { create(:customer) } + + let(:lines) do + [ + { + 'lineItems' => [ + { + 'defaultshipping' => true, + 'defaultbilling' => true, + 'subObjectId' => 'addressbookaddress', + 'subObject' => { + 'addr1' => customer.address_line1, + 'addr2' => customer.address_line2, + 'city' => customer.city, + 'zip' => customer.zipcode, + 'state' => customer.state, + 'country' => customer.country + } + } + ], + 'sublistId' => 'addressbook' + } + ] + end + + it 'returns the payload body' do + expect(subject).to eq payload_body + end end end