diff --git a/app/services/integrations/aggregator/base_payload.rb b/app/services/integrations/aggregator/base_payload.rb index 1a66f26bb45..8dd541cc49e 100644 --- a/app/services/integrations/aggregator/base_payload.rb +++ b/app/services/integrations/aggregator/base_payload.rb @@ -3,6 +3,16 @@ module Integrations module Aggregator class BasePayload + class Failure < BaseService::FailedResult + attr_reader :code + + def initialize(result, code:) + @code = code + + super(result, code) + end + end + def initialize(integration:) @integration = integration end diff --git a/app/services/integrations/aggregator/credit_notes/create_service.rb b/app/services/integrations/aggregator/credit_notes/create_service.rb index 0d9a241d664..1c6596c79f9 100644 --- a/app/services/integrations/aggregator/credit_notes/create_service.rb +++ b/app/services/integrations/aggregator/credit_notes/create_service.rb @@ -50,6 +50,8 @@ def call return result if e.error_code.to_i < 500 raise e + rescue Integrations::Aggregator::BasePayload::Failure => e + deliver_error_webhook(customer:, code: e.code, message: e.code.humanize) end def call_async diff --git a/app/services/integrations/aggregator/credit_notes/payloads/base_payload.rb b/app/services/integrations/aggregator/credit_notes/payloads/base_payload.rb index da0b240d115..4f0f02d3ba3 100644 --- a/app/services/integrations/aggregator/credit_notes/payloads/base_payload.rb +++ b/app/services/integrations/aggregator/credit_notes/payloads/base_payload.rb @@ -66,7 +66,9 @@ def item(credit_note_item) subscription_item end - return {} unless mapped_item + unless mapped_item + raise Integrations::Aggregator::BasePayload::Failure.new(nil, code: 'invalid_mapping') + end precise_unit_amount = credit_note_item.amount_cents diff --git a/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb b/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb index 58bf69ab20b..da9ef819ca2 100644 --- a/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb @@ -48,7 +48,9 @@ def item(credit_note_item) subscription_item end - return {} unless mapped_item + unless mapped_item + raise Integrations::Aggregator::BasePayload::Failure.new(nil, code: 'invalid_mapping') + end { 'item' => mapped_item.external_id, diff --git a/app/services/integrations/aggregator/invoices/create_service.rb b/app/services/integrations/aggregator/invoices/create_service.rb index 0f08f44103d..07a9d65b996 100644 --- a/app/services/integrations/aggregator/invoices/create_service.rb +++ b/app/services/integrations/aggregator/invoices/create_service.rb @@ -44,6 +44,8 @@ def call return result if e.error_code.to_i < 500 raise e + rescue Integrations::Aggregator::BasePayload::Failure => e + deliver_error_webhook(customer:, code: e.code, message: e.code.humanize) end def call_async diff --git a/app/services/integrations/aggregator/invoices/payloads/base_payload.rb b/app/services/integrations/aggregator/invoices/payloads/base_payload.rb index d52202d73f9..88932a4493d 100644 --- a/app/services/integrations/aggregator/invoices/payloads/base_payload.rb +++ b/app/services/integrations/aggregator/invoices/payloads/base_payload.rb @@ -66,7 +66,9 @@ def item(fee) subscription_item end - return {} unless mapped_item + unless mapped_item + raise Integrations::Aggregator::BasePayload::Failure.new(nil, code: 'invalid_mapping') + end { 'external_id' => mapped_item.external_id, diff --git a/app/services/integrations/aggregator/invoices/payloads/netsuite.rb b/app/services/integrations/aggregator/invoices/payloads/netsuite.rb index 7363af4712a..4080932f6c6 100644 --- a/app/services/integrations/aggregator/invoices/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/invoices/payloads/netsuite.rb @@ -71,7 +71,9 @@ def item(fee) subscription_item end - return {} unless mapped_item + unless mapped_item + raise Integrations::Aggregator::BasePayload::Failure.new(nil, code: 'invalid_mapping') + end { 'item' => mapped_item.external_id, diff --git a/spec/services/integrations/aggregator/credit_notes/create_service_spec.rb b/spec/services/integrations/aggregator/credit_notes/create_service_spec.rb index aee54b53c00..ecc9d2bc341 100644 --- a/spec/services/integrations/aggregator/credit_notes/create_service_spec.rb +++ b/spec/services/integrations/aggregator/credit_notes/create_service_spec.rb @@ -136,7 +136,7 @@ 'tranid' => credit_note.number, 'entity' => integration_customer.external_customer_id, 'istaxable' => true, - 'taxitem' => integration_collection_mapping5.external_id, + 'taxitem' => integration_collection_mapping5&.external_id, 'taxamountoverride' => 80.0, 'otherrefnum' => credit_note.number, 'custbody_lago_id' => credit_note.id, @@ -340,5 +340,41 @@ end end end + + context 'when there is payload error' do + let(:integration) { create(:xero_integration, organization:) } + let(:integration_customer) { create(:xero_customer, integration:, customer:) } + let(:lago_client) { instance_double(LagoHttpClient::Client) } + let(:endpoint) { 'https://api.nango.dev/v1/xero/creditnotes' } + let(:integration_collection_mapping1) { nil } + let(:integration_collection_mapping2) { nil } + let(:integration_collection_mapping3) { nil } + let(:integration_collection_mapping4) { nil } + let(:integration_collection_mapping5) { nil } + let(:integration_collection_mapping6) { nil } + let(:integration_mapping_add_on) { nil } + let(:integration_mapping_bm) { nil } + let(:response) { instance_double(Net::HTTPOK) } + let(:headers) do + { + 'Connection-Id' => integration.connection_id, + 'Authorization' => "Bearer #{ENV["NANGO_SECRET_KEY"]}", + 'Provider-Config-Key' => 'xero' + } + end + let(:body) do + path = Rails.root.join('spec/fixtures/integration_aggregator/credit_notes/success_hash_response.json') + File.read(path) + end + + before do + allow(lago_client).to receive(:post_with_response).with(params, headers).and_return(response) + allow(response).to receive(:body).and_return(body) + end + + it 'sends error webhook' do + expect { service_call }.to have_enqueued_job(SendWebhookJob) + end + end end end diff --git a/spec/services/integrations/aggregator/invoices/create_service_spec.rb b/spec/services/integrations/aggregator/invoices/create_service_spec.rb index 7343e194a68..97d188a6316 100644 --- a/spec/services/integrations/aggregator/invoices/create_service_spec.rb +++ b/spec/services/integrations/aggregator/invoices/create_service_spec.rb @@ -143,7 +143,7 @@ 'tranid' => invoice.id, 'entity' => integration_customer.external_customer_id, 'istaxable' => true, - 'taxitem' => integration_collection_mapping5.external_id, + 'taxitem' => integration_collection_mapping5&.external_id, 'taxamountoverride' => 80.0, 'otherrefnum' => invoice.number, 'custbody_lago_id' => invoice.id, @@ -371,5 +371,41 @@ end end end + + context 'when there is payload error' do + let(:integration) { create(:xero_integration, organization:) } + let(:integration_customer) { create(:xero_customer, integration:, customer:) } + let(:lago_client) { instance_double(LagoHttpClient::Client) } + let(:endpoint) { 'https://api.nango.dev/v1/xero/invoices' } + let(:integration_collection_mapping1) { nil } + let(:integration_collection_mapping2) { nil } + let(:integration_collection_mapping3) { nil } + let(:integration_collection_mapping4) { nil } + let(:integration_collection_mapping5) { nil } + let(:integration_collection_mapping6) { nil } + let(:integration_mapping_add_on) { nil } + let(:integration_mapping_bm) { nil } + let(:response) { instance_double(Net::HTTPOK) } + let(:headers) do + { + 'Connection-Id' => integration.connection_id, + 'Authorization' => "Bearer #{ENV["NANGO_SECRET_KEY"]}", + 'Provider-Config-Key' => 'xero' + } + end + let(:body) do + path = Rails.root.join('spec/fixtures/integration_aggregator/invoices/success_hash_response.json') + File.read(path) + end + + before do + allow(lago_client).to receive(:post_with_response).with(params, headers).and_return(response) + allow(response).to receive(:body).and_return(body) + end + + it 'sends error webhook' do + expect { service_call }.to have_enqueued_job(SendWebhookJob) + end + end end end