1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-17 06:52:27 +01:00

export collected VAT by rate

This commit is contained in:
Sylvain 2021-12-29 17:00:49 +01:00
parent 16242d2127
commit 00b9bce587
9 changed files with 135 additions and 8 deletions

View File

@ -70,6 +70,8 @@ class API::ExportsController < API::ApiController
case type
when 'acd'
export = export.where('created_at > ?', Invoice.maximum('updated_at'))
when 'vat'
export = export.where('created_at > ?', Invoice.maximum('updated_at'))
else
raise ArgumentError, "Unknown type accounting/#{type}"
end

View File

@ -1414,6 +1414,16 @@ Application.Controllers.controller('AccountingExportModalController', ['$scope',
decimalSeparator: ',',
exportInvoicesAtZero: false,
columns: ['journal_code', 'date', 'account_code', 'account_label', 'piece', 'line_label', 'debit_origin', 'credit_origin', 'debit_euro', 'credit_euro', 'lettering']
},
vat: {
format: 'csv',
encoding: 'UTF-8',
separator: ';',
dateFormat: '%Y-%m-%d',
labelMaxLength: 'N/A',
decimalSeparator: '.',
exportInvoicesAtZero: false,
columns: ['start_date', 'end_date', 'vat_rate', 'amount']
}
};
@ -1433,6 +1443,7 @@ Application.Controllers.controller('AccountingExportModalController', ['$scope',
// binding to radio button "export to"
$scope.exportTarget = {
type: null,
software: null,
startDate: null,
endDate: null,

View File

@ -42,11 +42,15 @@
</div>
</div>
<div class="row">
<h4 class="control-label m-l" translate>{{ 'app.admin.invoices.export_to' }}</h4>
<h4 class="control-label m-l" translate>{{ 'app.admin.invoices.export_what' }}</h4>
<div class="form-group m-l-lg">
<label for="acd">
<label for="vat" class="block">
<input type="radio" name="vat" id="vat" ng-model="exportTarget.software" ng-value="'vat'" ng-click="fillSettings('vat')" required/>
{{ 'app.admin.invoices.export_VAT' | translate }}
</label>
<label for="acd" class="block">
<input type="radio" name="acd" id="acd" ng-model="exportTarget.software" ng-value="'acd'" ng-click="fillSettings('acd')" required/>
{{ 'app.admin.invoices.acd' | translate }}
{{ 'app.admin.invoices.export_to_ACD' | translate }}
</label>
</div>
</div>

View File

@ -40,8 +40,10 @@ class InvoiceItem < Footprintable
def invoice_item_type
if object_type == Reservation.name
object.try(:reservable_type) || ''
elsif object_type == Subscription.name
elsif [Subscription.name, OfferDay.name].include? object_type
Subscription.name
elsif object_type == StatisticProfilePrepaidPack.name
object.prepaid_pack.priceable_type
else
''
end

View File

@ -16,7 +16,6 @@ class AccountingExportService
@label_max_length = 50
@export_zeros = false
@journal_code = Setting.get('accounting_journal_code') || ''
@date_format = date_format
@columns = columns
end

View File

@ -0,0 +1,97 @@
# frozen_string_literal: false
# Provides the routine to export the collected VAT data to a CSV file.
class VatExportService
include ActionView::Helpers::NumberHelper
attr_reader :encoding, :format, :separator, :date_format, :columns, :decimal_separator
def initialize(columns, encoding: 'UTF-8', format: 'CSV', separator: ';')
@encoding = encoding
@format = format
@separator = separator
@decimal_separator = '.'
@date_format = '%Y-%m-%d'
@columns = columns
end
def set_options(decimal_separator: ',', date_format: '%d/%m/%Y', label_max_length: nil, export_zeros: nil)
@decimal_separator = decimal_separator
@date_format = date_format
end
def export(start_date, end_date, file)
# build CSV content
content = header_row
invoices = Invoice.where('created_at >= ? AND created_at <= ?', start_date, end_date).order('created_at ASC')
vat_totals = compute_vat_totals(invoices)
content << generate_rows(vat_totals, start_date, end_date)
# 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("vat_export.#{column}") << separator
end
"#{row}\n"
end
def generate_rows(vat_totals, start_date, end_date)
rows = ''
vat_totals.each do |rate, total|
next if rate.zero?
rows += "#{row(
start_date,
end_date,
rate,
total
)}\n"
end
rows
end
def compute_vat_totals(invoices)
vat_total = []
service = VatHistoryService.new
invoices.each do |i|
puts "processing invoice #{i.id}..." unless Rails.env.test?
vat_total.push service.invoice_vat(i)
end
vat_total.map(&:values).flatten.group_by { |tot| tot[:vat_rate] }.map { |k, v| [k, v.map { |t| t[:total_vat] }.reduce(:+)] }.to_h
end
# Generate a row of the export, filling the configured columns with the provided values
def row(start_date, end_date, vat_rate, amount)
row = ''
columns.each do |column|
case column
when 'start_date'
row << DateTime.parse(start_date).strftime(date_format)
when 'end_date'
row << DateTime.parse(end_date).strftime(date_format)
when 'vat_rate'
row << vat_rate.to_s
when 'amount'
row << format_number(amount / 100.0)
else
puts "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
end

View File

@ -10,7 +10,8 @@ class AccountingExportWorker
raise SecurityError, 'Not allowed to export' unless export.user.admin?
data = JSON.parse(export.query)
service = AccountingExportService.new(
service = export.export_type == 'vat' ? VatExportService : AccountingExportService
service = service.new(
data['columns'],
encoding: data['encoding'], format: export.extension, separator: export.key
)

View File

@ -679,9 +679,10 @@ en:
codes_customization_success: "Customization of the accounting codes successfully saved."
unexpected_error_occurred: "An unexpected error occurred while saving the codes. Please try again later."
export_accounting_data: "Export accounting data"
export_to: "Export to the accounting software"
export_what: "What do you want to export?"
export_VAT: "Export the collected VAT"
export_to_ACD: "Export all data to the accounting software ACD"
export_is_running: "Export is running. You'll be notified when it's ready."
acd: "ACD"
export_form_date: "Export from"
export_to_date: "Export until"
format: "File format"
@ -704,6 +705,10 @@ en:
debit_euro: "Euro debit"
credit_euro: "Euro credit"
lettering: "Lettering"
start_date: "Start date"
end_date: "End date"
vat_rate: "VAT rate"
amount: "Total amount"
payment:
payment_settings: "Payment settings"
online_payment: "Online payment"

View File

@ -147,6 +147,11 @@ en:
Event_reservation: "event reserv."
Space_reservation: "space reserv."
wallet: "wallet"
vat_export:
start_date: "Start date"
end_date: "End date"
vat_rate: "VAT rate"
amount: "Total amount"
#training availabilities
trainings:
i_ve_reserved: "I've reserved"
@ -331,6 +336,7 @@ en:
users_reservations: "of the reservations' list"
availabilities_index: "of the reservations availabilities"
accounting_acd: "of the accounting data to ACD"
accounting_vat: "of the collected VAT"
is_over: "is over."
download_here: "Download here"
notify_admin_import_complete: