mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-29 10:24:20 +01:00
Merge branch 'dev' for release 5.9.1
This commit is contained in:
commit
96834987c3
@ -1,5 +1,11 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
## v5.9.1 2023 March 22
|
||||
|
||||
- Fix a bug: logical sequence of invoices references has duplicates
|
||||
- Fix a bug: in some cases, unable to export to excel files
|
||||
- Fix a security issue: updated rack to 2.2.6.4 to fix [CVE-2023-27539](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-27539)
|
||||
|
||||
## v5.9.0 2023 March 20
|
||||
|
||||
- Ability to restrict machine reservations per plan
|
||||
|
@ -299,7 +299,7 @@ GEM
|
||||
activesupport (>= 3.0.0)
|
||||
raabro (1.4.0)
|
||||
racc (1.6.1)
|
||||
rack (2.2.6.3)
|
||||
rack (2.2.6.4)
|
||||
rack-oauth2 (1.19.0)
|
||||
activesupport
|
||||
attr_required
|
||||
|
@ -135,13 +135,13 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$tra
|
||||
// the moment when the slot selection changed for the last time, used to trigger changes in the cart
|
||||
$scope.selectionTime = null;
|
||||
|
||||
// the last clicked event in the calender
|
||||
// the last clicked event in the calendar
|
||||
$scope.selectedEvent = null;
|
||||
|
||||
// indicates the state of the current view : calendar or plans information
|
||||
$scope.plansAreShown = false;
|
||||
|
||||
// will store the user's plan if he choosed to buy one
|
||||
// will store the user's plan if he chose to buy one
|
||||
$scope.selectedPlan = null;
|
||||
|
||||
// the moment when the plan selection changed for the last time, used to trigger changes in the cart
|
||||
|
@ -41,6 +41,9 @@ class Availability < ApplicationRecord
|
||||
validate :length_must_be_slot_multiple, unless: proc { end_at.blank? or start_at.blank? }
|
||||
validate :should_be_associated
|
||||
|
||||
# cache
|
||||
after_update :refresh_places_cache
|
||||
|
||||
## elastic callbacks
|
||||
after_save { AvailabilityIndexerWorker.perform_async(:index, id) }
|
||||
after_destroy { AvailabilityIndexerWorker.perform_async(:delete, id) }
|
||||
@ -128,7 +131,7 @@ class Availability < ApplicationRecord
|
||||
slots.map(&:reserved_users).flatten
|
||||
end
|
||||
|
||||
# @param user [User]
|
||||
# @param user_id [Integer]
|
||||
# @return [Boolean]
|
||||
def reserved_by?(user_id)
|
||||
reserved_users.include?(user_id)
|
||||
@ -195,4 +198,10 @@ class Availability < ApplicationRecord
|
||||
|
||||
errors.add(:machine_ids, I18n.t('availabilities.must_be_associated_with_at_least_1_machine'))
|
||||
end
|
||||
|
||||
def refresh_places_cache
|
||||
slots.each do |slot|
|
||||
Slots::PlacesCacheService.refresh(slot)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -14,10 +14,6 @@ class Avoir < Invoice
|
||||
|
||||
delegate :order_number, to: :invoice
|
||||
|
||||
def generate_reference
|
||||
super(created_at)
|
||||
end
|
||||
|
||||
def expire_subscription
|
||||
user.subscription.expire
|
||||
end
|
||||
|
@ -34,8 +34,6 @@ class Footprintable < ApplicationRecord
|
||||
FootprintService.debug_footprint(self.class, self)
|
||||
end
|
||||
|
||||
#protected
|
||||
|
||||
def compute_footprint
|
||||
FootprintService.compute_footprint(self.class, self)
|
||||
end
|
||||
|
@ -50,11 +50,9 @@ class Invoice < PaymentDocument
|
||||
end
|
||||
|
||||
def order_number
|
||||
return order.reference unless order.nil?
|
||||
return order.reference unless order.nil? || order.reference.nil?
|
||||
|
||||
if !payment_schedule_item.nil? && !payment_schedule_item.first?
|
||||
return payment_schedule_item.payment_schedule.ordered_items.first.invoice.order_number
|
||||
end
|
||||
return payment_schedule_item.payment_schedule.order_number if !payment_schedule_item.nil? && !payment_schedule_item.first?
|
||||
|
||||
PaymentDocumentService.generate_order_number(self)
|
||||
end
|
||||
|
@ -20,6 +20,8 @@ class Order < PaymentDocument
|
||||
|
||||
delegate :user, to: :statistic_profile
|
||||
|
||||
alias_attribute :order_number, :reference
|
||||
|
||||
def generate_reference(_date = Time.current)
|
||||
self.reference = PaymentDocumentService.generate_order_number(self)
|
||||
end
|
||||
|
@ -4,7 +4,7 @@
|
||||
class PaymentDocument < Footprintable
|
||||
self.abstract_class = true
|
||||
|
||||
def generate_reference(date = Time.current)
|
||||
def generate_reference(date = created_at)
|
||||
self.reference = PaymentDocumentService.generate_reference(self, date: date)
|
||||
end
|
||||
|
||||
|
@ -38,6 +38,10 @@ class PaymentSchedule < PaymentDocument
|
||||
"#{prefix}-#{id}_#{created_at.strftime('%d%m%Y')}.pdf"
|
||||
end
|
||||
|
||||
def order_number
|
||||
ordered_items.first&.invoice&.order_number || PaymentDocumentService.generate_order_number(self)
|
||||
end
|
||||
|
||||
##
|
||||
# This is useful to check the first item because its amount may be different from the others
|
||||
##
|
||||
|
@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Allows splinting a StatisticIndex into multiple types.
|
||||
# e.g. The StatisticIndex "subscriptions" may have types like "1 month", "1 year", etc.
|
||||
class StatisticType < ApplicationRecord
|
||||
has_one :statistic_index
|
||||
has_many :statistic_type_sub_types
|
||||
belongs_to :statistic_index
|
||||
has_many :statistic_type_sub_types, dependent: :destroy
|
||||
has_many :statistic_sub_types, through: :statistic_type_sub_types
|
||||
has_many :statistic_custom_aggregations
|
||||
has_many :statistic_custom_aggregations, dependent: :destroy
|
||||
end
|
||||
|
30
app/services/excel_service.rb
Normal file
30
app/services/excel_service.rb
Normal file
@ -0,0 +1,30 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Provides methods around Excel files specification
|
||||
class ExcelService
|
||||
class << self
|
||||
# remove all unauthorized characters from the given Excel's worksheet name
|
||||
# @param name [String]
|
||||
# @param replace [String]
|
||||
# @return [String]
|
||||
def name_safe(name, replace = '-')
|
||||
name.gsub(%r{[*|\\:"<>?/]}, replace).truncate(31)
|
||||
end
|
||||
|
||||
# Generate a name for the current type, compatible with Excel worksheet names
|
||||
# @param type [StatisticType]
|
||||
# @param workbook [Axlsx::Workbook]
|
||||
# @return [String]
|
||||
def statistic_type_sheet_name(type, workbook)
|
||||
# see https://msdn.microsoft.com/fr-fr/library/c6bdca6y(v=vs.90).aspx for unauthorized character list
|
||||
name = "#{type.statistic_index.label} - #{type.label}".gsub(%r{[*|\\:"<>?/]}, '')
|
||||
# sheet name is limited to 31 characters
|
||||
if name.length > 31
|
||||
name = "#{type.statistic_index.label.truncate(4, omission: '.')} - #{type.label}".gsub(%r{[*|\\:"<>?/]}, '').truncate(31)
|
||||
end
|
||||
# we cannot have two sheets with the same name
|
||||
name = name[0..30] + String((rand * 10).to_i) until workbook.sheet_by_name(name).nil?
|
||||
name
|
||||
end
|
||||
end
|
||||
end
|
62
app/services/invoices/number_service.rb
Normal file
62
app/services/invoices/number_service.rb
Normal file
@ -0,0 +1,62 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# module definition
|
||||
module Invoices; end
|
||||
|
||||
# The invoice number is based on the previous invoice
|
||||
class Invoices::NumberService
|
||||
class << self
|
||||
# Get the order number or reference number for the given invoice (not the whole identifier).
|
||||
# The date part, online payment part, etc. will be excluded and only the number part will be returned.
|
||||
# @param document [PaymentDocument,NilClass]
|
||||
# @param setting [String] 'invoice_reference' | 'invoice_order-nb'
|
||||
# @return [Integer,NilClass]
|
||||
def number(document, 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?
|
||||
|
||||
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+/)
|
||||
|
||||
saved_number[start_idx..end_idx]&.to_i
|
||||
end
|
||||
|
||||
# @param document [PaymentDocument,NilClass]
|
||||
# @param setting [String] 'invoice_reference' | 'invoice_order-nb'
|
||||
# @return [String,NilClass] 'global' | 'year' | 'month' | 'day'
|
||||
def number_periodicity(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)
|
||||
|
||||
return 'global' if pattern.match?(/n+/)
|
||||
return 'year' if pattern.match?(/y+/)
|
||||
return 'month' if pattern.match?(/m+/)
|
||||
return 'day' if pattern.match?(/d+/)
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
# Get the pattern applicable to generate the number of the given invoice.
|
||||
# @param document [PaymentDocument]
|
||||
# @param setting [String] 'invoice_reference' | 'invoice_order-nb'
|
||||
# @return [String]
|
||||
def pattern(document, setting = 'invoice_reference')
|
||||
raise TypeError, "invalid setting #{setting}" unless %w[invoice_order-nb invoice_reference].include?(setting)
|
||||
|
||||
value = Setting.find_by(name: setting).value_at(document.created_at)
|
||||
value || if document.created_at < Setting.find_by(name: setting).first_update
|
||||
Setting.find_by(name: setting).first_value
|
||||
else
|
||||
Setting.get(setting)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -7,56 +7,23 @@ class PaymentDocumentService
|
||||
# @param document [PaymentDocument]
|
||||
# @param date [Time]
|
||||
def generate_reference(document, date: Time.current)
|
||||
pattern = Setting.get('invoice_reference').to_s
|
||||
pattern = Invoices::NumberService.pattern(document, 'invoice_reference')
|
||||
|
||||
reference = replace_document_number_pattern(pattern, document, document.created_at)
|
||||
reference = replace_document_number_pattern(pattern, document)
|
||||
reference = replace_date_pattern(reference, date)
|
||||
|
||||
case document
|
||||
when Avoir
|
||||
# information about refund/avoir (R[text])
|
||||
reference.gsub!(/R\[([^\]]+)\]/, '\1')
|
||||
|
||||
# remove information about online selling (X[text])
|
||||
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
# remove information about payment schedule (S[text])
|
||||
reference.gsub!(/S\[([^\]]+)\]/, ''.to_s)
|
||||
when PaymentSchedule
|
||||
# information about payment schedule
|
||||
reference.gsub!(/S\[([^\]]+)\]/, '\1')
|
||||
# remove information about online selling (X[text])
|
||||
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
# remove information about refunds (R[text])
|
||||
reference.gsub!(/R\[([^\]]+)\]/, ''.to_s)
|
||||
when Invoice
|
||||
# information about online selling (X[text])
|
||||
if document.paid_by_card?
|
||||
reference.gsub!(/X\[([^\]]+)\]/, '\1')
|
||||
else
|
||||
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
end
|
||||
|
||||
# remove information about refunds (R[text])
|
||||
reference.gsub!(/R\[([^\]]+)\]/, ''.to_s)
|
||||
# remove information about payment schedule (S[text])
|
||||
reference.gsub!(/S\[([^\]]+)\]/, ''.to_s)
|
||||
else
|
||||
raise TypeError
|
||||
end
|
||||
|
||||
reference
|
||||
replace_document_type_pattern(document, reference)
|
||||
end
|
||||
|
||||
# @param document [PaymentDocument]
|
||||
def generate_order_number(document)
|
||||
pattern = Setting.get('invoice_order-nb')
|
||||
pattern = Invoices::NumberService.pattern(document, 'invoice_order-nb')
|
||||
|
||||
# global document number (nn..nn)
|
||||
reference = pattern.gsub(/n+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(number_of_order('global', document, document.created_at), match.to_s.length)
|
||||
pad_and_truncate(order_number(document, 'global'), match.to_s.length)
|
||||
end
|
||||
|
||||
reference = replace_document_number_pattern(reference, document, document.created_at, :number_of_order)
|
||||
reference = replace_document_number_pattern(reference, document, :order_number)
|
||||
replace_date_pattern(reference, document.created_at)
|
||||
end
|
||||
|
||||
@ -70,58 +37,65 @@ class PaymentDocumentService
|
||||
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'
|
||||
# @param document [PaymentDocument]
|
||||
# @param date [Time] the ending date
|
||||
# @return [Integer]
|
||||
def number_of_documents(range, document, date = Time.current)
|
||||
start = case range.to_s
|
||||
when 'day'
|
||||
date.beginning_of_day
|
||||
when 'month'
|
||||
date.beginning_of_month
|
||||
when 'year'
|
||||
date.beginning_of_year
|
||||
else
|
||||
nil
|
||||
end
|
||||
ending = date
|
||||
# @param periodicity [String] 'day' | 'month' | 'year' | 'global'
|
||||
# @return [PaymentDocument,NilClass]
|
||||
def previous_document(document, periodicity)
|
||||
previous = document.class.base_class.where('created_at < ?', db_time(document.created_at))
|
||||
.order(created_at: :desc)
|
||||
.limit(1)
|
||||
if %w[day month year].include?(periodicity)
|
||||
previous = previous.where('date_trunc(:periodicity, created_at) = :date',
|
||||
periodicity: periodicity,
|
||||
date: document.created_at.utc.send("beginning_of_#{periodicity}").to_date)
|
||||
end
|
||||
|
||||
documents = document.class.base_class
|
||||
.where('created_at <= :end_date', end_date: db_time(ending))
|
||||
|
||||
documents = documents.where('created_at >= :start_date', start_date: db_time(start)) unless start.nil?
|
||||
|
||||
documents.count
|
||||
previous.first
|
||||
end
|
||||
|
||||
def number_of_order(range, _document, date = Time.current)
|
||||
start = case range.to_s
|
||||
when 'day'
|
||||
date.beginning_of_day
|
||||
when 'month'
|
||||
date.beginning_of_month
|
||||
when 'year'
|
||||
date.beginning_of_year
|
||||
else
|
||||
nil
|
||||
end
|
||||
ending = date
|
||||
orders = Order.where('created_at <= :end_date', end_date: db_time(ending))
|
||||
orders = orders.where('created_at >= :start_date', start_date: db_time(start)) unless start.nil?
|
||||
|
||||
schedules = PaymentSchedule.where('created_at <= :end_date', end_date: db_time(ending))
|
||||
schedules = schedules.where('created_at >= :start_date', start_date: db_time(start)) unless start.nil?
|
||||
# @param document [PaymentDocument]
|
||||
# @param periodicity [String] 'day' | 'month' | 'year' | 'global'
|
||||
def previous_order(document, periodicity)
|
||||
start = periodicity == 'global' ? nil : document.created_at.send("beginning_of_#{periodicity}")
|
||||
ending = document.created_at
|
||||
orders = orders_in_range(document, start, ending)
|
||||
schedules = schedules_in_range(document, start, ending)
|
||||
|
||||
invoices = Invoice.where(type: nil)
|
||||
.where.not(id: orders.map(&:invoice_id))
|
||||
.where.not(id: schedules.map(&:payment_schedule_items).flatten.map(&:invoice_id).filter(&:present?))
|
||||
.where('created_at <= :end_date', end_date: db_time(ending))
|
||||
.where('created_at < :end_date', end_date: db_time(ending))
|
||||
invoices = invoices.where('created_at >= :start_date', start_date: db_time(start)) unless start.nil?
|
||||
|
||||
orders.count + schedules.count + invoices.count
|
||||
[
|
||||
orders.order(created_at: :desc).limit(1).first,
|
||||
schedules.order(created_at: :desc).limit(1).first,
|
||||
invoices.order(created_at: :desc).limit(1).first
|
||||
].filter(&:present?).max_by { |item| item&.created_at }
|
||||
end
|
||||
|
||||
# @param document [PaymentDocument] invoice to exclude
|
||||
# @param start [Time,NilClass]
|
||||
# @param ending [Time]
|
||||
# @return [ActiveRecord::Relation<Order>,ActiveRecord::QueryMethods::WhereChain]
|
||||
def orders_in_range(document, start, ending)
|
||||
orders = Order.where('created_at < :end_date', end_date: db_time(ending))
|
||||
orders = orders.where('created_at >= :start_date', start_date: db_time(start)) unless start.nil?
|
||||
orders = orders.where.not(id: document.order.id) if document.is_a?(Invoice) && document.order.present?
|
||||
orders
|
||||
end
|
||||
|
||||
# @param document [PaymentDocument] invoice to exclude
|
||||
# @param start [Time,NilClass]
|
||||
# @param ending [Time]
|
||||
# @return [ActiveRecord::Relation<PaymentSchedule>,ActiveRecord::QueryMethods::WhereChain]
|
||||
def schedules_in_range(document, start, ending)
|
||||
schedules = PaymentSchedule.where('created_at < :end_date', end_date: db_time(ending))
|
||||
schedules = schedules.where('created_at >= :start_date', start_date: db_time(start)) unless start.nil?
|
||||
if document.is_a?(Invoice) && document.payment_schedule_item.present?
|
||||
schedules = schedules.where.not(id: document.payment_schedule_item.payment_schedule.id)
|
||||
end
|
||||
schedules
|
||||
end
|
||||
|
||||
# Replace the date elements in the provided pattern with the date values, from the provided date
|
||||
@ -155,25 +129,92 @@ class PaymentDocumentService
|
||||
copy
|
||||
end
|
||||
|
||||
# @param document [PaymentDocument]
|
||||
# @param periodicity [String] 'day' | 'month' | 'year' | 'global'
|
||||
# @return [Integer]
|
||||
def document_number(document, periodicity)
|
||||
previous = previous_document(document, periodicity)
|
||||
number = Invoices::NumberService.number(previous) if Invoices::NumberService.number_periodicity(previous) == periodicity
|
||||
number ||= 0
|
||||
|
||||
number + 1
|
||||
end
|
||||
|
||||
# @param document [PaymentDocument]
|
||||
# @param periodicity [String] 'day' | 'month' | 'year' | 'global'
|
||||
# @return [Integer]
|
||||
def order_number(document, periodicity)
|
||||
previous = previous_order(document, periodicity)
|
||||
if Invoices::NumberService.number_periodicity(previous, 'invoice_order-nb') == periodicity
|
||||
number = Invoices::NumberService.number(previous, 'invoice_order-nb')
|
||||
end
|
||||
number ||= 0
|
||||
|
||||
number + 1
|
||||
end
|
||||
|
||||
# Replace the document number elements in the provided pattern with counts from the database
|
||||
# @param reference [String]
|
||||
# @param document [PaymentDocument]
|
||||
# @param date [Time]
|
||||
# @param count_method [Symbol] :number_of_documents OR :number_of_order
|
||||
def replace_document_number_pattern(reference, document, date, count_method = :number_of_documents)
|
||||
# @param numeration_method [Symbol] :document_number OR :order_number
|
||||
def replace_document_number_pattern(reference, document, numeration_method = :document_number)
|
||||
copy = reference.dup
|
||||
|
||||
# document number per year (yy..yy)
|
||||
copy.gsub!(/y+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(send(count_method, 'year', document, date), match.to_s.length)
|
||||
pad_and_truncate(send(numeration_method, document, 'year'), match.to_s.length)
|
||||
end
|
||||
# document number per month (mm..mm)
|
||||
copy.gsub!(/m+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(send(count_method, 'month', document, date), match.to_s.length)
|
||||
pad_and_truncate(send(numeration_method, document, 'month'), match.to_s.length)
|
||||
end
|
||||
# document number per day (dd..dd)
|
||||
copy.gsub!(/d+(?![^\[]*\])/) do |match|
|
||||
pad_and_truncate(send(count_method, 'day', document, date), match.to_s.length)
|
||||
pad_and_truncate(send(numeration_method, document, 'day'), match.to_s.length)
|
||||
end
|
||||
|
||||
copy
|
||||
end
|
||||
|
||||
# @param document [PaymentDocument]
|
||||
# @param pattern [String]
|
||||
# @return [String]
|
||||
def replace_document_type_pattern(document, pattern)
|
||||
copy = pattern.dup
|
||||
case document
|
||||
when Avoir
|
||||
# information about refund/avoir (R[text])
|
||||
copy.gsub!(/R\[([^\]]+)\]/, '\1')
|
||||
|
||||
# remove information about online selling (X[text])
|
||||
copy.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
# remove information about payment schedule (S[text])
|
||||
copy.gsub!(/S\[([^\]]+)\]/, ''.to_s)
|
||||
when PaymentSchedule
|
||||
# information about payment schedule
|
||||
copy.gsub!(/S\[([^\]]+)\]/, '\1')
|
||||
# remove information about online selling (X[text])
|
||||
copy.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
# remove information about refunds (R[text])
|
||||
copy.gsub!(/R\[([^\]]+)\]/, ''.to_s)
|
||||
when Invoice
|
||||
# information about online selling (X[text])
|
||||
if document.paid_by_card?
|
||||
copy.gsub!(/X\[([^\]]+)\]/, '\1')
|
||||
else
|
||||
copy.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
end
|
||||
|
||||
# remove information about refunds (R[text])
|
||||
copy.gsub!(/R\[([^\]]+)\]/, ''.to_s)
|
||||
# remove information about payment schedule (S[text])
|
||||
copy.gsub!(/S\[([^\]]+)\]/, ''.to_s)
|
||||
else
|
||||
# maybe an Order or anything else,
|
||||
# remove all informations
|
||||
copy.gsub!(/S\[([^\]]+)\]/, ''.to_s)
|
||||
copy.gsub!(/X\[([^\]]+)\]/, ''.to_s)
|
||||
copy.gsub!(/R\[([^\]]+)\]/, ''.to_s)
|
||||
end
|
||||
|
||||
copy
|
||||
|
@ -6,7 +6,7 @@ header = wb.styles.add_style b: true, bg_color: Stylesheet.primary.upcase.gsub('
|
||||
date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_format
|
||||
|
||||
## Machines slots
|
||||
wb.add_worksheet(name: t('export_availabilities.machines')) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(t('export_availabilities.machines'))) do |sheet|
|
||||
|
||||
## data table
|
||||
# heading labels
|
||||
@ -45,7 +45,7 @@ end
|
||||
|
||||
|
||||
## Trainings availabilities
|
||||
wb.add_worksheet(name: t('export_availabilities.trainings')) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(t('export_availabilities.trainings'))) do |sheet|
|
||||
|
||||
## data table
|
||||
# heading labels
|
||||
@ -73,7 +73,7 @@ end
|
||||
|
||||
## Spaces slots
|
||||
if Setting.get('spaces_module')
|
||||
wb.add_worksheet(name: t('export_availabilities.spaces')) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(t('export_availabilities.spaces'))) do |sheet|
|
||||
|
||||
## data table
|
||||
# heading labels
|
||||
@ -109,7 +109,7 @@ end
|
||||
|
||||
|
||||
## Events availabilities
|
||||
wb.add_worksheet(name: t('export_availabilities.events')) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(t('export_availabilities.events'))) do |sheet|
|
||||
|
||||
## data table
|
||||
# heading labels
|
||||
|
@ -6,12 +6,10 @@ bold = wb.styles.add_style b: true
|
||||
header = wb.styles.add_style b: true, bg_color: Stylesheet.primary.upcase.gsub('#', 'FF'), fg_color: 'FFFFFFFF'
|
||||
date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_format
|
||||
|
||||
wb.add_worksheet(name: @index.label) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(@index.label)) do |sheet|
|
||||
## heading stats for the current page
|
||||
sheet.add_row [t('export.entries'), @results['hits']['total']], style: [bold, nil], types: %i[string integer]
|
||||
if @index.ca
|
||||
sheet.add_row [t('export.revenue'), @results['aggregations']['total_ca']['value']], style: [bold, nil], types: %i[string float]
|
||||
end
|
||||
sheet.add_row [t('export.revenue'), @results['aggregations']['total_ca']['value']], style: [bold, nil], types: %i[string float] if @index.ca
|
||||
sheet.add_row [t('export.average_age'), @results['aggregations']['average_age']['value']], style: [bold, nil], types: %i[string float]
|
||||
unless @type.simple
|
||||
sheet.add_row ["#{t('export.total')} #{@type.label}", @results['aggregations']['total_stat']['value']],
|
||||
|
@ -9,9 +9,7 @@ date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_for
|
||||
next unless index.table
|
||||
|
||||
index.statistic_types.each do |type|
|
||||
# see https://msdn.microsoft.com/fr-fr/library/c6bdca6y(v=vs.90).aspx for unauthorized character list
|
||||
sheet_name = "#{index.label} - #{type.label}".gsub(%r{[*|\\:"<>?/]}, '').truncate(31)
|
||||
wb.add_worksheet(name: sheet_name) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.statistic_type_sheet_name(type, wb)) do |sheet|
|
||||
## data table
|
||||
# heading labels
|
||||
columns = [t('export.date'), t('export.user'), t('export.email'), t('export.phone'), t('export.gender'), t('export.age'),
|
||||
|
@ -5,7 +5,7 @@ wb = xlsx_package.workbook
|
||||
header = wb.styles.add_style b: true, bg_color: Stylesheet.primary.upcase.gsub('#', 'FF'), fg_color: 'FFFFFFFF'
|
||||
date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_format
|
||||
|
||||
wb.add_worksheet(name: t('export_members.members')) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(t('export_members.members'))) do |sheet|
|
||||
## data table
|
||||
# heading labels
|
||||
columns = [t('export_members.id'),
|
||||
|
@ -5,7 +5,7 @@ wb = xlsx_package.workbook
|
||||
header = wb.styles.add_style b: true, bg_color: Stylesheet.primary.upcase.gsub('#', 'FF'), fg_color: 'FFFFFFFF'
|
||||
date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_format
|
||||
|
||||
wb.add_worksheet(name: t('export_reservations.reservations')) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(t('export_reservations.reservations'))) do |sheet|
|
||||
|
||||
## data table
|
||||
# heading labels
|
||||
|
@ -5,7 +5,7 @@ wb = xlsx_package.workbook
|
||||
header = wb.styles.add_style b: true, bg_color: Stylesheet.primary.upcase.gsub('#', 'FF'), fg_color: 'FFFFFFFF'
|
||||
date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_format
|
||||
|
||||
wb.add_worksheet(name: t('export_subscriptions.subscriptions')) do |sheet|
|
||||
wb.add_worksheet(name: ExcelService.name_safe(t('export_subscriptions.subscriptions'))) do |sheet|
|
||||
|
||||
## data table
|
||||
# heading labels
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fab-manager",
|
||||
"version": "5.9.0",
|
||||
"version": "5.9.1",
|
||||
"description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.",
|
||||
"keywords": [
|
||||
"fablab",
|
||||
|
10
test/fixtures/availabilities.yml
vendored
10
test/fixtures/availabilities.yml
vendored
@ -219,3 +219,13 @@ availability_22:
|
||||
updated_at: 2023-01-24 13:34:43.841240000 Z
|
||||
nb_total_places: 5
|
||||
destroying: false
|
||||
|
||||
availbility_23:
|
||||
id: 23
|
||||
start_at: 2022-01-01 10:00:00.00000000 Z
|
||||
end_at: 2022-01-01 11:00:00.00000000 Z
|
||||
available_type: machines
|
||||
created_at: 2021-12-24 13:34:43.841240000 Z
|
||||
updated_at: 2021-12-24 13:34:43.841240000 Z
|
||||
nb_total_places:
|
||||
destroying: false
|
||||
|
5
test/fixtures/machines_availabilities.yml
vendored
5
test/fixtures/machines_availabilities.yml
vendored
@ -108,3 +108,8 @@ machines_availability_22:
|
||||
id: 22
|
||||
machine_id: 1
|
||||
availability_id: 19
|
||||
|
||||
machines_availability_23:
|
||||
id: 23
|
||||
machine_id: 1
|
||||
availability_id: 23
|
||||
|
4
test/fixtures/payment_schedules.yml
vendored
4
test/fixtures/payment_schedules.yml
vendored
@ -1,7 +1,7 @@
|
||||
payment_schedule_12:
|
||||
id: 12
|
||||
total: 180000
|
||||
reference: 210600309/E
|
||||
reference: 2106309/E
|
||||
payment_method: card
|
||||
wallet_amount:
|
||||
wallet_transaction_id:
|
||||
@ -17,7 +17,7 @@ payment_schedule_12:
|
||||
payment_schedule_13:
|
||||
id: 13
|
||||
total: 180000
|
||||
reference: <%= 9.months.ago.utc.strftime('%y%m00310/E') %>
|
||||
reference: <%= 9.months.ago.utc.strftime('%y%m310/E') %>
|
||||
payment_method: card
|
||||
wallet_amount:
|
||||
wallet_transaction_id:
|
||||
|
9
test/fixtures/slots.yml
vendored
9
test/fixtures/slots.yml
vendored
@ -655,3 +655,12 @@ slot_134:
|
||||
updated_at: 2023-01-24 13:34:43.841240000 Z
|
||||
availability_id: 22
|
||||
places: [{"user_ids": [], "reservable_id": 4, "reservable_type": "Training", "reserved_places": 0}]
|
||||
|
||||
slot_135:
|
||||
id: 135
|
||||
start_at: 2022-01-01 10:00:00.00000000 Z
|
||||
end_at: 2022-01-01 11:00:00.00000000 Z
|
||||
created_at: 2021-12-24 13:34:43.841240000 Z
|
||||
updated_at: 2021-12-24 13:34:43.841240000 Z
|
||||
availability_id: 23
|
||||
places: [{"user_ids": [], "reservable_id": 1, "reservable_type": "Machine", "reserved_places": 0}]
|
||||
|
20
test/fixtures/users.yml
vendored
20
test/fixtures/users.yml
vendored
@ -1,5 +1,5 @@
|
||||
# admin without subscription
|
||||
user_1:
|
||||
user1:
|
||||
id: 1
|
||||
username: admin
|
||||
email: admin@fab-manager.com
|
||||
@ -32,7 +32,7 @@ user_1:
|
||||
is_allow_newsletter: true
|
||||
|
||||
# member without subscription
|
||||
user_2:
|
||||
user2:
|
||||
id: 2
|
||||
username: jdupond
|
||||
email: jean.dupond@gmail.com
|
||||
@ -65,7 +65,7 @@ user_2:
|
||||
is_allow_newsletter: true
|
||||
|
||||
# member with 1 month subscription (plan 2/standard)
|
||||
user_3:
|
||||
user3:
|
||||
id: 3
|
||||
username: pdurand
|
||||
email: paulette.durand@hotmail.fr
|
||||
@ -98,7 +98,7 @@ user_3:
|
||||
is_allow_newsletter: false
|
||||
|
||||
# member with 1 month subscription (plan 3/students)
|
||||
user_4:
|
||||
user4:
|
||||
id: 4
|
||||
username: kdumas
|
||||
email: kevin.dumas@orange.fr
|
||||
@ -131,7 +131,7 @@ user_4:
|
||||
is_allow_newsletter: false
|
||||
|
||||
# member with 10€ on wallet
|
||||
user_5:
|
||||
user5:
|
||||
id: 5
|
||||
username: vlonchamp
|
||||
email: vanessa.lonchamp@sfr.fr
|
||||
@ -164,7 +164,7 @@ user_5:
|
||||
is_allow_newsletter: true
|
||||
|
||||
# partner of plan 2
|
||||
user_6:
|
||||
user6:
|
||||
id: 6
|
||||
username: GilbertPartenaire
|
||||
email: gilbert.partenaire@nicolas.com
|
||||
@ -197,7 +197,7 @@ user_6:
|
||||
is_allow_newsletter: true
|
||||
|
||||
# member with 255€ on wallet
|
||||
user_7:
|
||||
user7:
|
||||
id: 7
|
||||
username: lseguin
|
||||
email: lucile.seguin@live.fr
|
||||
@ -229,7 +229,7 @@ user_7:
|
||||
merged_at:
|
||||
is_allow_newsletter: false
|
||||
|
||||
user_8:
|
||||
user8:
|
||||
id: 8
|
||||
username: atiermoulin
|
||||
email: a.tiermoulin@mail.fr
|
||||
@ -261,7 +261,7 @@ user_8:
|
||||
merged_at:
|
||||
is_allow_newsletter: false
|
||||
|
||||
user_9:
|
||||
user9:
|
||||
id: 9
|
||||
username: pjproudhon
|
||||
email: pj.proudhon@la-propriete.org
|
||||
@ -294,7 +294,7 @@ user_9:
|
||||
is_allow_newsletter: true
|
||||
|
||||
# member with 1 year subscription
|
||||
user_10:
|
||||
user10:
|
||||
id: 10
|
||||
username: acamus
|
||||
email: albert.camus@letranger.org
|
||||
|
@ -60,7 +60,7 @@ module InvoiceHelper
|
||||
gateway_object_type: 'Stripe::PaymentIntent'
|
||||
)
|
||||
end
|
||||
invoice.save
|
||||
invoice.save!
|
||||
invoice
|
||||
end
|
||||
|
||||
|
@ -27,10 +27,10 @@ module PaymentScheduleHelper
|
||||
options = { payment_method: 'card', payment_id: 'pi_3LpALs2sOmf47Nz91QyFI7nP', payment_type: 'Stripe::PaymentIntent' }
|
||||
end
|
||||
schedule = PaymentScheduleService.new.create([subscription], 113_600, customer, operator: operator, **options)
|
||||
schedule.save
|
||||
schedule.save!
|
||||
first_item = schedule.ordered_items.first
|
||||
PaymentScheduleService.new.generate_invoice(first_item, **options)
|
||||
first_item.update(state: 'paid', payment_method: operator.privileged? ? 'check' : 'card')
|
||||
first_item.update!(state: 'paid', payment_method: operator.privileged? ? 'check' : 'card')
|
||||
schedule
|
||||
end
|
||||
|
||||
|
@ -104,11 +104,7 @@ class Exports::StatisticsExportTest < ActionDispatch::IntegrationTest
|
||||
workbook = RubyXL::Parser.parse(e.file)
|
||||
|
||||
# test worksheets
|
||||
StatisticIndex.where(table: true).includes(:statistic_fields, statistic_types: [:statistic_sub_types]).each do |index|
|
||||
index.statistic_types.each do |type|
|
||||
sheet_name = "#{index.label} - #{type.label}".gsub(%r{[*|\\:"<>?/]}, '').truncate(31)
|
||||
assert_not_nil workbook[sheet_name], "#{sheet_name} not found"
|
||||
end
|
||||
end
|
||||
assert_equal StatisticIndex.where(table: true).includes(:statistic_types).map(&:statistic_types).flatten.count,
|
||||
workbook.worksheets.length
|
||||
end
|
||||
end
|
||||
|
@ -31,6 +31,8 @@ class CreateCartItemTest < ActionDispatch::IntegrationTest
|
||||
|
||||
test 'create a machine reservation' do
|
||||
machine = Machine.first
|
||||
slots = Availabilities::AvailabilitiesService.new(@user)
|
||||
.machines([machine], @user, { start: Time.current, end: 10.days.from_now })
|
||||
post '/api/cart/create_item',
|
||||
params: {
|
||||
order_token: @order.token,
|
||||
@ -38,7 +40,7 @@ class CreateCartItemTest < ActionDispatch::IntegrationTest
|
||||
reservable_id: machine.id,
|
||||
reservable_type: 'Machine',
|
||||
slots_reservations_attributes: [
|
||||
{ slot_id: machine.availabilities.last&.slots&.last&.id }
|
||||
{ slot_id: slots&.last&.id }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,8 @@ class Reservations::PayWithWalletTest < ActionDispatch::IntegrationTest
|
||||
wallet_transactions_count = WalletTransaction.count
|
||||
|
||||
machine = Machine.find(1)
|
||||
availability = machine.availabilities.last
|
||||
slots = Availabilities::AvailabilitiesService.new(user)
|
||||
.machines([machine], user, { start: Time.current, end: 1.day.from_now })
|
||||
plan = Plan.find_by(group_id: user.group.id, type: 'Plan', base_name: 'Abonnement mensualisable')
|
||||
|
||||
VCR.use_cassette('reservations_machine_subscription_with_payment_schedule_coupon_wallet') do
|
||||
@ -203,7 +204,7 @@ class Reservations::PayWithWalletTest < ActionDispatch::IntegrationTest
|
||||
reservable_type: machine.class.name,
|
||||
slots_reservations_attributes: [
|
||||
{
|
||||
slot_id: availability.slots.first.id
|
||||
slot_id: slots.first.id
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class WalletsTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
|
||||
test 'cant get wallet of an user if not admin' do
|
||||
user5 = users(:user_4)
|
||||
user5 = users(:user4)
|
||||
get "/api/wallet/by_user/#{user5.id}"
|
||||
assert_equal 403, response.status
|
||||
end
|
||||
@ -55,13 +55,13 @@ class WalletsTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
|
||||
test 'only admin and wallet owner can show their transactions' do
|
||||
user5 = users(:user_4)
|
||||
user5 = users(:user4)
|
||||
get "/api/wallet/#{user5.wallet.id}/transactions"
|
||||
assert_equal 403, response.status
|
||||
end
|
||||
|
||||
test 'admin can credit amount to a wallet' do
|
||||
admin = users(:user_1)
|
||||
admin = users(:user1)
|
||||
login_as(admin, scope: :user)
|
||||
w = @vlonchamp.wallet
|
||||
amount = 10.5
|
||||
@ -81,7 +81,7 @@ class WalletsTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
|
||||
test 'admin credit wallet with refund invoice generation' do
|
||||
admin = users(:user_1)
|
||||
admin = users(:user1)
|
||||
login_as(admin, scope: :user)
|
||||
w = @vlonchamp.wallet
|
||||
amount = 10
|
||||
|
143
test/services/invoices/number_service_test.rb
Normal file
143
test/services/invoices/number_service_test.rb
Normal file
@ -0,0 +1,143 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class Invoices::NumberServiceTest < ActiveSupport::TestCase
|
||||
test 'invoice 1 numbers' do
|
||||
invoice = Invoice.find(1)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 1, reference
|
||||
assert_equal 1, order_number
|
||||
periodicity = Invoices::NumberService.number_periodicity(invoice)
|
||||
assert_equal 'month', periodicity
|
||||
end
|
||||
|
||||
test 'invoice 2 numbers' do
|
||||
invoice = Invoice.find(2)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 2, reference
|
||||
assert_equal 2, order_number
|
||||
periodicity = Invoices::NumberService.number_periodicity(invoice, 'invoice_order-nb')
|
||||
assert_equal 'global', periodicity
|
||||
end
|
||||
|
||||
test 'invoice 3 numbers' do
|
||||
invoice = Invoice.find(3)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 1, reference
|
||||
assert_equal 3, order_number
|
||||
end
|
||||
|
||||
test 'invoice 4 numbers' do
|
||||
invoice = Invoice.find(4)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 2, reference
|
||||
assert_equal 4, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5 numbers' do
|
||||
invoice = Invoice.find(5)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 31, reference
|
||||
assert_equal 5, order_number
|
||||
end
|
||||
|
||||
test 'invoice 6 numbers' do
|
||||
invoice = Invoice.find(6)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 41, reference
|
||||
assert_equal 6, order_number
|
||||
end
|
||||
|
||||
test 'payment schedule 12 numbers' do
|
||||
schedule = PaymentSchedule.find(12)
|
||||
reference = Invoices::NumberService.number(schedule)
|
||||
order_number = Invoices::NumberService.number(schedule, 'invoice_order-nb')
|
||||
assert_equal 309, reference
|
||||
assert_equal 7, order_number
|
||||
end
|
||||
|
||||
test 'payment schedule 13 numbers' do
|
||||
schedule = PaymentSchedule.find(13)
|
||||
reference = Invoices::NumberService.number(schedule)
|
||||
order_number = Invoices::NumberService.number(schedule, 'invoice_order-nb')
|
||||
assert_equal 310, reference
|
||||
assert_equal 8, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5811 numbers' do
|
||||
invoice = Invoice.find(5811)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 2, reference
|
||||
assert_equal 9, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5812 numbers' do
|
||||
invoice = Invoice.find(5812)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 4, reference
|
||||
assert_equal 5877, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5816 numbers' do
|
||||
invoice = Invoice.find(5816)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 2, reference
|
||||
assert_equal 5888, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5817 numbers' do
|
||||
invoice = Invoice.find(5817)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 4, reference
|
||||
assert_equal 5890, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5818 numbers' do
|
||||
invoice = Invoice.find(5818)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 6, reference
|
||||
assert_equal 5892, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5819 numbers' do
|
||||
invoice = Invoice.find(5819)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 8, reference
|
||||
assert_equal 5894, order_number
|
||||
end
|
||||
|
||||
test 'invoice 5820 numbers' do
|
||||
invoice = Invoice.find(5820)
|
||||
reference = Invoices::NumberService.number(invoice)
|
||||
order_number = Invoices::NumberService.number(invoice, 'invoice_order-nb')
|
||||
assert_equal 10, reference
|
||||
assert_equal 5882, order_number
|
||||
end
|
||||
|
||||
test 'daily periodicy' do
|
||||
Setting.set('invoice_reference', 'YYMDDddddddX[/VL]R[/A]S[/E]')
|
||||
invoice = sample_reservation_invoice(users(:user10), users(:user1))
|
||||
periodicity = Invoices::NumberService.number_periodicity(invoice)
|
||||
assert_equal 'day', periodicity
|
||||
end
|
||||
|
||||
test 'monthly periodicy' do
|
||||
Setting.set('invoice_order-nb', 'MYYYYmmmm')
|
||||
invoice = sample_reservation_invoice(users(:user10), users(:user1))
|
||||
periodicity = Invoices::NumberService.number_periodicity(invoice, 'invoice_order-nb')
|
||||
assert_equal 'month', periodicity
|
||||
end
|
||||
end
|
@ -15,7 +15,7 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
|
||||
test 'invoice for local payment' do
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001", invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
end
|
||||
|
||||
test 'invoice with custom format' do
|
||||
@ -29,31 +29,31 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'invoice with other custom format' do
|
||||
travel_to(Time.current.beginning_of_year)
|
||||
travel_to('2022-01-01')
|
||||
Setting.set('invoice_reference', 'YYMDDyyyyX[/VL]R[/A]S[/E]')
|
||||
Setting.set('invoice_order-nb', 'DMYYYYnnnnnn')
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%-m%d')}0001", invoice.reference
|
||||
assert_equal "#{Time.current.strftime('%-d%-m%Y')}000018", invoice.order_number
|
||||
assert_equal "#{Time.current.strftime('%-d%-m%Y')}000008", invoice.order_number
|
||||
travel_back
|
||||
end
|
||||
|
||||
test 'invoice for online card payment' do
|
||||
invoice = sample_reservation_invoice(@acamus, @acamus)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001/VL", invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
end
|
||||
|
||||
test 'refund' do
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001", invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
refund = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
|
||||
refund.save
|
||||
refund.reload
|
||||
assert_equal "#{Time.current.strftime('%y%m')}002/A", refund.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
end
|
||||
|
||||
test 'payment schedule' do
|
||||
@ -62,31 +62,31 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001/E", schedule.reference
|
||||
first_item = schedule.ordered_items.first
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001", first_item.invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", first_item.invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", first_item.invoice.order_number
|
||||
second_item = schedule.ordered_items[1]
|
||||
PaymentScheduleService.new.generate_invoice(second_item, payment_method: 'check')
|
||||
assert_equal "#{Time.current.strftime('%y%m')}002", second_item.invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", second_item.invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", second_item.invoice.order_number
|
||||
third_item = schedule.ordered_items[2]
|
||||
PaymentScheduleService.new.generate_invoice(third_item, payment_method: 'check')
|
||||
assert_equal "#{Time.current.strftime('%y%m')}003", third_item.invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", third_item.invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", third_item.invoice.order_number
|
||||
fourth_item = schedule.ordered_items[3]
|
||||
PaymentScheduleService.new.generate_invoice(fourth_item, payment_method: 'check')
|
||||
assert_equal "#{Time.current.strftime('%y%m')}004", fourth_item.invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", fourth_item.invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", fourth_item.invoice.order_number
|
||||
fifth_item = schedule.ordered_items[2]
|
||||
PaymentScheduleService.new.generate_invoice(fifth_item, payment_method: 'check')
|
||||
assert_equal "#{Time.current.strftime('%y%m')}005", fifth_item.invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", fifth_item.invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", fifth_item.invoice.order_number
|
||||
end
|
||||
|
||||
test 'order' do
|
||||
cart = Cart::FindOrCreateService.new(users(:user_2)).call(nil)
|
||||
cart = Cart::FindOrCreateService.new(users(:user2)).call(nil)
|
||||
cart = Cart::AddItemService.new.call(cart, Product.find_by(slug: 'panneaux-de-mdf'), 1)
|
||||
Checkout::PaymentService.new.payment(cart, @admin, nil)
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", cart.invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", cart.invoice.order_number
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001", cart.invoice.reference
|
||||
end
|
||||
|
||||
@ -95,94 +95,94 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001", invoice.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
refund = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
|
||||
refund.save
|
||||
refund.reload
|
||||
assert_equal "#{Time.current.strftime('%y%m')}002/A", refund.reference
|
||||
assert_equal "000023-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
assert_equal "005905-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}003", invoice.reference
|
||||
assert_equal "000024-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005906-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @acamus)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}004/VL", invoice.reference
|
||||
assert_equal "000025-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005907-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}005", invoice.reference
|
||||
assert_equal "000026-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005908-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}006", invoice.reference
|
||||
assert_equal "000027-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005909-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @acamus)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}007/VL", invoice.reference
|
||||
assert_equal "000028-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005910-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @acamus)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}008/VL", invoice.reference
|
||||
assert_equal "000029-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005911-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
refund = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
|
||||
refund.save
|
||||
refund.reload
|
||||
assert_equal "#{Time.current.strftime('%y%m')}009/A", refund.reference
|
||||
assert_equal "000029-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
assert_equal "005911-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @acamus)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}010/VL", invoice.reference
|
||||
assert_equal "000030-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005912-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
invoice2 = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}011", invoice2.reference
|
||||
assert_equal "000031-#{Time.current.strftime('%m-%y')}", invoice2.order_number
|
||||
assert_equal "005913-#{Time.current.strftime('%m-%y')}", invoice2.order_number
|
||||
|
||||
refund = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
|
||||
refund.save
|
||||
refund.reload
|
||||
assert_equal "#{Time.current.strftime('%y%m')}012/A", refund.reference
|
||||
assert_equal "000030-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
assert_equal "005912-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
|
||||
refund = invoice2.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
|
||||
refund.save
|
||||
refund.reload
|
||||
assert_equal "#{Time.current.strftime('%y%m')}013/A", refund.reference
|
||||
assert_equal "000031-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
assert_equal "005913-#{Time.current.strftime('%m-%y')}", refund.order_number
|
||||
|
||||
schedule = sample_schedule(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}001/E", schedule.reference
|
||||
assert_equal "#{Time.current.strftime('%y%m')}014", schedule.ordered_items.first.invoice.reference
|
||||
assert_equal "000032-#{Time.current.strftime('%m-%y')}", schedule.ordered_items.first.invoice.order_number
|
||||
assert_equal "005914-#{Time.current.strftime('%m-%y')}", schedule.ordered_items.first.invoice.order_number
|
||||
|
||||
schedule = sample_schedule(users(:user_2), users(:user_2))
|
||||
schedule = sample_schedule(users(:user2), users(:user2))
|
||||
assert_equal "#{Time.current.strftime('%y%m')}002/E", schedule.reference
|
||||
assert_equal "#{Time.current.strftime('%y%m')}015/VL", schedule.ordered_items.first.invoice.reference
|
||||
assert_equal "000033-#{Time.current.strftime('%m-%y')}", schedule.ordered_items.first.invoice.order_number
|
||||
assert_equal "005915-#{Time.current.strftime('%m-%y')}", schedule.ordered_items.first.invoice.order_number
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @acamus)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}016/VL", invoice.reference
|
||||
assert_equal "000034-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005916-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
|
||||
cart = Cart::FindOrCreateService.new(users(:user_2)).call(nil)
|
||||
cart = Cart::FindOrCreateService.new(users(:user2)).call(nil)
|
||||
cart = Cart::AddItemService.new.call(cart, Product.find_by(slug: 'panneaux-de-mdf'), 1)
|
||||
Checkout::PaymentService.new.payment(cart, @admin, nil)
|
||||
assert_equal "000035-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number
|
||||
assert_equal "000035-#{Time.current.strftime('%m-%y')}", cart.invoice.order_number
|
||||
assert_equal "005917-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number
|
||||
assert_equal "005917-#{Time.current.strftime('%m-%y')}", cart.invoice.order_number
|
||||
assert_equal "#{Time.current.strftime('%y%m')}017", cart.invoice.reference
|
||||
|
||||
cart = Cart::FindOrCreateService.new(users(:user_2)).call(nil)
|
||||
cart = Cart::FindOrCreateService.new(users(:user2)).call(nil)
|
||||
cart = Cart::AddItemService.new.call(cart, Product.find_by(slug: 'panneaux-de-mdf'), 1)
|
||||
Checkout::PaymentService.new.payment(cart, @admin, nil)
|
||||
assert_equal "000036-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number
|
||||
assert_equal "000036-#{Time.current.strftime('%m-%y')}", cart.invoice.order_number
|
||||
assert_equal "005918-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number
|
||||
assert_equal "005918-#{Time.current.strftime('%m-%y')}", cart.invoice.order_number
|
||||
assert_equal "#{Time.current.strftime('%y%m')}018", cart.invoice.reference
|
||||
|
||||
invoice = sample_reservation_invoice(@acamus, @admin)
|
||||
assert_equal "#{Time.current.strftime('%y%m')}019", invoice.reference
|
||||
assert_equal "000037-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
assert_equal "005919-#{Time.current.strftime('%m-%y')}", invoice.order_number
|
||||
end
|
||||
end
|
||||
|
@ -44,13 +44,14 @@ class ReservationLimitServiceTest < ActiveSupport::TestCase
|
||||
test 'reservation exceeds plan limit' do
|
||||
@plan.update(limiting: true, plan_limitations_attributes: [{ limitable_id: @machine.id, limitable_type: 'Machine', limit: 2 }])
|
||||
slots = Availabilities::AvailabilitiesService.new(@acamus)
|
||||
.machines([@machine], @acamus, { start: Time.current, end: 10.days.from_now })
|
||||
.machines([@machine], @acamus, { start: 1.day.from_now.beginning_of_day,
|
||||
end: 1.day.from_now.end_of_day })
|
||||
|
||||
reservation = CartItem::MachineReservation.new(
|
||||
customer_profile: @acamus.invoicing_profile,
|
||||
operator_profile: @acamus.invoicing_profile,
|
||||
reservable: @machine,
|
||||
cart_item_reservation_slots_attributes: [{ slot: slots[2] }, { slot: slots[3] }, { slot: slots[4] }]
|
||||
cart_item_reservation_slots_attributes: [{ slot: slots[0] }, { slot: slots[1] }, { slot: slots[2] }]
|
||||
)
|
||||
assert_not ReservationLimitService.authorized?(@plan, @acamus, reservation, [])
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user