From bbb164602f00aa98510f9c73c2cdaa9e0e9f1b67 Mon Sep 17 00:00:00 2001 From: Oleksandr Chebotarov Date: Mon, 16 Dec 2024 18:13:19 +0200 Subject: [PATCH 1/2] Add services for simple credit note export --- app/models/data_export.rb | 1 + app/services/data_exports/csv/credit_notes.rb | 84 +++++++++++++++++++ .../data_exports/export_resources_service.rb | 13 +++ spec/models/data_export_spec.rb | 8 ++ .../data_exports/csv/credit_notes_spec.rb | 60 +++++++++++++ 5 files changed, 166 insertions(+) create mode 100644 app/services/data_exports/csv/credit_notes.rb create mode 100644 spec/services/data_exports/csv/credit_notes_spec.rb diff --git a/app/models/data_export.rb b/app/models/data_export.rb index 3fc631074b2..21816b7fd14 100644 --- a/app/models/data_export.rb +++ b/app/models/data_export.rb @@ -55,6 +55,7 @@ def file_url def export_class case resource_type + when "credit_notes" then DataExports::Csv::CreditNotes when "invoices" then DataExports::Csv::Invoices when "invoice_fees" then DataExports::Csv::InvoiceFees end diff --git a/app/services/data_exports/csv/credit_notes.rb b/app/services/data_exports/csv/credit_notes.rb new file mode 100644 index 00000000000..e289845fb7c --- /dev/null +++ b/app/services/data_exports/csv/credit_notes.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'csv' +require 'forwardable' + +module DataExports + module Csv + class CreditNotes < BaseCsvService + extend Forwardable + + def initialize(data_export_part:, serializer_klass: V1::CreditNoteSerializer) + @data_export_part = data_export_part + @serializer_klass = serializer_klass + super + end + + def self.headers + %w[ + lago_id + sequential_id + issuing_date + customer_lago_id + customer_external_id + customer_name + customer_country + customer_tax_identification_number + number + invoice_number + credit_status + refund_status + reason + description + currency + total_amount_cents + taxes_amount_cents + sub_total_excluding_taxes_amount_cents + coupons_adjustment_amount_cents + credit_amount_cents + balance_amount_cents + refund_amount_cents + file_url + ] + end + + private + + attr_reader :data_export_part, :serializer_klass + + def serialize_item(credit_note, csv) + serialized_note = serializer_klass.new(credit_note, includes: %i[customer]).serialize + + csv << [ + serialized_note[:lago_id], + serialized_note[:sequential_id], + serialized_note[:issuing_date], + serialized_note.dig(:customer, :lago_id), + serialized_note.dig(:customer, :external_id), + serialized_note.dig(:customer, :name), + serialized_note.dig(:customer, :country), + serialized_note.dig(:customer, :tax_identification_number), + serialized_note[:number], + serialized_note[:invoice_number], + serialized_note[:credit_status], + serialized_note[:refund_status], + serialized_note[:reason], + serialized_note[:description], + serialized_note[:currency], + serialized_note[:total_amount_cents], + serialized_note[:taxes_amount_cents], + serialized_note[:sub_total_excluding_taxes_amount_cents], + serialized_note[:coupons_adjustment_amount_cents], + serialized_note[:credit_amount_cents], + serialized_note[:balance_amount_cents], + serialized_note[:refund_amount_cents], + serialized_note[:file_url] + ] + end + + def collection + CreditNote.find(data_export_part.object_ids) + end + end + end +end diff --git a/app/services/data_exports/export_resources_service.rb b/app/services/data_exports/export_resources_service.rb index 657317096f5..edf0a1261e8 100644 --- a/app/services/data_exports/export_resources_service.rb +++ b/app/services/data_exports/export_resources_service.rb @@ -46,6 +46,7 @@ def call def all_object_ids case resource_type + when "credit_notes" then credit_note_ids when "invoices", "invoice_fees" then all_invoice_ids else raise ResourceTypeNotSupportedError.new( @@ -65,5 +66,17 @@ def all_invoice_ids filters: ).invoices.pluck(:id) end + + def credit_note_ids + search_term = resource_query.delete("search_term") + filters = resource_query + + CreditNotesQuery.call( + organization:, + pagination: nil, + search_term:, + filters: + ).credit_notes.pluck(:id) + end end end diff --git a/spec/models/data_export_spec.rb b/spec/models/data_export_spec.rb index ccb299dd0f4..5286d9f9bc3 100644 --- a/spec/models/data_export_spec.rb +++ b/spec/models/data_export_spec.rb @@ -112,6 +112,14 @@ end end + context "when resource_type is credit notes" do + let(:resource_type) { "credit_notes" } + + it "returns DataExports::Csv::CreditNotes" do + expect(data_export.export_class).to eq(DataExports::Csv::CreditNotes) + end + end + context "when resource_type is an unsupported value" do let(:resource_type) { "unsupported" } diff --git a/spec/services/data_exports/csv/credit_notes_spec.rb b/spec/services/data_exports/csv/credit_notes_spec.rb new file mode 100644 index 00000000000..87e3ba4d6a6 --- /dev/null +++ b/spec/services/data_exports/csv/credit_notes_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe DataExports::Csv::CreditNotes do + describe "#call" do + subject(:result) { described_class.new(data_export_part:).call } + + let(:data_export) { create(:data_export, resource_type: "credit_notes") } + let(:credit_notes) { create_pair(:credit_note) } + + let(:data_export_part) do + create(:data_export_part, data_export:, object_ids: credit_notes.pluck(:id)) + end + + let(:expected_rows) do + credit_notes.map do |credit_note| + [ + credit_note.id, + credit_note.sequential_id, + credit_note.issuing_date.iso8601, + credit_note.customer.id, + credit_note.customer.external_id, + credit_note.customer.name, + credit_note.customer.country, + credit_note.customer.tax_identification_number, + credit_note.number, + credit_note.invoice.number, + credit_note.credit_status, + credit_note.refund_status, + credit_note.reason, + credit_note.description, + credit_note.currency, + credit_note.total_amount_cents, + credit_note.taxes_amount_cents, + credit_note.sub_total_excluding_taxes_amount_cents, + credit_note.coupons_adjustment_amount_cents, + credit_note.credit_amount_cents, + credit_note.balance_amount_cents, + credit_note.refund_amount_cents, + credit_note.file_url, + ].map(&:to_s) + end + end + + before { create(:credit_note) } + + after do + file = result.csv_file + file.close + File.unlink(file.path) + end + + it "adds serialized credit notes to csv", :aggregate_failures do + expect(result).to be_success + parsed_rows = CSV.parse(result.csv_file, nil_value: "") + expect(parsed_rows).to eq(expected_rows) + end + end +end From 8803d90d576af49380aaba06f3e98f269bdefaf5 Mon Sep 17 00:00:00 2001 From: Oleksandr Chebotarov Date: Tue, 17 Dec 2024 18:22:55 +0200 Subject: [PATCH 2/2] Fix rubocop warning --- spec/services/data_exports/csv/credit_notes_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/data_exports/csv/credit_notes_spec.rb b/spec/services/data_exports/csv/credit_notes_spec.rb index 87e3ba4d6a6..93a4e1aba65 100644 --- a/spec/services/data_exports/csv/credit_notes_spec.rb +++ b/spec/services/data_exports/csv/credit_notes_spec.rb @@ -38,7 +38,7 @@ credit_note.credit_amount_cents, credit_note.balance_amount_cents, credit_note.refund_amount_cents, - credit_note.file_url, + credit_note.file_url ].map(&:to_s) end end