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:
parent
16242d2127
commit
00b9bce587
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
97
app/services/vat_export_service.rb
Normal file
97
app/services/vat_export_service.rb
Normal 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
|
@ -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
|
||||
)
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user