mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-28 09:24:24 +01:00
Merge branch 'dev' for release 6.3.1
This commit is contained in:
commit
4979accf11
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,5 +1,16 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
## v6.3.1 2023 November 10
|
||||
|
||||
- Fix a bug: statistic_sub_type.label of plan was nil
|
||||
- adds a migrations to fix all statistic_sub_types of plans having label = nil
|
||||
- Fix a bug: unable to show wallet payment mean for avoir
|
||||
- updates spanish translations and adds translations
|
||||
- Fix a bug: avoids crash due to oidc config with scope = nil
|
||||
- Fix a bug: unable to see value for input group with long label on eventModal
|
||||
- Improvement: when deleting an event, all reservations are canceled
|
||||
- Improvement: replace original image by large generated version (event, machine, space, training)
|
||||
|
||||
## v6.3.0 2023 November 3
|
||||
|
||||
- Fix a bug: fix all failing tasks of rake task file chain.rake
|
||||
@ -13,6 +24,7 @@
|
||||
- Fix a bug: replaces custom ServerLocale middleware with sidekiq i18n middleware
|
||||
- adds a rake task to erase all reservations and invoices (fablab:maintenance:delete_all_reservations_and_invoices)
|
||||
- improvement: dynamic label (i18n) for stats structure tables
|
||||
- [TODO DEPLOY] upgrade to v6.2.0 BEFORE upgrading to v6.3.0 !!!
|
||||
|
||||
## v6.2.0 2023 October 13
|
||||
|
||||
@ -22,6 +34,7 @@
|
||||
- Fix a bug: fix members tour (help), a selector was not valid anymore
|
||||
- Fix a bug: unable to save OpenID extra_authorize_params as json
|
||||
- Fix machine list bug : when there is no user logged in and access machines list with at least one machine associated to a space
|
||||
- [TODO DEPLOY] `rails db:seed`
|
||||
|
||||
## v6.1.2 2023 October 2
|
||||
|
||||
|
@ -77,6 +77,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer.btn-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
content: none;
|
||||
}
|
||||
|
||||
& > * {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
height: 100%;
|
||||
}
|
||||
|
@ -82,18 +82,18 @@
|
||||
<p class="text-center font-sbold" translate>{{ 'app.admin.calendar.divide_this_availability' }}</p>
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" ng-model="slots_nb" step="1" min="1" required="true" />
|
||||
<span class="input-group-addon" translate>{{ 'app.admin.calendar.slots' }}</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="slots_nb" type="number" class="form-control" ng-model="slots_nb" step="1" min="1" required="true" />
|
||||
<label for="slots_nb" translate>{{ 'app.admin.calendar.slots' }}</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="col-md-2 middle-of-inputs" translate>
|
||||
{{ 'app.admin.calendar.slots_of' }}
|
||||
</p>
|
||||
<div class="col-md-5">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" ng-model="availability.slot_duration" min="1" required="true" />
|
||||
<span class="input-group-addon" translate>{{ 'app.admin.calendar.minutes' }}</span>
|
||||
<div class="form-group">
|
||||
<input id="slot_duration" type="number" class="form-control" ng-model="availability.slot_duration" min="1" required="true" />
|
||||
<label for="slot_duration" translate>{{ 'app.admin.calendar.minutes' }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -223,7 +223,7 @@
|
||||
<p class="text-center font-sbold" translate>{{ 'app.admin.calendar.summary' }}</p>
|
||||
<div class="row">
|
||||
<span>{{ 'app.admin.calendar.about_to_create' | translate:{NUMBER:occurrences.length,TYPE:availability.available_type} }}</span>
|
||||
<ul>
|
||||
<ul style="max-height: 25vh; overflow: auto;">
|
||||
<li ng-repeat="slot in occurrences">{{slot.start_at | amDateFormat:'L LT'}} - {{slot.end_at | amDateFormat:'LT'}}</li>
|
||||
</ul>
|
||||
<div class="alert alert-info text-xs" ng-show="availability.slot_duration">
|
||||
|
@ -17,37 +17,37 @@
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="m-lg events-management"
|
||||
ui-tour="events"
|
||||
ui-tour-backdrop="true"
|
||||
ui-tour-template-url="'/shared/tour-step-template.html'"
|
||||
ui-tour-use-hotkeys="true"
|
||||
ui-tour-scroll-parent-id="content-main"
|
||||
post-render="setupEventsTour">
|
||||
<div class="row">
|
||||
<div class="col-md-12" ng-if="isAuthorized('admin')">
|
||||
<uib-tabset justified="true" active="tabs.active">
|
||||
<uib-tab heading="{{ 'app.admin.events.settings' | translate }}" index="0">
|
||||
<events-settings on-error="onError" on-success="onSuccess" ui-router="uiRouter"></events-settings>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.events.events_monitoring' | translate }}" index="1">
|
||||
<ng-include src="'/admin/events/monitoring.html'"></ng-include>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.events.manage_filters' | translate }}" index="2">
|
||||
<ng-include src="'/admin/events/filters.html'"></ng-include>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.events.manage_prices_categories' | translate }}" index="3" class="prices-tab">
|
||||
<ng-include src="'/admin/events/prices.html'"></ng-include>
|
||||
</uib-tab>
|
||||
</uib-tabset>
|
||||
</div>
|
||||
<div class="col-md-12" ng-if="isAuthorized('manager')">
|
||||
<ng-include src="'/admin/events/monitoring.html'"></ng-include>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="m-lg events-management"
|
||||
ui-tour="events"
|
||||
ui-tour-backdrop="true"
|
||||
ui-tour-template-url="'/shared/tour-step-template.html'"
|
||||
ui-tour-use-hotkeys="true"
|
||||
ui-tour-scroll-parent-id="content-main"
|
||||
post-render="setupEventsTour">
|
||||
<div class="row">
|
||||
<div class="col-md-12" ng-if="isAuthorized('admin')">
|
||||
<uib-tabset justified="true" active="tabs.active">
|
||||
<uib-tab heading="{{ 'app.admin.events.settings' | translate }}" index="0">
|
||||
<events-settings on-error="onError" on-success="onSuccess" ui-router="uiRouter"></events-settings>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.events.events_monitoring' | translate }}" index="1">
|
||||
<ng-include src="'/admin/events/monitoring.html'"></ng-include>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.events.manage_filters' | translate }}" index="2">
|
||||
<ng-include src="'/admin/events/filters.html'"></ng-include>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.events.manage_prices_categories' | translate }}" index="3" class="prices-tab">
|
||||
<ng-include src="'/admin/events/prices.html'"></ng-include>
|
||||
</uib-tab>
|
||||
</uib-tabset>
|
||||
</div>
|
||||
<div class="col-md-12" ng-if="isAuthorized('manager')">
|
||||
<ng-include src="'/admin/events/monitoring.html'"></ng-include>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -5,6 +5,7 @@
|
||||
<div class="modal-body">
|
||||
<p ng-hide="isRecurrent" translate>{{ 'app.public.events_show.do_you_really_want_to_delete_this_event' }}</p>
|
||||
<p ng-show="isRecurrent" translate>{{ 'app.public.events_show.delete_recurring_event' }}</p>
|
||||
<p translate>{{ 'app.public.events_show.all_reservations_for_this_event_will_be_canceled' }}</p>
|
||||
<div ng-show="isRecurrent" class="form-group">
|
||||
<label class="checkbox">
|
||||
<input type="radio" name="delete_mode" ng-model="deleteMode" value="single" required/>
|
||||
|
@ -17,61 +17,60 @@
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="events-list-page">
|
||||
<events-editorial-block on-error="onError"></events-editorial-block>
|
||||
|
||||
<section class="events-list-page">
|
||||
<events-editorial-block on-error="onError"></events-editorial-block>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3" ng-show="categories.length > 0">
|
||||
<select ng-model="filters.category_id" ng-change="filterEvents()" class="form-control" ng-options="c.id as c.name for c in categories">
|
||||
<option value="" translate>{{ 'app.public.events_list.all_categories' }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3" ng-show="themes.length > 0">
|
||||
<select ng-model="filters.theme_id" ng-change="filterEvents()" class="form-control" ng-options="t.id as t.name for t in themes">
|
||||
<option value="" translate>{{ 'app.public.events_list.all_themes' }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3" ng-show="ageRanges.length > 0">
|
||||
<select ng-model="filters.age_range_id" ng-change="filterEvents()" class="form-control" ng-options="a.id as a.name for a in ageRanges">
|
||||
<option value="" translate>{{ 'app.public.events_list.for_all' }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3" ng-show="categories.length > 0">
|
||||
<select ng-model="filters.category_id" ng-change="filterEvents()" class="form-control" ng-options="c.id as c.name for c in categories">
|
||||
<option value="" translate>{{ 'app.public.events_list.all_categories' }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="event-focus" ng-if="featuredEevent && (!currentUser || currentUser.role === 'member')">
|
||||
<div class="col-md-3" ng-show="themes.length > 0">
|
||||
<select ng-model="filters.theme_id" ng-change="filterEvents()" class="form-control" ng-options="t.id as t.name for t in themes">
|
||||
<option value="" translate>{{ 'app.public.events_list.all_themes' }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3" ng-show="ageRanges.length > 0">
|
||||
<select ng-model="filters.age_range_id" ng-change="filterEvents()" class="form-control" ng-options="a.id as a.name for a in ageRanges">
|
||||
<option value="" translate>{{ 'app.public.events_list.for_all' }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="event-focus" ng-if="featuredEevent && (!currentUser || currentUser.role === 'member')">
|
||||
<event-card style="display: contents"
|
||||
event="featuredEevent"
|
||||
card-type="'lg'"
|
||||
ui-sref="app.public.events_show({id: featuredEevent.id})">
|
||||
</event-card>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="month in monthOrder">
|
||||
<h1>{{monthNames[month.split(',')[0] - 1]}}, {{month.split(',')[1]}}</h1>
|
||||
|
||||
<div class="event-monthList">
|
||||
<event-card style="display: contents"
|
||||
event="featuredEevent"
|
||||
card-type="'lg'"
|
||||
ui-sref="app.public.events_show({id: featuredEevent.id})">
|
||||
event="event"
|
||||
ng-repeat="event in eventsGroupByMonth[month]"
|
||||
card-type="'sm'"
|
||||
ng-if="isAuthorized(['admin', 'manager']) || event.id !== featuredEevent.id"
|
||||
ng-class="{'featured-event': event.id === featuredEevent.id}"
|
||||
ui-sref="app.public.events_show({id: event.id})">
|
||||
</event-card>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="month in monthOrder">
|
||||
<h1>{{monthNames[month.split(',')[0] - 1]}}, {{month.split(',')[1]}}</h1>
|
||||
</div>
|
||||
|
||||
<div class="event-monthList">
|
||||
<event-card style="display: contents"
|
||||
event="event"
|
||||
ng-repeat="event in eventsGroupByMonth[month]"
|
||||
card-type="'sm'"
|
||||
ng-if="isAuthorized(['admin', 'manager']) || event.id !== featuredEevent.id"
|
||||
ng-class="{'featured-event': event.id === featuredEevent.id}"
|
||||
ui-sref="app.public.events_show({id: event.id})">
|
||||
</event-card>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-12 text-center m-t-md">
|
||||
<a class="btn btn-warning" ng-click="loadMoreEvents()" ng-hide="noMoreResults" translate>{{ 'app.public.events_list.load_the_next_events' }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-12 text-center m-t-md">
|
||||
<a class="btn btn-warning" ng-click="loadMoreEvents()" ng-hide="noMoreResults" translate>{{ 'app.public.events_list.load_the_next_events' }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<p ng-show="object.user && currentUser.id !== object.user.id" translate translate-values="{NAME: object.user.name}">{{ 'app.shared.confirm_modify_slot_modal.do_you_want_to_change_NAME_s_booking_slot_initially_planned_at' }}</p>
|
||||
<p><strong>{{object.start | amDateFormat: 'LL'}} : {{object.start | amDateFormat:'LT'}} - {{object.end | amDateFormat:'LT'}}</strong></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="modal-footer btn-stack">
|
||||
<button class="btn btn-warning" ng-class="{'m-b':object.cancelable&&object.movable}" ng-click="ok('cancel')" ng-show="object.cancelable" translate>{{ 'app.shared.confirm_modify_slot_modal.cancel_this_reservation' }}</button>
|
||||
<button class="btn btn-info" ng-click="ok('move')" ng-show="object.movable" translate>{{ 'app.shared.confirm_modify_slot_modal.i_want_to_change_date' }}</button>
|
||||
<button class="btn btn-default" ng-click="cancel()" translate>{{ 'app.shared.buttons.cancel' }}</button>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="" id="loginModal">
|
||||
<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="" class="modal-logo"/>
|
||||
<i class="fa fa-times close-modal-button" ng-click="dismiss()"></i>
|
||||
<h1 translate translate-default="Login">
|
||||
{{ 'app.public.common.connection' }}
|
||||
|
@ -160,7 +160,9 @@ class Invoice < PaymentDocument
|
||||
# return a summary of the payment means used
|
||||
def payment_means
|
||||
res = []
|
||||
res.push(means: :wallet, amount: wallet_amount) if paid_by_wallet?
|
||||
res.push(means: :wallet, amount: wallet_amount || total) if paid_by_wallet?
|
||||
return res if is_a?(Avoir)
|
||||
|
||||
if paid_by_card?
|
||||
res.push(means: :card, amount: amount_paid)
|
||||
else
|
||||
@ -195,7 +197,7 @@ class Invoice < PaymentDocument
|
||||
end
|
||||
|
||||
def paid_by_wallet?
|
||||
wallet_transaction && wallet_amount.positive?
|
||||
(wallet_transaction && wallet_amount.positive?) || payment_method == 'wallet'
|
||||
end
|
||||
|
||||
def render_resource
|
||||
|
@ -35,8 +35,8 @@ class Plan < ApplicationRecord
|
||||
|
||||
after_create :create_machines_prices
|
||||
after_create :create_spaces_prices
|
||||
after_create :create_statistic_type
|
||||
after_create :set_name
|
||||
after_create :create_statistic_type
|
||||
after_create :update_gateway_product
|
||||
after_update :update_gateway_product, if: :saved_change_to_base_name?
|
||||
|
||||
|
@ -71,7 +71,16 @@ class EventService
|
||||
events.each do |e|
|
||||
method = e.destroyable? ? :destroy : :soft_destroy!
|
||||
# we use double negation because destroy can return either a boolean (false) or an Event (in case of delete success)
|
||||
results.push status: !!e.send(method), event: e # rubocop:disable Style/DoubleNegation
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
status = !!e.send(method)
|
||||
if status
|
||||
e.reservations.preload(:slots_reservations).map(&:slots_reservations).flatten.map do |slots_reservation|
|
||||
SlotsReservationsService.cancel(slots_reservation)
|
||||
end
|
||||
end
|
||||
results.push status: status, event: e # rubocop:disable Style/DoubleNegation
|
||||
end
|
||||
end
|
||||
results
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ class SlotsReservationsService
|
||||
class << self
|
||||
def cancel(slot_reservation)
|
||||
# first we mark ths slot reservation as cancelled in DB, to free a ticket
|
||||
slot_reservation.update(canceled_at: Time.current)
|
||||
slot_reservation.update!(canceled_at: Time.current)
|
||||
|
||||
# then we try to remove this reservation from ElasticSearch, to keep the statistics up-to-date
|
||||
model_name = slot_reservation.reservation.reservable.class.name
|
||||
|
@ -7,7 +7,7 @@ if event.event_image
|
||||
json.event_image_attributes do
|
||||
json.id event.event_image.id
|
||||
json.attachment_name event.event_image.attachment_identifier
|
||||
json.attachment_url "#{event.event_image.attachment_url}?#{event.event_image.updated_at.to_i}"
|
||||
json.attachment_url "#{event.event_image.attachment.large.url}?#{event.event_image.updated_at.to_i}"
|
||||
end
|
||||
end
|
||||
json.event_files_attributes event.event_files do |f|
|
||||
|
@ -6,7 +6,7 @@ if machine.machine_image
|
||||
json.machine_image_attributes do
|
||||
json.id machine.machine_image.id
|
||||
json.attachment_name machine.machine_image.attachment_identifier
|
||||
json.attachment_url machine.machine_image.attachment.url
|
||||
json.attachment_url machine.machine_image.attachment.large.url
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,7 +5,7 @@ if space.space_image
|
||||
json.space_image_attributes do
|
||||
json.id space.space_image.id
|
||||
json.attachment_name space.space_image.attachment_identifier
|
||||
json.attachment_url space.space_image.attachment.url
|
||||
json.attachment_url space.space_image.attachment.large.url
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -7,7 +7,7 @@ if training.training_image
|
||||
json.training_image_attributes do
|
||||
json.id training.training_image.id
|
||||
json.attachment_name training.training_image.attachment_identifier
|
||||
json.attachment_url training.training_image.attachment.url
|
||||
json.attachment_url training.training_image.attachment.large.url
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,10 +75,10 @@ es:
|
||||
associated_machines: "Máquinas asociadas"
|
||||
associated_machines_help: "Si asocia una máquina a esta formación, los miembros deberán superar con éxito esta formación antes de poder reservar la máquina."
|
||||
default_seats: "Número predeterminado de asientos"
|
||||
public_page: "Mostrar en la lista de formaciones"
|
||||
public_help: "Si esta opción no está seleccionada, la formación no aparecerá en la lista de formaciones."
|
||||
public_page: "Mostrar en la lista de capacitaciones"
|
||||
public_help: "Si esta opción no está seleccionada, la capacitación no aparecerá en la lista de capacitaciones."
|
||||
disable_training: "Desactivar la formación"
|
||||
disabled_help: "Si está desactivada, la formación no se podrá reservar y no aparecerá por defecto en la lista de formaciones."
|
||||
disabled_help: "Si está desactivada, la capacitación no se podrá reservar y no aparecerá por defecto en la lista de capacitaciones."
|
||||
automatic_cancellation: "Cancelación automática"
|
||||
automatic_cancellation_info: "Si edita condiciones específicas aquí, las condiciones generales de cancelación dejarán de tenerse en cuenta. Se le notificará si se cancela una sesión. Los abonos y reembolsos serán automáticos si el monedero está activado. En caso contrario, tendrás que hacerlo manualmente."
|
||||
automatic_cancellation_switch: "Activar la cancelación automática para esta formación"
|
||||
@ -337,7 +337,7 @@ es:
|
||||
select_none: "No"
|
||||
manage_machines: "Haga clic aquí para añadir o eliminar máquinas."
|
||||
manage_spaces: "Haga clic aquí para añadir o eliminar espacios."
|
||||
manage_trainings: "Haga clic aquí para añadir o eliminar formaciones."
|
||||
manage_trainings: "Haga clic aquí para añadir o eliminar capacitaciones."
|
||||
number_of_tickets: "Número de tickets: "
|
||||
adjust_the_opening_hours: "Ajustar el horario de apertura"
|
||||
to_time: "a" #e.g. from 18:00 to 21:00
|
||||
@ -372,7 +372,7 @@ es:
|
||||
min_slot_duration: "Debe especificar una duración válida para las franjas horarias."
|
||||
export_is_running_you_ll_be_notified_when_its_ready: "La exportación se está ejecutando. Se le notificará cuando esté listo."
|
||||
actions: "Acciones"
|
||||
block_reservations: "Reservas de bloques"
|
||||
block_reservations: "Bloquear las reservas"
|
||||
do_you_really_want_to_block_this_slot: "¿Realmente desea bloquear nuevas reservas en esta franja horaria? Se volverá invisible para los usuarios."
|
||||
locking_success: "Franja horaria correctamente bloqueada, ya no aparecerá en el calendario del usuario"
|
||||
locking_failed: "Ocurrió un error. El bloqueo de la franja horaria ha fallado"
|
||||
@ -401,7 +401,7 @@ es:
|
||||
minutes: "minutos"
|
||||
deleted_user: "Usuario suprimido"
|
||||
select_type: "Seleccione un tipo para continuar"
|
||||
no_modules_available: "No hay ningún módulo reservable disponible. Habilite al menos un módulo (máquinas, espacios o formaciones) en la sección Personalización."
|
||||
no_modules_available: "No hay ningún módulo reservable disponible. Habilite al menos un módulo (máquinas, espacios o capacitaciones) en la sección Personalización."
|
||||
#import external iCal calendar
|
||||
icalendar:
|
||||
icalendar_import: "Importar iCalendar"
|
||||
@ -489,7 +489,7 @@ es:
|
||||
#track and monitor the trainings
|
||||
trainings:
|
||||
trainings_monitoring: "Seguimiento de la formación"
|
||||
all_trainings: "Todas las formaciones"
|
||||
all_trainings: "Todas las capacitaciones"
|
||||
add_a_new_training: "Añadir una nueva formación"
|
||||
name: "Nombre"
|
||||
associated_machines: "Máquinas asociadas"
|
||||
@ -533,9 +533,9 @@ es:
|
||||
add_a_new_training: "Añadir una nueva formación"
|
||||
trainings_settings:
|
||||
title: "Configuración"
|
||||
automatic_cancellation: "Cancelación automática de formaciones"
|
||||
automatic_cancellation: "Cancelación automática de capacitaciones"
|
||||
automatic_cancellation_info: "Se requiere un número mínimo de participantes para mantener una sesión. Se le notificará si se cancela una sesión. Los abonos y reembolsos serán automáticos si el monedero está habilitado. De lo contrario, tendrá que hacerlo manualmente."
|
||||
automatic_cancellation_switch: "Activar la cancelación automática de todos las formaciones"
|
||||
automatic_cancellation_switch: "Activar la cancelación automática de todos las capacitaciones"
|
||||
automatic_cancellation_threshold: "Número mínimo de inscripciones para mantener una sesión"
|
||||
must_be_positive: "Debe especificar un número superior o igual a 0"
|
||||
automatic_cancellation_deadline: "Fecha límite, en horas antes de la cancelación automática"
|
||||
@ -549,7 +549,7 @@ es:
|
||||
validation_rule_switch: "Activar la regla de validación"
|
||||
validation_rule_period: "Límite de tiempo en meses"
|
||||
generic_text_block: "Bloque de texto editorial"
|
||||
generic_text_block_info: "Muestra un bloque editorial encima de la lista de formaciones visibles para los miembros."
|
||||
generic_text_block_info: "Muestra un bloque editorial encima de la lista de capacitaciones visibles para los miembros."
|
||||
generic_text_block_switch: "Mostrar bloque editorial"
|
||||
cta_switch: "Mostrar un botón"
|
||||
cta_label: "Etiqueta del botón"
|
||||
@ -1266,7 +1266,7 @@ es:
|
||||
#members bulk import
|
||||
members_import:
|
||||
import_members: "Importar miembros"
|
||||
info: "Puede cargar un archivo CSV para crear nuevos miembros o actualizar los existentes. Su archivo debe utilizar los identificadores siguientes para especificar el grupo, las formaciones y las etiquetas de los miembros."
|
||||
info: "Puede cargar un archivo CSV para crear nuevos miembros o actualizar los existentes. Su archivo debe utilizar los identificadores siguientes para especificar el grupo, las capacitaciones y las etiquetas de los miembros."
|
||||
required_fields: "Su fichero debe contener, al menos, los siguientes datos para cada usuario a crear: email, nombre, apellidos y grupo. Si la contraseña está vacía, se generará. En las actualizaciones, los campos vacíos se mantendrán tal cual."
|
||||
about_example_html: "Consulte el archivo de ejemplo proporcionado para generar un archivo CSV correcto.<br>Este ejemplo:<ol><li>creará un nuevo miembro (Jean Dupont) con una contraseña generada</li><li>actualizará la contraseña de un miembro existente (ID 43) con la nueva contraseña generada.</li></ol><br>Tenga cuidado de utilizar la codificación <strong>Unicode UTF-8</strong>."
|
||||
groups: "Grupos"
|
||||
@ -1645,8 +1645,8 @@ es:
|
||||
customize_information_messages: "Personalizar mensajes de información"
|
||||
message_of_the_machine_booking_page: "Mensaje de la página de reserva de la máquina:"
|
||||
type_the_message_content: "Escriba el contenido del mensaje"
|
||||
warning_message_of_the_training_booking_page: "Mensaje de advertencia de la pagina de reservación de las formaciones:"
|
||||
information_message_of_the_training_reservation_page: "Mensaje de información en la página de reservación de las formaciones:"
|
||||
warning_message_of_the_training_booking_page: "Mensaje de advertencia de la pagina de reservación de las capacitaciones:"
|
||||
information_message_of_the_training_reservation_page: "Mensaje de información en la página de reservación de las capacitaciones:"
|
||||
message_of_the_subscriptions_page: "Mensaje de advertencia de la página de reserva de formación:"
|
||||
message_of_the_events_page: "Mensaje de la página de eventos:"
|
||||
message_of_the_spaces_page: "Mensaje de la página de espacios:"
|
||||
@ -1797,7 +1797,7 @@ es:
|
||||
enable_plans: "Activar los planes"
|
||||
plans_module: "módulo de planes"
|
||||
trainings: "Formaciones"
|
||||
trainings_info_html: "<p>Las formaciones están totalmente integradas en la agenda del gestor de Fab. Si la activas, tus miembros podrán reservar y pagar formaciones.</p><p>Las formaciones permiten evitar que los miembros reserven algunas máquinas si no han realizado el curso previo.</p>"
|
||||
trainings_info_html: "<p>Las capacitaciones están totalmente integradas en la agenda del gestor de Fab. Si la activas, tus miembros podrán reservar y pagar capacitaciones.</p><p>Las capacitaciones permiten evitar que los miembros reserven algunas máquinas si no han realizado el curso previo.</p>"
|
||||
enable_trainings: "Activar la formación"
|
||||
trainings_module: "módulo de formación"
|
||||
store: "Tienda"
|
||||
@ -1828,7 +1828,7 @@ es:
|
||||
recaptcha_site_key: "Clave del sitio reCAPTCHA"
|
||||
recaptcha_secret_key: "Clave secreta de reCAPTCHA"
|
||||
feature_tour_display: "activar la visita guiada"
|
||||
email_from: "dirección del expedidor"
|
||||
email_from: "dirección del remitente"
|
||||
disqus_shortname: "Nombre corto de Disqus"
|
||||
COUNT_items_removed: "{COUNT, plural, one {}=1{Un elemento eliminado} other{{COUNT} elementos eliminados}}"
|
||||
item_added: "Un elemento añadido"
|
||||
@ -1916,7 +1916,7 @@ es:
|
||||
notifications: "Notificaciones"
|
||||
email: "Email"
|
||||
email_info: "La dirección de email desde la que se enviarán las notificaciones. Puede utilizar una dirección inexistente (como noreply@...) o una dirección existente si desea permitir a sus miembros responder a las notificaciones que reciban."
|
||||
email_from: "Dirección del expedidor"
|
||||
email_from: "Dirección del remitente"
|
||||
wallet: "Cartera"
|
||||
wallet_info_html: "<p>La cartera virtual permite asignar una suma de dinero a los usuarios. Luego, pueden gastar este dinero como deseen, en Fab-manager.</p><p>los miembros no pueden acreditar su cartera a sí mismos, es un privilegio de los gestores y administradores.</p>"
|
||||
enable_wallet: "Activar cartera"
|
||||
@ -2099,12 +2099,12 @@ es:
|
||||
trainings:
|
||||
welcome:
|
||||
title: "Formaciones"
|
||||
content: "Aquí puede crear, modificar y eliminar formaciones. También es el lugar donde puede validar los cursos de formación seguidos por sus miembros."
|
||||
content: "Aquí puede crear, modificar y eliminar capacitaciones. También es el lugar donde puede validar los cursos de capacitación seguidos por sus miembros."
|
||||
welcome_manager:
|
||||
title: "Formaciones"
|
||||
content: "Este es el lugar donde puedes ver las formaciones y sus asociaciones con las máquinas. También es el lugar donde puede validar las formaciones seguidas por sus miembros."
|
||||
content: "Este es el lugar donde puedes ver las capacitaciones y sus asociaciones con las máquinas. También es el lugar donde puede validar las capacitaciones seguidas por sus miembros."
|
||||
trainings:
|
||||
title: "Administrar formaciones"
|
||||
title: "Administrar capacitaciones"
|
||||
content: "<p>A cada formación se le asocia un número de plazas por defecto. Sin embargo, el número de plazas reales puede modificarse para cada sesión.</p><p>Las sesiones de formación se programan desde la pestaña del administrador \"Calendario\".</p><p>Además, una formación puede asociarse a una o varias máquinas. Además, una formación puede estar asociada a una o varias máquinas.</p>"
|
||||
filter:
|
||||
title: "Filtro"
|
||||
|
@ -119,9 +119,9 @@ es:
|
||||
collaborators: "Colaboradores"
|
||||
#dashboard: my trainings
|
||||
trainings:
|
||||
your_next_trainings: "Sus próximas formaciones"
|
||||
your_previous_trainings: "Sus formaciones anteriores"
|
||||
your_approved_trainings: "Sus formaciones aprobadas"
|
||||
your_next_trainings: "Sus próximas capacitaciones"
|
||||
your_previous_trainings: "Sus capacitaciones anteriores"
|
||||
your_approved_trainings: "Sus capacitaciones aprobadas"
|
||||
no_trainings: "Ninguna formación"
|
||||
your_training_credits: "Tus créditos de entrenamiento"
|
||||
subscribe_for_credits: "Suscríbete para beneficiarte de entrenamientos gratuitos"
|
||||
@ -264,7 +264,7 @@ es:
|
||||
trainings_reserve:
|
||||
trainings_planning: "Plan de la formación"
|
||||
planning_of: "Plan de " #eg. Planning of 3d printer training
|
||||
all_trainings: "Todas las formaciones"
|
||||
all_trainings: "Todas las capacitaciones"
|
||||
cancel_my_selection: "Cancelar mi selección"
|
||||
i_change: "Cambio"
|
||||
i_shift: "Cambio"
|
||||
|
@ -352,6 +352,7 @@ de:
|
||||
you_can_shift_this_reservation_on_the_following_slots: "Sie können diese Reservierung auf die folgenden Slots verschieben:"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_event: "Möchten Sie diese Veranstaltung wirklich löschen?"
|
||||
all_reservations_for_this_event_will_be_canceled: All reservations for this event will be canceled.
|
||||
delete_recurring_event: "Sie sind dabei, eine wiederkehrende Veranstaltung zu löschen. Was möchten Sie tun?"
|
||||
delete_this_event: "Nur diese Veranstaltung"
|
||||
delete_this_and_next: "Diese Veranstaltung sowie die folgenden"
|
||||
|
@ -352,6 +352,7 @@ en:
|
||||
you_can_shift_this_reservation_on_the_following_slots: "You can shift this reservation on the following slots:"
|
||||
confirmation_required: "Confirmation required"
|
||||
do_you_really_want_to_delete_this_event: "Do you really want to delete this event?"
|
||||
all_reservations_for_this_event_will_be_canceled: All reservations for this event will be canceled.
|
||||
delete_recurring_event: "You're about to delete a periodic event. What do you want to do?"
|
||||
delete_this_event: "Only this event"
|
||||
delete_this_and_next: "This event and the following"
|
||||
|
@ -13,12 +13,12 @@ es:
|
||||
decline: "Rechazar"
|
||||
#dashboard sections
|
||||
dashboard: "Panel"
|
||||
my_profile: "My Perfil"
|
||||
my_profile: "Mi Perfil"
|
||||
my_children: "Mis hijos"
|
||||
my_settings: "Mis ajustes"
|
||||
my_supporting_documents_files: "Mis documentos justificativos"
|
||||
my_projects: "Mis proyectos"
|
||||
my_trainings: "Mis formaciones"
|
||||
my_trainings: "Mis capacitaciones"
|
||||
my_reservations: "Mis reservas"
|
||||
my_events: "Mis eventos"
|
||||
my_invoices: "Mis facturas"
|
||||
@ -39,7 +39,7 @@ es:
|
||||
#left menu (public)
|
||||
home: "Menú principal"
|
||||
reserve_a_machine: "Reservar una máquina"
|
||||
trainings_registrations: "Registro de formaciones"
|
||||
trainings_registrations: "Registro de capacitaciones"
|
||||
events_registrations: "Registro de eventos"
|
||||
reserve_a_space: "Reservar un espacio"
|
||||
projects_gallery: "Galería de proyectos"
|
||||
@ -259,7 +259,7 @@ es:
|
||||
#list of trainings
|
||||
trainings_list:
|
||||
book: "Reservar"
|
||||
the_trainings: "Lista de formaciones"
|
||||
the_trainings: "Lista de capacitaciones"
|
||||
#details of a training
|
||||
training_show:
|
||||
book_this_training: "Reservar la formación"
|
||||
@ -352,6 +352,7 @@ es:
|
||||
you_can_shift_this_reservation_on_the_following_slots: "Puede cambiar la reserva en los siguientes campos:"
|
||||
confirmation_required: "Confirmación requerida"
|
||||
do_you_really_want_to_delete_this_event: "¿Realmente desea eliminar este evento?"
|
||||
all_reservations_for_this_event_will_be_canceled: Todas las reservas de este evento serán canceladas.
|
||||
delete_recurring_event: "Estás a punto de eliminar un evento periódico. ¿Qué quieres hacer?"
|
||||
delete_this_event: "Solo este evento"
|
||||
delete_this_and_next: "Este evento y lo siguiente"
|
||||
@ -376,7 +377,7 @@ es:
|
||||
#public calendar
|
||||
calendar:
|
||||
calendar: "Calendario"
|
||||
show_unavailables: "Mostrar campos inválidos"
|
||||
show_unavailables: "Mostrar las franjas horarias indisponibles"
|
||||
filter_calendar: "Filtrar calendario"
|
||||
trainings: "Formaciones"
|
||||
machines: "Máquinas"
|
||||
@ -537,7 +538,7 @@ es:
|
||||
content: "<p>Esta página le permitirá consultar la lista de todas las máquinas y reservar una franja horaria en nombre de un miembro.</p><p>Una máquina puede ser, por ejemplo, una impresora 3D.</p><p>Los miembros también pueden acceder a esta página y reservar ellos mismos una máquina, si está habilitado el pago con tarjeta de crédito o si algunos precios son iguales a 0.</p>"
|
||||
trainings:
|
||||
title: "Formaciones"
|
||||
content: "<p>Esta página le permitirá consultar la lista de todas las sesiones de formación e inscribir a un miembro en una sesión de formación.</p><p>Las formaciones pueden establecerse como requisitos previos antes de permitir la reserva de determinadas máquinas.</p><p>Los miembros también pueden acceder a esta página e inscribirse ellos mismos en una sesión de formación, si está habilitado el pago con tarjeta de crédito o si algunos precios son iguales a 0.</p>"
|
||||
content: "<p>Esta página le permitirá consultar la lista de todas las sesiones de capacitación e inscribir a un miembro en una sesión de capacitación.</p><p>Las capacitaciones pueden establecerse como requisitos previos antes de permitir la reserva de determinadas máquinas.</p><p>Los miembros también pueden acceder a esta página e inscribirse ellos mismos en una sesión de capacitación, si está habilitado el pago con tarjeta de crédito o si algunos precios son iguales a 0.</p>"
|
||||
spaces:
|
||||
title: "Espacios"
|
||||
content: "<p>Esta página le permitirá consultar la lista de todos los espacios disponibles y reservar una plaza en una franja horaria, en nombre de un miembro.</p><p>Un espacio puede ser, por ejemplo, un taller de carpintería o una sala de reuniones.</p><p>Su particularidad es que pueden ser reservados por varias personas al mismo tiempo.</p><p>Los miembros también pueden acceder a esta página y reservar ellos mismos una máquina, si está habilitado el pago con tarjeta de crédito o si algunos precios son iguales a 0.</p>"
|
||||
|
@ -352,6 +352,7 @@ fr:
|
||||
you_can_shift_this_reservation_on_the_following_slots: "Vous pouvez déplacer cette réservation sur les créneaux suivants :"
|
||||
confirmation_required: "Confirmation requise"
|
||||
do_you_really_want_to_delete_this_event: "Voulez-vous vraiment supprimer cet événement ?"
|
||||
all_reservations_for_this_event_will_be_canceled: Toutes les réservations de cet événement seront annulées.
|
||||
delete_recurring_event: "Vous êtes sur le point de supprimer un événement périodique. Que voulez-vous supprimer ?"
|
||||
delete_this_event: "Uniquement cet événement"
|
||||
delete_this_and_next: "Cet événement et tous les suivants"
|
||||
|
@ -352,6 +352,7 @@ it:
|
||||
you_can_shift_this_reservation_on_the_following_slots: "È possibile spostare questa prenotazione sui seguenti slot:"
|
||||
confirmation_required: "Conferma richiesta"
|
||||
do_you_really_want_to_delete_this_event: "Volete davvero cancellare questo evento?"
|
||||
all_reservations_for_this_event_will_be_canceled: All reservations for this event will be canceled.
|
||||
delete_recurring_event: "Stai per eliminare un evento multiplo. Cosa vuoi fare?"
|
||||
delete_this_event: "Solo questo evento"
|
||||
delete_this_and_next: "Questo evento e il successivo"
|
||||
|
@ -352,6 +352,7 @@
|
||||
you_can_shift_this_reservation_on_the_following_slots: "Du kan flytte denne reservasjonen til følgende tidsluke:"
|
||||
confirmation_required: "Bekreftelse påkrevd"
|
||||
do_you_really_want_to_delete_this_event: "Vil du virkelig slette denne hendelsen?"
|
||||
all_reservations_for_this_event_will_be_canceled: All reservations for this event will be canceled.
|
||||
delete_recurring_event: "Du er ferd med å oppdatere en gjentakende hendelse. Hva vil du gjøre?"
|
||||
delete_this_event: "Bare denne hendelsen"
|
||||
delete_this_and_next: "Denne hendelsen og de følgende"
|
||||
|
@ -352,6 +352,7 @@ pt:
|
||||
you_can_shift_this_reservation_on_the_following_slots: "Você pode alterar essa reserva nos campos a seguir:"
|
||||
confirmation_required: "Confirmação obrigatória"
|
||||
do_you_really_want_to_delete_this_event: "Vocêrealmente deseja remover este evento?"
|
||||
all_reservations_for_this_event_will_be_canceled: All reservations for this event will be canceled.
|
||||
delete_recurring_event: "Você está prestes a excluir um evento periódico. O que você deseja fazer?"
|
||||
delete_this_event: "Apenas este evento"
|
||||
delete_this_and_next: "Este evento e os seguintes"
|
||||
|
@ -352,6 +352,7 @@ zu:
|
||||
you_can_shift_this_reservation_on_the_following_slots: "crwdns28338:0crwdne28338:0"
|
||||
confirmation_required: "crwdns28340:0crwdne28340:0"
|
||||
do_you_really_want_to_delete_this_event: "crwdns28342:0crwdne28342:0"
|
||||
all_reservations_for_this_event_will_be_canceled: crwdns38132:0crwdne38132:0
|
||||
delete_recurring_event: "crwdns28344:0crwdne28344:0"
|
||||
delete_this_event: "crwdns28346:0crwdne28346:0"
|
||||
delete_this_and_next: "crwdns28348:0crwdne28348:0"
|
||||
|
@ -540,7 +540,7 @@ es:
|
||||
stock_external: "Stock público"
|
||||
calendar:
|
||||
calendar: "Agenda"
|
||||
show_unavailables: "Mostrar todas las franjas horarias"
|
||||
show_unavailables: "Mostrar las franjas horarias llenas"
|
||||
filter_calendar: "Filtrar calendario"
|
||||
trainings: "Formaciones"
|
||||
machines: "Máquinas"
|
||||
|
@ -383,7 +383,7 @@ es:
|
||||
statistics_machine: "de estadísticas sobre slots de máquina"
|
||||
statistics_project: "de estadísticas sobre proyectos"
|
||||
statistics_subscription: "de estadísticas de suscripción"
|
||||
statistics_training: "de estadísticas de formaciones"
|
||||
statistics_training: "de estadísticas de capacitaciones"
|
||||
statistics_space: "de estadísticas sobre espacios"
|
||||
statistics_order: "de estadísticas sobre los pedidos de la tienda"
|
||||
users_members: "de la lista de miembros"
|
||||
@ -672,7 +672,7 @@ es:
|
||||
recaptcha_site_key: "clave del sitio reCAPTCHA"
|
||||
recaptcha_secret_key: "clave secreta de reCAPTCHA"
|
||||
feature_tour_display: "Modo de visualización de la visita guiada"
|
||||
email_from: "Dirección del expedidor"
|
||||
email_from: "Dirección del remitente"
|
||||
disqus_shortname: "Nombre corto de Disqus"
|
||||
allowed_cad_extensions: "Extensiones de archivos CAD permitidas"
|
||||
allowed_cad_mime_types: "Archivos CAD permitidos tipos MIME"
|
||||
@ -729,11 +729,11 @@ es:
|
||||
external_id: "identificador externo"
|
||||
prevent_invoices_zero: "impedir la creación de facturas a 0"
|
||||
invoice_VAT-name: "Nombre IVA"
|
||||
trainings_auto_cancel: "Cancelación automática de formaciones"
|
||||
trainings_auto_cancel: "Cancelación automática de capacitaciones"
|
||||
trainings_auto_cancel_threshold: "Mínimo de participantes para la cancelación automática"
|
||||
trainings_auto_cancel_deadline: "Plazo de cancelación automática"
|
||||
trainings_authorization_validity: "Período de validez de las formaciones"
|
||||
trainings_authorization_validity_duration: "Duración del periodo de validez de las formaciones"
|
||||
trainings_authorization_validity: "Período de validez de las capacitaciones"
|
||||
trainings_authorization_validity_duration: "Duración del periodo de validez de las capacitaciones"
|
||||
trainings_invalidation_rule: "Formaciones invalidación automática"
|
||||
trainings_invalidation_rule_period: "Periodo de gracia antes de invalidar una formación"
|
||||
projects_list_member_filter_presence: "Presencia del filtro de miembros en la lista de proyectos"
|
||||
|
@ -15,7 +15,7 @@ es:
|
||||
account_name: "Nombre de usuario:"
|
||||
password: "Contraseña:"
|
||||
temporary_password: "Esta es una contraseña temporal, puede modificarla en la pagina «Mi cuenta»."
|
||||
keep_advantages: "Con esta cuenta, guarda todas las ventajas relacionadas con su perfil de usuario de Fab Lab (formaciones, planes de suscripción)."
|
||||
keep_advantages: "Con esta cuenta, guarda todas las ventajas relacionadas con su perfil de usuario de Fab Lab (capacitaciones, planes de suscripción)."
|
||||
to_use_platform: "Para usar el sitio web, por favor"
|
||||
logon_or_login: "crea una nueva cuenta o inicia sesión haciendo clic aquí."
|
||||
token_if_link_problem: "Si experimenta problemas con el enlace, puede introducir el siguiente código en el primer intento de conexión:"
|
||||
@ -330,7 +330,7 @@ es:
|
||||
notify_admin_objects_stripe_sync:
|
||||
subject: "Sincronización de Stripe"
|
||||
body:
|
||||
objects_sync: "Todos los miembros, cupones, máquinas, formaciones, espacios y planes se sincronizaron correctamente en Stripe."
|
||||
objects_sync: "Todos los miembros, cupones, máquinas, capacitaciones, espacios y planes se sincronizaron correctamente en Stripe."
|
||||
notify_admin_order_is_paid:
|
||||
subject: "Nuevo pedido"
|
||||
body:
|
||||
|
13
db/migrate/20231108094433_fix_plan_statistic_sub_types.rb
Normal file
13
db/migrate/20231108094433_fix_plan_statistic_sub_types.rb
Normal file
@ -0,0 +1,13 @@
|
||||
class FixPlanStatisticSubTypes < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
StatisticSubType.joins(statistic_types: :statistic_index).where(statistic_indices: { es_type_key: "subscription" }, label: nil).each do |statistic_sub_type|
|
||||
plan = Plan.find_by(slug: statistic_sub_type.key)
|
||||
if plan
|
||||
statistic_sub_type.update_column(:label, plan.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
end
|
||||
end
|
@ -9203,6 +9203,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20230831103208'),
|
||||
('20230901090637'),
|
||||
('20230907124230'),
|
||||
('20231103093436');
|
||||
('20231103093436'),
|
||||
('20231108094433');
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ class ProviderConfig
|
||||
|
||||
(@config[:providable_attributes].keys.filter { |n| !n.start_with?('client__') && n != 'profile_url' }.map do |n|
|
||||
val = @config[:providable_attributes][n]
|
||||
val.join(' ') if n == 'scope'
|
||||
val&.join(' ') if n == 'scope'
|
||||
[n, val]
|
||||
end).push(
|
||||
['client_options', @config[:providable_attributes].keys.filter { |n| n.start_with?('client__') }.to_h do |n|
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fab-manager",
|
||||
"version": "6.3.0",
|
||||
"version": "6.3.1",
|
||||
"description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.",
|
||||
"keywords": [
|
||||
"fablab",
|
||||
|
@ -5,6 +5,8 @@ require 'test_helper'
|
||||
module Events; end
|
||||
|
||||
class Events::DeleteTest < ActionDispatch::IntegrationTest
|
||||
include ActionMailer::TestHelper
|
||||
|
||||
setup do
|
||||
admin = User.with_role(:admin).first
|
||||
login_as(admin, scope: :user)
|
||||
@ -55,7 +57,10 @@ class Events::DeleteTest < ActionDispatch::IntegrationTest
|
||||
assert_equal 201, response.status, response.body
|
||||
|
||||
assert_not event.destroyable?
|
||||
delete "/api/events/#{event.id}?mode=single", headers: default_headers
|
||||
assert_enqueued_emails 2 do
|
||||
delete "/api/events/#{event.id}?mode=single", headers: default_headers
|
||||
end
|
||||
assert event.availability.slots_reservations.all? { |sr| sr.canceled_at }
|
||||
assert_response :success
|
||||
res = json_response(response.body)
|
||||
assert_equal 1, res[:deleted]
|
||||
|
Loading…
Reference in New Issue
Block a user