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:
parent
5fca8370ff
commit
ecf80b0591
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}],
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 || ''
|
||||
|
@ -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"
|
||||
|
@ -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 l’enregistrement des codes. Veuillez réessayer plus tard."
|
||||
export_accounting_data: "Exporter les données comptables"
|
||||
|
@ -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}"
|
||||
|
@ -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}"
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user