From 12ff8df9a00dc4f8ff18706d412d20985105c4b7 Mon Sep 17 00:00:00 2001 From: Ivan Novosad Date: Tue, 24 Sep 2024 10:30:29 +0200 Subject: [PATCH] feat(netsuite-taxes): Adjust netsuite credit note payload - add taxes --- .../credit_notes/payloads/netsuite.rb | 82 ++++++++++++++++++- .../aggregator/invoices/payloads/netsuite.rb | 2 +- .../credit_notes/create_service_spec.rb | 12 +-- .../invoices/create_service_spec.rb | 21 +++-- .../sales_orders/create_service_spec.rb | 21 +++-- 5 files changed, 111 insertions(+), 27 deletions(-) diff --git a/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb b/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb index b4c26bd440e..b86a63b4324 100644 --- a/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/credit_notes/payloads/netsuite.rb @@ -6,24 +6,47 @@ module CreditNotes module Payloads class Netsuite < BasePayload def body - { + result = { 'type' => 'creditmemo', 'isDynamic' => true, 'columns' => columns, 'lines' => [ { 'sublistId' => 'item', - 'lineItems' => credit_note.items.map { |credit_note_item| item(credit_note_item) } + coupons + 'lineItems' => credit_note_items + coupons } ], 'options' => { 'ignoreMandatoryFields' => false } } + + if tax_item_complete? + result['taxdetails'] = [ + { + 'sublistId' => 'taxdetails', + 'lineItems' => tax_line_items_with_adjusted_taxes + coupon_taxes + } + ] + end + + result end private + def credit_note_items + items.map { |credit_note_item| item(credit_note_item) } + end + + def tax_line_items + items.map { |credit_note_item| tax_line_item(credit_note_item) } + end + + def items + @items ||= credit_note.items.order(created_at: :asc) + end + def columns result = { 'tranid' => credit_note.number, @@ -71,6 +94,41 @@ def item(credit_note_item) } end + def tax_line_item(credit_note_item) + { + 'taxdetailsreference' => credit_note_item.id, + 'taxamount' => amount(taxes_amount(credit_note_item), resource: credit_note_item.credit_note), + 'taxbasis' => 1, + 'taxrate' => credit_note_item.fee.taxes_rate, + 'taxtype' => tax_item.tax_type, + 'taxcode' => tax_item.tax_code + } + end + + def tax_line_items_with_adjusted_taxes + taxes_amount_cents_sum = tax_line_items.sum { |f| f['taxamount'].to_d } + + return tax_line_items if taxes_amount_cents_sum == credit_note.taxes_amount_cents + + adjusted_first_tax = false + + tax_line_items.map do |credit_note_item| + if credit_note_item['taxamount'] > 0 && !adjusted_first_tax + amount = amount(credit_note.taxes_amount_cents, resource: credit_note) + credit_note_item['taxamount'] += amount - taxes_amount_cents_sum + adjusted_first_tax = true + end + + credit_note_item + end + end + + def taxes_amount(credit_note_item) + subunit_to_unit = credit_note_item.amount.currency.subunit_to_unit.to_d + amount = credit_note_item.amount_cents.fdiv(subunit_to_unit) * credit_note_item.credit_note.taxes_rate + amount.round(2) + end + def coupons output = [] @@ -79,7 +137,25 @@ def coupons 'item' => coupon_item&.external_id, 'account' => coupon_item&.external_account_code, 'quantity' => 1, - 'rate' => -amount(credit_note.coupons_adjustment_amount_cents, resource: credit_note) + 'rate' => -amount(credit_note.coupons_adjustment_amount_cents, resource: credit_note), + 'taxdetailsreference' => 'coupon_item' + } + end + + output + end + + def coupon_taxes + output = [] + + if credit_note.coupons_adjustment_amount_cents > 0 + output << { + 'taxbasis' => 1, + 'taxamount' => 0, + 'taxrate' => credit_note.taxes_rate, + 'taxtype' => tax_item.tax_type, + 'taxcode' => tax_item.tax_code, + 'taxdetailsreference' => 'coupon_item' } end diff --git a/app/services/integrations/aggregator/invoices/payloads/netsuite.rb b/app/services/integrations/aggregator/invoices/payloads/netsuite.rb index 01162db895e..1bf7a841a72 100644 --- a/app/services/integrations/aggregator/invoices/payloads/netsuite.rb +++ b/app/services/integrations/aggregator/invoices/payloads/netsuite.rb @@ -158,7 +158,7 @@ def discount_taxes output << { 'taxbasis' => 1, - 'taxamount' => amount((tax_diff_amount_cents || 0).abs, resource: invoice), + 'taxamount' => amount(tax_diff_amount_cents, resource: invoice), 'taxrate' => invoice.taxes_rate, 'taxtype' => tax_item.tax_type, 'taxcode' => tax_item.tax_code, 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 ecc9d2bc341..c8c0d32d0b0 100644 --- a/spec/services/integrations/aggregator/credit_notes/create_service_spec.rb +++ b/spec/services/integrations/aggregator/credit_notes/create_service_spec.rb @@ -135,10 +135,10 @@ 'columns' => { 'tranid' => credit_note.number, 'entity' => integration_customer.external_customer_id, - 'istaxable' => true, - 'taxitem' => integration_collection_mapping5&.external_id, - 'taxamountoverride' => 80.0, + 'taxregoverride' => true, + 'taxdetailsoverride' => true, 'otherrefnum' => credit_note.number, + 'custbody_ava_disable_tax_calculation' => true, 'custbody_lago_id' => credit_note.id, 'tranId' => credit_note.id }, @@ -150,13 +150,15 @@ 'item' => 'm2', 'account' => 'm22', 'quantity' => 1, - 'rate' => 2.12 + 'rate' => 2.12, + 'taxdetailsreference' => anything }, { 'item' => '2', 'account' => '22', 'quantity' => 1, - 'rate' => -20.0 + 'rate' => -20.0, + 'taxdetailsreference' => 'coupon_item' } ] } diff --git a/spec/services/integrations/aggregator/invoices/create_service_spec.rb b/spec/services/integrations/aggregator/invoices/create_service_spec.rb index 97d188a6316..4bb7e9fa9be 100644 --- a/spec/services/integrations/aggregator/invoices/create_service_spec.rb +++ b/spec/services/integrations/aggregator/invoices/create_service_spec.rb @@ -142,9 +142,6 @@ 'columns' => { 'tranid' => invoice.id, 'entity' => integration_customer.external_customer_id, - 'istaxable' => true, - 'taxitem' => integration_collection_mapping5&.external_id, - 'taxamountoverride' => 80.0, 'otherrefnum' => invoice.number, 'custbody_lago_id' => invoice.id, 'custbody_ava_disable_tax_calculation' => true, @@ -159,37 +156,43 @@ 'item' => '3', 'account' => '33', 'quantity' => 0.0, - 'rate' => 0.0 + 'rate' => 0.0, + 'taxdetailsreference' => anything }, { 'item' => '4', 'account' => '44', 'quantity' => 0.0, - 'rate' => 0.0 + 'rate' => 0.0, + 'taxdetailsreference' => anything }, { 'item' => 'm2', 'account' => 'm22', 'quantity' => 2, - 'rate' => 4.1212121212334 + 'rate' => 4.1212121212334, + 'taxdetailsreference' => anything }, { 'item' => '2', 'account' => '22', 'quantity' => 1, - 'rate' => -20.0 + 'rate' => -20.0, + 'taxdetailsreference' => 'coupon_item' }, { 'item' => '6', 'account' => '66', 'quantity' => 1, - 'rate' => -40.0 + 'rate' => -40.0, + 'taxdetailsreference' => 'credit_item' }, { 'item' => '1', # Fallback item instead of credit note 'account' => '11', 'quantity' => 1, - 'rate' => -60.0 + 'rate' => -60.0, + 'taxdetailsreference' => 'credit_note_item' } ] } diff --git a/spec/services/integrations/aggregator/sales_orders/create_service_spec.rb b/spec/services/integrations/aggregator/sales_orders/create_service_spec.rb index 6a6e0b1a67c..233ab559998 100644 --- a/spec/services/integrations/aggregator/sales_orders/create_service_spec.rb +++ b/spec/services/integrations/aggregator/sales_orders/create_service_spec.rb @@ -138,9 +138,6 @@ 'columns' => { 'tranid' => invoice.id, 'entity' => integration_customer.external_customer_id, - 'istaxable' => true, - 'taxitem' => integration_collection_mapping5.external_id, - 'taxamountoverride' => 80.0, 'otherrefnum' => invoice.number, 'custbody_lago_id' => invoice.id, 'custbody_ava_disable_tax_calculation' => true, @@ -155,37 +152,43 @@ 'item' => '3', 'account' => '33', 'quantity' => 0.0, - 'rate' => 0.0 + 'rate' => 0.0, + 'taxdetailsreference' => anything }, { 'item' => '4', 'account' => '44', 'quantity' => 0.0, - 'rate' => 0.0 + 'rate' => 0.0, + 'taxdetailsreference' => anything }, { 'item' => 'm2', 'account' => 'm22', 'quantity' => 2, - 'rate' => 4.12 + 'rate' => 4.12, + 'taxdetailsreference' => anything }, { 'item' => '2', 'account' => '22', 'quantity' => 1, - 'rate' => -20.0 + 'rate' => -20.0, + 'taxdetailsreference' => 'coupon_item' }, { 'item' => '6', 'account' => '66', 'quantity' => 1, - 'rate' => -40.0 + 'rate' => -40.0, + 'taxdetailsreference' => 'credit_item' }, { 'item' => '1', # Fallback item instead of credit note 'account' => '11', 'quantity' => 1, - 'rate' => -60.0 + 'rate' => -60.0, + 'taxdetailsreference' => 'credit_note_item' } ] }