1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-19 08:52:25 +01:00

Merge branch 'Guichaguri-feature/each-reservation-deadlines' into dev

This commit is contained in:
Sylvain 2023-03-20 10:40:37 +01:00
commit 4283425fdb
22 changed files with 138 additions and 33 deletions

View File

@ -81,7 +81,10 @@ export const bookingSettings = [
'reminder_delay', 'reminder_delay',
'visibility_yearly', 'visibility_yearly',
'visibility_others', 'visibility_others',
'reservation_deadline', 'machine_reservation_deadline',
'training_reservation_deadline',
'event_reservation_deadline',
'space_reservation_deadline',
'display_name_enable', 'display_name_enable',
'book_overlapping_slots', 'book_overlapping_slots',
'slot_duration', 'slot_duration',

View File

@ -1175,7 +1175,8 @@ angular.module('application.router', ['ui.router'])
"'renew_pack_threshold', 'pack_only_for_subscription', 'overlapping_categories', 'public_registrations'," + "'renew_pack_threshold', 'pack_only_for_subscription', 'overlapping_categories', 'public_registrations'," +
"'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key', 'user_validation_required', " + "'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key', 'user_validation_required', " +
"'user_validation_required_list', 'machines_module', 'user_change_group', 'show_username_in_admin_list', " + "'user_validation_required_list', 'machines_module', 'user_change_group', 'show_username_in_admin_list', " +
"'store_module', 'reservation_deadline']" "'store_module', 'machine_reservation_deadline', 'training_reservation_deadline', 'event_reservation_deadline', " +
"'space_reservation_deadline']"
}).$promise; }).$promise;
}], }],
privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }], privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }],

View File

@ -108,9 +108,33 @@
<div class="row"> <div class="row">
<h3 class="m-l m-t-lg" translate>{{ 'app.admin.settings.reservation_deadline' }}</h3> <h3 class="m-l m-t-lg" translate>{{ 'app.admin.settings.reservation_deadline' }}</h3>
<p class="alert alert-warning m-h-md" translate>{{ 'app.admin.settings.reservation_deadline_help' }}</p> <p class="alert alert-warning m-h-md" translate>{{ 'app.admin.settings.reservation_deadline_help' }}</p>
<number-setting name="reservation_deadline" <number-setting name="machine_reservation_deadline"
settings="allSettings" settings="allSettings"
label="app.admin.settings.deadline_minutes" label="app.admin.settings.machine_deadline_minutes"
classes="col-md-4"
fa-icon="fas fa-clock"
min="0"
required="true">
</number-setting>
<number-setting name="training_reservation_deadline"
settings="allSettings"
label="app.admin.settings.training_deadline_minutes"
classes="col-md-4"
fa-icon="fas fa-clock"
min="0"
required="true">
</number-setting>
<number-setting name="event_reservation_deadline"
settings="allSettings"
label="app.admin.settings.event_deadline_minutes"
classes="col-md-4"
fa-icon="fas fa-clock"
min="0"
required="true">
</number-setting>
<number-setting name="space_reservation_deadline"
settings="allSettings"
label="app.admin.settings.space_deadline_minutes"
classes="col-md-4" classes="col-md-4"
fa-icon="fas fa-clock" fa-icon="fas fa-clock"
min="0" min="0"

View File

@ -58,7 +58,10 @@ module SettingsHelper
space_explications_alert space_explications_alert
visibility_yearly visibility_yearly
visibility_others visibility_others
reservation_deadline machine_reservation_deadline
training_reservation_deadline
event_reservation_deadline
space_reservation_deadline
display_name_enable display_name_enable
machines_sort_by machines_sort_by
accounting_sales_journal_code accounting_sales_journal_code

View File

@ -71,4 +71,8 @@ class CartItem::EventReservation < CartItem::Reservation
def total_tickets def total_tickets
(normal_tickets || 0) + (cart_item_event_reservation_tickets.map(&:booked).reduce(:+) || 0) (normal_tickets || 0) + (cart_item_event_reservation_tickets.map(&:booked).reduce(:+) || 0)
end end
def reservation_deadline_minutes
return Setting.get('event_reservation_deadline').to_i
end
end end

View File

@ -49,4 +49,8 @@ class CartItem::MachineReservation < CartItem::Reservation
machine_credit = plan.machine_credits.find { |credit| credit.creditable_id == reservable.id } machine_credit = plan.machine_credits.find { |credit| credit.creditable_id == reservable.id }
credits_hours(machine_credit, new_plan_being_bought: new_subscription) credits_hours(machine_credit, new_plan_being_bought: new_subscription)
end end
def reservation_deadline_minutes
return Setting.get('machine_reservation_deadline').to_i
end
end end

View File

@ -63,8 +63,6 @@ class CartItem::Reservation < CartItem::BaseItem
pending_subscription = all_items.find { |i| i.is_a?(CartItem::Subscription) } pending_subscription = all_items.find { |i| i.is_a?(CartItem::Subscription) }
plan = pending_subscription&.plan || customer&.subscribed_plan plan = pending_subscription&.plan || customer&.subscribed_plan
reservation_deadline_minutes = Setting.get('reservation_deadline').to_i
unless ReservationLimitService.authorized?(plan, customer, self, all_items) unless ReservationLimitService.authorized?(plan, customer, self, all_items)
errors.add(:reservation, I18n.t('cart_item_validation.limit_reached', { errors.add(:reservation, I18n.t('cart_item_validation.limit_reached', {
HOURS: ReservationLimitService.limit(plan, reservable).limit, HOURS: ReservationLimitService.limit(plan, reservable).limit,
@ -74,7 +72,7 @@ class CartItem::Reservation < CartItem::BaseItem
end end
cart_item_reservation_slots.each do |sr| cart_item_reservation_slots.each do |sr|
return false unless validate_slot_reservation(sr, pending_subscription, reservation_deadline_minutes, errors) return false unless validate_slot_reservation(sr, pending_subscription, errors)
end end
true true
@ -246,12 +244,18 @@ class CartItem::Reservation < CartItem::BaseItem
operator.admin? operator.admin?
end end
##
# Gets the deadline in minutes for slots in this reservation
##
def reservation_deadline_minutes
return 0
end
# @param reservation_slot [CartItem::ReservationSlot] # @param reservation_slot [CartItem::ReservationSlot]
# @param pending_subscription [CartItem::Subscription, NilClass] # @param pending_subscription [CartItem::Subscription, NilClass]
# @param reservation_deadline [Integer]
# @param errors [ActiveModel::Errors] # @param errors [ActiveModel::Errors]
# @return [Boolean] # @return [Boolean]
def validate_slot_reservation(reservation_slot, pending_subscription, reservation_deadline, errors) def validate_slot_reservation(reservation_slot, pending_subscription, errors)
slot = reservation_slot.slot slot = reservation_slot.slot
if slot.nil? if slot.nil?
errors.add(:slot, I18n.t('cart_item_validation.slot')) errors.add(:slot, I18n.t('cart_item_validation.slot'))
@ -269,7 +273,7 @@ class CartItem::Reservation < CartItem::BaseItem
return false return false
end end
if slot.start_at < reservation_deadline.minutes.since && !operator.privileged? if slot.start_at < reservation_deadline_minutes.minutes.since && !operator.privileged?
errors.add(:slot, I18n.t('cart_item_validation.deadline', { MINUTES: reservation_deadline })) errors.add(:slot, I18n.t('cart_item_validation.deadline', { MINUTES: reservation_deadline }))
return false return false
end end

View File

@ -34,4 +34,8 @@ class CartItem::SpaceReservation < CartItem::Reservation
space_credit = plan.space_credits.find { |credit| credit.creditable_id == reservable.id } space_credit = plan.space_credits.find { |credit| credit.creditable_id == reservable.id }
credits_hours(space_credit, new_plan_being_bought: new_subscription) credits_hours(space_credit, new_plan_being_bought: new_subscription)
end end
def reservation_deadline_minutes
return Setting.get('space_reservation_deadline').to_i
end
end end

View File

@ -45,4 +45,8 @@ class CartItem::TrainingReservation < CartItem::Reservation
is_creditable = plan&.training_credits&.select { |credit| credit.creditable_id == reservable&.id }&.any? is_creditable = plan&.training_credits&.select { |credit| credit.creditable_id == reservable&.id }&.any?
is_creditable ? plan&.training_credit_nb : 0 is_creditable ? plan&.training_credit_nb : 0
end end
def reservation_deadline_minutes
return Setting.get('training_reservation_deadline').to_i
end
end end

View File

@ -6,11 +6,6 @@ class Availabilities::AvailabilitiesService
# @param level [String] 'slot' | 'availability' # @param level [String] 'slot' | 'availability'
def initialize(current_user, level = 'slot') def initialize(current_user, level = 'slot')
@current_user = current_user @current_user = current_user
@maximum_visibility = {
year: Setting.get('visibility_yearly').to_i.months.since,
other: Setting.get('visibility_others').to_i.months.since
}
@minimum_visibility = Setting.get('reservation_deadline').to_i.minutes.since
@level = level @level = level
end end

View File

@ -7,7 +7,12 @@ class Availabilities::VisibilityService
year: Setting.get('visibility_yearly').to_i.months.since, year: Setting.get('visibility_yearly').to_i.months.since,
other: Setting.get('visibility_others').to_i.months.since other: Setting.get('visibility_others').to_i.months.since
} }
@minimum_visibility = Setting.get('reservation_deadline').to_i.minutes.since @minimum_visibility = {
machine: Setting.get('machine_reservation_deadline').to_i.minutes.since,
training: Setting.get('training_reservation_deadline').to_i.minutes.since,
event: Setting.get('event_reservation_deadline').to_i.minutes.since,
space: Setting.get('space_reservation_deadline').to_i.minutes.since
}
end end
# @param user [User,NilClass] # @param user [User,NilClass]
@ -24,8 +29,15 @@ class Availabilities::VisibilityService
end_at = @maximum_visibility[:year] if subscription_year?(user) && available_type != 'training' end_at = @maximum_visibility[:year] if subscription_year?(user) && available_type != 'training'
end_at = @maximum_visibility[:year] if show_more_trainings?(user) && available_type == 'training' end_at = @maximum_visibility[:year] if show_more_trainings?(user) && available_type == 'training'
end_at = subscription_visibility(user, available_type) || end_at end_at = subscription_visibility(user, available_type) || end_at
minimum_visibility = 0.minutes.since
minimum_visibility = @minimum_visibility[:machine] if available_type == 'machines'
minimum_visibility = @minimum_visibility[:training] if available_type == 'training'
minimum_visibility = @minimum_visibility[:event] if available_type == 'event'
minimum_visibility = @minimum_visibility[:space] if available_type == 'space'
window_end = [end_at, range_end].min window_end = [end_at, range_end].min
window_start = [range_start, @minimum_visibility].max window_start = [range_start, minimum_visibility].max
end end
[window_start, window_end] [window_start, window_end]
end end

View File

@ -1608,7 +1608,10 @@ de:
visibility_for_other_members: "Für alle anderen Mitglieder" visibility_for_other_members: "Für alle anderen Mitglieder"
reservation_deadline: "Prevent last minute booking" reservation_deadline: "Prevent last minute booking"
reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start." reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start."
deadline_minutes: "Prior period (minutes)" machine_deadline_minutes: "Machine prior period (minutes)"
training_deadline_minutes: "Training prior period (minutes)"
event_deadline_minutes: "Event prior period (minutes)"
space_deadline_minutes: "Space prior period (minutes)"
ability_for_the_users_to_move_their_reservations: "Möglichkeit für die Benutzer, ihre Reservierungen zu verschieben" ability_for_the_users_to_move_their_reservations: "Möglichkeit für die Benutzer, ihre Reservierungen zu verschieben"
reservations_shifting: "Verschiebung von Reservierungen" reservations_shifting: "Verschiebung von Reservierungen"
prior_period_hours: "Vorheriger Zeitraum (Stunden)" prior_period_hours: "Vorheriger Zeitraum (Stunden)"

View File

@ -1608,7 +1608,10 @@ en:
visibility_for_other_members: "For all other members" visibility_for_other_members: "For all other members"
reservation_deadline: "Prevent last minute booking" reservation_deadline: "Prevent last minute booking"
reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start." reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start."
deadline_minutes: "Prior period (minutes)" machine_deadline_minutes: "Machine prior period (minutes)"
training_deadline_minutes: "Training prior period (minutes)"
event_deadline_minutes: "Event prior period (minutes)"
space_deadline_minutes: "Space prior period (minutes)"
ability_for_the_users_to_move_their_reservations: "Ability for the users to move their reservations" ability_for_the_users_to_move_their_reservations: "Ability for the users to move their reservations"
reservations_shifting: "Reservations shifting" reservations_shifting: "Reservations shifting"
prior_period_hours: "Prior period (hours)" prior_period_hours: "Prior period (hours)"

View File

@ -1608,7 +1608,10 @@ es:
visibility_for_other_members: "Para todos los demás miembros" visibility_for_other_members: "Para todos los demás miembros"
reservation_deadline: "Prevent last minute booking" reservation_deadline: "Prevent last minute booking"
reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start." reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start."
deadline_minutes: "Prior period (minutes)" machine_deadline_minutes: "Machine prior period (minutes)"
training_deadline_minutes: "Training prior period (minutes)"
event_deadline_minutes: "Event prior period (minutes)"
space_deadline_minutes: "Space prior period (minutes)"
ability_for_the_users_to_move_their_reservations: "Capacidad para que los usuarios muevan sus reservas" ability_for_the_users_to_move_their_reservations: "Capacidad para que los usuarios muevan sus reservas"
reservations_shifting: "Cambio de reservas" reservations_shifting: "Cambio de reservas"
prior_period_hours: "Período anterior (horas)" prior_period_hours: "Período anterior (horas)"

View File

@ -1608,7 +1608,10 @@ fr:
visibility_for_other_members: "Pour tous les autres membres" visibility_for_other_members: "Pour tous les autres membres"
reservation_deadline: "Empêcher les réservations de dernière minute" reservation_deadline: "Empêcher les réservations de dernière minute"
reservation_deadline_help: "Si vous augmentez le délai préalable, les membres ne pourront pas réserver un créneau X minutes avant le début de celui-ci." reservation_deadline_help: "Si vous augmentez le délai préalable, les membres ne pourront pas réserver un créneau X minutes avant le début de celui-ci."
deadline_minutes: "Délai préalable (en minutes)" machine_deadline_minutes: "Délai préalable pour les machines (en minutes)"
training_deadline_minutes: "Délai préalable pour les formations (en minutes)"
event_deadline_minutes: "Délai préalable pour les événements (en minutes)"
space_deadline_minutes: "Délai préalable pour les espaces (en minutes)"
ability_for_the_users_to_move_their_reservations: "Possibilité pour l'utilisateur de déplacer ses réservations" ability_for_the_users_to_move_their_reservations: "Possibilité pour l'utilisateur de déplacer ses réservations"
reservations_shifting: "Déplacement des réservations" reservations_shifting: "Déplacement des réservations"
prior_period_hours: "Délai préalable (en heures)" prior_period_hours: "Délai préalable (en heures)"

View File

@ -1608,7 +1608,10 @@
visibility_for_other_members: "For alle andre medlemmer" visibility_for_other_members: "For alle andre medlemmer"
reservation_deadline: "Prevent last minute booking" reservation_deadline: "Prevent last minute booking"
reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start." reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start."
deadline_minutes: "Prior period (minutes)" machine_deadline_minutes: "Machine prior period (minutes)"
training_deadline_minutes: "Training prior period (minutes)"
event_deadline_minutes: "Event prior period (minutes)"
space_deadline_minutes: "Space prior period (minutes)"
ability_for_the_users_to_move_their_reservations: "Om brukerne kan flytte sine bestillinger" ability_for_the_users_to_move_their_reservations: "Om brukerne kan flytte sine bestillinger"
reservations_shifting: "Reservasjonsendringer" reservations_shifting: "Reservasjonsendringer"
prior_period_hours: "Tidligere perioder (timer)" prior_period_hours: "Tidligere perioder (timer)"

View File

@ -1608,7 +1608,10 @@ pt:
visibility_for_other_members: "Para todos os outros membros" visibility_for_other_members: "Para todos os outros membros"
reservation_deadline: "Impedir a reserva da última hora" reservation_deadline: "Impedir a reserva da última hora"
reservation_deadline_help: "Se você aumentar o período prévio, os membros não serão capazes de reservar um slot X minutos antes do seu início." reservation_deadline_help: "Se você aumentar o período prévio, os membros não serão capazes de reservar um slot X minutos antes do seu início."
deadline_minutes: "Período prévio (minutos)" machine_deadline_minutes: "Machine prior period (minutes)"
training_deadline_minutes: "Training prior period (minutes)"
event_deadline_minutes: "Event prior period (minutes)"
space_deadline_minutes: "Space prior period (minutes)"
ability_for_the_users_to_move_their_reservations: "Habilidade para os usuários mover suas reservas" ability_for_the_users_to_move_their_reservations: "Habilidade para os usuários mover suas reservas"
reservations_shifting: "Mudança de reservas" reservations_shifting: "Mudança de reservas"
prior_period_hours: "Período anterior (horas)" prior_period_hours: "Período anterior (horas)"

View File

@ -1608,7 +1608,10 @@ zu:
visibility_for_other_members: "crwdns26448:0crwdne26448:0" visibility_for_other_members: "crwdns26448:0crwdne26448:0"
reservation_deadline: "crwdns31751:0crwdne31751:0" reservation_deadline: "crwdns31751:0crwdne31751:0"
reservation_deadline_help: "crwdns36265:0crwdne36265:0" reservation_deadline_help: "crwdns36265:0crwdne36265:0"
deadline_minutes: "crwdns31753:0crwdne31753:0" machine_deadline_minutes: "crwdns37593:0crwdne37593:0"
training_deadline_minutes: "crwdns37595:0crwdne37595:0"
event_deadline_minutes: "crwdns37597:0crwdne37597:0"
space_deadline_minutes: "crwdns37599:0crwdne37599:0"
ability_for_the_users_to_move_their_reservations: "crwdns26450:0crwdne26450:0" ability_for_the_users_to_move_their_reservations: "crwdns26450:0crwdne26450:0"
reservations_shifting: "crwdns26452:0crwdne26452:0" reservations_shifting: "crwdns26452:0crwdne26452:0"
prior_period_hours: "crwdns26454:0crwdne26454:0" prior_period_hours: "crwdns26454:0crwdne26454:0"

View File

@ -103,7 +103,7 @@ zu:
must_accept_terms: "crwdns28700:0crwdne28700:0" must_accept_terms: "crwdns28700:0crwdne28700:0"
save: "crwdns28702:0crwdne28702:0" save: "crwdns28702:0crwdne28702:0"
gender_input: gender_input:
label: "crwdns37591:0crwdne37591:0" label: "crwdns37601:0crwdne37601:0"
man: "crwdns28704:0crwdne28704:0" man: "crwdns28704:0crwdne28704:0"
woman: "crwdns28706:0crwdne28706:0" woman: "crwdns28706:0crwdne28706:0"
change_password: change_password:

View File

@ -418,7 +418,15 @@ Setting.set('visibility_yearly', 3) unless Setting.find_by(name: 'visibility_yea
Setting.set('visibility_others', 1) unless Setting.find_by(name: 'visibility_others').try(:value) Setting.set('visibility_others', 1) unless Setting.find_by(name: 'visibility_others').try(:value)
Setting.set('reservation_deadline', 0) unless Setting.find_by(name: 'reservation_deadline').try(:value) reservation_deadline = Setting.get('reservation_deadline') || 0
Setting.set('machine_reservation_deadline', reservation_deadline) unless Setting.find_by(name: 'machine_reservation_deadline').try(:value)
Setting.set('training_reservation_deadline', reservation_deadline) unless Setting.find_by(name: 'training_reservation_deadline').try(:value)
Setting.set('event_reservation_deadline', reservation_deadline) unless Setting.find_by(name: 'event_reservation_deadline').try(:value)
Setting.set('space_reservation_deadline', reservation_deadline) unless Setting.find_by(name: 'space_reservation_deadline').try(:value)
Setting.set('display_name_enable', false) unless Setting.find_by(name: 'display_name_enable').try(:value) Setting.set('display_name_enable', false) unless Setting.find_by(name: 'display_name_enable').try(:value)

View File

@ -737,10 +737,28 @@ export const settings: Array<Setting> = [
localized: 'éviter la génération de factures à 0' localized: 'éviter la génération de factures à 0'
}, },
{ {
name: 'reservation_deadline', name: 'machine_reservation_deadline',
value: '0', value: '0',
last_update: '2022-11-29T21:02:47-0300', last_update: '2023-03-01T16:28:23-0300',
localized: "Empêcher la réservation avant qu'elle ne commence" localized: 'Machine prior period (minutes)'
},
{
name: 'training_reservation_deadline',
value: '0',
last_update: '2023-03-01T16:28:23-0300',
localized: 'Training prior period (minutes)'
},
{
name: 'event_reservation_deadline',
value: '0',
last_update: '2023-03-01T16:28:23-0300',
localized: 'Event prior period (minutes)'
},
{
name: 'space_reservation_deadline',
value: '0',
last_update: '2023-03-01T16:28:23-0300',
localized: 'Space prior period (minutes)'
}, },
{ {
name: 'invoice_VAT-name', name: 'invoice_VAT-name',

View File

@ -13,7 +13,7 @@ class Reservations::LastMinuteTest < ActionDispatch::IntegrationTest
end end
test 'user cannot reserve last minute booking' do test 'user cannot reserve last minute booking' do
Setting.set('reservation_deadline', '120') Setting.set('space_reservation_deadline', '120')
login_as(@user, scope: :user) login_as(@user, scope: :user)
@ -44,7 +44,7 @@ class Reservations::LastMinuteTest < ActionDispatch::IntegrationTest
end end
test 'user can reserve last minute booking' do test 'user can reserve last minute booking' do
Setting.set('reservation_deadline', '0') Setting.set('space_reservation_deadline', '0')
login_as(@user, scope: :user) login_as(@user, scope: :user)
@ -85,7 +85,7 @@ class Reservations::LastMinuteTest < ActionDispatch::IntegrationTest
end end
test 'admin can reserve last minute booking anyway' do test 'admin can reserve last minute booking anyway' do
Setting.set('reservation_deadline', '120') Setting.set('space_reservation_deadline', '120')
login_as(@admin, scope: :user) login_as(@admin, scope: :user)