mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-22 11:52:21 +01:00
(merge) merge branch pre_inscription
This commit is contained in:
commit
3f1d6bf378
@ -10,7 +10,7 @@ class API::ChildrenController < API::APIController
|
|||||||
authorize Child
|
authorize Child
|
||||||
user_id = current_user.id
|
user_id = current_user.id
|
||||||
user_id = params[:user_id] if current_user.privileged? && params[:user_id]
|
user_id = params[:user_id] if current_user.privileged? && params[:user_id]
|
||||||
@children = Child.where(user_id: user_id).includes(:supporting_document_files).order(:created_at)
|
@children = Child.where(user_id: user_id).where('birthday >= ?', 18.years.ago).includes(:supporting_document_files).order(:created_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
# availability by Availability.slot_duration, or otherwise globally by Setting.get('slot_duration')
|
# availability by Availability.slot_duration, or otherwise globally by Setting.get('slot_duration')
|
||||||
class API::SlotsReservationsController < API::APIController
|
class API::SlotsReservationsController < API::APIController
|
||||||
before_action :authenticate_user!
|
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
|
respond_to :json
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@ -28,6 +28,11 @@ class API::SlotsReservationsController < API::APIController
|
|||||||
SlotsReservationsService.validate(@slot_reservation)
|
SlotsReservationsService.validate(@slot_reservation)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invalidate
|
||||||
|
authorize @slot_reservation
|
||||||
|
SlotsReservationsService.invalidate(@slot_reservation)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_slots_reservation
|
def set_slots_reservation
|
||||||
|
@ -100,7 +100,7 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
|
|||||||
* Callback triggered when the user validates the machine form: handle create or update
|
* Callback triggered when the user validates the machine form: handle create or update
|
||||||
*/
|
*/
|
||||||
const onSubmit: SubmitHandler<Event> = (data: Event) => {
|
const onSubmit: SubmitHandler<Event> = (data: Event) => {
|
||||||
if (data.pre_registration_end_date.toString() === 'Invalid Date') {
|
if (data.pre_registration_end_date?.toString() === 'Invalid Date') {
|
||||||
data.pre_registration_end_date = null;
|
data.pre_registration_end_date = null;
|
||||||
}
|
}
|
||||||
if (action === 'update') {
|
if (action === 'update') {
|
||||||
|
@ -44,9 +44,9 @@ export const EventReservationItem: React.FC<EventReservationItemProps> = ({ rese
|
|||||||
* Return the pre-registration status
|
* Return the pre-registration status
|
||||||
*/
|
*/
|
||||||
const preRegistrationStatus = () => {
|
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');
|
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');
|
return t('app.logged.event_reservation_item.settle_your_payment');
|
||||||
} else if (reservation.is_paid && !reservation.canceled_at) {
|
} else if (reservation.is_paid && !reservation.canceled_at) {
|
||||||
return t('app.logged.event_reservation_item.paid');
|
return t('app.logged.event_reservation_item.paid');
|
||||||
|
@ -458,7 +458,7 @@ Application.Controllers.controller('ShowEventReservationsController', ['$scope',
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
$scope.isValidated = function (reservation) {
|
$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}
|
* @param reservation {Reservation}
|
||||||
*/
|
*/
|
||||||
$scope.validateReservation = function (reservation) {
|
$scope.validateReservation = function (reservation) {
|
||||||
dialogs.confirm({
|
SlotsReservation.validate({
|
||||||
resolve: {
|
id: reservation.slots_reservations_attributes[0].id
|
||||||
object: function () {
|
}, () => { // successfully validated
|
||||||
return {
|
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_validated'));
|
||||||
title: _t('app.admin.event_reservations.validate_the_reservation'),
|
const index = $scope.reservations.indexOf(reservation);
|
||||||
msg: _t('app.admin.event_reservations.do_you_really_want_to_validate_this_reservation_this_apply_to_all_booked_tickets')
|
$scope.reservations[index].slots_reservations_attributes[0].is_valid = true;
|
||||||
};
|
}, () => {
|
||||||
}
|
growl.warning(_t('app.admin.event_reservations.validation_failed'));
|
||||||
}
|
});
|
||||||
}, function () { // validate confirmed
|
};
|
||||||
SlotsReservation.validate({
|
|
||||||
id: reservation.slots_reservations_attributes[0].id
|
/**
|
||||||
}, () => { // successfully validated
|
* Callback to invalidate a reservation
|
||||||
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_validated'));
|
* @param reservation {Reservation}
|
||||||
const index = $scope.reservations.indexOf(reservation);
|
*/
|
||||||
$scope.reservations[index].slots_reservations_attributes[0].validated_at = new Date();
|
$scope.invalidateReservation = function (reservation) {
|
||||||
}, () => {
|
SlotsReservation.invalidate({
|
||||||
growl.warning(_t('app.admin.event_reservations.validation_failed'));
|
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'));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -511,6 +516,9 @@ Application.Controllers.controller('ShowEventReservationsController', ['$scope',
|
|||||||
templateUrl: '/admin/events/pay_reservation_modal.html',
|
templateUrl: '/admin/events/pay_reservation_modal.html',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
resolve: {
|
resolve: {
|
||||||
|
event () {
|
||||||
|
return $scope.event;
|
||||||
|
},
|
||||||
reservation () {
|
reservation () {
|
||||||
return reservation;
|
return reservation;
|
||||||
},
|
},
|
||||||
@ -524,8 +532,10 @@ Application.Controllers.controller('ShowEventReservationsController', ['$scope',
|
|||||||
return mkCartItems(reservation);
|
return mkCartItems(reservation);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
controller: ['$scope', '$uibModalInstance', 'reservation', 'price', 'wallet', 'cartItems', 'helpers', '$filter', '_t', 'Reservation',
|
controller: ['$scope', '$uibModalInstance', 'reservation', 'price', 'wallet', 'cartItems', 'helpers', '$filter', '_t', 'Reservation', 'event',
|
||||||
function ($scope, $uibModalInstance, reservation, price, wallet, cartItems, helpers, $filter, _t, Reservation) {
|
function ($scope, $uibModalInstance, reservation, price, wallet, cartItems, helpers, $filter, _t, Reservation, event) {
|
||||||
|
$scope.event = event;
|
||||||
|
|
||||||
// User's wallet amount
|
// User's wallet amount
|
||||||
$scope.wallet = wallet;
|
$scope.wallet = wallet;
|
||||||
|
|
||||||
@ -609,7 +619,11 @@ Application.Controllers.controller('ShowEventReservationsController', ['$scope',
|
|||||||
if (r.id === reservation.id) {
|
if (r.id === reservation.id) {
|
||||||
return reservation;
|
return reservation;
|
||||||
}
|
}
|
||||||
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_paid'));
|
if ($scope.event.amount === 0) {
|
||||||
|
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_present'));
|
||||||
|
} else {
|
||||||
|
growl.success(_t('app.admin.event_reservations.reservation_was_successfully_paid'));
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
|
@ -644,7 +644,7 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
|||||||
if (!user.booked) {
|
if (!user.booked) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($scope.enableChildValidationRequired && user.booked.type === 'Child' && !user.booked.validatedAt) {
|
if ($scope.enableChildValidationRequired && user.booked.type === 'Child' && !user.booked.validated_at) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,9 +675,10 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
|||||||
|
|
||||||
// get the current user's reservations into $scope.reservations
|
// get the current user's reservations into $scope.reservations
|
||||||
if ($scope.currentUser) {
|
if ($scope.currentUser) {
|
||||||
getReservations($scope.event.id, 'Event', $scope.currentUser.id);
|
getReservations($scope.event.id, 'Event', $scope.currentUser.id).then(function (reservations) {
|
||||||
getChildren($scope.currentUser.id).then(function (children) {
|
getChildren($scope.currentUser.id).then(function (children) {
|
||||||
updateNbReservePlaces();
|
updateNbReservePlaces();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,7 +697,7 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
|||||||
* @param user_id {number} the user's id (current or managed)
|
* @param user_id {number} the user's id (current or managed)
|
||||||
*/
|
*/
|
||||||
const getReservations = function (reservable_id, reservable_type, user_id) {
|
const getReservations = function (reservable_id, reservable_type, user_id) {
|
||||||
Reservation.query({
|
return Reservation.query({
|
||||||
reservable_id,
|
reservable_id,
|
||||||
reservable_type,
|
reservable_type,
|
||||||
user_id
|
user_id
|
||||||
@ -727,6 +728,14 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const r of $scope.reservations) {
|
||||||
|
for (const user of r.booking_users_attributes) {
|
||||||
|
const key = user.booked_type === 'User' ? `user_${user.booked_id}` : `child_${user.booked_id}`;
|
||||||
|
if (key === userKey) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -748,7 +757,7 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
|||||||
name: child.first_name + ' ' + child.last_name,
|
name: child.first_name + ' ' + child.last_name,
|
||||||
id: child.id,
|
id: child.id,
|
||||||
type: 'Child',
|
type: 'Child',
|
||||||
validatedAt: child.validated_at,
|
validated_at: child.validated_at,
|
||||||
birthday: child.birthday
|
birthday: child.birthday
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -761,7 +770,10 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
|||||||
*/
|
*/
|
||||||
const updateNbReservePlaces = function () {
|
const updateNbReservePlaces = function () {
|
||||||
if ($scope.event.event_type === 'family') {
|
if ($scope.event.event_type === 'family') {
|
||||||
const maxPlaces = $scope.children.length + 1;
|
const reservedPlaces = $scope.reservations.reduce((sum, reservation) => {
|
||||||
|
return sum + reservation.booking_users_attributes.length;
|
||||||
|
}, 0);
|
||||||
|
const maxPlaces = $scope.children.length + 1 - reservedPlaces;
|
||||||
if ($scope.event.nb_free_places > maxPlaces) {
|
if ($scope.event.nb_free_places > maxPlaces) {
|
||||||
$scope.reserve.nbPlaces.normal = __range__(0, maxPlaces, true);
|
$scope.reserve.nbPlaces.normal = __range__(0, maxPlaces, true);
|
||||||
for (let evt_px_cat of Array.from($scope.event.event_price_categories_attributes)) {
|
for (let evt_px_cat of Array.from($scope.event.event_price_categories_attributes)) {
|
||||||
@ -976,11 +988,11 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
|||||||
Reservation.get({ id: invoice.main_object.id }, function (reservation) {
|
Reservation.get({ id: invoice.main_object.id }, function (reservation) {
|
||||||
$scope.event.nb_free_places = $scope.event.nb_free_places - reservation.total_booked_seats;
|
$scope.event.nb_free_places = $scope.event.nb_free_places - reservation.total_booked_seats;
|
||||||
$scope.reservations.push(reservation);
|
$scope.reservations.push(reservation);
|
||||||
|
resetEventReserve();
|
||||||
|
updateNbReservePlaces();
|
||||||
|
$scope.reserveSuccess = true;
|
||||||
|
$scope.coupon.applied = null;
|
||||||
});
|
});
|
||||||
resetEventReserve();
|
|
||||||
updateNbReservePlaces();
|
|
||||||
$scope.reserveSuccess = true;
|
|
||||||
$scope.coupon.applied = null;
|
|
||||||
if ($scope.currentUser.role === 'admin') {
|
if ($scope.currentUser.role === 'admin') {
|
||||||
return $scope.ctrl.member = null;
|
return $scope.ctrl.member = null;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,8 @@ export interface Reservation {
|
|||||||
event_type?: string,
|
event_type?: string,
|
||||||
event_title?: string,
|
event_title?: string,
|
||||||
event_pre_registration?: boolean
|
event_pre_registration?: boolean
|
||||||
validated_at?: TDateISO,
|
canceled_at?: TDateISO,
|
||||||
|
is_valid?: boolean,
|
||||||
is_paid?: boolean,
|
is_paid?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,10 @@ Application.Services.factory('SlotsReservation', ['$resource', function ($resour
|
|||||||
validate: {
|
validate: {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: '/api/slots_reservations/:id/validate'
|
url: '/api/slots_reservations/:id/validate'
|
||||||
|
},
|
||||||
|
invalidate: {
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/api/slots_reservations/:id/invalidate'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,45 +1,52 @@
|
|||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<img ng-src="{{logoBlack.custom_asset_file_attributes.attachment_url}}" alt="{{logo.custom_asset_file_attributes.attachment}}" class="modal-logo"/>
|
<img ng-src="{{logoBlack.custom_asset_file_attributes.attachment_url}}" alt="{{logo.custom_asset_file_attributes.attachment}}" class="modal-logo"/>
|
||||||
<h1 translate ng-show="reservation">{{ 'app.admin.event_reservations.confirm_payment' }}</h1>
|
<h1 translate ng-show="reservation && event.amount !== 0">{{ 'app.admin.event_reservations.confirm_payment' }}</h1>
|
||||||
|
<h1 translate ng-show="reservation && event.amount === 0">{{ 'app.admin.event_reservations.confirm_present' }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<uib-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</uib-alert>
|
<div ng-show="event.amount !== 0">
|
||||||
<div class="row" ng-show="!offered">
|
<div class="row" ng-show="!offered">
|
||||||
<wallet-info current-user="currentUser"
|
<wallet-info current-user="currentUser"
|
||||||
cart="cartItems"
|
cart="cartItems"
|
||||||
price="price.price"
|
price="price.price"
|
||||||
wallet="wallet"/>
|
wallet="wallet"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="row m-b">
|
<div class="row m-b">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<label for="offerSlot" class="control-label m-r" translate>{{ 'app.admin.event_reservations.offer_this_reservation' }}</label>
|
<label for="offerSlot" class="control-label m-r" translate>{{ 'app.admin.event_reservations.offer_this_reservation' }}</label>
|
||||||
<input bs-switch
|
<input bs-switch
|
||||||
ng-model="offered"
|
ng-model="offered"
|
||||||
id="offerSlot"
|
id="offerSlot"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
switch-on-text="{{ 'app.shared.buttons.yes' | translate }}"
|
switch-on-text="{{ 'app.shared.buttons.yes' | translate }}"
|
||||||
switch-off-text="{{ 'app.shared.buttons.no' | translate }}"
|
switch-off-text="{{ 'app.shared.buttons.no' | translate }}"
|
||||||
switch-animate="true"
|
switch-animate="true"
|
||||||
ng-change="computeEventAmount()"/>
|
ng-change="computeEventAmount()"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<coupon show="true" coupon="coupon.applied" total="price.price_without_coupon" user-id="{{reservation.user_id}}"></coupon>
|
<coupon show="true" coupon="coupon.applied" total="price.price_without_coupon" user-id="{{reservation.user_id}}"></coupon>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-sm-12">
|
<div class="form-group col-sm-12">
|
||||||
<div class="checkbox-group">
|
<div class="checkbox-group">
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
name="paymentReceived"
|
name="paymentReceived"
|
||||||
id="paymentReceived"
|
id="paymentReceived"
|
||||||
ng-model="payment" />
|
ng-model="payment" />
|
||||||
<label for="paymentReceived" translate>{{ 'app.admin.event_reservations.i_have_received_the_payment' }}</label>
|
<label for="paymentReceived" translate>{{ 'app.admin.event_reservations.i_have_received_the_payment' }}</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div ng-if="event.amount === 0">
|
||||||
|
<p translate>{{ 'app.admin.event_reservations.confirm_present_info' }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-info" ng-click="ok()" ng-disabled="attempting || !payment" ng-bind-html="validButtonName"></button>
|
<button class="btn btn-info" ng-if="event.amount !== 0" ng-click="ok()" ng-disabled="attempting || !payment" ng-bind-html="validButtonName"></button>
|
||||||
|
<button class="btn btn-info" ng-if="event.amount === 0" ng-click="ok()" ng-disabled="attempting" ng-bind-html="validButtonName"></button>
|
||||||
<button class="btn btn-default" ng-click="cancel()" translate>{{ 'app.shared.buttons.cancel' }}</button>
|
<button class="btn btn-default" ng-click="cancel()" translate>{{ 'app.shared.buttons.cancel' }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
<table class="table" ng-if="reservations.length > 0">
|
<table class="table" ng-if="reservations.length > 0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width:25%" translate>{{ 'app.admin.event_reservations.booked_by' }}</th>
|
<th translate>{{ 'app.admin.event_reservations.booked_by' }}</th>
|
||||||
<th style="width:25%" translate>{{ 'app.admin.event_reservations.reservations' }}</th>
|
<th translate>{{ 'app.admin.event_reservations.reservations' }}</th>
|
||||||
<th style="width:25%" translate>{{ 'app.admin.event_reservations.date' }}</th>
|
<th translate>{{ 'app.admin.event_reservations.date' }}</th>
|
||||||
<th style="width:25%" translate>{{ 'app.admin.event_reservations.reserved_tickets' }}</th>
|
<th translate>{{ 'app.admin.event_reservations.reserved_tickets' }}</th>
|
||||||
<th ng-if="event.pre_registration" style="width:25%" translate>{{ 'app.admin.event_reservations.status' }}</th>
|
<th ng-if="event.pre_registration" translate>{{ 'app.admin.event_reservations.status' }}</th>
|
||||||
<th ng-if="event.pre_registration" style="width:25%" translate>{{ 'app.admin.event_reservations.gestion' }}</th>
|
<th ng-if="event.pre_registration" translate>{{ 'app.admin.event_reservations.validation' }}</th>
|
||||||
<th style="width:5%"></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -38,6 +38,7 @@
|
|||||||
<span ng-if="event.event_type === 'standard'">{{ reservation.user_full_name }} </span>
|
<span ng-if="event.event_type === 'standard'">{{ reservation.user_full_name }} </span>
|
||||||
<div ng-repeat="bu in reservation.booking_users_attributes">
|
<div ng-repeat="bu in reservation.booking_users_attributes">
|
||||||
<span>{{bu.name}}</span>
|
<span>{{bu.name}}</span>
|
||||||
|
<span ng-if="bu.booked_type === 'Child'" class="m-l-sm">({{ 'app.admin.event_reservations.age' | translate:{NUMBER: bu.age} }})</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ reservation.created_at | amDateFormat:'LL LTS' }}</td>
|
<td>{{ reservation.created_at | amDateFormat:'LL LTS' }}</td>
|
||||||
@ -48,16 +49,27 @@
|
|||||||
<td ng-if="event.pre_registration">
|
<td ng-if="event.pre_registration">
|
||||||
<span ng-if="!isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" class="v-middle badge text-sm bg-info" translate="">{{ 'app.admin.event_reservations.event_status.pre_registered' }}</span>
|
<span ng-if="!isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" class="v-middle badge text-sm bg-info" translate="">{{ 'app.admin.event_reservations.event_status.pre_registered' }}</span>
|
||||||
<span ng-if="isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" class="v-middle badge text-sm bg-stage" translate="">{{ 'app.admin.event_reservations.event_status.to_pay' }}</span>
|
<span ng-if="isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" class="v-middle badge text-sm bg-stage" translate="">{{ 'app.admin.event_reservations.event_status.to_pay' }}</span>
|
||||||
<span ng-if="reservation.is_paid && !isCancelled(reservation)" class="v-middle badge text-sm bg-success" translate="">{{ 'app.admin.event_reservations.event_status.paid' }}</span>
|
<span ng-if="event.amount !== 0 && reservation.is_paid && !isCancelled(reservation)" class="v-middle badge text-sm bg-success" translate="">{{ 'app.admin.event_reservations.event_status.paid' }}</span>
|
||||||
|
<span ng-if="event.amount === 0 && reservation.is_paid && !isCancelled(reservation)" class="v-middle badge text-sm bg-success" translate="">{{ 'app.admin.event_reservations.event_status.present' }}</span>
|
||||||
<span ng-if="isCancelled(reservation)" class="v-middle badge text-sm bg-event" translate="">{{ 'app.admin.event_reservations.event_status.canceled' }}</span>
|
<span ng-if="isCancelled(reservation)" class="v-middle badge text-sm bg-event" translate="">{{ 'app.admin.event_reservations.event_status.canceled' }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td ng-if="event.pre_registration">
|
<td ng-if="event.pre_registration">
|
||||||
<button class="btn btn-default" ng-click="validateReservation(reservation)" ng-if="!isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" translate>
|
<div>
|
||||||
{{ 'app.admin.event_reservations.validate' }}
|
<div ng-if="!isCancelled(reservation) && !reservation.is_paid">
|
||||||
</button>
|
<label class="m-r-sm">
|
||||||
<button class="btn btn-default" ng-click="payReservation(reservation)" ng-if="isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid" translate>
|
<span translate>{{ 'app.admin.event_reservations.negative' }}</span>
|
||||||
{{ 'app.admin.event_reservations.pay' }}
|
<input type="radio" name="validate" ng-value="false" ng-click="invalidateReservation(reservation)" ng-model="reservation.slots_reservations_attributes[0].is_valid" >
|
||||||
</button>
|
</label>
|
||||||
|
<label>
|
||||||
|
<span translate>{{ 'app.admin.event_reservations.affirmative' }}</span>
|
||||||
|
<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="payReservation(reservation)" ng-if="isValidated(reservation) && !isCancelled(reservation) && !reservation.is_paid">
|
||||||
|
<span ng-if="event.amount !== 0" translate>{{ 'app.admin.event_reservations.pay' }}</span>
|
||||||
|
<span ng-if="event.amount === 0" translate>{{ 'app.admin.event_reservations.present' }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
|
@ -142,7 +142,7 @@
|
|||||||
class="form-control">
|
class="form-control">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
</select>
|
</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.validated_at" style="margin-bottom: 0.8rem;">
|
||||||
<span class="text-sm">
|
<span class="text-sm">
|
||||||
<i class="fa fa-warning"></i>
|
<i class="fa fa-warning"></i>
|
||||||
<span translate>{{ 'app.shared.cart.child_validation_required_alert' }}</span>
|
<span translate>{{ 'app.shared.cart.child_validation_required_alert' }}</span>
|
||||||
@ -180,7 +180,7 @@
|
|||||||
class="form-control">
|
class="form-control">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
</select>
|
</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">
|
<p class="text-sm">
|
||||||
<i class="fa fa-warning"></i>
|
<i class="fa fa-warning"></i>
|
||||||
<span translate>{{ 'app.shared.cart.child_validation_required_alert' }}</span>
|
<span translate>{{ 'app.shared.cart.child_validation_required_alert' }}</span>
|
||||||
|
@ -89,7 +89,7 @@ class Event < ApplicationRecord
|
|||||||
else
|
else
|
||||||
reserved_places = reservations.joins(:slots_reservations)
|
reserved_places = reservations.joins(:slots_reservations)
|
||||||
.where('slots_reservations.canceled_at': nil)
|
.where('slots_reservations.canceled_at': nil)
|
||||||
.where.not('slots_reservations.validated_at': nil)
|
.where('slots_reservations.is_valid': true)
|
||||||
.map(&:total_booked_seats)
|
.map(&:total_booked_seats)
|
||||||
.inject(0) { |sum, t| sum + t }
|
.inject(0) { |sum, t| sum + t }
|
||||||
self.nb_free_places = (nb_total_places - reserved_places)
|
self.nb_free_places = (nb_total_places - reserved_places)
|
||||||
@ -99,7 +99,7 @@ class Event < ApplicationRecord
|
|||||||
def nb_places_for_pre_registration
|
def nb_places_for_pre_registration
|
||||||
reservations.joins(:slots_reservations)
|
reservations.joins(:slots_reservations)
|
||||||
.where('slots_reservations.canceled_at': nil)
|
.where('slots_reservations.canceled_at': nil)
|
||||||
.where('slots_reservations.validated_at': nil)
|
.where('slots_reservations.is_valid': nil)
|
||||||
.map(&:total_booked_seats)
|
.map(&:total_booked_seats)
|
||||||
.inject(0) { |sum, t| sum + t }
|
.inject(0) { |sum, t| sum + t }
|
||||||
end
|
end
|
||||||
|
@ -19,4 +19,8 @@ class SlotsReservationPolicy < ApplicationPolicy
|
|||||||
def validate?
|
def validate?
|
||||||
user.admin? || user.manager?
|
user.admin? || user.manager?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invalidate?
|
||||||
|
user.admin? || user.manager?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -23,7 +23,7 @@ class SlotsReservationsService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def validate(slot_reservation)
|
def validate(slot_reservation)
|
||||||
if slot_reservation.update(validated_at: Time.current)
|
if slot_reservation.update(is_valid: true)
|
||||||
reservable = slot_reservation.reservation.reservable
|
reservable = slot_reservation.reservation.reservable
|
||||||
if reservable.is_a?(Event)
|
if reservable.is_a?(Event)
|
||||||
reservable.update_nb_free_places
|
reservable.update_nb_free_places
|
||||||
@ -39,5 +39,23 @@ class SlotsReservationsService
|
|||||||
end
|
end
|
||||||
false
|
false
|
||||||
end
|
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
|
||||||
|
NotificationCenter.call type: 'notify_member_reservation_invalidated',
|
||||||
|
receiver: slot_reservation.reservation.user,
|
||||||
|
attached_object: slot_reservation.reservation
|
||||||
|
NotificationCenter.call type: 'notify_admin_reservation_invalidated',
|
||||||
|
receiver: User.admins_and_managers,
|
||||||
|
attached_object: slot_reservation.reservation
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -18,7 +18,7 @@ json.array!(@members) do |member|
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
json.validated_at member.validated_at
|
json.validated_at member.validated_at
|
||||||
json.children member.children.order(:created_at) do |child|
|
json.children member.children.where('birthday >= ?', 18.years.ago).order(:created_at) do |child|
|
||||||
json.extract! child, :id, :first_name, :last_name, :email, :birthday, :phone, :user_id, :validated_at
|
json.extract! child, :id, :first_name, :last_name, :email, :birthday, :phone, :user_id, :validated_at
|
||||||
json.supporting_document_files_attributes child.supporting_document_files do |f|
|
json.supporting_document_files_attributes child.supporting_document_files do |f|
|
||||||
json.id f.id
|
json.id f.id
|
||||||
|
@ -87,7 +87,7 @@ json.events_reservations @member.reservations.where(reservable_type: 'Event').jo
|
|||||||
json.event_type sr.reservation.reservable.event_type
|
json.event_type sr.reservation.reservable.event_type
|
||||||
json.event_title sr.reservation.reservable.title
|
json.event_title sr.reservation.reservable.title
|
||||||
json.event_pre_registration sr.reservation.reservable.pre_registration
|
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.is_paid sr.reservation.invoice_items.count.positive?
|
||||||
json.canceled_at sr.canceled_at
|
json.canceled_at sr.canceled_at
|
||||||
json.booking_users_attributes sr.reservation.booking_users.order(booked_type: :desc) do |bu|
|
json.booking_users_attributes sr.reservation.booking_users.order(booked_type: :desc) do |bu|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
json.title notification.notification_type
|
||||||
|
json.description t('.a_RESERVABLE_reservation_was_invalidated_html',
|
||||||
|
RESERVABLE: notification.attached_object.reservable.name,
|
||||||
|
NAME: notification.attached_object.user&.profile&.full_name || t('api.notifications.deleted_user'))
|
@ -0,0 +1,3 @@
|
|||||||
|
json.title notification.notification_type
|
||||||
|
json.description t('.your_reservation_RESERVABLE_was_invalidated_html',
|
||||||
|
RESERVABLE: notification.attached_object.reservable.name)
|
@ -0,0 +1,6 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
json.title notification.notification_type
|
||||||
|
json.description t('.child_age_will_be_18_years_ago',
|
||||||
|
NAME: notification.attached_object.full_name,
|
||||||
|
DATE: I18n.l(notification.attached_object.birthday, format: :default))
|
@ -7,7 +7,7 @@ json.message reservation.message
|
|||||||
json.slots_reservations_attributes reservation.slots_reservations do |sr|
|
json.slots_reservations_attributes reservation.slots_reservations do |sr|
|
||||||
json.id sr.id
|
json.id sr.id
|
||||||
json.canceled_at sr.canceled_at&.iso8601
|
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_id sr.slot_id
|
||||||
json.slot_attributes do
|
json.slot_attributes do
|
||||||
json.id sr.slot_id
|
json.id sr.slot_id
|
||||||
@ -40,5 +40,7 @@ json.booking_users_attributes reservation.booking_users.order(booked_type: :desc
|
|||||||
json.event_price_category_id bu.event_price_category_id
|
json.event_price_category_id bu.event_price_category_id
|
||||||
json.booked_id bu.booked_id
|
json.booked_id bu.booked_id
|
||||||
json.booked_type bu.booked_type
|
json.booked_type bu.booked_type
|
||||||
|
json.age ((Time.zone.now - bu.booked.birthday.to_time) / 1.year.seconds).floor if bu.booked_type == 'Child'
|
||||||
end
|
end
|
||||||
|
json.is_valid reservation.slots_reservations[0].is_valid
|
||||||
json.is_paid reservation.invoice_items.count.positive?
|
json.is_paid reservation.invoice_items.count.positive?
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= t('.body.reservation_invalidated_html',
|
||||||
|
NAME: @attached_object.user&.profile&.full_name || t('api.notifications.deleted_user'),
|
||||||
|
RESERVABLE: @attached_object.reservable.name) %>
|
||||||
|
</p>
|
@ -0,0 +1,3 @@
|
|||||||
|
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||||
|
|
||||||
|
<p><%= t('.body.reservation_invalidated_html', RESERVATION: @attached_object.reservable.name) %></p>
|
@ -0,0 +1,6 @@
|
|||||||
|
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||||
|
|
||||||
|
<%= t('.body.child_age_will_be_18_years_ago', **{
|
||||||
|
NAME: @attached_object.full_name,
|
||||||
|
DATE: I18n.l(@attached_object.birthday, format: :default),
|
||||||
|
}) %>
|
15
app/workers/child_age_worker.rb
Normal file
15
app/workers/child_age_worker.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# send a notification if child age > 18 years ago
|
||||||
|
class ChildAgeWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
|
||||||
|
def perform
|
||||||
|
children = Child.where('birthday = ?', 18.years.ago + 2.days)
|
||||||
|
children.each do |child|
|
||||||
|
NotificationCenter.call type: 'notify_user_when_child_age_will_be_18',
|
||||||
|
receiver: child.user,
|
||||||
|
attached_object: child
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -647,22 +647,33 @@ en:
|
|||||||
reservations: "Reservations"
|
reservations: "Reservations"
|
||||||
status: "Status"
|
status: "Status"
|
||||||
gestion: "Gestion"
|
gestion: "Gestion"
|
||||||
|
validation: "Validation"
|
||||||
event_status:
|
event_status:
|
||||||
pre_registered: "Pre-registered"
|
pre_registered: "Pre-registered"
|
||||||
to_pay: "To pay"
|
to_pay: "To pay"
|
||||||
paid: "Paid"
|
paid: "Paid"
|
||||||
canceled: "Canceled"
|
canceled: "Canceled"
|
||||||
|
present: "Present"
|
||||||
|
affirmative: "yes"
|
||||||
|
negative: "no"
|
||||||
validate: "Validate"
|
validate: "Validate"
|
||||||
pay: "Pay"
|
pay: "Pay"
|
||||||
validate_the_reservation: "Validate the reservation"
|
validate_the_reservation: "Validate the reservation"
|
||||||
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."
|
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."
|
reservation_was_successfully_validated: "Reservation was successfully validated."
|
||||||
validation_failed: "Validation failed."
|
validation_failed: "Validation failed."
|
||||||
|
reservation_was_successfully_invalidated: "Reservation was successfully invalidated."
|
||||||
|
invalidation_failed: "Invalidation failed."
|
||||||
confirm_payment: "Confirm payment"
|
confirm_payment: "Confirm payment"
|
||||||
confirm_payment_of_html: "{ROLE, select, admin{Cash} other{Pay}}: {AMOUNT}" #(contexte : validate a payment of $20,00)
|
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"
|
offer_this_reservation: "I offer this reservation"
|
||||||
i_have_received_the_payment: "I have received the payment"
|
i_have_received_the_payment: "I have received the payment"
|
||||||
reservation_was_successfully_paid: "Reservation was successfully paid."
|
reservation_was_successfully_paid: "Reservation was successfully paid."
|
||||||
|
present: "Present"
|
||||||
|
confirm_present: "Confirm presence"
|
||||||
|
confirm_present_info: "Confirm the presence of the user for this event"
|
||||||
|
reservation_was_successfully_present: "The presence of the user was successfully confirmed."
|
||||||
|
age: "{NUMBER} years old"
|
||||||
events_settings:
|
events_settings:
|
||||||
title: "Settings"
|
title: "Settings"
|
||||||
generic_text_block: "Editorial text block"
|
generic_text_block: "Editorial text block"
|
||||||
|
@ -647,22 +647,33 @@ fr:
|
|||||||
reservations: "Réservations"
|
reservations: "Réservations"
|
||||||
status: "Statut"
|
status: "Statut"
|
||||||
gestion: "Gestion"
|
gestion: "Gestion"
|
||||||
|
validation: "Validation"
|
||||||
event_status:
|
event_status:
|
||||||
pre_registered: "Pré-inscrit"
|
pre_registered: "Pré-inscrit"
|
||||||
to_pay: "À payer"
|
to_pay: "À payer"
|
||||||
paid: "Payé"
|
paid: "Payé"
|
||||||
canceled: "Annulée"
|
canceled: "Annulée"
|
||||||
|
present: "Présent"
|
||||||
|
affirmative: "Oui"
|
||||||
|
negative: "Non"
|
||||||
validate: "Valider"
|
validate: "Valider"
|
||||||
pay: "Payer"
|
pay: "Payer"
|
||||||
validate_the_reservation: "Valider la réservation"
|
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."
|
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é."
|
reservation_was_successfully_validated: "La réservation a bien été validé."
|
||||||
validation_failed: "La validation a échoué."
|
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: "Confirmer le paiement"
|
||||||
confirm_payment_of_html: "{ROLE, select, admin{Encaisser} other{Payer}} : {AMOUNT}" #(contexte : validate a payment of $20,00)
|
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"
|
offer_this_reservation: "J'offre cette réservation"
|
||||||
i_have_received_the_payment: "J'ai reçu le paiement"
|
i_have_received_the_payment: "J'ai reçu le paiement"
|
||||||
reservation_was_successfully_paid: "La réservation a bien été payée."
|
reservation_was_successfully_paid: "La réservation a bien été payée."
|
||||||
|
present: "Présenter"
|
||||||
|
confirm_present: "Confirmer la présence"
|
||||||
|
confirm_present_info: "Confirmer la présence de l'utilisateur à l'événement"
|
||||||
|
reservation_was_successfully_present: "La présence a bien été confirmée."
|
||||||
|
age: "{NUMBER} ans"
|
||||||
events_settings:
|
events_settings:
|
||||||
title: "Paramètres"
|
title: "Paramètres"
|
||||||
generic_text_block: "Bloc de texte rédactionnel"
|
generic_text_block: "Bloc de texte rédactionnel"
|
||||||
|
@ -336,9 +336,9 @@ fr:
|
|||||||
ticket: "{NUMBER, plural, =0{place} one{place} other{places}}"
|
ticket: "{NUMBER, plural, =0{place} one{place} other{places}}"
|
||||||
make_a_gift_of_this_reservation: "Offrir cette réservation"
|
make_a_gift_of_this_reservation: "Offrir cette réservation"
|
||||||
thank_you_your_payment_has_been_successfully_registered: "Merci. Votre paiement a bien été pris en compte !"
|
thank_you_your_payment_has_been_successfully_registered: "Merci. Votre paiement a bien été pris en compte !"
|
||||||
thank_you_your_pre_registration_has_been_successfully_saved: "Merci. Votre demande a bien été pris en compte !"
|
thank_you_your_pre_registration_has_been_successfully_saved: "Merci. Votre demande a bien été prise en compte !"
|
||||||
you_can_find_your_reservation_s_details_on_your_: "Vous pouvez retrouver le détail de votre réservation sur votre"
|
you_can_find_your_reservation_s_details_on_your_: "Vous pouvez retrouver le détail de votre réservation sur votre"
|
||||||
informed_by_email_your_pre_registration: "vous serez tenu informé par email de la suite donnée à votre pré-inscription"
|
informed_by_email_your_pre_registration: "Vous serez tenu informé par email de la suite donnée à votre pré-inscription"
|
||||||
dashboard: "tableau de bord"
|
dashboard: "tableau de bord"
|
||||||
you_booked_DATE: "Vous avez réservé ({DATE}) :"
|
you_booked_DATE: "Vous avez réservé ({DATE}) :"
|
||||||
you_pre_booked_DATE: "Votre pré-inscription ({DATE}) :"
|
you_pre_booked_DATE: "Votre pré-inscription ({DATE}) :"
|
||||||
|
@ -477,6 +477,12 @@ en:
|
|||||||
your_reservation_RESERVABLE_was_validated_html: "Your reservation <strong><em>%{RESERVABLE}</em></strong> was successfully validated."
|
your_reservation_RESERVABLE_was_validated_html: "Your reservation <strong><em>%{RESERVABLE}</em></strong> was successfully validated."
|
||||||
notify_admin_reservation_validated:
|
notify_admin_reservation_validated:
|
||||||
a_RESERVABLE_reservation_was_validated_html: "A <strong><em>%{RESERVABLE}</em></strong> reservation of <strong><em>%{USER}</em></strong> was validated."
|
a_RESERVABLE_reservation_was_validated_html: "A <strong><em>%{RESERVABLE}</em></strong> reservation of <strong><em>%{USER}</em></strong> was validated."
|
||||||
|
notify_member_reservation_invalidated:
|
||||||
|
your_reservation_RESERVABLE_was_invalidated_html: "Your pre-registration of <strong><em>%{RESERVABLE}</em></strong> wasn't validated."
|
||||||
|
notify_admin_reservation_invalidated:
|
||||||
|
a_RESERVABLE_reservation_was_invalidated_html: "A <strong><em>%{RESERVABLE}</em></strong> pre-registration of <strong><em>%{USER}</em></strong> was invalidated."
|
||||||
|
notify_user_when_child_age_will_be_18:
|
||||||
|
child_age_will_be_18_years_ago: "Your child %{NAME} will turn 18 on %{DATE}, at which point they will be automatically detached from your Family account. They will need to create their own account in order to make reservations."
|
||||||
#statistics tools for admins
|
#statistics tools for admins
|
||||||
statistics:
|
statistics:
|
||||||
subscriptions: "Subscriptions"
|
subscriptions: "Subscriptions"
|
||||||
|
@ -477,6 +477,12 @@ fr:
|
|||||||
your_reservation_RESERVABLE_was_validated_html: "Votre réservation de <strong><em>%{RESERVABLE}</em></strong> a été validée."
|
your_reservation_RESERVABLE_was_validated_html: "Votre réservation de <strong><em>%{RESERVABLE}</em></strong> a été validée."
|
||||||
notify_admin_reservation_validated:
|
notify_admin_reservation_validated:
|
||||||
a_RESERVABLE_reservation_was_validated_html: "La réservation de <strong><em>%{RESERVABLE}</em></strong> de <strong><em>%{NAME}</em></strong> a été validée."
|
a_RESERVABLE_reservation_was_validated_html: "La réservation de <strong><em>%{RESERVABLE}</em></strong> de <strong><em>%{NAME}</em></strong> a été validée."
|
||||||
|
notify_member_reservation_invalidated:
|
||||||
|
your_reservation_RESERVABLE_was_invalidated_html: "Votre demande de pré-inscription de <strong><em>%{RESERVABLE}</em></strong> n'a pas été validée."
|
||||||
|
notify_admin_reservation_invalidated:
|
||||||
|
a_RESERVABLE_reservation_was_invalidated_html: "La réservation de <strong><em>%{RESERVABLE}</em></strong> de <strong><em>%{NAME}</em></strong> a été invalidée."
|
||||||
|
notify_user_when_child_age_will_be_18:
|
||||||
|
child_age_will_be_18_years_ago: "Votre enfant %{NAME} va avoir 18ans, le %{DATE}, date à laquelle il sera automatiquement détaché de votre compte Famille. Il devra se créer son propre compte pour effectuer ses réservations."
|
||||||
#statistics tools for admins
|
#statistics tools for admins
|
||||||
statistics:
|
statistics:
|
||||||
subscriptions: "Abonnements"
|
subscriptions: "Abonnements"
|
||||||
|
@ -467,7 +467,19 @@ en:
|
|||||||
reservation_validated_html: "<strong><em>%{RESERVABLE}</em></strong> was validated."
|
reservation_validated_html: "<strong><em>%{RESERVABLE}</em></strong> was validated."
|
||||||
your_reserved_slots: "Your reserved slots are:"
|
your_reserved_slots: "Your reserved slots are:"
|
||||||
notify_admin_reservation_validated:
|
notify_admin_reservation_validated:
|
||||||
subject: "Réservation a bien été validé"
|
subject: "Pre-registration was validated"
|
||||||
body:
|
body:
|
||||||
reservation_validated_html: "<strong><em>%{RESERVABLE}</em></strong> of %{NAME} was validated."
|
reservation_validated_html: "<strong><em>%{RESERVABLE}</em></strong> of %{NAME} was validated."
|
||||||
reserved_slots: "Reserved slots are:"
|
reserved_slots: "Reserved slots are:"
|
||||||
|
notify_member_reservation_invalidated:
|
||||||
|
subject: "Your pre-registration wasn't validated"
|
||||||
|
body:
|
||||||
|
reservation_invalidated_html: "<strong><em>%{RESERVABLE}</em></strong> wasn't validated."
|
||||||
|
notify_admin_reservation_invalidated:
|
||||||
|
subject: "Pre-registration wasn't validated"
|
||||||
|
body:
|
||||||
|
reservation_invalidated_html: "<strong><em>%{RESERVABLE}</em></strong> of %{NAME} wasn't validated."
|
||||||
|
notify_user_when_child_age_will_be_18:
|
||||||
|
subject: "Your child will be 18 years old"
|
||||||
|
body:
|
||||||
|
child_age_will_be_18_years_ago: "Your child %{NAME} will turn 18 on %{DATE}, at which point they will be automatically detached from your Family account. They will need to create their own account in order to make reservations."
|
||||||
|
@ -471,3 +471,15 @@ fr:
|
|||||||
body:
|
body:
|
||||||
reservation_validated_html: "<strong><em>%{RESERVABLE}</em></strong> du membre %{NAME} a bien été validé."
|
reservation_validated_html: "<strong><em>%{RESERVABLE}</em></strong> du membre %{NAME} a bien été validé."
|
||||||
reserved_slots: "Les créneaux réservés sont :"
|
reserved_slots: "Les créneaux réservés sont :"
|
||||||
|
notify_member_reservation_invalidated:
|
||||||
|
subject: "Votre demande of pré-inscription n'a pas été validée"
|
||||||
|
body:
|
||||||
|
reservation_invalidated_html: "Votre réservation <strong><em>%{RESERVATION}</em></strong> n'a pas été validée."
|
||||||
|
notify_admin_reservation_invalidated:
|
||||||
|
subject: "Demande of pré-inscription n'a pas été validée"
|
||||||
|
body:
|
||||||
|
reservation_invalidated_html: "<strong><em>%{RESERVABLE}</em></strong> du membre %{NAME} n'a pas été validée."
|
||||||
|
notify_user_when_child_age_will_be_18:
|
||||||
|
subject: "Votre enfant va avoir 18ans"
|
||||||
|
body:
|
||||||
|
child_age_will_be_18_years_ago: "Votre enfant %{NAME} va avoir 18ans, le %{DATE}, date à laquelle il sera automatiquement détaché de votre compte Famille. Il devra se créer son propre compte pour effectuer ses réservations."
|
||||||
|
@ -126,6 +126,7 @@ Rails.application.routes.draw do
|
|||||||
resources :slots_reservations, only: [:update] do
|
resources :slots_reservations, only: [:update] do
|
||||||
put 'cancel', on: :member
|
put 'cancel', on: :member
|
||||||
put 'validate', on: :member
|
put 'validate', on: :member
|
||||||
|
put 'invalidate', on: :member
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :events do
|
resources :events do
|
||||||
|
@ -62,4 +62,9 @@ auto_cancel_authorizations:
|
|||||||
class: TrainingAuthorizationWorker
|
class: TrainingAuthorizationWorker
|
||||||
queue: default
|
queue: default
|
||||||
|
|
||||||
|
child_age_will_be_18:
|
||||||
|
cron: "0 0 0 * * *" # every day, at midnight
|
||||||
|
class: ChildAgeWorker
|
||||||
|
queue: default
|
||||||
|
|
||||||
<%= PluginRegistry.insert_code('yml.schedule') %>
|
<%= PluginRegistry.insert_code('yml.schedule') %>
|
||||||
|
@ -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
|
@ -92,7 +92,10 @@ NOTIFICATIONS_TYPES = [
|
|||||||
{ name: 'notify_member_reservation_validated', category: 'agenda', is_configurable: false },
|
{ name: 'notify_member_reservation_validated', category: 'agenda', is_configurable: false },
|
||||||
{ name: 'notify_admin_reservation_validated', category: 'agenda', is_configurable: true },
|
{ name: 'notify_admin_reservation_validated', category: 'agenda', is_configurable: true },
|
||||||
{ name: 'notify_member_pre_booked_reservation', category: 'agenda', is_configurable: false },
|
{ name: 'notify_member_pre_booked_reservation', category: 'agenda', is_configurable: false },
|
||||||
{ name: 'notify_admin_member_pre_booked_reservation', category: 'agenda', is_configurable: true }
|
{ name: 'notify_admin_member_pre_booked_reservation', category: 'agenda', is_configurable: true },
|
||||||
|
{ name: 'notify_member_reservation_invalidated', category: 'agenda', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_reservation_invalidated', category: 'agenda', is_configurable: true },
|
||||||
|
{ name: 'notify_user_when_child_age_will_be_18', category: 'users_accounts', is_configurable: false },
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
NOTIFICATIONS_TYPES.each do |notification_type|
|
NOTIFICATIONS_TYPES.each do |notification_type|
|
||||||
|
@ -9,6 +9,13 @@ SET xmloption = content;
|
|||||||
SET client_min_messages = warning;
|
SET client_min_messages = warning;
|
||||||
SET row_security = off;
|
SET row_security = off;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: public; Type: SCHEMA; Schema: -; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
-- *not* creating schema, since initdb creates it
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
|
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
|
||||||
--
|
--
|
||||||
@ -3273,7 +3280,7 @@ CREATE TABLE public.slots_reservations (
|
|||||||
ex_end_at timestamp without time zone,
|
ex_end_at timestamp without time zone,
|
||||||
canceled_at timestamp without time zone,
|
canceled_at timestamp without time zone,
|
||||||
offered boolean DEFAULT false,
|
offered boolean DEFAULT false,
|
||||||
validated_at timestamp(6) without time zone
|
is_valid boolean
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -9064,9 +9071,10 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||||||
('20230524083558'),
|
('20230524083558'),
|
||||||
('20230524110215'),
|
('20230524110215'),
|
||||||
('20230525101006'),
|
('20230525101006'),
|
||||||
('20230612123250');
|
('20230612123250'),
|
||||||
('20230626103314');
|
('20230626103314'),
|
||||||
('20230626122844'),
|
('20230626122844'),
|
||||||
('20230626122947');
|
('20230626122947'),
|
||||||
|
('20230710072403');
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user