From 06d5433cd6055fe4f2a7afeabaf4440631480ded Mon Sep 17 00:00:00 2001 From: Ivan Novosad Date: Thu, 7 Nov 2024 12:40:07 +0100 Subject: [PATCH 1/4] fix(netsuite): Fix netsuite payment payload --- .../aggregator/payments/payloads/netsuite.rb | 18 +++--- .../payments/payloads/netsuite_spec.rb | 61 +++++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb diff --git a/app/services/integrations/aggregator/payments/payloads/netsuite.rb b/app/services/integrations/aggregator/payments/payloads/netsuite.rb index 7824c7912fd..4977fe14ded 100644 --- a/app/services/integrations/aggregator/payments/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/payments/payloads/netsuite.rb @@ -10,19 +10,15 @@ def body 'type' => 'customerpayment', 'isDynamic' => true, 'columns' => { - 'customer' => integration_customer.external_customer_id + 'customer' => integration_customer.external_customer_id, + 'payment' => amount(payment.amount_cents, resource: invoice), + 'autoapply' => true }, - 'lines' => [ + 'applyTransactions' => [ { - 'sublistId' => 'apply', - 'lineItems' => [ - { - # If the invoice is not synced yet, lets raise an error and retry. (doc: nil is an invalid request) - 'doc' => integration_invoice&.external_id, - 'apply' => true, - 'amount' => amount(payment.amount_cents, resource: invoice) - } - ] + 'internalId' => integration_invoice&.external_id, + 'apply' => true, + 'amount' => amount(payment.amount_cents, resource: invoice) } ], 'options' => { diff --git a/spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb b/spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb new file mode 100644 index 00000000000..c3c8596f22d --- /dev/null +++ b/spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Integrations::Aggregator::Payments::Payloads::Netsuite do + let(:payload) { described_class.new(integration:, payment:) } + let(:integration_customer) { create(:netsuite_customer, integration:, customer:) } + let(:integration) { create(:netsuite_integration, organization:) } + let(:customer) { create(:customer, organization:) } + let(:organization) { create(:organization) } + let(:payment) { create(:payment, payable: invoice, amount_cents: 100) } + let(:integration_invoice) { create(:integration_resource, syncable: invoice) } + + let(:invoice) do + create( + :invoice, + customer:, + organization:, + coupons_amount_cents: 2000, + prepaid_credit_amount_cents: 4000, + credit_notes_amount_cents: 6000, + taxes_amount_cents: 200, + issuing_date: DateTime.new(2024, 7, 8) + ) + end + + let(:body) do + { + 'type' => 'customerpayment', + 'isDynamic' => true, + 'columns' => { + 'customer' => integration_customer.external_customer_id, + 'payment' => payment.amount_cents / 100.0, + 'autoapply' => true + }, + 'applyTransactions' => [ + { + 'internalId' => integration_invoice&.external_id, + 'apply' => true, + 'amount' => payment.amount_cents / 100.0 + } + ], + 'options' => { + 'ignoreMandatoryFields' => false + } + } + end + + before do + integration_customer + integration_invoice + end + + describe '#body' do + subject(:body_call) { payload.body } + + it 'returns payload body' do + expect(subject).to eq(body) + end + end +end From 7cefc76e7b4f5b0184de4cb6704d6dfd0f91d51b Mon Sep 17 00:00:00 2001 From: Ivan Novosad Date: Thu, 7 Nov 2024 13:35:58 +0100 Subject: [PATCH 2/4] fix(netsuite): Fix netsuite payment payload specs --- .../aggregator/payments/create_service_spec.rb | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/spec/services/integrations/aggregator/payments/create_service_spec.rb b/spec/services/integrations/aggregator/payments/create_service_spec.rb index 9702348121d..acf89d7d7f8 100644 --- a/spec/services/integrations/aggregator/payments/create_service_spec.rb +++ b/spec/services/integrations/aggregator/payments/create_service_spec.rb @@ -28,18 +28,15 @@ 'type' => 'customerpayment', 'isDynamic' => true, 'columns' => { - 'customer' => integration_customer.external_customer_id + 'customer' => integration_customer.external_customer_id, + 'payment' => payment.amount_cents.div(100).to_f, + 'autoapply' => true }, - 'lines' => [ + 'applyTransactions' => [ { - 'sublistId' => 'apply', - 'lineItems' => [ - { - 'doc' => integration_invoice.external_id, - 'apply' => true, - 'amount' => payment.amount_cents.div(100).to_f - } - ] + 'internalId' => integration_invoice.external_id, + 'apply' => true, + 'amount' => payment.amount_cents.div(100).to_f } ], 'options' => { From 7e102e76e8c52879cbd03bea8c5ac608cb07f3fe Mon Sep 17 00:00:00 2001 From: Ivan Novosad Date: Mon, 11 Nov 2024 10:25:31 +0100 Subject: [PATCH 3/4] fix(netsuite): Fix netsuite payment payload --- .../aggregator/invoices/create_service.rb | 1 + .../aggregator/payments/payloads/netsuite.rb | 26 +++++++++++-------- .../invoices/create_service_spec.rb | 4 +++ .../payments/create_service_spec.rb | 26 +++++++++++-------- .../payments/payloads/netsuite_spec.rb | 26 +++++++++++-------- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/app/services/integrations/aggregator/invoices/create_service.rb b/app/services/integrations/aggregator/invoices/create_service.rb index 07a9d65b996..f09b39691bf 100644 --- a/app/services/integrations/aggregator/invoices/create_service.rb +++ b/app/services/integrations/aggregator/invoices/create_service.rb @@ -46,6 +46,7 @@ def call raise e rescue Integrations::Aggregator::BasePayload::Failure => e deliver_error_webhook(customer:, code: e.code, message: e.code.humanize) + result end def call_async diff --git a/app/services/integrations/aggregator/payments/payloads/netsuite.rb b/app/services/integrations/aggregator/payments/payloads/netsuite.rb index 4977fe14ded..9722b4b2fe8 100644 --- a/app/services/integrations/aggregator/payments/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/payments/payloads/netsuite.rb @@ -7,23 +7,27 @@ module Payloads class Netsuite < BasePayload def body { - 'type' => 'customerpayment', 'isDynamic' => true, 'columns' => { 'customer' => integration_customer.external_customer_id, - 'payment' => amount(payment.amount_cents, resource: invoice), - 'autoapply' => true + 'payment' => amount(payment.amount_cents, resource: invoice) }, - 'applyTransactions' => [ - { - 'internalId' => integration_invoice&.external_id, - 'apply' => true, - 'amount' => amount(payment.amount_cents, resource: invoice) - } - ], 'options' => { 'ignoreMandatoryFields' => false - } + }, + 'type' => 'customerpayment', + 'lines' => [ + { + 'lineItems' => [ + { + 'amount' => amount(payment.amount_cents, resource: invoice), + 'apply' => true, + 'doc' => integration_invoice&.external_id + } + ], + 'sublistId' => 'apply' + } + ] } 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 cebe8fc0e3e..bc61731141f 100644 --- a/spec/services/integrations/aggregator/invoices/create_service_spec.rb +++ b/spec/services/integrations/aggregator/invoices/create_service_spec.rb @@ -410,6 +410,10 @@ it 'sends error webhook' do expect { service_call }.to have_enqueued_job(SendWebhookJob) end + + it 'returns result' do + expect(service_call).to be_a(BaseService::Result) + end end end end diff --git a/spec/services/integrations/aggregator/payments/create_service_spec.rb b/spec/services/integrations/aggregator/payments/create_service_spec.rb index acf89d7d7f8..dd0ab172273 100644 --- a/spec/services/integrations/aggregator/payments/create_service_spec.rb +++ b/spec/services/integrations/aggregator/payments/create_service_spec.rb @@ -25,23 +25,27 @@ let(:params) do { - 'type' => 'customerpayment', 'isDynamic' => true, 'columns' => { 'customer' => integration_customer.external_customer_id, - 'payment' => payment.amount_cents.div(100).to_f, - 'autoapply' => true + 'payment' => payment.amount_cents.div(100).to_f }, - 'applyTransactions' => [ - { - 'internalId' => integration_invoice.external_id, - 'apply' => true, - 'amount' => payment.amount_cents.div(100).to_f - } - ], 'options' => { 'ignoreMandatoryFields' => false - } + }, + 'type' => 'customerpayment', + 'lines' => [ + { + 'lineItems' => [ + { + 'amount' => payment.amount_cents.div(100).to_f, + 'apply' => true, + 'doc' => integration_invoice.external_id + } + ], + 'sublistId' => 'apply' + } + ] } end diff --git a/spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb b/spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb index c3c8596f22d..88742bd6101 100644 --- a/spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb +++ b/spec/services/integrations/aggregator/payments/payloads/netsuite_spec.rb @@ -26,23 +26,27 @@ let(:body) do { - 'type' => 'customerpayment', 'isDynamic' => true, 'columns' => { 'customer' => integration_customer.external_customer_id, - 'payment' => payment.amount_cents / 100.0, - 'autoapply' => true + 'payment' => payment.amount_cents.div(100).to_f }, - 'applyTransactions' => [ - { - 'internalId' => integration_invoice&.external_id, - 'apply' => true, - 'amount' => payment.amount_cents / 100.0 - } - ], 'options' => { 'ignoreMandatoryFields' => false - } + }, + 'type' => 'customerpayment', + 'lines' => [ + { + 'lineItems' => [ + { + 'amount' => payment.amount_cents.div(100).to_f, + 'apply' => true, + 'doc' => integration_invoice.external_id + } + ], + 'sublistId' => 'apply' + } + ] } end From 987c5a0a123bb28252c275b3480e963e499c95ec Mon Sep 17 00:00:00 2001 From: Ivan Novosad Date: Mon, 11 Nov 2024 13:24:55 +0100 Subject: [PATCH 4/4] fix(netsuite): Fix aggregator payment jobs --- app/jobs/integrations/aggregator/payments/create_job.rb | 1 + .../aggregator/payments/payloads/base_payload.rb | 9 +++++++-- .../aggregator/payments/payloads/netsuite.rb | 2 +- .../aggregator/payments/payloads/base_payload_spec.rb | 6 +++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/jobs/integrations/aggregator/payments/create_job.rb b/app/jobs/integrations/aggregator/payments/create_job.rb index 50c7283a553..dafba9a2c11 100644 --- a/app/jobs/integrations/aggregator/payments/create_job.rb +++ b/app/jobs/integrations/aggregator/payments/create_job.rb @@ -7,6 +7,7 @@ class CreateJob < ApplicationJob queue_as 'integrations' retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 5 + retry_on Integrations::Aggregator::BasePayload::Failure, wait: :polynomially_longer, attempts: 10 retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100 def perform(payment:) diff --git a/app/services/integrations/aggregator/payments/payloads/base_payload.rb b/app/services/integrations/aggregator/payments/payloads/base_payload.rb index 3b08c3996ff..80cde0c1d6c 100644 --- a/app/services/integrations/aggregator/payments/payloads/base_payload.rb +++ b/app/services/integrations/aggregator/payments/payloads/base_payload.rb @@ -14,7 +14,7 @@ def initialize(integration:, payment:) def body [ { - 'invoice_id' => integration_invoice&.external_id, + 'invoice_id' => integration_invoice.external_id, 'account_code' => account_item&.external_account_code, 'date' => payment.created_at.utc.iso8601, 'amount_cents' => payment.amount_cents @@ -31,7 +31,12 @@ def invoice end def integration_invoice - invoice.integration_resources.where(resource_type: 'invoice', syncable_type: 'Invoice').first + integration_resource = + invoice.integration_resources.where(resource_type: 'invoice', syncable_type: 'Invoice').first + + raise Integrations::Aggregator::BasePayload::Failure.new(nil, code: 'invoice_missing') unless integration_resource + + integration_resource end def integration_customer diff --git a/app/services/integrations/aggregator/payments/payloads/netsuite.rb b/app/services/integrations/aggregator/payments/payloads/netsuite.rb index 9722b4b2fe8..0c6f6267210 100644 --- a/app/services/integrations/aggregator/payments/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/payments/payloads/netsuite.rb @@ -22,7 +22,7 @@ def body { 'amount' => amount(payment.amount_cents, resource: invoice), 'apply' => true, - 'doc' => integration_invoice&.external_id + 'doc' => integration_invoice.external_id } ], 'sublistId' => 'apply' diff --git a/spec/services/integrations/aggregator/payments/payloads/base_payload_spec.rb b/spec/services/integrations/aggregator/payments/payloads/base_payload_spec.rb index 36312f5a5c4..45bdef031d2 100644 --- a/spec/services/integrations/aggregator/payments/payloads/base_payload_spec.rb +++ b/spec/services/integrations/aggregator/payments/payloads/base_payload_spec.rb @@ -36,11 +36,15 @@ end describe '#body' do + let(:integration_invoice) { create(:integration_resource, syncable: invoice, integration:) } + + before { integration_invoice } + it 'returns correct body' do expect(payload.body).to eq( [ { - 'invoice_id' => nil, + 'invoice_id' => integration_invoice.external_id, 'account_code' => nil, 'date' => payment.created_at.utc.iso8601, 'amount_cents' => payment.amount_cents