1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-20 14:54:15 +01:00

(feat) task to fix missing references

This commit is contained in:
Sylvain 2023-03-23 09:33:43 +01:00
parent db5796816a
commit 5295cc94ef
3 changed files with 112 additions and 5 deletions

View File

@ -18,12 +18,24 @@ class Invoices::NumberService
saved_number = setting == 'invoice_reference' ? document.reference : document.order_number
return nil if saved_number.nil?
pattern = pattern(document, setting)
pattern = PaymentDocumentService.send(:replace_document_type_pattern, document, pattern)
start_idx = pattern.index(/n+|y+|m+|d+/)
end_idx = pattern.rindex(/n+|y+|m+|d+/)
indices = number_indices(document, setting)
saved_number[indices[0]..indices[1]]&.to_i
end
saved_number[start_idx..end_idx]&.to_i
# Replace the number of the reference of the given document and return the new reference
# @param document [PaymentDocument,NilClass]
# @param setting [String] 'invoice_reference' | 'invoice_order-nb'
# @return [String,NilClass]
def change_number(document, new_number, setting = 'invoice_reference')
raise TypeError, "invalid setting #{setting}" unless %w[invoice_order-nb invoice_reference].include?(setting)
return nil if document.nil?
saved_number = setting == 'invoice_reference' ? document.reference : document.order_number
return nil if saved_number.nil?
indices = number_indices(document, setting)
saved_number[indices[0]..indices[1]] = pad_and_truncate(new_number, indices[1] - indices[0])
saved_number
end
# @param document [PaymentDocument,NilClass]
@ -58,5 +70,30 @@ class Invoices::NumberService
Setting.get(setting)
end
end
private
# Output the given integer with leading zeros. If the given value is longer than the given
# length, it will be truncated.
# @param value [Integer] the integer to pad
# @param length [Integer] the length of the resulting string.
def pad_and_truncate(value, length)
value.to_s.rjust(length, '0').gsub(/^.*(.{#{length},}?)$/m, '\1')
end
# Return the indices of the number in the document's reference
# @param document [PaymentDocument,NilClass]
# @param setting [String] 'invoice_reference' | 'invoice_order-nb'
# @return [Array<Integer>]
def number_indices(document, setting = 'invoice_reference')
raise TypeError, "invalid setting #{setting}" unless %w[invoice_order-nb invoice_reference].include?(setting)
return nil if document.nil?
pattern = pattern(document, setting)
pattern = PaymentDocumentService.send(:replace_document_type_pattern, document, pattern)
start_idx = pattern.index(/n+|y+|m+|d+/)
end_idx = pattern.rindex(/n+|y+|m+|d+/)
[start_idx, end_idx]
end
end
end

View File

@ -0,0 +1,69 @@
# frozen_string_literal: true
require 'integrity/archive_helper'
namespace :fablab do
desc 'Fill the holes in the logical sequence of invoices references and regenerate invoices w/ duplicate reference'
task fix_references: :environment do |_task, _args|
include ActionView::Helpers::NumberHelper
user = User.adminsys || User.admins.first
# check the footprints
Integrity::ArchiveHelper.check_footprints
ActiveRecord::Base.transaction do
missing_references = {}
# browse invoices to list missing reference
not_closed(Invoice).order(created_at: :desc).each do |invoice|
number = Invoices::NumberService.number(invoice)
next if number == 1
previous = Invoices::NumberService.change_number(invoice, number - 1)
next unless Invoice.find_by(reference: previous).nil?
missing_references[invoice.created_at] ||= []
missing_references[invoice.created_at].push(previous)
end
# create placeholder invoices for found missing references
missing_references.each_pair do |date, references|
references.reverse_each.with_index do |reference, index|
Invoice.create!(
total: 0,
invoicing_profile: user.invoicing_profile,
statistic_profile: user.statistic_profile,
operator_profile: user.invoicing_profile,
payment_method: '',
reference: reference,
created_at: date - (index + 1).seconds,
description: 'Facture à néant, saut de facturation suite à un dysfonctionnement du logiciel Fab Manager',
invoice_items_attributes: [{
amount: 0,
description: 'facture à zéro',
object_type: 'Error',
object_id: 1,
main: true
}]
)
end
end
# chain records
puts 'Chaining all record. This may take a while...'
not_closed(InvoiceItem).order(:id).find_each(&:chain_record)
not_closed(Invoice).order(:id).find_each(&:chain_record)
end
end
# @param klass [Class]
# @return [ActiveRecord::Relation<klass>,Class]
def not_closed(klass)
if AccountingPeriod.count.positive?
last_period = AccountingPeriod.order(start_at: :desc).first
klass.where('created_at > ?', last_period.end_at)
else
klass
end
end
end

View File

@ -42,6 +42,7 @@ module InvoiceHelper
)
reservation.save
invoice = Invoice.new(
total: 1000,
invoicing_profile: customer.invoicing_profile,
statistic_profile: customer.statistic_profile,
operator_profile: operator.invoicing_profile,