Skip to content

Commit

Permalink
Merge pull request #288 from diegosteiner/develop
Browse files Browse the repository at this point in the history
23.12.2
  • Loading branch information
diegosteiner committed Dec 28, 2023
2 parents 16314e6 + 891a118 commit 5a24164
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 41 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## Unreleased

## Version 23.12.2

Released on 28.12.2023

- Feature: Add column_config for data digests
- Feature: Improve deposit detection
- Bugfixes

## Version 23.12.1

Released on 19.12.2023
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
V23.12.1
V23.12.2
2 changes: 1 addition & 1 deletion app/controllers/manage/payments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def new_import
@bookings = bookings_for_import
@invoices = invoices_for_import
@payments = params[:camt_file].presence &&
Payment::Factory.new(current_organisation).from_camt_file(params[:camt_file])
CamtService.new(current_organisation).payments_from_file(params[:camt_file])

render 'import' if @payments.present?
rescue CamtParser::Errors::BaseError, Nokogiri::SyntaxError => e
Expand Down
2 changes: 1 addition & 1 deletion app/models/invoice/factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def payable_until(invoice)
settings = invoice.booking.organisation.settings
if invoice.is_a?(Invoices::Deposit)
return [settings.deposit_payment_deadline.from_now,
invoice.booking.begins_at]
invoice.booking.begins_at].min
end

settings.invoice_payment_deadline.from_now
Expand Down
12 changes: 12 additions & 0 deletions app/models/invoice_part/factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def initialize(invoice)
def call
I18n.with_locale(invoice.locale || I18n.locale) do
[
from_payments.presence,
from_deposits.presence,
from_supersede_invoice.presence,
from_usages.presence
Expand All @@ -32,6 +33,17 @@ def from_usages(usages = booking.usages.ordered.where.not(id: invoice.invoice_pa
end.flatten
end

def from_payments
payed_amount = @invoice.booking.payments.where(invoice: nil, write_off: false).sum(:amount)
return [] unless payed_amount.positive? && @invoice.new_record?

[
InvoiceParts::Text.new(apply: suggest?, label: Invoices::Deposit.model_name.human),
InvoiceParts::Add.new(apply: suggest?, label: I18n.t('invoice_parts.deposited_amount'),
amount: - payed_amount)
]
end

def from_deposits
deposits = Invoices::Deposit.of(@invoice.booking).kept
deposited_amount = deposits.sum(&:amount_paid)
Expand Down
38 changes: 0 additions & 38 deletions app/models/payment/factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,6 @@ def initialize(organisation)
@organisation = organisation
end

def from_camt_file(file)
camt = CamtParser::String.parse file.read
camt.notifications.map do |notification|
notification.entries.flat_map { |entry| from_camt_entry(entry) }
end.flatten.compact
end

def from_camt_entry(entry)
return unless entry.booked? && entry.credit? && entry.currency.upcase == @organisation.currency.upcase

entry.transactions.map do |transaction|
from_camt_transaction(transaction, entry)
end
end

def find_invoice_by_ref(ref)
@organisation.invoice_ref_strategy.find_invoice_by_ref(ref, scope: @organisation.invoices.kept)
end

def from_camt_transaction(transaction, entry)
ref = transaction.creditor_reference
invoice = find_invoice_by_ref(ref)
remarks = [transaction.name, entry.description].compact_blank.join("\n\n")

Payment.new(
invoice:, booking: invoice&.booking, applies: invoice.present?, ref:,
paid_at: entry.value_date, amount: transaction.amount, data: camt_transaction_to_h(transaction),
camt_instr_id: transaction.reference, remarks:
)
end

def camt_transaction_to_h(transaction)
fields = %i[amount amount_in_cents currency name iban bic debit sign
remittance_information swift_code reference bank_reference end_to_end_reference mandate_reference
creditor_reference transaction_id creditor_identifier payment_information additional_information]
fields.index_with { |field| transaction.try(field) }
end

def from_import(payments_params)
payments = payments_params.values.filter_map { |payment_params| Payment.new(payment_params) }
payments = payments.select(&:applies)
Expand Down
50 changes: 50 additions & 0 deletions app/services/camt_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

class CamtService
def initialize(organisation)
@organisation = organisation
end

def payments_from_file(file) # rubocop:disable Metrics/CyclomaticComplexity
camt = CamtParser::String.parse file.read
entries = case camt
when CamtParser::Format053::Base
camt.statements.flat_map(&:entries)
when CamtParser::Format054::Base
camt.notifications.flat_map(&:entries)
end

entries&.flat_map { |entry| payments_from_entry(entry) }&.compact
end

def payments_from_entry(entry)
return unless entry.booked? && entry.credit? && entry.currency.upcase == @organisation.currency.upcase

entry.transactions.map do |transaction|
payment_from_transaction(transaction, entry)
end
end

def payment_from_transaction(transaction, entry)
ref = transaction.creditor_reference
invoice = find_invoice_by_ref(ref)
remarks = [transaction.name, entry.description].compact_blank.join("\n\n")

Payment.new(
invoice:, booking: invoice&.booking, applies: invoice.present?, ref:,
paid_at: entry.value_date, amount: transaction.amount, data: transaction_to_h(transaction),
camt_instr_id: transaction.reference, remarks:
)
end

def find_invoice_by_ref(ref)
@organisation.invoice_ref_strategy.find_invoice_by_ref(ref, scope: @organisation.invoices.kept)
end

def transaction_to_h(transaction)
fields = %i[amount amount_in_cents currency name iban bic debit sign
remittance_information swift_code reference bank_reference end_to_end_reference mandate_reference
creditor_reference transaction_id creditor_identifier payment_information additional_information]
fields.index_with { |field| transaction.try(field) }
end
end
3 changes: 3 additions & 0 deletions config/initializers/camt_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

CamtParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.054.001.08', :camt054)

0 comments on commit 5a24164

Please sign in to comment.