1
0
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:
Du Peng 2023-07-11 10:36:44 +02:00
parent a8dedfe040
commit d271fa59e6
18 changed files with 112 additions and 47 deletions

View File

@ -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

View File

@ -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');

View File

@ -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'));
});
};

View File

@ -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
});
}

View File

@ -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,
}

View File

@ -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'
}
}
);

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -19,4 +19,8 @@ class SlotsReservationPolicy < ApplicationPolicy
def validate?
user.admin? || user.manager?
end
def invalidate?
user.admin? || user.manager?
end
end

View File

@ -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

View File

@ -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|

View File

@ -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?

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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');