1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-29 10:24:20 +01:00
fab-manager/app/services/accounting/accounting_export_service.rb

98 lines
3.0 KiB
Ruby

# frozen_string_literal: false
# module definition
module Accounting; end
# Provides the routine to export the accounting data to an external accounting software
class Accounting::AccountingExportService
include ActionView::Helpers::NumberHelper
attr_reader :encoding, :format, :separator, :date_format, :columns, :decimal_separator, :label_max_length, :export_zeros
def initialize(columns, encoding: 'UTF-8', format: 'CSV', separator: ';')
@encoding = encoding
@format = format
@separator = separator
@decimal_separator = ','
@date_format = '%d/%m/%Y'
@label_max_length = 50
@export_zeros = false
@columns = columns
end
def set_options(decimal_separator: ',', date_format: '%d/%m/%Y', label_max_length: 50, export_zeros: false)
@decimal_separator = decimal_separator
@date_format = date_format
@label_max_length = label_max_length
@export_zeros = export_zeros
end
def export(start_date, end_date, file)
# build CSV content
content = header_row
lines = AccountingLine.where('date >= ? AND date <= ?', start_date, end_date)
.order('date ASC')
lines = lines.joins(:invoice).where('invoices.total > 0') unless export_zeros
lines.each do |l|
Rails.logger.debug { "processing invoice #{l.invoice_id}..." } unless Rails.env.test?
content << "#{row(l)}\n"
end
# write content to file
File.open(file, "w:#{encoding}") { |f| f.puts content.encode(encoding, invalid: :replace, undef: :replace) }
end
private
def header_row
row = ''
columns.each do |column|
row << I18n.t("accounting_export.#{column}") << separator
end
"#{row}\n"
end
# Generate a row of the export, filling the configured columns with the provided values
def row(line)
row = ''
columns.each do |column|
case column
when 'journal_code'
row << line.journal_code.to_s
when 'date'
row << line.date&.strftime(date_format)
when 'account_code'
row << line.account_code.to_s
when 'account_label'
row << line.account_label.to_s
when 'piece'
row << line.invoice.reference
when 'line_label'
row << label(line)
when 'debit_origin', 'debit_euro'
row << format_number(line.debit / 100.00)
when 'credit_origin', 'credit_euro'
row << format_number(line.credit / 100.00)
when 'lettering'
row << ''
else
Rails.logger.warn { "Unsupported column: #{column}" }
end
row << separator
end
row
end
# Format the given number as a string, using the configured separator
def format_number(num)
number_to_currency(num, unit: '', separator: decimal_separator, delimiter: '', precision: 2)
end
# Create a text from the given invoice, matching the accounting software rules for the labels
def label(line)
name = "#{line.invoicing_profile.last_name} #{line.invoicing_profile.first_name}".tr separator, ''
summary = line.summary
"#{name.truncate(label_max_length - summary.length)}, #{summary}"
end
end