1
0
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:
Sylvain 2023-03-22 09:20:50 +01:00
commit 96834987c3
35 changed files with 501 additions and 188 deletions

View File

@ -1,5 +1,11 @@
# Changelog Fab-manager # 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 ## v5.9.0 2023 March 20
- Ability to restrict machine reservations per plan - Ability to restrict machine reservations per plan

View File

@ -299,7 +299,7 @@ GEM
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.4.0) raabro (1.4.0)
racc (1.6.1) racc (1.6.1)
rack (2.2.6.3) rack (2.2.6.4)
rack-oauth2 (1.19.0) rack-oauth2 (1.19.0)
activesupport activesupport
attr_required attr_required

View File

@ -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 // the moment when the slot selection changed for the last time, used to trigger changes in the cart
$scope.selectionTime = null; $scope.selectionTime = null;
// the last clicked event in the calender // the last clicked event in the calendar
$scope.selectedEvent = null; $scope.selectedEvent = null;
// indicates the state of the current view : calendar or plans information // indicates the state of the current view : calendar or plans information
$scope.plansAreShown = false; $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; $scope.selectedPlan = null;
// the moment when the plan selection changed for the last time, used to trigger changes in the cart // the moment when the plan selection changed for the last time, used to trigger changes in the cart

View File

@ -41,6 +41,9 @@ class Availability < ApplicationRecord
validate :length_must_be_slot_multiple, unless: proc { end_at.blank? or start_at.blank? } validate :length_must_be_slot_multiple, unless: proc { end_at.blank? or start_at.blank? }
validate :should_be_associated validate :should_be_associated
# cache
after_update :refresh_places_cache
## elastic callbacks ## elastic callbacks
after_save { AvailabilityIndexerWorker.perform_async(:index, id) } after_save { AvailabilityIndexerWorker.perform_async(:index, id) }
after_destroy { AvailabilityIndexerWorker.perform_async(:delete, id) } after_destroy { AvailabilityIndexerWorker.perform_async(:delete, id) }
@ -128,7 +131,7 @@ class Availability < ApplicationRecord
slots.map(&:reserved_users).flatten slots.map(&:reserved_users).flatten
end end
# @param user [User] # @param user_id [Integer]
# @return [Boolean] # @return [Boolean]
def reserved_by?(user_id) def reserved_by?(user_id)
reserved_users.include?(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')) errors.add(:machine_ids, I18n.t('availabilities.must_be_associated_with_at_least_1_machine'))
end end
def refresh_places_cache
slots.each do |slot|
Slots::PlacesCacheService.refresh(slot)
end
end
end end

View File

@ -14,10 +14,6 @@ class Avoir < Invoice
delegate :order_number, to: :invoice delegate :order_number, to: :invoice
def generate_reference
super(created_at)
end
def expire_subscription def expire_subscription
user.subscription.expire user.subscription.expire
end end

View File

@ -34,8 +34,6 @@ class Footprintable < ApplicationRecord
FootprintService.debug_footprint(self.class, self) FootprintService.debug_footprint(self.class, self)
end end
#protected
def compute_footprint def compute_footprint
FootprintService.compute_footprint(self.class, self) FootprintService.compute_footprint(self.class, self)
end end

View File

@ -50,11 +50,9 @@ class Invoice < PaymentDocument
end end
def order_number 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.order_number if !payment_schedule_item.nil? && !payment_schedule_item.first?
return payment_schedule_item.payment_schedule.ordered_items.first.invoice.order_number
end
PaymentDocumentService.generate_order_number(self) PaymentDocumentService.generate_order_number(self)
end end

View File

@ -20,6 +20,8 @@ class Order < PaymentDocument
delegate :user, to: :statistic_profile delegate :user, to: :statistic_profile
alias_attribute :order_number, :reference
def generate_reference(_date = Time.current) def generate_reference(_date = Time.current)
self.reference = PaymentDocumentService.generate_order_number(self) self.reference = PaymentDocumentService.generate_order_number(self)
end end

View File

@ -4,7 +4,7 @@
class PaymentDocument < Footprintable class PaymentDocument < Footprintable
self.abstract_class = true self.abstract_class = true
def generate_reference(date = Time.current) def generate_reference(date = created_at)
self.reference = PaymentDocumentService.generate_reference(self, date: date) self.reference = PaymentDocumentService.generate_reference(self, date: date)
end end

View File

@ -38,6 +38,10 @@ class PaymentSchedule < PaymentDocument
"#{prefix}-#{id}_#{created_at.strftime('%d%m%Y')}.pdf" "#{prefix}-#{id}_#{created_at.strftime('%d%m%Y')}.pdf"
end 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 # This is useful to check the first item because its amount may be different from the others
## ##

View File

@ -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 class StatisticType < ApplicationRecord
has_one :statistic_index belongs_to :statistic_index
has_many :statistic_type_sub_types has_many :statistic_type_sub_types, dependent: :destroy
has_many :statistic_sub_types, through: :statistic_type_sub_types has_many :statistic_sub_types, through: :statistic_type_sub_types
has_many :statistic_custom_aggregations has_many :statistic_custom_aggregations, dependent: :destroy
end end

View 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

View 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

View File

@ -7,56 +7,23 @@ class PaymentDocumentService
# @param document [PaymentDocument] # @param document [PaymentDocument]
# @param date [Time] # @param date [Time]
def generate_reference(document, date: Time.current) 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) reference = replace_date_pattern(reference, date)
replace_document_type_pattern(document, reference)
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
end end
# @param document [PaymentDocument] # @param document [PaymentDocument]
def generate_order_number(document) def generate_order_number(document)
pattern = Setting.get('invoice_order-nb') pattern = Invoices::NumberService.pattern(document, 'invoice_order-nb')
# global document number (nn..nn) # global document number (nn..nn)
reference = pattern.gsub(/n+(?![^\[]*\])/) do |match| 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 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) replace_date_pattern(reference, document.created_at)
end end
@ -70,58 +37,65 @@ class PaymentDocumentService
value.to_s.rjust(length, '0').gsub(/^.*(.{#{length},}?)$/m, '\1') value.to_s.rjust(length, '0').gsub(/^.*(.{#{length},}?)$/m, '\1')
end 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 document [PaymentDocument]
# @param date [Time] the ending date # @param periodicity [String] 'day' | 'month' | 'year' | 'global'
# @return [Integer] # @return [PaymentDocument,NilClass]
def number_of_documents(range, document, date = Time.current) def previous_document(document, periodicity)
start = case range.to_s previous = document.class.base_class.where('created_at < ?', db_time(document.created_at))
when 'day' .order(created_at: :desc)
date.beginning_of_day .limit(1)
when 'month' if %w[day month year].include?(periodicity)
date.beginning_of_month previous = previous.where('date_trunc(:periodicity, created_at) = :date',
when 'year' periodicity: periodicity,
date.beginning_of_year date: document.created_at.utc.send("beginning_of_#{periodicity}").to_date)
else end
nil
end
ending = date
documents = document.class.base_class previous.first
.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
end end
def number_of_order(range, _document, date = Time.current) # @param document [PaymentDocument]
start = case range.to_s # @param periodicity [String] 'day' | 'month' | 'year' | 'global'
when 'day' def previous_order(document, periodicity)
date.beginning_of_day start = periodicity == 'global' ? nil : document.created_at.send("beginning_of_#{periodicity}")
when 'month' ending = document.created_at
date.beginning_of_month orders = orders_in_range(document, start, ending)
when 'year' schedules = schedules_in_range(document, start, ending)
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?
invoices = Invoice.where(type: nil) invoices = Invoice.where(type: nil)
.where.not(id: orders.map(&:invoice_id)) .where.not(id: orders.map(&:invoice_id))
.where.not(id: schedules.map(&:payment_schedule_items).flatten.map(&:invoice_id).filter(&:present?)) .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? 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 end
# Replace the date elements in the provided pattern with the date values, from the provided date # Replace the date elements in the provided pattern with the date values, from the provided date
@ -155,25 +129,92 @@ class PaymentDocumentService
copy copy
end 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 # Replace the document number elements in the provided pattern with counts from the database
# @param reference [String] # @param reference [String]
# @param document [PaymentDocument] # @param document [PaymentDocument]
# @param date [Time] # @param numeration_method [Symbol] :document_number OR :order_number
# @param count_method [Symbol] :number_of_documents OR :number_of_order def replace_document_number_pattern(reference, document, numeration_method = :document_number)
def replace_document_number_pattern(reference, document, date, count_method = :number_of_documents)
copy = reference.dup copy = reference.dup
# document number per year (yy..yy) # document number per year (yy..yy)
copy.gsub!(/y+(?![^\[]*\])/) do |match| 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 end
# document number per month (mm..mm) # document number per month (mm..mm)
copy.gsub!(/m+(?![^\[]*\])/) do |match| 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 end
# document number per day (dd..dd) # document number per day (dd..dd)
copy.gsub!(/d+(?![^\[]*\])/) do |match| 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 end
copy copy

View File

@ -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 date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_format
## Machines slots ## 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 ## data table
# heading labels # heading labels
@ -45,7 +45,7 @@ end
## Trainings availabilities ## 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 ## data table
# heading labels # heading labels
@ -73,7 +73,7 @@ end
## Spaces slots ## Spaces slots
if Setting.get('spaces_module') 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 ## data table
# heading labels # heading labels
@ -109,7 +109,7 @@ end
## Events availabilities ## 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 ## data table
# heading labels # heading labels

View File

@ -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' 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 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 ## heading stats for the current page
sheet.add_row [t('export.entries'), @results['hits']['total']], style: [bold, nil], types: %i[string integer] 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] 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.average_age'), @results['aggregations']['average_age']['value']], style: [bold, nil], types: %i[string float] sheet.add_row [t('export.average_age'), @results['aggregations']['average_age']['value']], style: [bold, nil], types: %i[string float]
unless @type.simple unless @type.simple
sheet.add_row ["#{t('export.total')} #{@type.label}", @results['aggregations']['total_stat']['value']], sheet.add_row ["#{t('export.total')} #{@type.label}", @results['aggregations']['total_stat']['value']],

View File

@ -9,9 +9,7 @@ date = wb.styles.add_style format_code: Rails.application.secrets.excel_date_for
next unless index.table next unless index.table
index.statistic_types.each do |type| index.statistic_types.each do |type|
# see https://msdn.microsoft.com/fr-fr/library/c6bdca6y(v=vs.90).aspx for unauthorized character list wb.add_worksheet(name: ExcelService.statistic_type_sheet_name(type, wb)) do |sheet|
sheet_name = "#{index.label} - #{type.label}".gsub(%r{[*|\\:"<>?/]}, '').truncate(31)
wb.add_worksheet(name: sheet_name) do |sheet|
## data table ## data table
# heading labels # heading labels
columns = [t('export.date'), t('export.user'), t('export.email'), t('export.phone'), t('export.gender'), t('export.age'), columns = [t('export.date'), t('export.user'), t('export.email'), t('export.phone'), t('export.gender'), t('export.age'),

View File

@ -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' 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 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 ## data table
# heading labels # heading labels
columns = [t('export_members.id'), columns = [t('export_members.id'),

View File

@ -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' 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 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 ## data table
# heading labels # heading labels

View File

@ -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' 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 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 ## data table
# heading labels # heading labels

View File

@ -1,6 +1,6 @@
{ {
"name": "fab-manager", "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.", "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": [ "keywords": [
"fablab", "fablab",

View File

@ -219,3 +219,13 @@ availability_22:
updated_at: 2023-01-24 13:34:43.841240000 Z updated_at: 2023-01-24 13:34:43.841240000 Z
nb_total_places: 5 nb_total_places: 5
destroying: false 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

View File

@ -108,3 +108,8 @@ machines_availability_22:
id: 22 id: 22
machine_id: 1 machine_id: 1
availability_id: 19 availability_id: 19
machines_availability_23:
id: 23
machine_id: 1
availability_id: 23

View File

@ -1,7 +1,7 @@
payment_schedule_12: payment_schedule_12:
id: 12 id: 12
total: 180000 total: 180000
reference: 210600309/E reference: 2106309/E
payment_method: card payment_method: card
wallet_amount: wallet_amount:
wallet_transaction_id: wallet_transaction_id:
@ -17,7 +17,7 @@ payment_schedule_12:
payment_schedule_13: payment_schedule_13:
id: 13 id: 13
total: 180000 total: 180000
reference: <%= 9.months.ago.utc.strftime('%y%m00310/E') %> reference: <%= 9.months.ago.utc.strftime('%y%m310/E') %>
payment_method: card payment_method: card
wallet_amount: wallet_amount:
wallet_transaction_id: wallet_transaction_id:

View File

@ -655,3 +655,12 @@ slot_134:
updated_at: 2023-01-24 13:34:43.841240000 Z updated_at: 2023-01-24 13:34:43.841240000 Z
availability_id: 22 availability_id: 22
places: [{"user_ids": [], "reservable_id": 4, "reservable_type": "Training", "reserved_places": 0}] 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}]

View File

@ -1,5 +1,5 @@
# admin without subscription # admin without subscription
user_1: user1:
id: 1 id: 1
username: admin username: admin
email: admin@fab-manager.com email: admin@fab-manager.com
@ -32,7 +32,7 @@ user_1:
is_allow_newsletter: true is_allow_newsletter: true
# member without subscription # member without subscription
user_2: user2:
id: 2 id: 2
username: jdupond username: jdupond
email: jean.dupond@gmail.com email: jean.dupond@gmail.com
@ -65,7 +65,7 @@ user_2:
is_allow_newsletter: true is_allow_newsletter: true
# member with 1 month subscription (plan 2/standard) # member with 1 month subscription (plan 2/standard)
user_3: user3:
id: 3 id: 3
username: pdurand username: pdurand
email: paulette.durand@hotmail.fr email: paulette.durand@hotmail.fr
@ -98,7 +98,7 @@ user_3:
is_allow_newsletter: false is_allow_newsletter: false
# member with 1 month subscription (plan 3/students) # member with 1 month subscription (plan 3/students)
user_4: user4:
id: 4 id: 4
username: kdumas username: kdumas
email: kevin.dumas@orange.fr email: kevin.dumas@orange.fr
@ -131,7 +131,7 @@ user_4:
is_allow_newsletter: false is_allow_newsletter: false
# member with 10€ on wallet # member with 10€ on wallet
user_5: user5:
id: 5 id: 5
username: vlonchamp username: vlonchamp
email: vanessa.lonchamp@sfr.fr email: vanessa.lonchamp@sfr.fr
@ -164,7 +164,7 @@ user_5:
is_allow_newsletter: true is_allow_newsletter: true
# partner of plan 2 # partner of plan 2
user_6: user6:
id: 6 id: 6
username: GilbertPartenaire username: GilbertPartenaire
email: gilbert.partenaire@nicolas.com email: gilbert.partenaire@nicolas.com
@ -197,7 +197,7 @@ user_6:
is_allow_newsletter: true is_allow_newsletter: true
# member with 255€ on wallet # member with 255€ on wallet
user_7: user7:
id: 7 id: 7
username: lseguin username: lseguin
email: lucile.seguin@live.fr email: lucile.seguin@live.fr
@ -229,7 +229,7 @@ user_7:
merged_at: merged_at:
is_allow_newsletter: false is_allow_newsletter: false
user_8: user8:
id: 8 id: 8
username: atiermoulin username: atiermoulin
email: a.tiermoulin@mail.fr email: a.tiermoulin@mail.fr
@ -261,7 +261,7 @@ user_8:
merged_at: merged_at:
is_allow_newsletter: false is_allow_newsletter: false
user_9: user9:
id: 9 id: 9
username: pjproudhon username: pjproudhon
email: pj.proudhon@la-propriete.org email: pj.proudhon@la-propriete.org
@ -294,7 +294,7 @@ user_9:
is_allow_newsletter: true is_allow_newsletter: true
# member with 1 year subscription # member with 1 year subscription
user_10: user10:
id: 10 id: 10
username: acamus username: acamus
email: albert.camus@letranger.org email: albert.camus@letranger.org

View File

@ -60,7 +60,7 @@ module InvoiceHelper
gateway_object_type: 'Stripe::PaymentIntent' gateway_object_type: 'Stripe::PaymentIntent'
) )
end end
invoice.save invoice.save!
invoice invoice
end end

View File

@ -27,10 +27,10 @@ module PaymentScheduleHelper
options = { payment_method: 'card', payment_id: 'pi_3LpALs2sOmf47Nz91QyFI7nP', payment_type: 'Stripe::PaymentIntent' } options = { payment_method: 'card', payment_id: 'pi_3LpALs2sOmf47Nz91QyFI7nP', payment_type: 'Stripe::PaymentIntent' }
end end
schedule = PaymentScheduleService.new.create([subscription], 113_600, customer, operator: operator, **options) schedule = PaymentScheduleService.new.create([subscription], 113_600, customer, operator: operator, **options)
schedule.save schedule.save!
first_item = schedule.ordered_items.first first_item = schedule.ordered_items.first
PaymentScheduleService.new.generate_invoice(first_item, **options) 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 schedule
end end

View File

@ -104,11 +104,7 @@ class Exports::StatisticsExportTest < ActionDispatch::IntegrationTest
workbook = RubyXL::Parser.parse(e.file) workbook = RubyXL::Parser.parse(e.file)
# test worksheets # test worksheets
StatisticIndex.where(table: true).includes(:statistic_fields, statistic_types: [:statistic_sub_types]).each do |index| assert_equal StatisticIndex.where(table: true).includes(:statistic_types).map(&:statistic_types).flatten.count,
index.statistic_types.each do |type| workbook.worksheets.length
sheet_name = "#{index.label} - #{type.label}".gsub(%r{[*|\\:"<>?/]}, '').truncate(31)
assert_not_nil workbook[sheet_name], "#{sheet_name} not found"
end
end
end end
end end

View File

@ -31,6 +31,8 @@ class CreateCartItemTest < ActionDispatch::IntegrationTest
test 'create a machine reservation' do test 'create a machine reservation' do
machine = Machine.first machine = Machine.first
slots = Availabilities::AvailabilitiesService.new(@user)
.machines([machine], @user, { start: Time.current, end: 10.days.from_now })
post '/api/cart/create_item', post '/api/cart/create_item',
params: { params: {
order_token: @order.token, order_token: @order.token,
@ -38,7 +40,7 @@ class CreateCartItemTest < ActionDispatch::IntegrationTest
reservable_id: machine.id, reservable_id: machine.id,
reservable_type: 'Machine', reservable_type: 'Machine',
slots_reservations_attributes: [ slots_reservations_attributes: [
{ slot_id: machine.availabilities.last&.slots&.last&.id } { slot_id: slots&.last&.id }
] ]
} }
} }

View File

@ -188,7 +188,8 @@ class Reservations::PayWithWalletTest < ActionDispatch::IntegrationTest
wallet_transactions_count = WalletTransaction.count wallet_transactions_count = WalletTransaction.count
machine = Machine.find(1) 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') 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 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, reservable_type: machine.class.name,
slots_reservations_attributes: [ slots_reservations_attributes: [
{ {
slot_id: availability.slots.first.id slot_id: slots.first.id
} }
] ]
} }

View File

@ -39,7 +39,7 @@ class WalletsTest < ActionDispatch::IntegrationTest
end end
test 'cant get wallet of an user if not admin' do 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}" get "/api/wallet/by_user/#{user5.id}"
assert_equal 403, response.status assert_equal 403, response.status
end end
@ -55,13 +55,13 @@ class WalletsTest < ActionDispatch::IntegrationTest
end end
test 'only admin and wallet owner can show their transactions' do 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" get "/api/wallet/#{user5.wallet.id}/transactions"
assert_equal 403, response.status assert_equal 403, response.status
end end
test 'admin can credit amount to a wallet' do test 'admin can credit amount to a wallet' do
admin = users(:user_1) admin = users(:user1)
login_as(admin, scope: :user) login_as(admin, scope: :user)
w = @vlonchamp.wallet w = @vlonchamp.wallet
amount = 10.5 amount = 10.5
@ -81,7 +81,7 @@ class WalletsTest < ActionDispatch::IntegrationTest
end end
test 'admin credit wallet with refund invoice generation' do test 'admin credit wallet with refund invoice generation' do
admin = users(:user_1) admin = users(:user1)
login_as(admin, scope: :user) login_as(admin, scope: :user)
w = @vlonchamp.wallet w = @vlonchamp.wallet
amount = 10 amount = 10

View 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

View File

@ -15,7 +15,7 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
test 'invoice for local payment' do test 'invoice for local payment' do
invoice = sample_reservation_invoice(@acamus, @admin) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}001", invoice.reference 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 end
test 'invoice with custom format' do test 'invoice with custom format' do
@ -29,31 +29,31 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
end end
test 'invoice with other custom format' do 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_reference', 'YYMDDyyyyX[/VL]R[/A]S[/E]')
Setting.set('invoice_order-nb', 'DMYYYYnnnnnn') Setting.set('invoice_order-nb', 'DMYYYYnnnnnn')
invoice = sample_reservation_invoice(@acamus, @admin) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%-m%d')}0001", invoice.reference 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 travel_back
end end
test 'invoice for online card payment' do test 'invoice for online card payment' do
invoice = sample_reservation_invoice(@acamus, @acamus) invoice = sample_reservation_invoice(@acamus, @acamus)
assert_equal "#{Time.current.strftime('%y%m')}001/VL", invoice.reference 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 end
test 'refund' do test 'refund' do
invoice = sample_reservation_invoice(@acamus, @admin) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}001", invoice.reference 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 = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
refund.save refund.save
refund.reload refund.reload
assert_equal "#{Time.current.strftime('%y%m')}002/A", refund.reference 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 end
test 'payment schedule' do test 'payment schedule' do
@ -62,31 +62,31 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
assert_equal "#{Time.current.strftime('%y%m')}001/E", schedule.reference assert_equal "#{Time.current.strftime('%y%m')}001/E", schedule.reference
first_item = schedule.ordered_items.first first_item = schedule.ordered_items.first
assert_equal "#{Time.current.strftime('%y%m')}001", first_item.invoice.reference 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] second_item = schedule.ordered_items[1]
PaymentScheduleService.new.generate_invoice(second_item, payment_method: 'check') PaymentScheduleService.new.generate_invoice(second_item, payment_method: 'check')
assert_equal "#{Time.current.strftime('%y%m')}002", second_item.invoice.reference 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] third_item = schedule.ordered_items[2]
PaymentScheduleService.new.generate_invoice(third_item, payment_method: 'check') PaymentScheduleService.new.generate_invoice(third_item, payment_method: 'check')
assert_equal "#{Time.current.strftime('%y%m')}003", third_item.invoice.reference 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] fourth_item = schedule.ordered_items[3]
PaymentScheduleService.new.generate_invoice(fourth_item, payment_method: 'check') PaymentScheduleService.new.generate_invoice(fourth_item, payment_method: 'check')
assert_equal "#{Time.current.strftime('%y%m')}004", fourth_item.invoice.reference 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] fifth_item = schedule.ordered_items[2]
PaymentScheduleService.new.generate_invoice(fifth_item, payment_method: 'check') PaymentScheduleService.new.generate_invoice(fifth_item, payment_method: 'check')
assert_equal "#{Time.current.strftime('%y%m')}005", fifth_item.invoice.reference 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 end
test 'order' do 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) cart = Cart::AddItemService.new.call(cart, Product.find_by(slug: 'panneaux-de-mdf'), 1)
Checkout::PaymentService.new.payment(cart, @admin, nil) Checkout::PaymentService.new.payment(cart, @admin, nil)
assert_equal "000023-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number assert_equal "005905-#{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.invoice.order_number
assert_equal "#{Time.current.strftime('%y%m')}001", cart.invoice.reference assert_equal "#{Time.current.strftime('%y%m')}001", cart.invoice.reference
end end
@ -95,94 +95,94 @@ class PaymentDocumentServiceTest < ActiveSupport::TestCase
invoice = sample_reservation_invoice(@acamus, @admin) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}001", invoice.reference 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 = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
refund.save refund.save
refund.reload refund.reload
assert_equal "#{Time.current.strftime('%y%m')}002/A", refund.reference 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) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}003", invoice.reference 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) invoice = sample_reservation_invoice(@acamus, @acamus)
assert_equal "#{Time.current.strftime('%y%m')}004/VL", invoice.reference 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) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}005", invoice.reference 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) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}006", invoice.reference 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) invoice = sample_reservation_invoice(@acamus, @acamus)
assert_equal "#{Time.current.strftime('%y%m')}007/VL", invoice.reference 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) invoice = sample_reservation_invoice(@acamus, @acamus)
assert_equal "#{Time.current.strftime('%y%m')}008/VL", invoice.reference 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 = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
refund.save refund.save
refund.reload refund.reload
assert_equal "#{Time.current.strftime('%y%m')}009/A", refund.reference 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) invoice = sample_reservation_invoice(@acamus, @acamus)
assert_equal "#{Time.current.strftime('%y%m')}010/VL", invoice.reference 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) invoice2 = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}011", invoice2.reference 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 = invoice.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
refund.save refund.save
refund.reload refund.reload
assert_equal "#{Time.current.strftime('%y%m')}012/A", refund.reference 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 = invoice2.build_avoir(payment_method: 'wallet', invoice_items_ids: invoice.invoice_items.map(&:id))
refund.save refund.save
refund.reload refund.reload
assert_equal "#{Time.current.strftime('%y%m')}013/A", refund.reference 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) schedule = sample_schedule(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}001/E", schedule.reference 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 "#{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')}002/E", schedule.reference
assert_equal "#{Time.current.strftime('%y%m')}015/VL", schedule.ordered_items.first.invoice.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) invoice = sample_reservation_invoice(@acamus, @acamus)
assert_equal "#{Time.current.strftime('%y%m')}016/VL", invoice.reference 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) cart = Cart::AddItemService.new.call(cart, Product.find_by(slug: 'panneaux-de-mdf'), 1)
Checkout::PaymentService.new.payment(cart, @admin, nil) Checkout::PaymentService.new.payment(cart, @admin, nil)
assert_equal "000035-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number assert_equal "005917-#{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.invoice.order_number
assert_equal "#{Time.current.strftime('%y%m')}017", cart.invoice.reference 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) cart = Cart::AddItemService.new.call(cart, Product.find_by(slug: 'panneaux-de-mdf'), 1)
Checkout::PaymentService.new.payment(cart, @admin, nil) Checkout::PaymentService.new.payment(cart, @admin, nil)
assert_equal "000036-#{Time.current.strftime('%m-%y')}", cart.reference # here reference = order number assert_equal "005918-#{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.invoice.order_number
assert_equal "#{Time.current.strftime('%y%m')}018", cart.invoice.reference assert_equal "#{Time.current.strftime('%y%m')}018", cart.invoice.reference
invoice = sample_reservation_invoice(@acamus, @admin) invoice = sample_reservation_invoice(@acamus, @admin)
assert_equal "#{Time.current.strftime('%y%m')}019", invoice.reference 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
end end

View File

@ -44,13 +44,14 @@ class ReservationLimitServiceTest < ActiveSupport::TestCase
test 'reservation exceeds plan limit' do test 'reservation exceeds plan limit' do
@plan.update(limiting: true, plan_limitations_attributes: [{ limitable_id: @machine.id, limitable_type: 'Machine', limit: 2 }]) @plan.update(limiting: true, plan_limitations_attributes: [{ limitable_id: @machine.id, limitable_type: 'Machine', limit: 2 }])
slots = Availabilities::AvailabilitiesService.new(@acamus) 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( reservation = CartItem::MachineReservation.new(
customer_profile: @acamus.invoicing_profile, customer_profile: @acamus.invoicing_profile,
operator_profile: @acamus.invoicing_profile, operator_profile: @acamus.invoicing_profile,
reservable: @machine, 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, []) assert_not ReservationLimitService.authorized?(@plan, @acamus, reservation, [])
end end