mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-28 09:24:24 +01:00
(feat) valid/invalid pre registration event
This commit is contained in:
parent
a8dedfe040
commit
d271fa59e6
@ -5,7 +5,7 @@
|
||||
# availability by Availability.slot_duration, or otherwise globally by Setting.get('slot_duration')
|
||||
class API::SlotsReservationsController < API::APIController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_slots_reservation, only: %i[update cancel validate]
|
||||
before_action :set_slots_reservation, only: %i[update cancel validate invalidate]
|
||||
respond_to :json
|
||||
|
||||
def update
|
||||
@ -28,6 +28,11 @@ class API::SlotsReservationsController < API::APIController
|
||||
SlotsReservationsService.validate(@slot_reservation)
|
||||
end
|
||||
|
||||
def invalidate
|
||||
authorize @slot_reservation
|
||||
SlotsReservationsService.invalidate(@slot_reservation)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_slots_reservation
|
||||
|
@ -44,9 +44,9 @@ export const EventReservationItem: React.FC<EventReservationItemProps> = ({ rese
|
||||
* Return the pre-registration status
|
||||
*/
|
||||
const preRegistrationStatus = () => {
|
||||
if (!reservation.validated_at && !reservation.canceled_at && !reservation.is_paid) {
|
||||
if (!reservation.is_valid && !reservation.canceled_at && !reservation.is_paid) {
|
||||
return t('app.logged.event_reservation_item.in_the_process_of_validation');
|
||||
} else if (reservation.validated_at && !reservation.canceled_at && !reservation.is_paid) {
|
||||
} else if (reservation.is_valid && !reservation.canceled_at && !reservation.is_paid) {
|
||||
return t('app.logged.event_reservation_item.settle_your_payment');
|
||||
} else if (reservation.is_paid && !reservation.canceled_at) {
|
||||
return t('app.logged.event_reservation_item.paid');
|
||||
|
@ -458,7 +458,7 @@ Application.Controllers.controller('ShowEventReservationsController', ['$scope',
|
||||
* @returns {boolean}
|
||||
*/
|
||||
$scope.isValidated = function (reservation) {
|
||||
return !!(reservation.slots_reservations_attributes[0].validated_at);
|
||||
return reservation.slots_reservations_attributes[0].is_valid === true || reservation.slots_reservations_attributes[0].is_valid === 'true';
|
||||
};
|
||||
|
||||
/**
|
||||
@ -466,25 +466,30 @@ Application.Controllers.controller('ShowEventReservationsController', ['$scope',
|
||||
* @param reservation {Reservation}
|
||||
*/
|
||||
$scope.validateReservation = function (reservation) {
|
||||
dialogs.confirm({
|
||||
resolve: {
|
||||
object: function () {
|
||||
return {
|
||||
title: _t('app.admin.event_reservations.validate_the_reservation'),
|
||||
msg: _t('app.admin.event_reservations.do_you_really_want_to_validate_this_reservation_this_apply_to_all_booked_tickets')
|
||||
};
|
||||
}
|
||||
}
|
||||
}, function () { // validate confirmed
|
||||
SlotsReservation.validate({
|
||||
id: reservation.slots_reservations_attributes[0].id
|
||||
}, () => { // successfully validated
|
||||
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_validated'));
|
||||
const index = $scope.reservations.indexOf(reservation);
|
||||
$scope.reservations[index].slots_reservations_attributes[0].validated_at = new Date();
|
||||
}, () => {
|
||||
growl.warning(_t('app.admin.event_reservations.validation_failed'));
|
||||
});
|
||||
SlotsReservation.validate({
|
||||
id: reservation.slots_reservations_attributes[0].id
|
||||
}, () => { // successfully validated
|
||||
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_validated'));
|
||||
const index = $scope.reservations.indexOf(reservation);
|
||||
$scope.reservations[index].slots_reservations_attributes[0].is_valid = true;
|
||||
}, () => {
|
||||
growl.warning(_t('app.admin.event_reservations.validation_failed'));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to invalidate a reservation
|
||||
* @param reservation {Reservation}
|
||||
*/
|
||||
$scope.invalidateReservation = function (reservation) {
|
||||
SlotsReservation.invalidate({
|
||||
id: reservation.slots_reservations_attributes[0].id
|
||||
}, () => { // successfully validated
|
||||
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_invalidated'));
|
||||
const index = $scope.reservations.indexOf(reservation);
|
||||
$scope.reservations[index].slots_reservations_attributes[0].is_valid = false;
|
||||
}, () => {
|
||||
growl.warning(_t('app.admin.event_reservations.invalidation_failed'));
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -644,7 +644,7 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
if (!user.booked) {
|
||||
return false;
|
||||
}
|
||||
if ($scope.enableChildValidationRequired && user.booked.type === 'Child' && !user.booked.validatedAt) {
|
||||
if ($scope.enableChildValidationRequired && user.booked.type === 'Child' && !user.booked.is_valid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -748,7 +748,7 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
name: child.first_name + ' ' + child.last_name,
|
||||
id: child.id,
|
||||
type: 'Child',
|
||||
validatedAt: child.validated_at,
|
||||
is_valid: child.is_valid,
|
||||
birthday: child.birthday
|
||||
});
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ export interface Reservation {
|
||||
event_type?: string,
|
||||
event_title?: string,
|
||||
event_pre_registration?: boolean
|
||||
validated_at?: TDateISO,
|
||||
canceled_at?: TDateISO,
|
||||
is_valid?: boolean,
|
||||
is_paid?: boolean,
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,10 @@ Application.Services.factory('SlotsReservation', ['$resource', function ($resour
|
||||
validate: {
|
||||
method: 'PUT',
|
||||
url: '/api/slots_reservations/:id/validate'
|
||||
},
|
||||
invalidate: {
|
||||
method: 'PUT',
|
||||
url: '/api/slots_reservations/:id/invalidate'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -53,19 +53,16 @@
|
||||
</td>
|
||||
<td ng-if="event.pre_registration">
|
||||
<div>
|
||||
<div ng-if="!isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid">
|
||||
<div ng-if="!isCancelled(reservation) && !reservation.is_paid">
|
||||
<label class="m-r-sm">
|
||||
<span translate>{{ 'app.admin.event_reservations.negative' }}</span>
|
||||
<input type="radio" name="validate" value="no">
|
||||
<input type="radio" name="validate" ng-value="false" ng-click="invalidateReservation(reservation)" ng-model="reservation.slots_reservations_attributes[0].is_valid" >
|
||||
</label>
|
||||
<label>
|
||||
<span translate>{{ 'app.admin.event_reservations.affirmative' }}</span>
|
||||
<input type="radio" name="validate" value="yes">
|
||||
<input type="radio" name="validate" ng-value="true" ng-click="validateReservation(reservation)" ng-model="reservation.slots_reservations_attributes[0].is_valid" >
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-default" ng-click="validateReservation(reservation)" ng-if="!isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" translate>
|
||||
{{ 'app.admin.event_reservations.validate' }}
|
||||
</button>
|
||||
<button class="btn btn-default" ng-click="payReservation(reservation)" ng-if="isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" translate>
|
||||
{{ 'app.admin.event_reservations.pay' }}
|
||||
</button>
|
||||
|
@ -142,7 +142,7 @@
|
||||
class="form-control">
|
||||
<option value=""></option>
|
||||
</select>
|
||||
<uib-alert type="danger" ng-if="enableChildValidationRequired && user.booked && user.booked.type === 'Child' && !user.booked.validatedAt" style="margin-bottom: 0.8rem;">
|
||||
<uib-alert type="danger" ng-if="enableChildValidationRequired && user.booked && user.booked.type === 'Child' && !user.booked.is_valid" style="margin-bottom: 0.8rem;">
|
||||
<span class="text-sm">
|
||||
<i class="fa fa-warning"></i>
|
||||
<span translate>{{ 'app.shared.cart.child_validation_required_alert' }}</span>
|
||||
@ -180,7 +180,7 @@
|
||||
class="form-control">
|
||||
<option value=""></option>
|
||||
</select>
|
||||
<uib-alert type="danger" ng-if="enableChildValidationRequired && user.booked && user.booked.type === 'Child' && !user.booked.validatedAt">
|
||||
<uib-alert type="danger" ng-if="enableChildValidationRequired && user.booked && user.booked.type === 'Child' && !user.booked.is_valid">
|
||||
<p class="text-sm">
|
||||
<i class="fa fa-warning"></i>
|
||||
<span translate>{{ 'app.shared.cart.child_validation_required_alert' }}</span>
|
||||
|
@ -89,7 +89,7 @@ class Event < ApplicationRecord
|
||||
else
|
||||
reserved_places = reservations.joins(:slots_reservations)
|
||||
.where('slots_reservations.canceled_at': nil)
|
||||
.where.not('slots_reservations.validated_at': nil)
|
||||
.where('slots_reservations.is_valid': true)
|
||||
.map(&:total_booked_seats)
|
||||
.inject(0) { |sum, t| sum + t }
|
||||
self.nb_free_places = (nb_total_places - reserved_places)
|
||||
@ -99,7 +99,7 @@ class Event < ApplicationRecord
|
||||
def nb_places_for_pre_registration
|
||||
reservations.joins(:slots_reservations)
|
||||
.where('slots_reservations.canceled_at': nil)
|
||||
.where('slots_reservations.validated_at': nil)
|
||||
.where('slots_reservations.is_valid': nil)
|
||||
.map(&:total_booked_seats)
|
||||
.inject(0) { |sum, t| sum + t }
|
||||
end
|
||||
|
@ -19,4 +19,8 @@ class SlotsReservationPolicy < ApplicationPolicy
|
||||
def validate?
|
||||
user.admin? || user.manager?
|
||||
end
|
||||
|
||||
def invalidate?
|
||||
user.admin? || user.manager?
|
||||
end
|
||||
end
|
||||
|
@ -23,7 +23,7 @@ class SlotsReservationsService
|
||||
end
|
||||
|
||||
def validate(slot_reservation)
|
||||
if slot_reservation.update(validated_at: Time.current)
|
||||
if slot_reservation.update(is_valid: true)
|
||||
reservable = slot_reservation.reservation.reservable
|
||||
if reservable.is_a?(Event)
|
||||
reservable.update_nb_free_places
|
||||
@ -39,5 +39,17 @@ class SlotsReservationsService
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def invalidate(slot_reservation)
|
||||
if slot_reservation.update(is_valid: false)
|
||||
reservable = slot_reservation.reservation.reservable
|
||||
if reservable.is_a?(Event)
|
||||
reservable.update_nb_free_places
|
||||
reservable.save
|
||||
end
|
||||
return true
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -87,7 +87,7 @@ json.events_reservations @member.reservations.where(reservable_type: 'Event').jo
|
||||
json.event_type sr.reservation.reservable.event_type
|
||||
json.event_title sr.reservation.reservable.title
|
||||
json.event_pre_registration sr.reservation.reservable.pre_registration
|
||||
json.validated_at sr.validated_at
|
||||
json.is_valid sr.is_valid
|
||||
json.is_paid sr.reservation.invoice_items.count.positive?
|
||||
json.canceled_at sr.canceled_at
|
||||
json.booking_users_attributes sr.reservation.booking_users.order(booked_type: :desc) do |bu|
|
||||
|
@ -7,7 +7,7 @@ json.message reservation.message
|
||||
json.slots_reservations_attributes reservation.slots_reservations do |sr|
|
||||
json.id sr.id
|
||||
json.canceled_at sr.canceled_at&.iso8601
|
||||
json.validated_at sr.validated_at&.iso8601
|
||||
json.is_valid sr.is_valid
|
||||
json.slot_id sr.slot_id
|
||||
json.slot_attributes do
|
||||
json.id sr.slot_id
|
||||
@ -41,4 +41,5 @@ json.booking_users_attributes reservation.booking_users.order(booked_type: :desc
|
||||
json.booked_id bu.booked_id
|
||||
json.booked_type bu.booked_type
|
||||
end
|
||||
json.is_valid reservation.slots_reservations[0].is_valid
|
||||
json.is_paid reservation.invoice_items.count.positive?
|
||||
|
@ -646,6 +646,7 @@ en:
|
||||
booked_by: "Booked by"
|
||||
reservations: "Reservations"
|
||||
status: "Status"
|
||||
gestion: "Gestion"
|
||||
validation: "Validation"
|
||||
event_status:
|
||||
pre_registered: "Pre-registered"
|
||||
@ -660,6 +661,8 @@ en:
|
||||
do_you_really_want_to_validate_this_reservation_this_apply_to_all_booked_tickets: "Do you really want to validate this reservation? This apply to ALL booked tickets."
|
||||
reservation_was_successfully_validated: "Reservation was successfully validated."
|
||||
validation_failed: "Validation failed."
|
||||
reservation_was_successfully_invalidated: "Reservation was successfully invalidated."
|
||||
invalidation_failed: "Invalidation failed."
|
||||
confirm_payment: "Confirm payment"
|
||||
confirm_payment_of_html: "{ROLE, select, admin{Cash} other{Pay}}: {AMOUNT}" #(contexte : validate a payment of $20,00)
|
||||
offer_this_reservation: "I offer this reservation"
|
||||
|
@ -647,17 +647,22 @@ fr:
|
||||
reservations: "Réservations"
|
||||
status: "Statut"
|
||||
gestion: "Gestion"
|
||||
validation: "Validation"
|
||||
event_status:
|
||||
pre_registered: "Pré-inscrit"
|
||||
to_pay: "À payer"
|
||||
paid: "Payé"
|
||||
canceled: "Annulée"
|
||||
affirmative: "Oui"
|
||||
negative: "Non"
|
||||
validate: "Valider"
|
||||
pay: "Payer"
|
||||
validate_the_reservation: "Valider la réservation"
|
||||
do_you_really_want_to_validate_this_reservation_this_apply_to_all_booked_tickets: "Êtes vous sur de vouloir valider cette réservation? Ceci s'applique à TOUTES les places réservées."
|
||||
reservation_was_successfully_validated: "La réservation a bien été validé."
|
||||
validation_failed: "La validation a échoué."
|
||||
reservation_was_successfully_invalidated: "La réservation a bien été invalidée."
|
||||
invalidation_failed: "L'invalidation a échoué."
|
||||
confirm_payment: "Confirmer le paiement"
|
||||
confirm_payment_of_html: "{ROLE, select, admin{Encaisser} other{Payer}} : {AMOUNT}" #(contexte : validate a payment of $20,00)
|
||||
offer_this_reservation: "J'offre cette réservation"
|
||||
|
@ -126,6 +126,7 @@ Rails.application.routes.draw do
|
||||
resources :slots_reservations, only: [:update] do
|
||||
put 'cancel', on: :member
|
||||
put 'validate', on: :member
|
||||
put 'invalidate', on: :member
|
||||
end
|
||||
|
||||
resources :events do
|
||||
|
@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# add is_valid to slots_reservations
|
||||
# remove validated_at from slots_reservations
|
||||
class AddIsValidToSlotsReservations < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
add_column :slots_reservations, :is_valid, :boolean
|
||||
SlotsReservation.reset_column_information
|
||||
SlotsReservation.all.each do |sr|
|
||||
sr.update_column(:is_valid, true) if sr.validated_at.present?
|
||||
end
|
||||
remove_column :slots_reservations, :validated_at
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :slots_reservations, :is_valid
|
||||
add_column :slots_reservations, :validated_at, :datetime
|
||||
end
|
||||
end
|
@ -9,6 +9,13 @@ SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Name: public; Type: SCHEMA; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
-- *not* creating schema, since initdb creates it
|
||||
|
||||
|
||||
--
|
||||
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
|
||||
--
|
||||
@ -3273,7 +3280,7 @@ CREATE TABLE public.slots_reservations (
|
||||
ex_end_at timestamp without time zone,
|
||||
canceled_at timestamp without time zone,
|
||||
offered boolean DEFAULT false,
|
||||
validated_at timestamp(6) without time zone
|
||||
is_valid boolean
|
||||
);
|
||||
|
||||
|
||||
@ -9056,17 +9063,18 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20230328094809'),
|
||||
('20230331132506'),
|
||||
('20230509121907'),
|
||||
('20230509161557');
|
||||
('20230510141305');
|
||||
('20230509161557'),
|
||||
('20230510141305'),
|
||||
('20230511080650'),
|
||||
('20230511081018');
|
||||
('20230511081018'),
|
||||
('20230524080448'),
|
||||
('20230524083558'),
|
||||
('20230524110215');
|
||||
('20230524110215'),
|
||||
('20230525101006'),
|
||||
('20230612123250'),
|
||||
('20230626103314'),
|
||||
('20230626122844'),
|
||||
('20230626122947');
|
||||
('20230612123250');
|
||||
('20230626103314');
|
||||
('20230626122947'),
|
||||
('20230710072403');
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user