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

ability to set invoices as erroneous

This commit is contained in:
Sylvain 2021-05-24 16:34:27 +02:00
parent 5fca8370ff
commit ecf80b0591
12 changed files with 64 additions and 23 deletions

View File

@ -7,6 +7,7 @@
- Fix a security issue: updated puma to 4.3.8 to fix [CVE-2019-16770](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16770)
- Fix a security issue: updated nokogiri to 1.11.4 to fix [GHSA-7rrm-v45f-jp64](https://github.com/advisories/GHSA-7rrm-v45f-jp64)
- [TODO DEPLOY] `rails fablab:fix_invoices`
- [TODO DEPLOY] `rails fablab:maintenance:regenerate_invoices[year,month]` Depending on the status of the above command, you'll need to run that one for the months with erroneous invoices
## v4.7.9 2021 May 17

View File

@ -177,6 +177,14 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
spaceLabel: {
name: 'accounting_Space_label',
value: settings.accounting_Space_label
},
errorCode: {
name: 'accounting_Error_code',
value: settings.accounting_Error_code
},
errorLabel: {
name: 'accounting_Error_label',
value: settings.accounting_Error_label
}
};

View File

@ -861,6 +861,7 @@ angular.module('application.router', ['ui.router'])
"'accounting_VAT_code', 'accounting_VAT_label', 'accounting_subscription_code', 'accounting_subscription_label', " +
"'accounting_Machine_code', 'accounting_Machine_label', 'accounting_Training_code', 'accounting_Training_label', " +
"'accounting_Event_code', 'accounting_Event_label', 'accounting_Space_code', 'accounting_Space_label', " +
"'accounting_Error_code', 'accounting_Error_label', " +
"'feature_tour_display', 'online_payment_module', 'stripe_public_key', 'stripe_currency', 'invoice_prefix']"
}).$promise;
}],

View File

@ -106,6 +106,16 @@
<input type="text" id="spaceLabel" ng-model="settings.spaceLabel.value" class="form-control" placeholder="{{ 'app.admin.invoices.general_space_label' | translate }}"/>
</div>
</div>
<div class="row">
<div class="col-md-6">
<label for="spaceCode" translate>{{ 'app.admin.invoices.accounting_Error_code' }}</label>
<input type="text" id="errorCode" ng-model="settings.errorCode.value" class="form-control" placeholder="{{ 'app.admin.invoices.general_error_code' | translate }}" />
</div>
<div class="col-md-6">
<label for="spaceLabel" translate>{{ 'app.admin.invoices.accounting_Error_label' }}</label>
<input type="text" id="errorLabel" ng-model="settings.errorLabel.value" class="form-control" placeholder="{{ 'app.admin.invoices.general_error_label' | translate }}"/>
</div>
</div>
<button name="button" class="btn btn-warning m-t-lg" ng-click="save()" translate>{{ 'app.shared.buttons.save' }}</button>
</div>
</div>
</div>

View File

@ -109,7 +109,9 @@ class Setting < ApplicationRecord
upcoming_events_shown
payment_schedule_prefix
trainings_module
address_required] }
address_required
accounting_Error_code
accounting_Error_label] }
# WARNING: when adding a new key, you may also want to add it in app/policies/setting_policy.rb#public_whitelist
def value

View File

@ -108,6 +108,8 @@ class PDF::Invoice < Prawn::Document
object = subscription_verbose(invoice.invoiced, name)
when 'OfferDay'
object = offer_day_verbose(invoice.invoiced, name)
when 'Error'
object = I18n.t('invoices.error_invoice')
else
puts "ERROR : specified invoiced type (#{invoice.invoiced_type}) is unknown"
end
@ -174,13 +176,8 @@ class PDF::Invoice < Prawn::Document
count: t.booked,
NAME: t.event_price_category.price_category.name)
end
### wallet credit
when nil
details = item.description
### Other cases (not expected)
else
details += I18n.t('invoices.reservation_other')
details += item.description
end
end

View File

@ -70,6 +70,11 @@ class AccountingExportService
end
elsif invoice.invoiced_type == 'WalletTransaction'
rows << "#{wallet_row(invoice)}\n"
elsif invoice.invoiced_type == 'Error'
items = invoice.invoice_items.select { |ii| ii.subscription.nil? }
items.each do |item|
rows << "#{error_row(invoice, item)}\n"
end
end
rows
end
@ -142,6 +147,16 @@ class AccountingExportService
)
end
def error_row(invoice, item)
row(
invoice,
account(invoice, :error),
account(invoice, :error, type: :label),
item.net_amount / 100.00,
line_label: label(invoice)
)
end
# Generate a row of the export, filling the configured columns with the provided values
def row(invoice, account_code, account_label, amount, line_label: '', debit_method: :debit, credit_method: :credit)
row = ''
@ -202,6 +217,8 @@ class AccountingExportService
else
puts "WARN: Invoice #{invoice.id} is not a wallet credit"
end
when :error
Setting.find_by(name: "accounting_Error_#{type}")&.value
else
puts "Unsupported account #{account}"
end || ''

View File

@ -598,6 +598,10 @@ en:
general_space_code: "Accounting code for all spaces"
accounting_Space_label: "Spaces label"
general_space_label: "Account label for all spaces"
accounting_Error_code: "Errors code"
general_error_code: "Accounting code for erroneous invoices"
accounting_Error_label: "Errors label"
general_error_label: "Account label for erroneous invoices"
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"

View File

@ -598,6 +598,10 @@ fr:
general_space_code: "Code comptable pour tous les espaces"
accounting_Space_label: "Libellé espaces"
general_space_label: "Libellé du compte pour tous les espaces"
accounting_Error_code: "Code erreurs"
general_error_code: "Code comptable pour les factures en erreur"
accounting_Error_label: "Libellé erreurs"
general_error_label: "Libellé du compte pour les factures en erreur"
codes_customization_success: "La personnalisation des codes comptables a bien été enregistrée."
unexpected_error_occurred: "Une erreur inattendue est survenue lors de lenregistrement des codes. Veuillez réessayer plus tard."
export_accounting_data: "Exporter les données comptables"

View File

@ -88,7 +88,6 @@ en:
other_rate_ticket:
one: "One %{NAME} ticket"
other: "%{count} %{NAME} tickets"
reservation_other: "Reservation (other)"
coupon_CODE_discount_of_DISCOUNT: "Coupon {CODE}: discount of {DISCOUNT}{TYPE, select, percent_off{%} other{}}" #messageFormat interpolation
total_including_all_taxes: "Total incl. all taxes"
including_VAT_RATE: "Including VAT %{RATE}%"
@ -113,6 +112,7 @@ en:
subscription_of_NAME_extended_starting_from_STARTDATE_until_ENDDATE: "Subscription of %{NAME} extended (Free days) starting from %{STARTDATE} until %{ENDDATE}"
and: 'and'
invoice_text_example: "Our association is not subject to VAT"
error_invoice: "Erroneous invoice. The items below ware not booked. Please contact the FabLab for a refund."
#PDF payment schedule generation
payment_schedules:
schedule_reference: "Payment schedule reference: %{REF}"

View File

@ -88,7 +88,6 @@ fr:
other_rate_ticket:
one: "Une place %{NAME}"
other: "%{count} places %{NAME}"
reservation_other: "Réservation (autre)"
coupon_CODE_discount_of_DISCOUNT: "Code {CODE} : remise de {DISCOUNT} {TYPE, select, percent_off{%} other{}}" #messageFormat interpolation
total_including_all_taxes: "Total TTC"
including_VAT_RATE: "Dont TVA %{RATE}%"
@ -113,6 +112,7 @@ fr:
subscription_of_NAME_extended_starting_from_STARTDATE_until_ENDDATE: "Prolongement Abonnement (Jours gratuits) de %{NAME} à compter du %{STARTDATE} jusqu'au %{ENDDATE}"
and: 'et'
invoice_text_example: "Notre association n'est pas assujettie à la TVA"
error_invoice: "Facture en erreur. Les éléments ci-dessous n'ont pas été réservés. Veuillez contacter le Fablab pour un remboursement."
#PDF payment schedule generation
payment_schedules:
schedule_reference: "Référence de l'échéancier : %{REF}"

View File

@ -8,7 +8,7 @@ require 'integrity/archive_helper'
namespace :fablab do
desc 'Remove the invoices w/o reservation or regenerate the reservation'
task fix_invoices: :environment do |_task, _args|
return unless Invoice.where(invoiced_id: nil).count.positive?
next unless Invoice.where(invoiced_id: nil).count.positive?
include ActionView::Helpers::NumberHelper
@ -19,17 +19,6 @@ namespace :fablab do
# fix invoices data
Invoice.where(invoiced_id: nil).each do |invoice|
if invoice.total.zero?
puts "Invoice #{invoice.id} has total = 0, destroying..."
invoice.destroy
next
end
if invoice.invoiced_type != 'Reservation'
STDERR.puts "WARNING: Invoice #{invoice.id} is about #{invoice.invoiced_type}. Please handle manually."
STDERR.puts 'Ignoring...'
next
end
ii = invoice.invoice_items.where(subscription_id: nil).first
puts '=============================================='
puts "Invoice #{invoice.id} (# #{invoice.reference})"
@ -39,12 +28,18 @@ namespace :fablab do
puts "Operator: #{invoice.operator_profile&.user&.profile&.full_name} (#{invoice.operator_profile&.user&.email})"
puts "Date: #{invoice.created_at}"
print 'Delete [d] OR create the missing reservation [c]? > '
print 'Delete [d], create the missing reservation [c] OR keep as error[e] ? > '
confirm = STDIN.gets.chomp
if confirm == 'd'
puts "Destroying #{invoice.id}..."
invoice.destroy
elsif confirm == 'c'
if invoice.invoiced_type != 'Reservation'
STDERR.puts "WARNING: Invoice #{invoice.id} is about #{invoice.invoiced_type}. Please handle manually."
STDERR.puts 'Ignoring...'
next
end
reservable = find_reservable(ii)
if reservable
if reservable.is_a? Event
@ -63,6 +58,8 @@ namespace :fablab do
STDERR.puts "WARNING: Unable to guess the reservable for invoice #{invoice.id}, please handle manually."
STDERR.puts 'Ignoring...'
end
elsif confirm == 'e'
invoice.update_attributes(invoiced_type: 'Error')
else
puts "Operation #{confirm} unknown. Ignoring invoice #{invoice.id}..."
end