mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-03-21 12:29:03 +01:00
factorized invoice reference & order number code
This commit is contained in:
parent
2d6f5c3e81
commit
a7dc3b2431
@ -10,45 +10,7 @@ class Avoir < Invoice
|
||||
attr_accessor :invoice_items_ids
|
||||
|
||||
def generate_reference
|
||||
pattern = Setting.find_by(name: 'invoice_reference').value
|
||||
|
||||
# invoice number per day (dd..dd)
|
||||
reference = pattern.gsub(/d+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('day'), match.to_s.length)
|
||||
end
|
||||
# invoice number per month (mm..mm)
|
||||
reference.gsub!(/m+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('month'), match.to_s.length)
|
||||
end
|
||||
# invoice number per year (yy..yy)
|
||||
reference.gsub!(/y+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('year'), match.to_s.length)
|
||||
end
|
||||
|
||||
# full year (YYYY)
|
||||
reference.gsub!(/YYYY(?![^\[]*\])/, created_at.strftime('%Y'))
|
||||
# year without century (YY)
|
||||
reference.gsub!(/YY(?![^\[]*\])/, created_at.strftime('%y'))
|
||||
|
||||
# abbreviated month name (MMM)
|
||||
reference.gsub!(/MMM(?![^\[]*\])/, created_at.strftime('%^b'))
|
||||
# month of the year, zero-padded (MM)
|
||||
reference.gsub!(/MM(?![^\[]*\])/, created_at.strftime('%m'))
|
||||
# month of the year, non zero-padded (M)
|
||||
reference.gsub!(/M(?![^\[]*\])/, created_at.strftime('%-m'))
|
||||
|
||||
# day of the month, zero-padded (DD)
|
||||
reference.gsub!(/DD(?![^\[]*\])/, created_at.strftime('%d'))
|
||||
# day of the month, non zero-padded (DD)
|
||||
reference.gsub!(/DD(?![^\[]*\])/, created_at.strftime('%-d'))
|
||||
|
||||
# information about refund/avoir (R[text])
|
||||
reference.gsub!(/R\[([^\]]+)\]/, '\1')
|
||||
|
||||
# remove information about online selling (X[text])
|
||||
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
|
||||
self.reference = reference
|
||||
self.reference = InvoiceReferenceService.generate_reference(self, date: created_at, avoir: true)
|
||||
end
|
||||
|
||||
def expire_subscription
|
||||
|
@ -48,52 +48,7 @@ class Invoice < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def generate_reference
|
||||
pattern = Setting.find_by(name: 'invoice_reference').value
|
||||
|
||||
# invoice number per day (dd..dd)
|
||||
reference = pattern.gsub(/d+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('day'), match.to_s.length)
|
||||
end
|
||||
# invoice number per month (mm..mm)
|
||||
reference.gsub!(/m+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('month'), match.to_s.length)
|
||||
end
|
||||
# invoice number per year (yy..yy)
|
||||
reference.gsub!(/y+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('year'), match.to_s.length)
|
||||
end
|
||||
|
||||
# full year (YYYY)
|
||||
reference.gsub!(/YYYY(?![^\[]*\])/, Time.now.strftime('%Y'))
|
||||
# year without century (YY)
|
||||
reference.gsub!(/YY(?![^\[]*\])/, Time.now.strftime('%y'))
|
||||
|
||||
# abreviated month name (MMM)
|
||||
reference.gsub!(/MMM(?![^\[]*\])/, Time.now.strftime('%^b'))
|
||||
# month of the year, zero-padded (MM)
|
||||
reference.gsub!(/MM(?![^\[]*\])/, Time.now.strftime('%m'))
|
||||
# month of the year, non zero-padded (M)
|
||||
reference.gsub!(/M(?![^\[]*\])/, Time.now.strftime('%-m'))
|
||||
|
||||
# day of the month, zero-padded (DD)
|
||||
reference.gsub!(/DD(?![^\[]*\])/, Time.now.strftime('%d'))
|
||||
# day of the month, non zero-padded (DD)
|
||||
reference.gsub!(/DD(?![^\[]*\])/, Time.now.strftime('%-d'))
|
||||
|
||||
# information about online selling (X[text])
|
||||
if paid_with_stripe?
|
||||
reference.gsub!(/X\[([^\]]+)\]/, '\1')
|
||||
else
|
||||
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
end
|
||||
|
||||
# information about wallet (W[text])
|
||||
# reference.gsub!(/W\[([^\]]+)\]/, ''.to_s)
|
||||
|
||||
# remove information about refunds (R[text])
|
||||
reference.gsub!(/R\[([^\]]+)\]/, ''.to_s)
|
||||
|
||||
self.reference = reference
|
||||
self.reference = InvoiceReferenceService.generate_reference(self)
|
||||
end
|
||||
|
||||
def update_reference
|
||||
@ -102,43 +57,7 @@ class Invoice < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def order_number
|
||||
pattern = Setting.find_by(name: 'invoice_order-nb').value
|
||||
|
||||
# global invoice number (nn..nn)
|
||||
reference = pattern.gsub(/n+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('global'), match.to_s.length)
|
||||
end
|
||||
# invoice number per year (yy..yy)
|
||||
reference.gsub!(/y+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('year'), match.to_s.length)
|
||||
end
|
||||
# invoice number per month (mm..mm)
|
||||
reference.gsub!(/m+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('month'), match.to_s.length)
|
||||
end
|
||||
# invoice number per day (dd..dd)
|
||||
reference.gsub!(/d+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices('day'), match.to_s.length)
|
||||
end
|
||||
|
||||
# full year (YYYY)
|
||||
reference.gsub!(/YYYY(?![^\[]*\])/, created_at.strftime('%Y'))
|
||||
# year without century (YY)
|
||||
reference.gsub!(/YY(?![^\[]*\])/, created_at.strftime('%y'))
|
||||
|
||||
# abbreviated month name (MMM)
|
||||
reference.gsub!(/MMM(?![^\[]*\])/, created_at.strftime('%^b'))
|
||||
# month of the year, zero-padded (MM)
|
||||
reference.gsub!(/MM(?![^\[]*\])/, created_at.strftime('%m'))
|
||||
# month of the year, non zero-padded (M)
|
||||
reference.gsub!(/M(?![^\[]*\])/, created_at.strftime('%-m'))
|
||||
|
||||
# day of the month, zero-padded (DD)
|
||||
reference.gsub!(/DD(?![^\[]*\])/, created_at.strftime('%d'))
|
||||
# day of the month, non zero-padded (DD)
|
||||
reference.gsub!(/DD(?![^\[]*\])/, created_at.strftime('%-d'))
|
||||
|
||||
reference
|
||||
InvoiceReferenceService.generate_order_number(self)
|
||||
end
|
||||
|
||||
# for debug & used by rake task "fablab:maintenance:regenerate_invoices"
|
||||
@ -148,7 +67,7 @@ class Invoice < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def build_avoir(attrs = {})
|
||||
raise Exception if refunded? === true || prevent_refund?
|
||||
raise Exception if refunded? == true || prevent_refund?
|
||||
|
||||
avoir = Avoir.new(dup.attributes)
|
||||
avoir.type = 'Avoir'
|
||||
@ -256,12 +175,10 @@ class Invoice < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def set_wallet_transaction(amount, transaction_id)
|
||||
if check_footprint
|
||||
update_columns(wallet_amount: amount, wallet_transaction_id: transaction_id)
|
||||
chain_record
|
||||
else
|
||||
raise InvalidFootprintError
|
||||
end
|
||||
raise InvalidFootprintError unless check_footprint
|
||||
|
||||
update_columns(wallet_amount: amount, wallet_transaction_id: transaction_id)
|
||||
chain_record
|
||||
end
|
||||
|
||||
def paid_with_stripe?
|
||||
@ -278,41 +195,6 @@ class Invoice < ActiveRecord::Base
|
||||
InvoiceWorker.perform_async(id, user&.subscription&.expired_at)
|
||||
end
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
##
|
||||
# Returns the number of current invoices in the given range around the current date.
|
||||
# If range is invalid or not specified, the total number of invoices is returned.
|
||||
# @param range {String} 'day', 'month', 'year'
|
||||
# @return {Integer}
|
||||
##
|
||||
def number_of_invoices(range)
|
||||
case range.to_s
|
||||
when 'day'
|
||||
start = DateTime.current.beginning_of_day
|
||||
ending = DateTime.current.end_of_day
|
||||
when 'month'
|
||||
start = DateTime.current.beginning_of_month
|
||||
ending = DateTime.current.end_of_month
|
||||
when 'year'
|
||||
start = DateTime.current.beginning_of_year
|
||||
ending = DateTime.current.end_of_year
|
||||
else
|
||||
return id
|
||||
end
|
||||
return Invoice.count unless defined? start && defined? ending
|
||||
|
||||
Invoice.where('created_at >= :start_date AND created_at < :end_date', start_date: start, end_date: ending).length
|
||||
end
|
||||
|
||||
def compute_footprint
|
||||
FootprintService.compute_footprint(Invoice, self)
|
||||
end
|
||||
|
135
app/services/invoice_reference_service.rb
Normal file
135
app/services/invoice_reference_service.rb
Normal file
@ -0,0 +1,135 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Provides methods to generate invoice references
|
||||
class InvoiceReferenceService
|
||||
class << self
|
||||
def generate_reference(invoice, date: Time.now, avoir: false)
|
||||
pattern = Setting.find_by(name: 'invoice_reference').value
|
||||
|
||||
reference = replace_invoice_number_pattern(pattern, invoice)
|
||||
reference = replace_date_pattern(reference, date)
|
||||
|
||||
if avoir
|
||||
# information about refund/avoir (R[text])
|
||||
reference.gsub!(/R\[([^\]]+)\]/, '\1')
|
||||
|
||||
# remove information about online selling (X[text])
|
||||
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
else
|
||||
# information about online selling (X[text])
|
||||
if invoice.paid_with_stripe?
|
||||
reference.gsub!(/X\[([^\]]+)\]/, '\1')
|
||||
else
|
||||
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
end
|
||||
|
||||
# remove information about refunds (R[text])
|
||||
reference.gsub!(/R\[([^\]]+)\]/, ''.to_s)
|
||||
end
|
||||
|
||||
reference
|
||||
end
|
||||
|
||||
def generate_order_number(invoice)
|
||||
pattern = Setting.find_by(name: 'invoice_order-nb').value
|
||||
|
||||
# global invoice number (nn..nn)
|
||||
reference = pattern.gsub(/n+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices(invoice, 'global'), match.to_s.length)
|
||||
end
|
||||
|
||||
reference = replace_invoice_number_pattern(reference, invoice)
|
||||
replace_date_pattern(reference, invoice.created_at)
|
||||
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
|
||||
|
||||
##
|
||||
# Returns the number of current invoices in the given range around the current date.
|
||||
# If range is invalid or not specified, the total number of invoices is returned.
|
||||
# @param invoice {Invoice}
|
||||
# @param range {String} 'day', 'month', 'year'
|
||||
# @return {Integer}
|
||||
##
|
||||
def number_of_invoices(invoice, range)
|
||||
case range.to_s
|
||||
when 'day'
|
||||
start = DateTime.current.beginning_of_day
|
||||
ending = DateTime.current.end_of_day
|
||||
when 'month'
|
||||
start = DateTime.current.beginning_of_month
|
||||
ending = DateTime.current.end_of_month
|
||||
when 'year'
|
||||
start = DateTime.current.beginning_of_year
|
||||
ending = DateTime.current.end_of_year
|
||||
else
|
||||
return invoice.id
|
||||
end
|
||||
return Invoice.count unless defined? start && defined? ending
|
||||
|
||||
Invoice.where('created_at >= :start_date AND created_at < :end_date', start_date: start, end_date: ending).length
|
||||
end
|
||||
|
||||
##
|
||||
# Replace the date elements in the provided pattern with the date values, from the provided date
|
||||
# @param reference {string}
|
||||
# @param date {DateTime}
|
||||
##
|
||||
def replace_date_pattern(reference, date)
|
||||
copy = reference.dup
|
||||
|
||||
# full year (YYYY)
|
||||
copy.gsub!(/YYYY(?![^\[]*\])/, date.strftime('%Y'))
|
||||
# year without century (YY)
|
||||
copy.gsub!(/YY(?![^\[]*\])/, date.strftime('%y'))
|
||||
|
||||
# abbreviated month name (MMM)
|
||||
copy.gsub!(/MMM(?![^\[]*\])/, date.strftime('%^b'))
|
||||
# month of the year, zero-padded (MM)
|
||||
copy.gsub!(/MM(?![^\[]*\])/, date.strftime('%m'))
|
||||
# month of the year, non zero-padded (M)
|
||||
copy.gsub!(/M(?![^\[]*\])/, date.strftime('%-m'))
|
||||
|
||||
# day of the month, zero-padded (DD)
|
||||
copy.gsub!(/DD(?![^\[]*\])/, date.strftime('%d'))
|
||||
# day of the month, non zero-padded (DD)
|
||||
copy.gsub!(/DD(?![^\[]*\])/, date.strftime('%-d'))
|
||||
|
||||
copy
|
||||
end
|
||||
|
||||
##
|
||||
# Replace the invoice number elements in the provided pattern with counts from the database
|
||||
# @param reference {string}
|
||||
# @param invoice {Invoice}
|
||||
##
|
||||
def replace_invoice_number_pattern(reference, invoice)
|
||||
copy = reference.dup
|
||||
|
||||
# invoice number per year (yy..yy)
|
||||
copy.gsub!(/y+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices(invoice, 'year'), match.to_s.length)
|
||||
end
|
||||
# invoice number per month (mm..mm)
|
||||
copy.gsub!(/m+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices(invoice, 'month'), match.to_s.length)
|
||||
end
|
||||
# invoice number per day (dd..dd)
|
||||
copy.gsub!(/d+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_invoices(invoice, 'day'), match.to_s.length)
|
||||
end
|
||||
|
||||
copy
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user