mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-29 10:24:20 +01:00
98 lines
3.0 KiB
Ruby
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
|