mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-27 21:54:27 +01:00
201 lines
6.0 KiB
Ruby
201 lines
6.0 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
# Provides the routine to export the accounting data to an external accounting software
|
||
|
class AccountingExportService
|
||
|
attr_reader :file, :encoding, :format, :separator, :log_code, :date_format
|
||
|
|
||
|
def initialize(file, columns, encoding = 'UTF-8', format = 'CSV', separator = ';')
|
||
|
@file = file
|
||
|
@encoding = encoding
|
||
|
@format = format
|
||
|
@separator = separator
|
||
|
@log_code = Setting.find_by(name: 'accounting-export_log-code').value
|
||
|
@date_format = Setting.find_by(name: 'accounting-export_date-format').value
|
||
|
@columns = columns
|
||
|
end
|
||
|
|
||
|
def export(start_date, end_date)
|
||
|
# build CVS content
|
||
|
content = ''
|
||
|
invoices = Invoice.where('created_at >= ? AND created_at <= ?', start_date, end_date).order('created_at ASC')
|
||
|
invoices.each do |i|
|
||
|
content << generate_rows(i)
|
||
|
end
|
||
|
|
||
|
# write content to file
|
||
|
File.open(file, "w:#{encoding}+b") { |f| f.puts content }
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def generate_rows(invoice)
|
||
|
client_row(invoice) << "\n" <<
|
||
|
items_rows(invoice) << "\n" <<
|
||
|
vat_row(invoice) << "\n"
|
||
|
end
|
||
|
|
||
|
# Generate the "subscription" and "reservation" rows associated with the provided invoice
|
||
|
def items_rows(invoice)
|
||
|
rows = invoice.subscription_invoice? ? subscription_row(invoice) << "\n" : ''
|
||
|
invoice.invoice_items.each do |item|
|
||
|
rows << reservation_row(invoice, item) << "\n"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Generate the "client" row, which contains the debit to the client account, all taxes included
|
||
|
def client_row(invoice)
|
||
|
row = ''
|
||
|
columns.each do |column|
|
||
|
case column
|
||
|
when :log_code
|
||
|
row << log_code
|
||
|
when :date
|
||
|
row << invoice.created_at.strftime(date_format)
|
||
|
when :account_code
|
||
|
row << account(invoice, :client)
|
||
|
when :account_label
|
||
|
row << account(invoice, :client, :label)
|
||
|
when :piece
|
||
|
row << invoice.reference
|
||
|
when :line_label
|
||
|
row << invoice.invoicing_profile.full_name
|
||
|
when :debit_origin
|
||
|
row << invoice.total / 100.0
|
||
|
when :credit_origin
|
||
|
row << 0
|
||
|
when :debit_euro
|
||
|
row << invoice.total / 100.0
|
||
|
when :credit_euro
|
||
|
row << 0
|
||
|
else
|
||
|
puts "Unsupported column: #{column}"
|
||
|
end
|
||
|
row << separator
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Generate the "reservation" row, which contains the credit to the reservation account, all taxes excluded
|
||
|
def reservation_row(invoice, item)
|
||
|
vat_rate = Setting.find_by(name: 'invoice_VAT-rate').value.to_f
|
||
|
wo_taxes = item.amount / (vat_rate / 100 + 1)
|
||
|
row = ''
|
||
|
columns.each do |column|
|
||
|
case column
|
||
|
when :log_code
|
||
|
row << log_code
|
||
|
when :date
|
||
|
row << invoice.created_at.strftime(date_format)
|
||
|
when :account_code
|
||
|
row << account(invoice, :reservation)
|
||
|
when :account_label
|
||
|
row << account(invoice, :reservation, :label)
|
||
|
when :piece
|
||
|
row << invoice.reference
|
||
|
when :line_label
|
||
|
row << item.description
|
||
|
when :debit_origin
|
||
|
row << 0
|
||
|
when :credit_origin
|
||
|
row << wo_taxes
|
||
|
when :debit_euro
|
||
|
row << 0
|
||
|
when :credit_euro
|
||
|
row << wo_taxes
|
||
|
else
|
||
|
puts "Unsupported column: #{column}"
|
||
|
end
|
||
|
row << separator
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Generate the "subscription" row, which contains the credit to the subscription account, all taxes excluded
|
||
|
def subscription_row(invoice)
|
||
|
subscription_item = invoice.invoice_items.select(&:subscription).first
|
||
|
vat_rate = Setting.find_by(name: 'invoice_VAT-rate').value.to_f
|
||
|
wo_taxes = subscription_item.amount / (vat_rate / 100 + 1)
|
||
|
row = ''
|
||
|
columns.each do |column|
|
||
|
case column
|
||
|
when :log_code
|
||
|
row << log_code
|
||
|
when :date
|
||
|
row << invoice.created_at.strftime(date_format)
|
||
|
when :account_code
|
||
|
row << account(invoice, :subscription)
|
||
|
when :account_label
|
||
|
row << account(invoice, :subscription, :label)
|
||
|
when :piece
|
||
|
row << invoice.reference
|
||
|
when :line_label
|
||
|
row << subscription_item.description
|
||
|
when :debit_origin
|
||
|
row << 0
|
||
|
when :credit_origin
|
||
|
row << wo_taxes
|
||
|
when :debit_euro
|
||
|
row << 0
|
||
|
when :credit_euro
|
||
|
row << wo_taxes
|
||
|
else
|
||
|
puts "Unsupported column: #{column}"
|
||
|
end
|
||
|
row << separator
|
||
|
end
|
||
|
end
|
||
|
# Generate the "VAT" row, which contains the credit to the VAT account, with VAT amount only
|
||
|
def vat_row(invoice)
|
||
|
# first compute the VAT amount
|
||
|
vat_rate = Setting.find_by(name: 'invoice_VAT-rate').value.to_f
|
||
|
vat = invoice.total - (invoice.total / (vat_rate / 100 + 1))
|
||
|
# now feed the row
|
||
|
row = ''
|
||
|
columns.each do |column|
|
||
|
case column
|
||
|
when :log_code
|
||
|
row << log_code
|
||
|
when :date
|
||
|
row << invoice.created_at.strftime(date_format)
|
||
|
when :account_code
|
||
|
row << account(invoice, :vat)
|
||
|
when :account_label
|
||
|
row << account(invoice, :vat, :label)
|
||
|
when :piece
|
||
|
row << invoice.reference
|
||
|
when :line_label
|
||
|
row << I18n.t('accounting_export.VAT')
|
||
|
when :debit_origin
|
||
|
row << vat
|
||
|
when :credit_origin
|
||
|
row << 0
|
||
|
when :debit_euro
|
||
|
row << vat
|
||
|
when :credit_euro
|
||
|
row << 0
|
||
|
else
|
||
|
puts "Unsupported column: #{column}"
|
||
|
end
|
||
|
row << separator
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Get the account code (or label) for the given invoice and the specified line type (client, vat, subscription or reservation)
|
||
|
def account(invoice, account, type = :code)
|
||
|
case account
|
||
|
when :client
|
||
|
Setting.find_by(name: "accounting-export_client-account-#{type.to_s}").value
|
||
|
when :vat
|
||
|
Setting.find_by(name: "accounting-export_VAT-account-#{type.to_s}").value
|
||
|
when :subscription
|
||
|
return if invoice.invoiced_type != 'Subscription'
|
||
|
|
||
|
Setting.find_by(name: "accounting-export_subscription-account-#{type.to_s}").value
|
||
|
when :reservation
|
||
|
return if invoice.invoiced_type != 'Reservation'
|
||
|
|
||
|
Setting.find_by(name: "accounting-export_#{invoice.invoiced.reservable_type}-account-#{type.to_s}").value
|
||
|
else
|
||
|
puts "Unsupported account #{account}"
|
||
|
end
|
||
|
end
|
||
|
end
|