1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-26 20:54:21 +01:00

Merge branch 'dev' for release 5.6.9

This commit is contained in:
Sylvain 2023-02-02 11:23:15 +01:00
commit 7f990074e1
57 changed files with 1655 additions and 1301 deletions

View File

@ -1,5 +1,19 @@
# Changelog Fab-manager
## v5.6.9 2023 February 02
- Updated shakapaker to 6.5.5
- Fix a bug: unable to filter statistics by slot date
- Fix a bug: unable to create a recurrent event
- Fix a bug: unable to create a non-rolling plan
- Fix a bug: invalid duration for machine/spaces reservations in statistics, when using slots of not 1 hour
- Fix a bug: invalid month in date format
- Fix a bug: do not show theme and age-range fields in event form if no options were set
- Fix a bug: do not show catgory select in plan form if no options were set
- Fix a bug: new setups doesn't log
- [TODO DEPLOY] `rails db:seed`
- [TODO DEPLOY] `rails fablab:es:build_stats` THEN `rails fablab:maintenance:regenerate_statistics[2014,1]`
## v5.6.8 2023 January 26
- Fix a bug: plan prices are not reported correctly in the interface

View File

@ -8,7 +8,7 @@ gem 'rails', '~> 5.2.8'
gem 'bootsnap'
# Use Puma as web server
gem 'puma', '4.3.12'
gem 'shakapacker', '6.2.0'
gem 'shakapacker', '6.5.5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'

View File

@ -310,7 +310,7 @@ GEM
httpclient
json-jwt (>= 1.11.0)
rack (>= 2.1.0)
rack-proxy (0.7.2)
rack-proxy (0.7.6)
rack
rack-test (2.0.2)
rack (>= 1.3)
@ -400,7 +400,7 @@ GEM
sentry-ruby (5.7.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
sha3 (1.0.1)
shakapacker (6.2.0)
shakapacker (6.5.5)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
@ -564,7 +564,7 @@ DEPENDENCIES
sentry-rails
sentry-ruby
sha3
shakapacker (= 6.2.0)
shakapacker (= 6.5.5)
sidekiq (>= 6.0.7)
sidekiq-scheduler
sidekiq-unique-jobs (~> 7.1.23)
@ -578,4 +578,4 @@ DEPENDENCIES
webmock
BUNDLED WITH
2.3.26
2.4.3

View File

@ -48,6 +48,7 @@ class API::TrainingsController < API::ApiController
head :no_content
end
# This endpoint is used to get a list of trainings to validate
def availabilities
authorize Training
@training = Training.find(params[:id])

View File

@ -180,12 +180,12 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
label={t('app.admin.event_form.event_category')}
options={categoriesOptions}
rules={{ required: true }} />
{themesOptions && <FormMultiSelect control={control}
{themesOptions?.length > 0 && <FormMultiSelect control={control}
id="event_theme_ids"
formState={formState}
options={themesOptions}
label={t('app.admin.event_form.event_themes')} />}
{ageRangeOptions && <FormSelect control={control}
{ageRangeOptions?.length > 0 && <FormSelect control={control}
id="age_range_id"
formState={formState}
options={ageRangeOptions}

View File

@ -156,7 +156,7 @@ export const PlanForm: React.FC<PlanFormProps> = ({ action, plan, onError, onSuc
disabled={action === 'update'}
label={t('app.admin.plan_form.group')}
id="group_id" />}
{categories && <FormSelect options={categories}
{categories?.length > 0 && <FormSelect options={categories}
formState={formState}
control={control}
id="plan_category_id"

View File

@ -233,6 +233,14 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
}
};
/**
* Return unique elements from the given array
* @param elements {Array<any>}
*/
$scope.uniq = function (elements) {
return [...new Set(elements)];
};
/**
* Retrieve the label for the given subtype in the current type
* @param key {string} statistic subtype key
@ -647,7 +655,7 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
}
}
return angular.forEach($scope.selectedIndex.additional_fields, function (field) {
angular.forEach($scope.selectedIndex.additional_fields, function (field) {
const filter = { key: field.key, label: field.label, values: [] };
switch (field.data_type) {
case 'index': filter.values.push('input_number'); break;

View File

@ -54,9 +54,9 @@ export default class FormatLib {
*/
private static parseISOdate = (date: TDateISO|TDateISODate, res: Date = new Date()): Date => {
const isoDateMatch = (date as string)?.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/);
res.setFullYear(parseInt(isoDateMatch[1], 10));
res.setMonth(parseInt(isoDateMatch[2], 10) - 1);
res.setDate(parseInt(isoDateMatch[3], 10));
res.setMonth(parseInt(isoDateMatch[2], 10) - 1);
res.setFullYear(parseInt(isoDateMatch[1], 10));
return res;
};

View File

@ -254,7 +254,8 @@
<table class="table">
<thead>
<tr>
<th translate>{{ 'app.admin.statistics.date' }}</th>
<th ng-if="['booking', 'hour'].includes(type.active.key)" translate>{{ 'app.admin.statistics.reservation_date' }}</th>
<th ng-if="!['booking', 'hour'].includes(type.active.key)" translate>{{ 'app.admin.statistics.date' }}</th>
<th translate>{{ 'app.admin.statistics.user' }}</th>
<th translate>{{ 'app.admin.statistics.gender' }}</th>
<th translate>{{ 'app.admin.statistics.age' }}</th>
@ -290,7 +291,7 @@
<ng-switch on="field.data_type">
<span ng-switch-when="date">{{formatDate(datum._source[field.key])}}</span>
<ul ng-switch-when="list">
<li ng-repeat="elem in datum._source[field.key]">{{elem.name}}</li>
<li ng-repeat="elem in uniq(datum._source[field.key])">{{elem.name}}</li>
</ul>
<span ng-switch-default>{{datum._source[field.key]}}</span>
</ng-switch>

View File

@ -169,7 +169,7 @@ class Setting < ApplicationRecord
# WARNING: when adding a new key, you may also want to add it in:
# - config/locales/en.yml#settings
# - app/frontend/src/javascript/models/setting.ts#SettingName
# - db/seeds.rb (to set the default value)
# - db/seeds/settings.rb (to set the default value)
# - app/policies/setting_policy.rb#public_whitelist (if the setting can be read by anyone)
# - test/fixtures/settings.yml (for backend testing)
# - test/fixtures/history_values.yml (example value for backend testing)

View File

@ -7,4 +7,5 @@ class Stats::Machine
include StatReservationConcern
attribute :machineId, Integer
attribute :machineDates, Array
end

View File

@ -7,4 +7,5 @@ class Stats::Space
include StatReservationConcern
attribute :spaceId, Integer
attribute :spaceDates, Array
end

View File

@ -65,7 +65,7 @@ class Event::CreateEventService
end
def occurrence_advanced_accounting(event)
AdvancedAccounting.new(code: event.advanced_accounting.code, analytical_section: event.advanced_accounting.analytical_section)
AdvancedAccounting.new(code: event.advanced_accounting&.code, analytical_section: event.advanced_accounting&.analytical_section)
end
end
end

View File

@ -30,6 +30,8 @@ class Statistics::Builders::ReservationsBuilderService
def add_custom_attributes(category, stat, reservation_data)
stat = add_event_attributes(category, stat, reservation_data)
stat = add_machine_attributes(category, stat, reservation_data)
stat = add_space_attributes(category, stat, reservation_data)
add_training_attributes(category, stat, reservation_data)
end
@ -50,5 +52,21 @@ class Statistics::Builders::ReservationsBuilderService
stat
end
def add_machine_attributes(category, stat, reservation_data)
return stat unless category == 'machine'
stat[:machineDates] = reservation_data[:slot_dates].map { |date| { name: date } }
stat
end
def add_space_attributes(category, stat, reservation_data)
return stat unless category == 'space'
stat[:spaceDates] = reservation_data[:slot_dates].map { |date| { name: date } }
stat
end
end
end

View File

@ -9,19 +9,21 @@ class Statistics::CleanerService
client = Elasticsearch::Model.client
%w[Account Event Machine Project Subscription Training User Space Order].each do |o|
model = "Stats::#{o}".constantize
client.delete_by_query(
index: model.index_name,
type: model.document_type,
body: {
query: {
terms: {
date: (to_date(options[:start_date]).to_date..to_date(options[:end_date]).to_date)
.to_a
.map { |d| format_date(d) }
dates = (to_date(options[:start_date]).to_date..to_date(options[:end_date]).to_date).to_a
# elasticsearch does not support more than 1024 query arguments
dates.each_slice(1024) do |slice_dates|
client.delete_by_query(
index: model.index_name,
type: model.document_type,
body: {
query: {
terms: {
date: slice_dates.map { |d| format_date(d) }
}
}
}
}
)
)
end
end
end
end

View File

@ -39,7 +39,7 @@ module Statistics::Concerns::HelpersConcern
def difference_in_hours(start_at, end_at)
if start_at.to_date == end_at.to_date
((end_at - start_at) / 60 / 60).to_i
((end_at - start_at) / 3600.0).to_i
else
end_at_to_start_date = end_at.change(year: start_at.year, month: start_at.month, day: start_at.day)
hours = ((end_at_to_start_date - start_at) / 60 / 60).to_i

View File

@ -54,7 +54,8 @@ class Statistics::FetcherService
machine_id: r.reservable.id,
machine_type: r.reservable.friendly_id,
machine_name: r.reservable.name,
nb_hours: r.slots.size,
slot_dates: r.slots.map(&:start_at).map(&:to_date),
nb_hours: (r.slots.map(&:duration).map(&:to_i).reduce(:+) / 3600.0).to_i,
ca: calcul_ca(r.original_invoice) }.merge(user_info(profile)))
end
result
@ -75,7 +76,8 @@ class Statistics::FetcherService
space_id: r.reservable.id,
space_name: r.reservable.name,
space_type: r.reservable.slug,
nb_hours: r.slots.size,
slot_dates: r.slots.map(&:start_at).map(&:to_date),
nb_hours: (r.slots.map(&:duration).map(&:to_i).reduce(:+) / 3600.0).to_i,
ca: calcul_ca(r.original_invoice) }.merge(user_info(profile)))
end
result

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
json.array!(@statistics) do |s|
json.extract! s, :id, :es_type_key, :label, :table, :ca
json.additional_fields s.statistic_fields do |f|
@ -12,8 +14,10 @@ json.array!(@statistics) do |s|
json.extract! st, :id, :key, :label
end
end
json.graph do
json.chart_type s.statistic_graph.chart_type
json.limit s.statistic_graph.limit
end if s.statistic_graph
end
if s.statistic_graph
json.graph do
json.chart_type s.statistic_graph.chart_type
json.limit s.statistic_graph.limit
end
end
end

View File

@ -16,7 +16,12 @@ module.exports = function (api) {
}
const defaultConfigFunc = require('shakapacker/package/babel/preset.js');
const resultConfig = defaultConfigFunc(api);
const resultConfig = {
...defaultConfigFunc(api),
assumptions: {
setPublicClassFields: true
}
};
const changesOnDefault = {
presets: [
@ -35,10 +40,7 @@ module.exports = function (api) {
isTestEnv && 'babel-plugin-dynamic-import-node',
'@babel/plugin-transform-destructuring',
[
'@babel/plugin-proposal-class-properties',
{
loose: true
}
'@babel/plugin-proposal-class-properties'
],
[
'@babel/plugin-proposal-object-rest-spread',

View File

@ -200,8 +200,8 @@ de:
#add a new machine
machines_new:
declare_a_new_machine: "Neue Maschine angeben"
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Achtung! Beim Erstellen einer neuen Maschine werden die Preise für alle Abonnements auf 0 initialisiert."
consider_changing_them_before_creating_any_reservation_slot: "Denken Sie daran, sie zu ändern, bevor Sie einen Reservierungsplatz erstellen."
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new machine, its prices are initialized at 0 for all subscriptions."
consider_changing_them_before_creating_any_reservation_slot: "Consider changing them before creating any reservation slot."
#machine edition
machines_edit:
machine_edit: "Maschine bearbeiten"
@ -370,12 +370,12 @@ de:
#track and monitor the trainings
trainings:
trainings_monitoring: "Schulungs-Überwachung"
plan_session: "Neue Sitzung planen"
trainings: "Schulungen"
plan_session: "Schedule a new session"
trainings: "Trainings"
add_a_new_training: "Neue Schulung hinzufügen"
name: "Name"
associated_machines: "Verknüpfte Maschinen"
number_of_tickets: "Anzahl der Tickets"
number_of_tickets: "Number of tickets"
select_a_training: "Schulung auswählen"
training: "Schulung"
date: "Datum"
@ -403,8 +403,8 @@ de:
#create a new training
trainings_new:
add_a_new_training: "Neue Schulung hinzufügen"
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Vorsicht bei der Erstellung eines Trainings, die Reservierungspreise stehen auf Null."
dont_forget_to_change_them_before_creating_slots_for_this_training: "Vergesse nicht, sie anzupassen, bevor du das Training aktivierst."
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Beware, when creating a training, its reservation prices are initialized at zero."
dont_forget_to_change_them_before_creating_slots_for_this_training: "Don't forget to change them before creating slots for this training."
#events tracking and management
events:
events_monitoring: "Ereignisüberwachung"
@ -610,15 +610,15 @@ de:
create_pack: "Dieses Paket erstellen"
pack_successfully_created: "Das neue Vorausbezahlungs-Paket wurde erfolgreich erstellt."
delete_pack:
pack_deleted: "Das Vorausbezahlungs-Paket wurde erfolgreich gelöscht."
unable_to_delete: "Paket konnte nicht gelöscht werden: "
delete_pack: "Vorausbezahlungs-Paket löschen"
confirm_delete: "Löschen"
delete_confirmation: "Sind Sie sicher, dass Sie dieses Paket löschen möchten? Dies ist nicht möglich, wenn das Paket bereits von Benutzern gekauft wurde."
pack_deleted: "The prepaid pack was successfully deleted."
unable_to_delete: "Unable to delete the prepaid pack: "
delete_pack: "Delete the prepaid pack"
confirm_delete: "Delete"
delete_confirmation: "Are you sure you want to delete this prepaid pack? This won't be possible if the pack was already bought by users."
edit_pack:
edit_pack: "Das Paket bearbeiten"
confirm_changes: "Änderungen bestätigen"
pack_successfully_updated: "Das Vorausbezahlungs-Paket wurde erfolgreich aktualisiert."
edit_pack: "Edit the pack"
confirm_changes: "Confirm changes"
pack_successfully_updated: "The prepaid pack was successfully updated."
create_extended_price:
new_extended_price: "Neuer erweiterter Preis"
new_extended_price_info: "Erweiterte Preise erlauben Ihnen die Festlegung von Preisen basierend auf benutzerdefinierten Zeitdauern anstelle der Standard-Stundensätze."
@ -1377,6 +1377,7 @@ de:
available_hours: "Öffnungszeiten für Buchung:"
available_tickets: "Verfügbare Tickets zur Buchung:"
date: "Datum"
reservation_date: "Reservation date"
user: "Nutzer"
gender: "Geschlecht"
age: "Alter"
@ -1821,9 +1822,9 @@ de:
#create a new space
space_new:
add_a_new_space: "Neuen Raum erstellen"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Achtung! Beim Erstellen eines neuen Raums wird sein Preis für alle Abonnements mit 0 angelegt."
consider_changing_its_prices_before_creating_any_reservation_slot: "Ändern Sie ggf. die Preise, bevor Sie Reservierungs-Slots erstellen."
add_this_space: "Diesen Raum hinzufügen"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new space, its prices are initialized at 0 for all subscriptions."
consider_changing_its_prices_before_creating_any_reservation_slot: "Consider changing its prices before creating any reservation slot."
add_this_space: "Add this space"
#modify an exiting space
space_edit:
edit_the_space_NAME: "Bearbeite den Raum: {NAME}"

View File

@ -1377,6 +1377,7 @@ en:
available_hours: "Hours available for booking:"
available_tickets: "Tickets available for booking:"
date: "Date"
reservation_date: "Reservation date"
user: "User"
gender: "Gender"
age: "Age"

View File

@ -200,8 +200,8 @@ es:
#add a new machine
machines_new:
declare_a_new_machine: "Declara una nueva máquina"
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Cuidado al crear una nueva máquina, los precios están inicializados a 0 para todas las subscripciones."
consider_changing_them_before_creating_any_reservation_slot: "Considera cambiarlos antes de crear cualquier ranura de reserva."
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new machine, its prices are initialized at 0 for all subscriptions."
consider_changing_them_before_creating_any_reservation_slot: "Consider changing them before creating any reservation slot."
#machine edition
machines_edit:
machine_edit: "Editar una máquina"
@ -403,8 +403,8 @@ es:
#create a new training
trainings_new:
add_a_new_training: "Add a new training"
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Tenga cuidado, al crear una formación, sus precios de reserva se inicializan en cero."
dont_forget_to_change_them_before_creating_slots_for_this_training: "No olvides cambiarlos antes de crear espacios para esta formación."
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Beware, when creating a training, its reservation prices are initialized at zero."
dont_forget_to_change_them_before_creating_slots_for_this_training: "Don't forget to change them before creating slots for this training."
#events tracking and management
events:
events_monitoring: "Monitoreo de eventos"
@ -1377,6 +1377,7 @@ es:
available_hours: "Horas disponibles para reservar:"
available_tickets: "Tickets disponibles para reservar:"
date: "Date"
reservation_date: "Reservation date"
user: "User"
gender: "Genero"
age: "Edad"
@ -1821,9 +1822,9 @@ es:
#create a new space
space_new:
add_a_new_space: "Añadir un espacio nuevo"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "¡Cuidado! Al crear un nuevo espacio, sus precios se inicializan en 0 para todas las suscripciones."
consider_changing_its_prices_before_creating_any_reservation_slot: "Considere cambiar sus precios antes de crear cualquier espacio de reserva."
add_this_space: "Añadir este espacio"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new space, its prices are initialized at 0 for all subscriptions."
consider_changing_its_prices_before_creating_any_reservation_slot: "Consider changing its prices before creating any reservation slot."
add_this_space: "Add this space"
#modify an exiting space
space_edit:
edit_the_space_NAME: "Edit the space: {NAME}"

View File

@ -1377,6 +1377,7 @@ fr:
available_hours: "Heures disponibles à la réservation :"
available_tickets: "Places disponibles à la reservation :"
date: "Date"
reservation_date: "Date de réservation"
user: "Utilisateur"
gender: "Genre"
age: "Âge"

View File

@ -200,8 +200,8 @@
#add a new machine
machines_new:
declare_a_new_machine: "Sett opp en ny maskin"
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Vær oppmerksom på at når en ny maskin settes opp blir alle priser satt lik null."
consider_changing_them_before_creating_any_reservation_slot: "Vurder å endre før nye reserveringer gjøres."
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new machine, its prices are initialized at 0 for all subscriptions."
consider_changing_them_before_creating_any_reservation_slot: "Consider changing them before creating any reservation slot."
#machine edition
machines_edit:
machine_edit: "Rediger en maskin"
@ -370,12 +370,12 @@
#track and monitor the trainings
trainings:
trainings_monitoring: "Oversikt over opplæring, kurs mm."
plan_session: "Planlegg en ny økt"
trainings: "Opplæringer/kurs"
plan_session: "Schedule a new session"
trainings: "Trainings"
add_a_new_training: "Legge til ny opplæring/nytt kurs"
name: "Navn"
associated_machines: "Tilknyttede maskiner"
number_of_tickets: "Antall billetter"
number_of_tickets: "Number of tickets"
select_a_training: "Velg opplæring/kurs"
training: "Opplæringer/kurs"
date: "Dato"
@ -403,8 +403,8 @@
#create a new training
trainings_new:
add_a_new_training: "Legge til ny opplæring/nytt kurs"
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Vær oppmerksom på at ved oppretting av kursing eller opplæring settes reservasjonsprisene lik null."
dont_forget_to_change_them_before_creating_slots_for_this_training: "Ikke glem å endre dem før du velger tidskluke for denne treningen."
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Beware, when creating a training, its reservation prices are initialized at zero."
dont_forget_to_change_them_before_creating_slots_for_this_training: "Don't forget to change them before creating slots for this training."
#events tracking and management
events:
events_monitoring: "Oversikt over arrangementer"
@ -610,15 +610,15 @@
create_pack: "Opprett denne pakken"
pack_successfully_created: "Den nye forhåndsbetalte pakken ble opprettet."
delete_pack:
pack_deleted: "Den forhåndsbetalte pakken ble slettet."
unable_to_delete: "Kan ikke slette forhåndsbetalt pakke: "
delete_pack: "Slette den forhåndsbetalte pakken"
confirm_delete: "Slett"
delete_confirmation: "Er du sikker på at du vil slette denne forhåndsbetalte pakken? Dette vil ikke være mulig hvis pakken allerede er kjøpt av brukere."
pack_deleted: "The prepaid pack was successfully deleted."
unable_to_delete: "Unable to delete the prepaid pack: "
delete_pack: "Delete the prepaid pack"
confirm_delete: "Delete"
delete_confirmation: "Are you sure you want to delete this prepaid pack? This won't be possible if the pack was already bought by users."
edit_pack:
edit_pack: "Rediger pakken"
confirm_changes: "Bekreft endringer"
pack_successfully_updated: "Den forhåndsbetalte pakken ble oppdatert."
edit_pack: "Edit the pack"
confirm_changes: "Confirm changes"
pack_successfully_updated: "The prepaid pack was successfully updated."
create_extended_price:
new_extended_price: "New extended price"
new_extended_price_info: "Extended prices allows you to define prices based on custom durations, instead of the default hourly rates."
@ -1377,6 +1377,7 @@
available_hours: "Timer tilgjengelig for reservering:"
available_tickets: "Billetter tilgjengelig for bestilling:"
date: "Dato"
reservation_date: "Reservation date"
user: "Bruker"
gender: "Kjønn"
age: "Alder"
@ -1821,9 +1822,9 @@
#create a new space
space_new:
add_a_new_space: "Legg til ny plass eller rom"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Pass på! Når du oppretter ny plass eller rom, settes alle priser til null for alle abonnementer."
consider_changing_its_prices_before_creating_any_reservation_slot: "Vurder å endre prisene før du lager en tidsluke."
add_this_space: "Legg til dette rommet/plassen"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new space, its prices are initialized at 0 for all subscriptions."
consider_changing_its_prices_before_creating_any_reservation_slot: "Consider changing its prices before creating any reservation slot."
add_this_space: "Add this space"
#modify an exiting space
space_edit:
edit_the_space_NAME: "Rediger rommet/plassen: {NAME}"

View File

@ -200,8 +200,8 @@ pt:
#add a new machine
machines_new:
declare_a_new_machine: "Criar nova máquina"
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Cuidado! Ao criar uma nova máquina, os preços são inicializados em 0 para todas as assinaturas."
consider_changing_them_before_creating_any_reservation_slot: "Concidere alterá-lo antes de criar qualquer slot de reserva."
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new machine, its prices are initialized at 0 for all subscriptions."
consider_changing_them_before_creating_any_reservation_slot: "Consider changing them before creating any reservation slot."
#machine edition
machines_edit:
machine_edit: "Editar máquina"
@ -370,12 +370,12 @@ pt:
#track and monitor the trainings
trainings:
trainings_monitoring: "Treinamentos"
plan_session: "Agendar uma nova sessão"
trainings: "Treinamentos"
plan_session: "Schedule a new session"
trainings: "Trainings"
add_a_new_training: "Adicionar um novo treinamento"
name: "Nome"
associated_machines: "Máquinas associadas"
number_of_tickets: "Número de vagas"
number_of_tickets: "Number of tickets"
select_a_training: "Selecione um treinamento"
training: "Treinamento"
date: "Data"
@ -403,8 +403,8 @@ pt:
#create a new training
trainings_new:
add_a_new_training: "Adicionar um novo treinamento"
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Cuidado, ao criar um treinamento, seu preço de reserva é inicializado em zero."
dont_forget_to_change_them_before_creating_slots_for_this_training: "Não se esqueça de alterá-lo antes de criar slots para este treinamento."
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Beware, when creating a training, its reservation prices are initialized at zero."
dont_forget_to_change_them_before_creating_slots_for_this_training: "Don't forget to change them before creating slots for this training."
#events tracking and management
events:
events_monitoring: "Monitoramento de eventos"
@ -610,15 +610,15 @@ pt:
create_pack: "Criar este pacote"
pack_successfully_created: "O novo pacote pré-pago foi criado com sucesso."
delete_pack:
pack_deleted: "O pacote pré-pago foi deletado com sucesso."
unable_to_delete: "Não foi possível deletar o pacote pré-pago: "
delete_pack: "Excluir o pacote pré-pago"
confirm_delete: "Deletar"
delete_confirmation: "Tem certeza que deseja excluir este pacote pré-pago? Isto não será possível se o pacote já foi comprado pelos usuários."
pack_deleted: "The prepaid pack was successfully deleted."
unable_to_delete: "Unable to delete the prepaid pack: "
delete_pack: "Delete the prepaid pack"
confirm_delete: "Delete"
delete_confirmation: "Are you sure you want to delete this prepaid pack? This won't be possible if the pack was already bought by users."
edit_pack:
edit_pack: "Editar o pacote"
confirm_changes: "Confirmar alterações"
pack_successfully_updated: "O pacote pré-pago foi atualizado com sucesso."
edit_pack: "Edit the pack"
confirm_changes: "Confirm changes"
pack_successfully_updated: "The prepaid pack was successfully updated."
create_extended_price:
new_extended_price: "Novo preço estendido"
new_extended_price_info: "Preços estendidos permitem que você defina preços baseados em durações personalizadas, ao invés das taxas padrão por hora."
@ -1377,6 +1377,7 @@ pt:
available_hours: "Horas disponíveis para reserva:"
available_tickets: "Vagas disponíveis para reserva:"
date: "Data"
reservation_date: "Reservation date"
user: "Usuário"
gender: "Gênero"
age: "Ano"
@ -1474,9 +1475,9 @@ pt:
max_visibility: "Visibilidade máxima (em meses)"
visibility_for_yearly_members: "Para inscrições atuais de pelo menos 1 ano"
visibility_for_other_members: "Para todos os outros membros"
reservation_deadline: "Prevent last minute booking"
reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start."
deadline_minutes: "Prior period (minutes)"
reservation_deadline: "Impedir a reserva da última hora"
reservation_deadline_help: "Se você aumentar o período prévio, os membros não serão capazes de reservar um slot X minutos antes do seu início."
deadline_minutes: "Período prévio (minutos)"
ability_for_the_users_to_move_their_reservations: "Habilidade para os usuários mover suas reservas"
reservations_shifting: "Mudança de reservas"
prior_period_hours: "Período anterior (horas)"
@ -1821,9 +1822,9 @@ pt:
#create a new space
space_new:
add_a_new_space: "Adicionar um novo espaço"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Cuidado! Ao criar um novo espaço, seus preços são inicializados em 0 para todas as assinaturas."
consider_changing_its_prices_before_creating_any_reservation_slot: "Considere alterar seus preços antes de criar qualquer slot de reserva."
add_this_space: "Adicionar este espaço"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new space, its prices are initialized at 0 for all subscriptions."
consider_changing_its_prices_before_creating_any_reservation_slot: "Consider changing its prices before creating any reservation slot."
add_this_space: "Add this space"
#modify an exiting space
space_edit:
edit_the_space_NAME: "Editar o espaço: {NAME}"

View File

@ -27,7 +27,7 @@ zu:
confirm: "crwdns36099:0crwdne36099:0"
deleted: "crwdns36101:0crwdne36101:0"
unable_to_delete: "crwdns36103:0crwdne36103:0"
confirm_delete_supporting_documents_type: "crwdns36105:0crwdne36105:0"
confirm_delete_supporting_documents_type: "crwdns36707:0crwdne36707:0"
machine_form:
name: "crwdns31659:0crwdne31659:0"
illustration: "crwdns31661:0crwdne31661:0"
@ -40,7 +40,7 @@ zu:
disabled_help: "crwdns31677:0crwdne31677:0"
reservable: "crwdns36217:0crwdne36217:0"
reservable_help: "crwdns36253:0crwdne36253:0"
ACTION_machine: "crwdns31757:0ACTION={ACTION}crwdne31757:0"
ACTION_machine: "crwdns36709:0ACTION={ACTION}crwdne36709:0"
create_success: "crwdns31759:0crwdne31759:0"
update_success: "crwdns31761:0crwdne31761:0"
training_form:
@ -56,7 +56,7 @@ zu:
public_help: "crwdns31781:0crwdne31781:0"
disable_training: "crwdns31783:0crwdne31783:0"
disabled_help: "crwdns31785:0crwdne31785:0"
ACTION_training: "crwdns31787:0ACTION={ACTION}crwdne31787:0"
ACTION_training: "crwdns36711:0ACTION={ACTION}crwdne36711:0"
create_success: "crwdns31789:0crwdne31789:0"
update_success: "crwdns31791:0crwdne31791:0"
space_form:
@ -69,7 +69,7 @@ zu:
default_seats: "crwdns31805:0crwdne31805:0"
disable_space: "crwdns31807:0crwdne31807:0"
disabled_help: "crwdns31809:0crwdne31809:0"
ACTION_space: "crwdns31811:0ACTION={ACTION}crwdne31811:0"
ACTION_space: "crwdns36713:0ACTION={ACTION}crwdne36713:0"
create_success: "crwdns31813:0crwdne31813:0"
update_success: "crwdns31815:0crwdne31815:0"
event_form:
@ -98,7 +98,7 @@ zu:
event_themes: "crwdns31861:0crwdne31861:0"
age_range: "crwdns31863:0crwdne31863:0"
add_price: "crwdns31865:0crwdne31865:0"
ACTION_event: "crwdns31867:0ACTION={ACTION}crwdne31867:0"
ACTION_event: "crwdns36715:0ACTION={ACTION}crwdne36715:0"
create_success: "crwdns31869:0crwdne31869:0"
events_updated: "crwdns31871:0COUNT={COUNT}crwdnd31871:0COUNT={COUNT}crwdne31871:0"
events_not_updated: "crwdns31873:0TOTAL={TOTAL}crwdnd31873:0TOTAL={TOTAL}crwdnd31873:0COUNT={COUNT}crwdnd31873:0COUNT={COUNT}crwdne31873:0"
@ -200,8 +200,8 @@ zu:
#add a new machine
machines_new:
declare_a_new_machine: "crwdns24050:0crwdne24050:0"
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "crwdns24052:0crwdne24052:0"
consider_changing_them_before_creating_any_reservation_slot: "crwdns24054:0crwdne24054:0"
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "crwdns36717:0crwdne36717:0"
consider_changing_them_before_creating_any_reservation_slot: "crwdns36719:0crwdne36719:0"
#machine edition
machines_edit:
machine_edit: "crwdns24056:0crwdne24056:0"
@ -370,12 +370,12 @@ zu:
#track and monitor the trainings
trainings:
trainings_monitoring: "crwdns24368:0crwdne24368:0"
plan_session: "crwdns24370:0crwdne24370:0"
trainings: "crwdns24372:0crwdne24372:0"
plan_session: "crwdns36721:0crwdne36721:0"
trainings: "crwdns36723:0crwdne36723:0"
add_a_new_training: "crwdns24374:0crwdne24374:0"
name: "crwdns24376:0crwdne24376:0"
associated_machines: "crwdns24378:0crwdne24378:0"
number_of_tickets: "crwdns24380:0crwdne24380:0"
number_of_tickets: "crwdns36725:0crwdne36725:0"
select_a_training: "crwdns24382:0crwdne24382:0"
training: "crwdns24384:0crwdne24384:0"
date: "crwdns24386:0crwdne24386:0"
@ -403,8 +403,8 @@ zu:
#create a new training
trainings_new:
add_a_new_training: "crwdns24430:0crwdne24430:0"
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "crwdns24432:0crwdne24432:0"
dont_forget_to_change_them_before_creating_slots_for_this_training: "crwdns24434:0crwdne24434:0"
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "crwdns36727:0crwdne36727:0"
dont_forget_to_change_them_before_creating_slots_for_this_training: "crwdns36729:0crwdne36729:0"
#events tracking and management
events:
events_monitoring: "crwdns24436:0crwdne24436:0"
@ -610,15 +610,15 @@ zu:
create_pack: "crwdns24804:0crwdne24804:0"
pack_successfully_created: "crwdns24806:0crwdne24806:0"
delete_pack:
pack_deleted: "crwdns24808:0crwdne24808:0"
unable_to_delete: "crwdns24810:0crwdne24810:0"
delete_pack: "crwdns24812:0crwdne24812:0"
confirm_delete: "crwdns24814:0crwdne24814:0"
delete_confirmation: "crwdns24816:0crwdne24816:0"
pack_deleted: "crwdns36731:0crwdne36731:0"
unable_to_delete: "crwdns36733:0crwdne36733:0"
delete_pack: "crwdns36735:0crwdne36735:0"
confirm_delete: "crwdns36737:0crwdne36737:0"
delete_confirmation: "crwdns36739:0crwdne36739:0"
edit_pack:
edit_pack: "crwdns24818:0crwdne24818:0"
confirm_changes: "crwdns24820:0crwdne24820:0"
pack_successfully_updated: "crwdns24822:0crwdne24822:0"
edit_pack: "crwdns36741:0crwdne36741:0"
confirm_changes: "crwdns36743:0crwdne36743:0"
pack_successfully_updated: "crwdns36745:0crwdne36745:0"
create_extended_price:
new_extended_price: "crwdns24824:0crwdne24824:0"
new_extended_price_info: "crwdns24826:0crwdne24826:0"
@ -1377,6 +1377,7 @@ zu:
available_hours: "crwdns26262:0crwdne26262:0"
available_tickets: "crwdns26264:0crwdne26264:0"
date: "crwdns26266:0crwdne26266:0"
reservation_date: "crwdns36747:0crwdne36747:0"
user: "crwdns26268:0crwdne26268:0"
gender: "crwdns26270:0crwdne26270:0"
age: "crwdns26272:0crwdne26272:0"
@ -1821,9 +1822,9 @@ zu:
#create a new space
space_new:
add_a_new_space: "crwdns27066:0crwdne27066:0"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "crwdns27068:0crwdne27068:0"
consider_changing_its_prices_before_creating_any_reservation_slot: "crwdns27070:0crwdne27070:0"
add_this_space: "crwdns27072:0crwdne27072:0"
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "crwdns36749:0crwdne36749:0"
consider_changing_its_prices_before_creating_any_reservation_slot: "crwdns36751:0crwdne36751:0"
add_this_space: "crwdns36753:0crwdne36753:0"
#modify an exiting space
space_edit:
edit_the_space_NAME: "crwdns27074:0{NAME}crwdne27074:0"
@ -2174,8 +2175,8 @@ zu:
assigning_category_info: "crwdns31428:0crwdne31428:0"
assigning_machines: "crwdns31430:0crwdne31430:0"
assigning_machines_info: "crwdns31432:0crwdne31432:0"
product_description: "crwdns31434:0crwdne31434:0"
product_description_info: "crwdns31436:0crwdne31436:0"
product_description: "crwdns36755:0crwdne36755:0"
product_description_info: "crwdns36757:0crwdne36757:0"
product_files: "crwdns31438:0crwdne31438:0"
product_files_info: "crwdns31440:0crwdne31440:0"
add_product_file: "crwdns31442:0crwdne31442:0"
@ -2191,7 +2192,7 @@ zu:
save_reminder: "crwdns31460:0crwdne31460:0"
low_stock_threshold: "crwdns31462:0crwdne31462:0"
stock_threshold_toggle: "crwdns31464:0crwdne31464:0"
stock_threshold_information: "crwdns31466:0crwdne31466:0"
stock_threshold_information: "crwdns36759:0crwdne36759:0"
low_stock: "crwdns31468:0crwdne31468:0"
threshold_level: "crwdns31470:0crwdne31470:0"
threshold_alert: "crwdns31472:0crwdne31472:0"

View File

@ -145,18 +145,18 @@ pt:
edit: "Editar"
reservations:
reservations_panel:
title_Space: "Minhas reservas de espaços"
title_Machine: "Minhas reservas de máquinas"
upcoming: "Próximas"
past: "Passadas"
slots_details: "Detalhes da reserva"
no_reservations: "Sem reservas"
show_more: "Mostrar mais"
title_Space: "My space reservations"
title_Machine: "My machines reservations"
upcoming: "Upcoming"
past: "Past"
slots_details: "Slots details"
no_reservations: "No reservations"
show_more: "Show more"
credits_panel:
title_Space: "Meus créditos de espaços"
title_Machine: "Meus créditos de máquinas"
reamaining_credits_html: "<strong>{NAME}</strong>: Você pode fazer <em>{REMAINING} {REMAINING, plural, one{reserva} other{reservas}}</em> gratuitamente. Você já usou {USED} {USED, plural, one{credito} other{creditos}} da sua assinatura."
no_credits: "Você não tem nenhum crédito ainda. Algumas assinaturas podem permitir que você reserve alguns slots gratuitamente."
title_Space: "My space credits"
title_Machine: "My machines credits"
reamaining_credits_html: "<strong>{NAME}</strong>: You can book <em>{REMAINING} {REMAINING, plural, one{slot} other{slots}}</em> for free. You have already used {USED} {USED, plural, one{credit} other{credits}} from your current subscription."
no_credits: "You don't have any credits yet. Some subscriptions may allow you to book some slots for free."
#public profil of a member
members_show:
members_list: "Lista de membros"

View File

@ -145,18 +145,18 @@ zu:
edit: "crwdns27632:0crwdne27632:0"
reservations:
reservations_panel:
title_Space: "crwdns36333:0crwdne36333:0"
title_Machine: "crwdns36335:0crwdne36335:0"
upcoming: "crwdns36337:0crwdne36337:0"
past: "crwdns36339:0crwdne36339:0"
slots_details: "crwdns36341:0crwdne36341:0"
no_reservations: "crwdns36343:0crwdne36343:0"
show_more: "crwdns36345:0crwdne36345:0"
title_Space: "crwdns36761:0crwdne36761:0"
title_Machine: "crwdns36763:0crwdne36763:0"
upcoming: "crwdns36765:0crwdne36765:0"
past: "crwdns36767:0crwdne36767:0"
slots_details: "crwdns36769:0crwdne36769:0"
no_reservations: "crwdns36771:0crwdne36771:0"
show_more: "crwdns36773:0crwdne36773:0"
credits_panel:
title_Space: "crwdns36347:0crwdne36347:0"
title_Machine: "crwdns36349:0crwdne36349:0"
reamaining_credits_html: "crwdns36351:0NAME={NAME}crwdnd36351:0REMAINING={REMAINING}crwdnd36351:0REMAINING={REMAINING}crwdnd36351:0USED={USED}crwdnd36351:0USED={USED}crwdne36351:0"
no_credits: "crwdns36353:0crwdne36353:0"
title_Space: "crwdns36775:0crwdne36775:0"
title_Machine: "crwdns36777:0crwdne36777:0"
reamaining_credits_html: "crwdns36779:0NAME={NAME}crwdnd36779:0REMAINING={REMAINING}crwdnd36779:0REMAINING={REMAINING}crwdnd36779:0USED={USED}crwdnd36779:0USED={USED}crwdne36779:0"
no_credits: "crwdns36781:0crwdne36781:0"
#public profil of a member
members_show:
members_list: "crwdns27656:0crwdne27656:0"

View File

@ -169,13 +169,13 @@ de:
projects_list:
the_fablab_projects: "The projects"
add_a_project: "Projekt hinzufügen"
search_over_the_whole_network: "Suche über das gesamte Fab-Manager-Netzwerk"
search_over_the_whole_network: "Search over the whole Fab-manager network"
tooltip_openlab_projects_switch: "Mit der Suche über das gesamte Netzwerk können Sie die Projekte aller Fab-Manager durchsuchen, die diese Funktion nutzen!"
openlab_search_not_available_at_the_moment: "Suche über das gesamte Netzwerk ist derzeit nicht verfügbar. Sie können nach Projekten auf dieser Plattform suchen."
project_search_result_is_empty: "Leider haben wir keine Ergebnisse gefunden, die Ihren Suchkriterien entsprechen."
reset_all_filters: "Alle Filter zurücksetzen"
keywords: "Schlüsselwörter"
search: "Suche"
search: "Search"
all_projects: "Alle Projekte"
my_projects: "Meine Projekte"
projects_to_whom_i_take_part_in: "Projekte, an denen ich beteiligt bin"

View File

@ -169,13 +169,13 @@ es:
projects_list:
the_fablab_projects: "The projects"
add_a_project: "Añadir un proyecto"
search_over_the_whole_network: "Buscar en toda la red de FabLab"
search_over_the_whole_network: "Search over the whole Fab-manager network"
tooltip_openlab_projects_switch: "La busqueda en toda la red le permite buscar los proyectos de todos los FabLab que usan esta característica"
openlab_search_not_available_at_the_moment: "La busqueda en toda la red no está disponible en este momento. Puede seguir buscando proyectos en este FabLab."
project_search_result_is_empty: "Lo sentimos, no hemos encontrado nada."
reset_all_filters: "Limpiar filtros"
keywords: "Palabras clave"
search: "Buscar"
search: "Search"
all_projects: "Todos los proyectos"
my_projects: "Mis proyectos"
projects_to_whom_i_take_part_in: "Proyectos de los que formo parte"

View File

@ -169,13 +169,13 @@
projects_list:
the_fablab_projects: "The projects"
add_a_project: "Legg til et prosjekt"
search_over_the_whole_network: "Søk over hele Fab-manager-nettverket"
search_over_the_whole_network: "Search over the whole Fab-manager network"
tooltip_openlab_projects_switch: "Søk i hele nettverket lar deg søke i prosjekter for hver Fab-manager ved hjelp av denne funksjonen!"
openlab_search_not_available_at_the_moment: "Det er ikke mulig å søke over hele nettverket for øyeblikket. Du kan fortsatt søke over prosjektene her."
project_search_result_is_empty: "Beklager, fant vi ingen resultater som samsvarte med dine søkekriterier."
reset_all_filters: "Tilbakestill alle filtre"
keywords: "Nøkkelord"
search: "Søk"
search: "Search"
all_projects: "Alle prosjekter"
my_projects: "Mine prosjekter"
projects_to_whom_i_take_part_in: "Prosjekter jeg deltar i"

View File

@ -169,13 +169,13 @@ pt:
projects_list:
the_fablab_projects: "The projects"
add_a_project: "Adicionar projeto"
search_over_the_whole_network: "Pesquisar em todos os FabLabs"
search_over_the_whole_network: "Search over the whole Fab-manager network"
tooltip_openlab_projects_switch: "A busca em todos os FabLabs busca projetos em todos os FabLabs que usam o Fab-manager !"
openlab_search_not_available_at_the_moment: "A busca em toda a rede de FabLabs não está disponível no momento. Você pode procurar por projetos nesta plataforma."
project_search_result_is_empty: "Desculpe, nós não achamos nenhum resultado para sua pesquisa."
reset_all_filters: "Resetar todos os filtros"
keywords: "Palavras-chave"
search: "Procurar"
search: "Search"
all_projects: "Todos os projetos"
my_projects: "Meus Projetos"
projects_to_whom_i_take_part_in: "Projetos que eu participo"

View File

@ -169,13 +169,13 @@ zu:
projects_list:
the_fablab_projects: "crwdns36237:0crwdne36237:0"
add_a_project: "crwdns28062:0crwdne28062:0"
search_over_the_whole_network: "crwdns28064:0crwdne28064:0"
search_over_the_whole_network: "crwdns36783:0crwdne36783:0"
tooltip_openlab_projects_switch: "crwdns28066:0crwdne28066:0"
openlab_search_not_available_at_the_moment: "crwdns28068:0crwdne28068:0"
project_search_result_is_empty: "crwdns28070:0crwdne28070:0"
reset_all_filters: "crwdns28072:0crwdne28072:0"
keywords: "crwdns28074:0crwdne28074:0"
search: "crwdns28076:0crwdne28076:0"
search: "crwdns36785:0crwdne36785:0"
all_projects: "crwdns28078:0crwdne28078:0"
my_projects: "crwdns28080:0crwdne28080:0"
projects_to_whom_i_take_part_in: "crwdns28082:0crwdne28082:0"

View File

@ -13,8 +13,8 @@ de:
activerecord:
attributes:
product:
amount: "The price"
slug: "URL"
amount: "Der Preis"
slug: "Link"
errors:
#CarrierWave
messages:
@ -64,7 +64,7 @@ de:
i_ve_reserved: "Ich reservierte"
length_must_be_slot_multiple: "muss mindestens %{MIN} Minuten nach dem Startdatum liegen"
must_be_associated_with_at_least_1_machine: "muss mindestens einer Maschine zugeordnet sein"
deleted_user: "Deleted user"
deleted_user: "Gelöschte Benutzer"
#members management
members:
unable_to_change_the_group_while_a_subscription_is_running: "Die Gruppe kann während eines Abonnements nicht geändert werden"
@ -133,8 +133,8 @@ de:
error_invoice: "Fehlerhafte Rechnung. Die folgenden Artikel sind nicht gebucht. Bitte kontaktieren Sie das FabLab für eine Rückerstattung."
prepaid_pack: "Prepaid-Stundenpaket"
pack_item: "Paket von %{COUNT} Stunden für %{ITEM}"
order: "Your order on the store"
unable_to_find_pdf: "We cannot find your invoice. If you ordered recently, it may have not been generated yet. Please retry in a moment."
order: "Ihre Bestellung im Shop"
unable_to_find_pdf: "Wir können Ihre Rechnung nicht finden. Wenn Sie erst kürzlich bestellt haben, wurde sie möglicherweise noch nicht generiert. Bitte versuchen Sie es in einem Moment erneut."
#PDF payment schedule generation
payment_schedules:
schedule_reference: "Zahlungsplan Referenz: %{REF}"
@ -373,7 +373,7 @@ de:
view_results: "Ergebnisse anzeigen."
notify_admin_low_stock_threshold:
low_stock: "Low stock for %{PRODUCT}. "
view_product: "View the product."
view_product: "Produkt anzeigen."
notify_member_about_coupon:
enjoy_a_discount_of_PERCENT_with_code_CODE: "Erhalten Sie %{PERCENT}% Rabatt mit dem Code %{CODE}"
enjoy_a_discount_of_AMOUNT_with_code_CODE: "Erhalten Sie %{AMOUNT}% Rabatt mit dem Code %{CODE}"
@ -418,11 +418,11 @@ de:
notify_admin_user_proof_of_identity_files_updated:
proof_of_identity_files_uploaded: "Proof of identity changed by Member <strong><em>%{NAME}</strong></em>."
notify_user_is_validated:
account_validated: "Your account is valid."
account_validated: "Dein Account ist gültig."
notify_user_is_invalidated:
account_invalidated: "Your account is invalid."
account_invalidated: "Dein Account ist ungültig."
notify_user_proof_of_identity_refusal:
refusal: "Your proof of identity are not accepted"
refusal: "Ihr Identitätsnachweis wird nicht akzeptiert"
notify_admin_user_proof_of_identity_refusal:
refusal: "Member's proof of identity <strong><em>%{NAME}</strong></em> refused."
notify_user_order_is_ready:
@ -435,8 +435,10 @@ de:
statistics:
subscriptions: "Abonnements"
machines_hours: "Maschinen-Slots"
machine_dates: "Slots dates"
space_dates: "Slots dates"
spaces: "Räume"
orders: "Orders"
orders: "Bestellungen"
trainings: "Schulungen"
events: "Veranstaltungen"
registrations: "Anmeldungen"
@ -453,6 +455,7 @@ de:
components: "Komponenten"
machines: "Maschinen"
user_id: "Nutzer-ID"
group: "Group"
bookings: "Buchungen"
hours_number: "Stundenzahl"
tickets_number: "Ticket Nummer"
@ -460,9 +463,9 @@ de:
account_creation: "Benutzerkontenerstellung"
project_publication: "Projektveröffentlichung"
duration: "Dauer"
store: "Store"
paid-processed: "Paid and/or processed"
aborted: "Aborted"
store: "Shop"
paid-processed: "Bezahlt und/oder bearbeitet"
aborted: "Abgebrochen"
#statistics exports to the Excel file format
export:
entries: "Einträge"
@ -478,7 +481,7 @@ de:
type: "Typ"
male: "Männlich"
female: "Weiblich"
deleted_user: "Deleted user"
deleted_user: "Gelöschte Benutzer"
#initial price's category for events, created to replace the old "reduced amount" property
price_category:
reduced_fare: "Ermäßigter Tarif"
@ -636,20 +639,20 @@ de:
overlapping_categories: "Kategorien zur Vorbeugung überlappender Buchungen"
extended_prices_in_same_day: "Erweiterte Preise am selben Tag"
public_registrations: "Öffentliche Registrierungen"
facebook: "facebook"
twitter: "twitter"
viadeo: "viadeo"
linkedin: "linkedin"
facebook: "Facebook"
twitter: "Twitter"
viadeo: "Viadeo"
linkedin: "LinkedIn"
instagram: "instagram"
youtube: "youtube"
vimeo: "vimeo"
dailymotion: "dailymotion"
github: "github"
youtube: "YouTube"
vimeo: "Vimeo"
dailymotion: "Dailymotion"
github: "Github"
echosciences: "echosciences"
pinterest: "pinterest"
lastfm: "lastfm"
flickr: "flickr"
machines_module: "Machines module"
pinterest: "Pinterest"
lastfm: "Lastfm"
flickr: "Flickr"
machines_module: "Maschinenmodul"
user_change_group: "Allow users to change their group"
show_username_in_admin_list: "Show the username in the admin's members list"
store_module: "Store module"

View File

@ -435,6 +435,8 @@ en:
statistics:
subscriptions: "Subscriptions"
machines_hours: "Machines slots"
machine_dates: "Slots dates"
space_dates: "Slots dates"
spaces: "Spaces"
orders: "Orders"
trainings: "Trainings"
@ -453,6 +455,7 @@ en:
components: "Components"
machines: "Machines"
user_id: "User ID"
group: "Group"
bookings: "Bookings"
hours_number: "Hours number"
tickets_number: "Tickets number"

View File

@ -435,6 +435,8 @@ es:
statistics:
subscriptions: "Suscripciones"
machines_hours: "Machine slots"
machine_dates: "Slots dates"
space_dates: "Slots dates"
spaces: "Espacios"
orders: "Orders"
trainings: "Cursos"
@ -453,6 +455,7 @@ es:
components: "Componentes"
machines: "Máquinas"
user_id: "ID de usuario"
group: "Group"
bookings: "Reservas"
hours_number: "Número de horas"
tickets_number: "Número de entradas"

View File

@ -435,6 +435,8 @@ fr:
statistics:
subscriptions: "Abonnements"
machines_hours: "Créneaux machines"
machine_dates: "Date des créneaux"
space_dates: "Dates des créneaux"
spaces: "Espaces"
orders: "Commandes"
trainings: "Formations"
@ -453,6 +455,7 @@ fr:
components: "Composants"
machines: "Machines"
user_id: "ID Utilisateur"
group: "Groupe"
bookings: "Réservations"
hours_number: "Nombre d'heures"
tickets_number: "Nombre de places"

View File

@ -247,7 +247,7 @@ de:
category_members: "der Mitglieder"
click_to_view_results: "Klicken Sie hier, um die Ergebnisse anzuzeigen"
notify_admin_low_stock_threshold:
subject: "Low stock alert"
subject: "Warnung niedriger Bestand"
body:
low_stock: "A new stock movement of %{PRODUCT} has exceeded the low stock threshold."
stocks_state_html: "Current stock status: <ul><li>internal: %{INTERNAL}</li><li>external: %{EXTERNAL}</li></ul>"

View File

@ -435,6 +435,8 @@
statistics:
subscriptions: "Subscriptions"
machines_hours: "Machines slots"
machine_dates: "Slots dates"
space_dates: "Slots dates"
spaces: "Spaces"
orders: "Orders"
trainings: "Trainings"
@ -453,6 +455,7 @@
components: "Komponenter"
machines: "Maskiner"
user_id: "Bruker-ID"
group: "Group"
bookings: "Reservasjoner"
hours_number: "Timer nummer"
tickets_number: "Tickets number"

View File

@ -435,6 +435,8 @@ pt:
statistics:
subscriptions: "Assinaturas"
machines_hours: "Slots de máquina"
machine_dates: "Slots dates"
space_dates: "Slots dates"
spaces: "Espaços"
orders: "Orders"
trainings: "Treinamentos"
@ -453,6 +455,7 @@ pt:
components: "Componentes"
machines: "Máquinas"
user_id: "ID de usuário"
group: "Group"
bookings: "Reservas"
hours_number: "Número de horas"
tickets_number: "Número de vagas"

View File

@ -435,6 +435,8 @@ zu:
statistics:
subscriptions: "crwdns3689:0crwdne3689:0"
machines_hours: "crwdns4561:0crwdne4561:0"
machine_dates: "crwdns36787:0crwdne36787:0"
space_dates: "crwdns36789:0crwdne36789:0"
spaces: "crwdns3693:0crwdne3693:0"
orders: "crwdns31713:0crwdne31713:0"
trainings: "crwdns3695:0crwdne3695:0"
@ -453,6 +455,7 @@ zu:
components: "crwdns3721:0crwdne3721:0"
machines: "crwdns3723:0crwdne3723:0"
user_id: "crwdns3725:0crwdne3725:0"
group: "crwdns36791:0crwdne36791:0"
bookings: "crwdns3727:0crwdne3727:0"
hours_number: "crwdns3729:0crwdne3729:0"
tickets_number: "crwdns3731:0crwdne3731:0"

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
# From this migration we remove is_rolling:true as the default value, because this introduced a bug:
# if the user leaves the form empty, the plan is considered as rolling which is not the desired behavior
class ChangeDefaultForPlanIsRolling < ActiveRecord::Migration[5.2]
def change
change_column_default :plans, :is_rolling, from: true, to: nil
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2023_01_19_143245) do
ActiveRecord::Schema.define(version: 2023_01_31_104958) do
# These are extensions that must be enabled in order to support this database
enable_extension "fuzzystrmatch"
@ -150,6 +150,110 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
t.index ["tag_id"], name: "index_availability_tags_on_tag_id"
end
create_table "cart_item_coupons", force: :cascade do |t|
t.bigint "coupon_id"
t.bigint "customer_profile_id"
t.bigint "operator_profile_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["coupon_id"], name: "index_cart_item_coupons_on_coupon_id"
t.index ["customer_profile_id"], name: "index_cart_item_coupons_on_customer_profile_id"
t.index ["operator_profile_id"], name: "index_cart_item_coupons_on_operator_profile_id"
end
create_table "cart_item_event_reservation_tickets", force: :cascade do |t|
t.integer "booked"
t.bigint "event_price_category_id"
t.bigint "cart_item_event_reservation_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["cart_item_event_reservation_id"], name: "index_cart_item_tickets_on_cart_item_event_reservation"
t.index ["event_price_category_id"], name: "index_cart_item_tickets_on_event_price_category"
end
create_table "cart_item_event_reservations", force: :cascade do |t|
t.integer "normal_tickets"
t.bigint "event_id"
t.bigint "operator_profile_id"
t.bigint "customer_profile_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["customer_profile_id"], name: "index_cart_item_event_reservations_on_customer_profile_id"
t.index ["event_id"], name: "index_cart_item_event_reservations_on_event_id"
t.index ["operator_profile_id"], name: "index_cart_item_event_reservations_on_operator_profile_id"
end
create_table "cart_item_free_extensions", force: :cascade do |t|
t.bigint "subscription_id"
t.datetime "new_expiration_date"
t.bigint "customer_profile_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["customer_profile_id"], name: "index_cart_item_free_extensions_on_customer_profile_id"
t.index ["subscription_id"], name: "index_cart_item_free_extensions_on_subscription_id"
end
create_table "cart_item_payment_schedules", force: :cascade do |t|
t.bigint "plan_id"
t.bigint "coupon_id"
t.boolean "requested"
t.datetime "start_at"
t.bigint "customer_profile_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["coupon_id"], name: "index_cart_item_payment_schedules_on_coupon_id"
t.index ["customer_profile_id"], name: "index_cart_item_payment_schedules_on_customer_profile_id"
t.index ["plan_id"], name: "index_cart_item_payment_schedules_on_plan_id"
end
create_table "cart_item_prepaid_packs", force: :cascade do |t|
t.bigint "prepaid_pack_id"
t.bigint "customer_profile_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["customer_profile_id"], name: "index_cart_item_prepaid_packs_on_customer_profile_id"
t.index ["prepaid_pack_id"], name: "index_cart_item_prepaid_packs_on_prepaid_pack_id"
end
create_table "cart_item_reservation_slots", force: :cascade do |t|
t.string "cart_item_type"
t.bigint "cart_item_id"
t.bigint "slot_id"
t.bigint "slots_reservation_id"
t.boolean "offered", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["cart_item_type", "cart_item_id"], name: "index_cart_item_slots_on_cart_item"
t.index ["slot_id"], name: "index_cart_item_reservation_slots_on_slot_id"
t.index ["slots_reservation_id"], name: "index_cart_item_reservation_slots_on_slots_reservation_id"
end
create_table "cart_item_reservations", force: :cascade do |t|
t.string "reservable_type"
t.bigint "reservable_id"
t.bigint "plan_id"
t.boolean "new_subscription"
t.bigint "customer_profile_id"
t.bigint "operator_profile_id"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["customer_profile_id"], name: "index_cart_item_reservations_on_customer_profile_id"
t.index ["operator_profile_id"], name: "index_cart_item_reservations_on_operator_profile_id"
t.index ["plan_id"], name: "index_cart_item_reservations_on_plan_id"
t.index ["reservable_type", "reservable_id"], name: "index_cart_item_reservations_on_reservable"
end
create_table "cart_item_subscriptions", force: :cascade do |t|
t.bigint "plan_id"
t.datetime "start_at"
t.bigint "customer_profile_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["customer_profile_id"], name: "index_cart_item_subscriptions_on_customer_profile_id"
t.index ["plan_id"], name: "index_cart_item_subscriptions_on_plan_id"
end
create_table "categories", id: :serial, force: :cascade do |t|
t.string "name"
t.datetime "created_at"
@ -173,6 +277,7 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
t.datetime "updated_at", null: false
t.string "validity_per_user"
t.integer "amount_off"
t.index ["code"], name: "index_coupons_on_code", unique: true
end
create_table "credits", id: :serial, force: :cascade do |t|
@ -621,7 +726,7 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "training_credit_nb", default: 0
t.boolean "is_rolling", default: true
t.boolean "is_rolling"
t.text "description"
t.string "type"
t.string "base_name"
@ -793,8 +898,10 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
t.datetime "published_at"
t.integer "author_statistic_profile_id"
t.tsvector "search_vector"
t.bigint "status_id"
t.index ["search_vector"], name: "projects_search_vector_idx", using: :gin
t.index ["slug"], name: "index_projects_on_slug", unique: true
t.index ["status_id"], name: "index_projects_on_status_id"
end
create_table "projects_components", id: :serial, force: :cascade do |t|
@ -899,13 +1006,15 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
t.datetime "end_at"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "availability_id"
t.integer "availability_id", null: false
t.jsonb "places", default: [], null: false
t.index ["availability_id"], name: "index_slots_on_availability_id"
t.index ["places"], name: "index_slots_on_places", using: :gin
end
create_table "slots_reservations", id: :serial, force: :cascade do |t|
t.integer "slot_id"
t.integer "reservation_id"
t.integer "slot_id", null: false
t.integer "reservation_id", null: false
t.datetime "ex_start_at"
t.datetime "ex_end_at"
t.datetime "canceled_at"
@ -1035,6 +1144,12 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
t.index ["statistic_index_id"], name: "index_statistic_types_on_statistic_index_id"
end
create_table "statuses", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "stylesheets", id: :serial, force: :cascade do |t|
t.text "contents"
t.datetime "created_at", null: false
@ -1084,6 +1199,13 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
t.text "description"
t.boolean "public_page", default: true
t.boolean "disabled"
t.boolean "auto_cancel"
t.integer "auto_cancel_threshold"
t.integer "auto_cancel_deadline"
t.boolean "authorization"
t.integer "authorization_period"
t.boolean "invalidation"
t.integer "invalidation_period"
t.index ["slug"], name: "index_trainings_on_slug", unique: true
end
@ -1217,6 +1339,28 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
add_foreign_key "auth_provider_mappings", "auth_providers"
add_foreign_key "availability_tags", "availabilities"
add_foreign_key "availability_tags", "tags"
add_foreign_key "cart_item_coupons", "coupons"
add_foreign_key "cart_item_coupons", "invoicing_profiles", column: "customer_profile_id"
add_foreign_key "cart_item_coupons", "invoicing_profiles", column: "operator_profile_id"
add_foreign_key "cart_item_event_reservation_tickets", "cart_item_event_reservations"
add_foreign_key "cart_item_event_reservation_tickets", "event_price_categories"
add_foreign_key "cart_item_event_reservations", "events"
add_foreign_key "cart_item_event_reservations", "invoicing_profiles", column: "customer_profile_id"
add_foreign_key "cart_item_event_reservations", "invoicing_profiles", column: "operator_profile_id"
add_foreign_key "cart_item_free_extensions", "invoicing_profiles", column: "customer_profile_id"
add_foreign_key "cart_item_free_extensions", "subscriptions"
add_foreign_key "cart_item_payment_schedules", "coupons"
add_foreign_key "cart_item_payment_schedules", "invoicing_profiles", column: "customer_profile_id"
add_foreign_key "cart_item_payment_schedules", "plans"
add_foreign_key "cart_item_prepaid_packs", "invoicing_profiles", column: "customer_profile_id"
add_foreign_key "cart_item_prepaid_packs", "prepaid_packs"
add_foreign_key "cart_item_reservation_slots", "slots"
add_foreign_key "cart_item_reservation_slots", "slots_reservations"
add_foreign_key "cart_item_reservations", "invoicing_profiles", column: "customer_profile_id"
add_foreign_key "cart_item_reservations", "invoicing_profiles", column: "operator_profile_id"
add_foreign_key "cart_item_reservations", "plans"
add_foreign_key "cart_item_subscriptions", "invoicing_profiles", column: "customer_profile_id"
add_foreign_key "cart_item_subscriptions", "plans"
add_foreign_key "event_price_categories", "events"
add_foreign_key "event_price_categories", "price_categories"
add_foreign_key "events", "categories"
@ -1260,6 +1404,7 @@ ActiveRecord::Schema.define(version: 2023_01_19_143245) do
add_foreign_key "project_users", "projects"
add_foreign_key "project_users", "users"
add_foreign_key "projects", "statistic_profiles", column: "author_statistic_profile_id"
add_foreign_key "projects", "statuses"
add_foreign_key "projects_components", "components"
add_foreign_key "projects_components", "projects"
add_foreign_key "projects_machines", "machines"

View File

@ -4,78 +4,8 @@
# Some of them are just some placeholders to prevent having an empty palce when starting fab-manager first.
# Other data are required default values, for various settings.
if StatisticIndex.count.zero?
StatisticIndex.create!([
{ id: 1, es_type_key: 'subscription', label: I18n.t('statistics.subscriptions') },
{ id: 2, es_type_key: 'machine', label: I18n.t('statistics.machines_hours') },
{ id: 3, es_type_key: 'training', label: I18n.t('statistics.trainings') },
{ id: 4, es_type_key: 'event', label: I18n.t('statistics.events') },
{ id: 5, es_type_key: 'account', label: I18n.t('statistics.registrations'), ca: false },
{ id: 6, es_type_key: 'project', label: I18n.t('statistics.projects'), ca: false },
{ id: 7, es_type_key: 'user', label: I18n.t('statistics.users'), table: false, ca: false }
])
connection = ActiveRecord::Base.connection
connection.execute("SELECT setval('statistic_indices_id_seq', 7);") if connection.instance_values['config'][:adapter] == 'postgresql'
end
if StatisticField.count.zero?
StatisticField.create!([
# available data_types : index, number, date, text, list
{ key: 'trainingId', label: I18n.t('statistics.training_id'), statistic_index_id: 3, data_type: 'index' },
{ key: 'trainingDate', label: I18n.t('statistics.training_date'), statistic_index_id: 3, data_type: 'date' },
{ key: 'eventId', label: I18n.t('statistics.event_id'), statistic_index_id: 4, data_type: 'index' },
{ key: 'eventDate', label: I18n.t('statistics.event_date'), statistic_index_id: 4, data_type: 'date' },
{ key: 'themes', label: I18n.t('statistics.themes'), statistic_index_id: 6, data_type: 'list' },
{ key: 'components', label: I18n.t('statistics.components'), statistic_index_id: 6, data_type: 'list' },
{ key: 'machines', label: I18n.t('statistics.machines'), statistic_index_id: 6, data_type: 'list' },
{ key: 'name', label: I18n.t('statistics.event_name'), statistic_index_id: 4, data_type: 'text' },
{ key: 'userId', label: I18n.t('statistics.user_id'), statistic_index_id: 7, data_type: 'index' },
{ key: 'eventTheme', label: I18n.t('statistics.event_theme'), statistic_index_id: 4, data_type: 'text' },
{ key: 'ageRange', label: I18n.t('statistics.age_range'), statistic_index_id: 4, data_type: 'text' }
])
end
unless StatisticField.find_by(key: 'groupName').try(:label)
field = StatisticField.find_or_initialize_by(key: 'groupName')
field.label = 'Groupe'
field.statistic_index_id = 1
field.data_type = 'text'
field.save!
end
if StatisticType.count.zero?
StatisticType.create!([
{ statistic_index_id: 2, key: 'booking', label: I18n.t('statistics.bookings'), graph: true, simple: true },
{ statistic_index_id: 2, key: 'hour', label: I18n.t('statistics.hours_number'), graph: true, simple: false },
{ statistic_index_id: 3, key: 'booking', label: I18n.t('statistics.bookings'), graph: false, simple: true },
{ statistic_index_id: 3, key: 'hour', label: I18n.t('statistics.hours_number'), graph: false, simple: false },
{ statistic_index_id: 4, key: 'booking', label: I18n.t('statistics.tickets_number'), graph: false,
simple: false },
{ statistic_index_id: 4, key: 'hour', label: I18n.t('statistics.hours_number'), graph: false, simple: false },
{ statistic_index_id: 5, key: 'member', label: I18n.t('statistics.users'), graph: true, simple: true },
{ statistic_index_id: 6, key: 'project', label: I18n.t('statistics.projects'), graph: false, simple: true },
{ statistic_index_id: 7, key: 'revenue', label: I18n.t('statistics.revenue'), graph: false, simple: false }
])
end
if StatisticSubType.count.zero?
StatisticSubType.create!([
{ key: 'created', label: I18n.t('statistics.account_creation'),
statistic_types: StatisticIndex.find_by(es_type_key: 'account').statistic_types },
{ key: 'published', label: I18n.t('statistics.project_publication'),
statistic_types: StatisticIndex.find_by(es_type_key: 'project').statistic_types }
])
end
if StatisticGraph.count.zero?
StatisticGraph.create!([
{ statistic_index_id: 1, chart_type: 'stackedAreaChart', limit: 0 },
{ statistic_index_id: 2, chart_type: 'stackedAreaChart', limit: 0 },
{ statistic_index_id: 3, chart_type: 'discreteBarChart', limit: 10 },
{ statistic_index_id: 4, chart_type: 'discreteBarChart', limit: 10 },
{ statistic_index_id: 5, chart_type: 'lineChart', limit: 0 },
{ statistic_index_id: 7, chart_type: 'discreteBarChart', limit: 10 }
])
Dir[Rails.root.join('db/seeds/**/*.rb')].sort.each do |seed|
load seed
end
if Group.count.zero?
@ -296,418 +226,9 @@ if Category.count.zero?
)
end
unless Setting.find_by(name: 'about_body').try(:value)
setting = Setting.find_or_initialize_by(name: 'about_body')
setting.value = <<~HTML
<p>
<a href="http://fab-manager.com" target="_blank">Fab-manager</a> est outil de gestion des atelier de fabrication
numérique, permettant de réserver des machines de découpe, des imprimantes 3D, etc. tout en gérant simplement
les aspect financier, comptable et statistiques de votre espace.
</p>
<p>
<a href="http://fab-manager.com" target="_blank">Fab-manager</a> est un projet libre : ouvert à tous, il offre la
possibilité de contribuer soi-même au code, de télécharger le logiciel, de l'étudier et de le redistribuer. Vous
n'êtes pas technicien ? Vous pouvez quand même participer à <a href="https://translate.fab-manager.com/">traduire
Fab-manager dans votre langue</a>.
</p>
<p>
Fab-manager favorise le partage de connaissances grâce au réseau OpenLab : les projets que vous documentez sont
partagés avec l'ensemble du réseau des Fab-managers.
</p>
HTML
setting.save
end
Setting.set('about_title', 'Imaginer, Fabriquer, <br>Partager avec Fab-manager') unless Setting.find_by(name: 'about_title').try(:value)
unless Setting.find_by(name: 'about_contacts').try(:value)
setting = Setting.find_or_initialize_by(name: 'about_contacts')
setting.value = <<~HTML
<dl>
<dt>Support technique :</dt>
<dd><a href="https://forum.fab-manager.com">Forum</a></dd>
<dd><a href="https://feedback.fab-manager.com">Feedback</a></dd>
<dd><a href="https://github.com/sleede/fab-manager/">GitHub</a></dd>
</dl>
<br><br>
<p><a href='http://fab-manager.com'>Visitez le site de Fab-manager</a></p>
HTML
setting.save
end
Setting.set('twitter_name', 'Fab_Manager') unless Setting.find_by(name: 'twitter_name').try(:value)
unless Setting.find_by(name: 'machine_explications_alert').try(:value)
setting = Setting.find_or_initialize_by(name: 'machine_explications_alert')
setting.value = 'Tout achat de créneau machine est définitif. Aucune ' \
'annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez en ' \
"modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais, " \
'aucun changement ne pourra être effectué.'
setting.save
end
unless Setting.find_by(name: 'training_explications_alert').try(:value)
setting = Setting.find_or_initialize_by(name: 'training_explications_alert')
setting.value = 'Toute réservation de formation est définitive. ' \
'Aucune annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez ' \
"en modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais, " \
'aucun changement ne pourra être effectué.'
setting.save
end
unless Setting.find_by(name: 'subscription_explications_alert').try(:value)
setting = Setting.find_or_initialize_by(name: 'subscription_explications_alert')
setting.value = <<~HTML
<p><b>Règle sur la date de début des abonnements</b></p>
<ul>
<li><span style=\"font-size: 1.6rem; line-height: 2.4rem;\">Si vous êtes un nouvel utilisateur - i.e aucune
formation d'enregistrée sur le site - votre abonnement débutera à la date de réservation de votre première
formation.</span></li>
<li><span style="font-size: 1.6rem; line-height: 2.4rem;">Si vous avez déjà une formation ou plus de validée,
votre abonnement débutera à la date de votre achat d'abonnement.</span></li>
</ul>
<p>Merci de bien prendre ses informations en compte, et merci de votre compréhension. L'équipe du Fab Lab.<br>
</p>
HTML
setting.save
end
unless Setting.find_by(name: 'invoice_logo').try(:value)
setting = Setting.find_or_initialize_by(name: 'invoice_logo')
setting.value = <<~BASE64
iVBORw0KGgoAAAANSUhEUgAAAG0AAABZCAYAAAA0E6rtAAAACXBIWXMAAAsTAAALEwEAmpwYAAA57WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94
cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIg
eDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogICA8cmRmOlJERiB4
bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91
dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8v
cHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8x
LjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9
Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFk
b2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHht
cDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVE
YXRlPjIwMTctMDEtMDNUMTE6MTg6MTgrMDE6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNy0wNi0wNlQxNTo1
NjoxMiswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTctMDYtMDZUMTU6NTY6MTIrMDI6MDA8L3htcDpN
ZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8
L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6MmYwMTE5MTMtODI5NS0zOTQ0LWJmZjYtMTY5ZTNh
ZTQ5OThlPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6ZGU3ZGE1MmYtNGFi
Zi0xMWU3LTljODAtYWJjY2ZlM2JkNzdmPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6
YTE5NTAzOTAtOGQwOS0zMzQ3LWFkNGQtMzkyNDQ2YjRiNWJiPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5
PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAg
ICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmEx
OTUwMzkwLThkMDktMzM0Ny1hZDRkLTM5MjQ0NmI0YjViYjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAx
Ny0wMS0wM1QxMToxODoxOCswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9z
aG9wIENDIDIwMTcgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJk
ZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAg
ICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDoyZjAxMTkxMy04Mjk1LTM5NDQtYmZmNi0xNjllM2FlNDk5OGU8L3N0RXZ0Omlu
c3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTctMDYtMDZUMTU6NTY6MTIrMDI6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAg
ICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE3IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4K
ICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAg
IDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgog
ICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcy
MDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAg
ICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTA5PC9leGlm
OlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjg5PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6
RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAog
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBh
Y2tldCBlbmQ9InciPz7jSvdMAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAACL8SURBVHja7J15nB5Ftfe/VdXLsy8z
k5lM9hASsrDKImgiuyCL7ILgq4KKu9flivuCiKjoFeWqCCoKQpTLIsiOrBqI5Bo2IQsJ2ZPJZPZn7ae7q94/+kkyQzIhExKSwVufT08mz3RX91Onzjm/
86tTp4Vh+9oKYCFQA/YlThaHB+jlBmxuIcdyesmQQVAixELjYOPRSo25KDoJMdQ4mjTLKNFInBUENOGzEoc4vphEYnwVe4KNPdmgJoMeKxAjDSYnEAnA
BgSgo0cxZQNdINYJ9CqfcJmAxQaWpulZW0GZEI9RJHgcRYDmEKCIxQbKOLhoYF9COrDoJsQGRpNhPj20U+Xs+g0Ha712jKXpRhwdsrObhcAIQ61apeZ7
xJXiQa+IxRvQNo5yWP/dABpDI8nRAn/mQcTfHmJN82GqTTjGECLw61fp+tn9ezObfhcIQAIKGwlIA2JlmRELfbz5LvajFeSTEJR0/ezh3qw3QmA1DApD
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
BASE64
setting.save
end
Setting.set('invoice_reference', 'YYMMmmmX[/VL]R[/A]S[/E]') unless Setting.find_by(name: 'invoice_reference').try(:value)
Setting.set('invoice_code-active', true) unless Setting.find_by(name: 'invoice_code-active').try(:value)
Setting.set('invoice_code-value', 'FABMGRFABLAB') unless Setting.find_by(name: 'invoice_code-value').try(:value)
Setting.set('invoice_order-nb', 'nnnnnn-MM-YY') unless Setting.find_by(name: 'invoice_order-nb').try(:value)
Setting.set('invoice_VAT-active', false) unless Setting.find_by(name: 'invoice_VAT-active').try(:value)
Setting.set('invoice_VAT-rate', 20.0) unless Setting.find_by(name: 'invoice_VAT-rate').try(:value)
Setting.set('invoice_text', I18n.t('invoices.invoice_text_example')) unless Setting.find_by(name: 'invoice_text').try(:value)
unless Setting.find_by(name: 'invoice_legals').try(:value)
setting = Setting.find_or_initialize_by(name: 'invoice_legals')
setting.value = 'Fab-manager<br/>' \
'41 rue du Colonel Moutarde, 21000 DIJON France<br/>' \
'Tél. : +33 1 23 45 67 98<br/>' \
'Fax. : +33 1 23 45 67 98<br/>' \
'SIRET : 237 082 474 00006 - APE 913 E'
setting.save
end
Setting.set('booking_window_start', '1970-01-01 08:00:00') unless Setting.find_by(name: 'booking_window_start').try(:value)
Setting.set('booking_window_end', '1970-01-01 23:59:59') unless Setting.find_by(name: 'booking_window_end').try(:value)
Setting.set('booking_move_enable', true) unless Setting.find_by(name: 'booking_move_enable').try(:value)
Setting.set('booking_move_delay', 24) unless Setting.find_by(name: 'booking_move_delay').try(:value)
Setting.set('booking_cancel_enable', false) unless Setting.find_by(name: 'booking_cancel_enable').try(:value)
Setting.set('booking_cancel_delay', 24) unless Setting.find_by(name: 'booking_cancel_delay').try(:value)
Setting.set('main_color', '#cb1117') unless Setting.find_by(name: 'main_color').try(:value)
Setting.set('secondary_color', '#ffdd00') unless Setting.find_by(name: 'secondary_color').try(:value)
Stylesheet.build_theme!
Stylesheet.build_home!
unless Setting.find_by(name: 'training_information_message').try(:value)
setting = Setting.find_or_initialize_by(name: 'training_information_message')
setting.value = "Avant de réserver une formation, nous vous conseillons de consulter nos offres d'abonnement qui " \
'proposent des conditions avantageuses sur le prix des formations et les créneaux machines.'
setting.save
end
Setting.set('fablab_name', 'Fab-manager') unless Setting.find_by(name: 'fablab_name').try(:value)
Setting.set('name_genre', 'male') unless Setting.find_by(name: 'name_genre').try(:value)
unless DatabaseProvider.count.positive?
db_provider = DatabaseProvider.new
db_provider.save
@ -721,376 +242,6 @@ unless DatabaseProvider.count.positive?
end
end
Setting.set('reminder_enable', true) unless Setting.find_by(name: 'reminder_enable').try(:value)
Setting.set('reminder_delay', 24) unless Setting.find_by(name: 'reminder_delay').try(:value)
Setting.set('visibility_yearly', 3) unless Setting.find_by(name: 'visibility_yearly').try(:value)
Setting.set('visibility_others', 1) unless Setting.find_by(name: 'visibility_others').try(:value)
Setting.set('reservation_deadline', 0) unless Setting.find_by(name: 'reservation_deadline').try(:value)
Setting.set('display_name_enable', false) unless Setting.find_by(name: 'display_name_enable').try(:value)
Setting.set('machines_sort_by', 'default') unless Setting.find_by(name: 'machines_sort_by').try(:value)
unless Setting.find_by(name: 'privacy_draft').try(:value)
setting = Setting.find_or_initialize_by(name: 'privacy_draft')
setting.value = <<~HTML
<p>La présente politique de confidentialité définit et vous informe de la manière dont _________ utilise et protège les
informations que vous nous transmettez, le cas échéant, lorsque vous utilisez le présent site accessible à partir de lURL suivante :
_________ (ci-après le « Site »).</p><p>Veuillez noter que cette politique de confidentialité est susceptible dêtre modifiée ou
complétée à tout moment par _________, notamment en vue de se conformer à toute évolution législative, réglementaire, jurisprudentielle
ou technologique. Dans un tel cas, la date de sa mise à jour sera clairement identifiée en tête de la présente politique et l'Utilisateur
sera informé par courriel. Ces modifications engagent lUtilisateur dès leur mise en ligne. Il convient par conséquent que lUtilisateur
consulte régulièrement la présente politique de confidentialité et dutilisation des cookies afin de prendre connaissance de ses
éventuelles modifications.</p><h3>I. DONNÉES PERSONNELLES</h3><p>Dune manière générale, il vous est possible de visiter le site de
_________ sans communiquer aucune information personnelle vous concernant. En toute hypothèse, vous nêtes en aucune manière obligé de
transmettre ces informations à _________.</p><p>Néanmoins, en cas de refus, il se peut que vous ne puissiez pas bénéficier de
certaines informations ou services que vous avez demandés. À ce titre en effet, _________ peut être amené dans certains cas à vous
demander de renseigner votre nom, prénom, pseudonyme, sexe, adresse mail, numéro de téléphone, entreprise et date de naissance (ci-après
vos « Informations Personnelles »). En fournissant ces informations, vous acceptez expressément quelles soient traitées par
_________, aux fins indiquées au point 2 ci-dessous.</p><p>Conformément au Règlement Général sur la Protection des Données (General
Data Protection Regulation) adopté par le Parlement européen le 14 avril 2016, et à la Loi Informatique et Libertés du 6 janvier 1978
modifiée, _________ vous informe des points suivants :</p><h4>1. Identité du responsable du traitement</h4><p>Le responsable du
traitement est (la société/l'association) _________ (adresse) _________, (code postal) _________ (ville)&nbsp;_________ (Pays)
_________ .</p><h4>2. Finalités du traitement</h4><p>_________ est susceptible de traiter vos Informations Personnelles :</p><p>(a)
aux fins de vous fournir les informations ou les services que vous avez demandés (notamment : l'envoi de notifications relatives à
vos activités sur le Site, lenvoi de la Newsletter, la correspondance par email, lenvoi dinformations commerciales, livres
blancs ou encore lévaluation de votre niveau de satisfaction quant aux services proposés) ;</p><p>(b) aux fins de recueillir des
informations nous permettant daméliorer notre Site, nos produits et services (notamment par le biais de cookies) ;</p><p>(c)
aux fins de pouvoir vous contacter à propos de différents événements relatifs à _________, incluant notamment la mise à jour des
produits et le support client.</p><h4>3. Destinataires</h4><p>Seul _________ est destinataire de vos Informations Personnelles.
Celles-ci, que ce soit sous forme individuelle ou agrégée, ne sont jamais transmises à un tiers, nonobstant les sous-traitants
auxquels _________ fait appel (vous trouverez de plus amples informations à leur sujet au point 7 ci-dessous). Ni _________,
ni lun quelconque de ses sous-traitants, ne procèdent à la commercialisation des données personnelles des visiteurs et Utilisateurs de
son Site.</p><h4>4. Durée de conservation</h4><p>Vos Informations Personnelles sont conservées par _________ uniquement pour le temps
correspondant à la finalité de la collecte tel quindiqué en 2 ci-dessus qui ne saurait en tout état de cause excéder 36 mois.</p><h4>5.
Droits Informatique et Libertés</h4><p>Vous disposez des droits suivants concernant vos Informations Personnelles, que vous pouvez exercer
en nous écrivant à ladresse postale mentionnée au point 1 ou en contactant le délégué à la protection des données, dont l'adresse est
mentionnée ci-contre.</p><p><b>o Droit daccès et de communication des données</b></p><p>Vous avez la faculté daccéder aux Informations
Personnelles qui vous concernent.</p><p>Cependant, en raison de lobligation de sécurité et de confidentialité dans le traitement des
données à caractère personnel qui incombe à _________, vous êtes informé que votre demande sera traitée sous réserve que vous apportiez la
preuve de votre identité, notamment par la production dun scan de votre titre didentité valide (en cas de demande par voie électronique)
ou dune photocopie signée de votre titre didentité valide (en cas de demande adressée par écrit).</p><p>_________ vous informe quil
sera en droit, le cas échéant, de sopposer aux demandes manifestement abusives (de par leur nombre, leur caractère répétitif ou
systématique).</p><p>Pour vous aider dans votre démarche, notamment si vous désirez exercer votre droit daccès par le biais dune
demande écrite à ladresse postale mentionnée au point 1, vous trouverez en cliquant sur le <a
href="https://www.cnil.fr/fr/modele/courrier/exercer-son-droit-dacces">lien</a> suivant un modèle de courrier élaboré par la Commission
Nationale de lInformatique et des Libertés (la « CNIL »).</p><p><b>o Droit de rectification des données</b></p><p>Au titre de ce droit,
la législation vous habilite à demander la rectification, la mise à jour, le verrouillage ou encore leffacement des données vous
concernant qui peuvent savérer le cas échéant inexactes, erronées, incomplètes ou obsolètes.</p><p>Egalement, vous pouvez définir des
directives générales et particulières relatives au sort des données à caractère personnel après votre décès. Le cas échéant, les héritiers
dune personne décédée peuvent exiger de prendre en considération le décès de leur proche et/ou de procéder aux mises à jour nécessaires.
</p><p>Pour vous aider dans votre démarche, notamment si vous désirez exercer, pour votre propre compte ou pour le compte de lun de vos
proches défunt, votre droit de rectification par le biais dune demande écrite à ladresse postale mentionnée au point 1, vous trouverez
en cliquant sur le <a href="https://www.cnil.fr/fr/modele/courrier/rectifier-des-donnees-inexactes-obsoletes-ou-perimees">lien</a>
suivant un modèle de courrier élaboré par la CNIL.</p><p><b>o Droit dopposition</b></p><p>Lexercice de ce droit nest possible que dans
lune des deux situations suivantes :</p><p>Lorsque lexercice de ce droit est fondé sur des motifs légitimes ; ou</p><p>Lorsque
lexercice de ce droit vise à faire obstacle à ce que les données recueillies soient utilisées à des fins de prospection commerciale.</p>
<p>Pour vous aider dans votre démarche, notamment si vous désirez exercer votre droit dopposition par le biais dune demande écrite
adressée à ladresse postale indiquée au point 1, vous trouverez en cliquant sur le <a
href="https://www.cnil.fr/fr/modele/courrier/supprimer-des-informations-vous-concernant-dun-site-internet">lien</a> suivant un modèle de
courrier élaboré par la CNIL.</p><h4>6. Délais de réponse</h4><p> _________ sengage à répondre à votre demande daccès, de rectification
ou dopposition ou toute autre demande complémentaire dinformations dans un délai raisonnable qui ne saurait dépasser 1 mois à compter
de la réception de votre demande.</p><h4>7. Prestataires habilités et transfert vers un pays tiers de lUnion Européenne</h4><p>_________
vous informe quil a recours à ses prestataires habilités pour faciliter le recueil et le traitement des données que vous nous avez
communiquées. Ces prestataires peuvent être situés en dehors de lUnion Européenne et ont communication des données recueillies par le
biais des divers formulaires présents sur le Site.</p><p>_________ sest préalablement assuré de la mise en œuvre par ses prestataires de
garanties adéquates et du respect de conditions strictes en matière de confidentialité, dusage et de protection des données. Tout
particulièrement, la vigilance sest portée sur lexistence dun fondement légal pour effectuer un quelconque transfert de données vers un
pays tiers. A ce titre, lun de nos prestataires est soumis à (nom de la règle) _________ approuvées par la (nom de l'autorité) _________
en (année d'approbation)&nbsp;_________.</p><h4>8. Plainte auprès de lautorité compétente</h4><p>Si vous considérez que _________ ne
respecte pas ses obligations au regard de vos Informations Personnelles, vous pouvez adresser une plainte ou une demande auprès de
lautorité compétente. En France, lautorité compétente est la CNIL à laquelle vous pouvez adresser une demande par voie électronique en
cliquant sur le lien suivant : <a href="https://www.cnil.fr/fr/plaintes/internet">https://www.cnil.fr/fr/plaintes/internet</a>.</p>
<h3>II. POLITIQUE RELATIVE AUX COOKIES</h3><p>Lors de votre première connexion sur le site web de _________, vous êtes avertis par un
bandeau en bas de votre écran que des informations relatives à votre navigation sont susceptibles dêtre enregistrées dans des fichiers
dénommés « cookies ». Notre politique dutilisation des cookies vous permet de mieux comprendre les dispositions que nous mettons en œuvre
en matière de navigation sur notre site web. Elle vous informe notamment sur lensemble des cookies présents sur notre site web, leur
finalité (partie I.) et vous donne la marche à suivre pour les paramétrer (partie II.)</p><h4>1. Informations générales sur les cookies
présents sur le site de _________</h4><p>_________, en tant quéditeur du présent site web, pourra procéder à limplantation dun cookie
sur le disque dur de votre terminal (ordinateur, tablette, mobile etc.) afin de vous garantir une navigation fluide et optimale sur notre
site Internet.</p><p>Les « cookies » (ou témoins de connexion) sont des petits fichiers texte de taille limitée qui nous permettent de
reconnaître votre ordinateur, votre tablette ou votre mobile aux fins de personnaliser les services que nous vous proposons.</p><p>Les
informations recueillies par le biais des cookies ne permettent en aucune manière de vous identifier nominativement. Elles sont utilisées
exclusivement pour nos besoins propres afin daméliorer linteractivité et la performance de notre site web et de vous adresser des
contenus adaptés à vos centres dintérêts. Aucune de ces informations ne fait lobjet dune communication auprès de tiers sauf lorsque
_________ a obtenu au préalable votre consentement ou bien lorsque la divulgation de ces informations est requise par la loi, sur ordre
dun tribunal ou toute autorité administrative ou judiciaire habilitée à en connaître.</p><p>Pour mieux vous éclairer sur les informations
que les cookies identifient, vous trouverez ci-dessous un tableau listant les différents types de cookies susceptibles dêtre utilisés sur
le site web de _________, leur nom, leur finalité ainsi que leur durée de conservation.</p><h4>2. Configuration de vos préférences sur les
cookies</h4><p>Vous pouvez accepter ou refuser le dépôt de cookies à tout moment.</p><p>Lors de votre première connexion sur le site web
de _________, une bannière présentant brièvement des informations relatives au dépôt de cookies et de technologies similaires apparaît en
bas de votre écran. Cette bannière vous demande de choisir explicitement d'accepter ou non le dépôt de cookies sur votre terminal.
</p><p>Après avoir fait votre choix, vous pouvez le modifier ultérieurement&nbsp; en vous connectant à votre compte utilisateur puis en
naviguant dans la section intitulée « mes paramètres&nbsp;», accessible via un clic sur votre nom, en haut à droite de l'écran.</p>
<p>Selon le type de cookie en cause, le recueil de votre consentement au dépôt et à la lecture de cookies sur votre terminal peut être
impératif.</p><h4>a. Les cookies exemptés de consentement</h4><p>Conformément aux recommandations de la Commission Nationale de
lInformatique et des Libertés (CNIL), certains cookies sont dispensés du recueil préalable de votre consentement dans la mesure ils
sont strictement nécessaires au fonctionnement du site internet ou ont pour finalité exclusive de permettre ou faciliter la communication
par voie électronique. Il sagit des cookies suivants :</p><p><b>o Identifiant de session</b> et&nbsp;<b>d'authentification</b> sur l'API de
Fab-manager.</p><p><b>o Identifiant de panier d'achat</b></b>, permettant de sauvegarder le contenu de votre panier d'achat, même lorsque
vous n'êtes pas connecté.</p>
<p><em>Les cookies ci-dessus sont intégralement soumis à la présente politique dans la mesure ils sont émis et gérés par _________.</em></p>
<p><b>o Stripe</b>, permettant de gérer les paiements par carte bancaire et dont la politique de confidentialité est accessible sur ce
<a href="https://stripe.com/fr/privacy">lien</a>.</p><p><b>o Disqus</b>, permettant de poster des commentaires sur les fiches projet et
dont la politique de confidentialité est accessible sur ce <a href="https://help.disqus.com/articles/1717103-disqus-privacy-policy">lien
</a>.</p><h4>b. Les cookies nécessitant le recueil préalable de votre consentement</h4><p>Cette
exigence concerne les cookies émis par des tiers et qui sont qualifiés de « persistants » dans la mesure ils demeurent dans votre
terminal jusquà leur effacement ou leur date dexpiration.</p><p>De tels cookies étant émis par des tiers, leur utilisation et leur dépôt
sont soumis à leurs propres politiques de confidentialité dont vous trouverez un lien ci-dessous. Cette famille de cookie comprend les
cookies de mesure daudience (Google Analytics).</p><p>Les cookies de mesure daudience établissent des statistiques concernant la
fréquentation et lutilisation de divers éléments du site web (comme les contenus/pages que vous avez visité).
Ces données participent à lamélioration de lergonomie du site web de _________. Un outil de mesure daudience est utilisé sur le
présent site internet :</p><p><b>o Google Analytics</b> pour gérer les statistiques de visites dont la politique de
confidentialité est disponible (uniquement en anglais) à partir du <a href="https://policies.google.com/privacy?hl=fr&amp;gl=ZZ">lien
</a> suivant. </p><h4>c. Vous disposez de divers outils de paramétrage des cookies</h4><p>La plupart
des navigateurs Internet sont configurés par défaut de façon à ce que le dépôt de cookies soit autorisé. Votre navigateur vous offre
lopportunité de modifier ces paramètres standards de manière que lensemble des cookies soit rejeté systématiquement ou bien à ce
quune partie seulement des cookies soit acceptée ou refusée en fonction de leur émetteur.</p><p><b>ATTENTION</b> : Nous attirons votre
attention sur le fait que le refus du dépôt de cookies sur votre terminal est néanmoins susceptible daltérer votre expérience
dutilisateur ainsi que votre accès à certains services ou fonctionnalités du présent site web. Le cas échéant, _________ décline toute
responsabilité concernant les conséquences liées à la dégradation de vos conditions de navigation qui interviennent en raison de votre
choix de refuser, supprimer ou bloquer les cookies nécessaires au fonctionnement du site.
Ces conséquences ne sauraient constituer un dommage et vous ne pourrez prétendre à aucune indemnité de ce fait.</p>
<p>Votre navigateur vous permet également de supprimer les cookies existants sur votre
terminal ou encore de vous signaler lorsque de nouveaux cookies sont susceptibles dêtre déposés sur votre terminal. Ces paramètres nont
pas dincidence sur votre navigation, mais vous font perdre tout le bénéfice apporté par le cookie.</p><p>Veuillez ci-dessous prendre
connaissance des multiples outils mis à votre disposition afin que vous puissiez paramétrer les cookies déposés sur votre terminal.</p>
<h4>d. Le paramétrage de votre navigateur Internet</h4><p>Chaque navigateur Internet propose ses propres paramètres de gestion des
cookies. Pour savoir de quelle manière modifier vos préférences en matière de cookies, vous trouverez ci-dessous les liens vers laide
nécessaire pour accéder au menu de votre navigateur prévu à cet effet :</p>
<ul>
<li><a href="https://support.google.com/chrome/answer/95647?hl=fr">Chrome</a></li>
<li><a href="https://mzl.la/3BX2oBb">Firefox</a></li>
<li><a href="https://support.microsoft.com/fr-fr/microsoft-edge/supprimer-les-cookies-dans-microsoft-edge-63947406-40ac-c3b8-57b9-2a946a29ae09">
Microsoft Edge</a></li>
<li><a href="https://help.opera.com/en/latest/web-preferences/#cookies">Opera</a></li>
<li><a href="https://support.apple.com/fr-fr/HT201265">Safari</a></li>
</ul>
<p>Pour de plus amples informations concernant les outils de maîtrise des cookies, vous pouvez consulter le
<a href="https://www.cnil.fr/fr/cookies-et-autres-traceurs/comment-se-proteger/maitriser-votre-navigateur">site internet</a> de la CNIL.</p>
HTML
setting.save
end
Setting.set('fab_analytics', true) unless Setting.find_by(name: 'fab_analytics').try(:value)
unless Setting.find_by(name: 'link_name').try(:value)
include ApplicationHelper # rubocop:disable Style/MixinUsage
name = Setting.get('fablab_name')
gender = Setting.get('name_genre')
setting = Setting.find_or_initialize_by(name: 'link_name')
setting.value = _t('app.public.common.about_the_fablab', NAME: name, GENDER: gender)
setting.save
end
unless Setting.find_by(name: 'home_content').try(:value)
setting = Setting.find_or_initialize_by(name: 'home_content')
setting.value = <<~HTML
<div>
<div class="m-sm">
<div id="news">#{I18n.t('app.admin.settings.item_news')}</div>
</div>
<div class="row wrapper">
<div class="col-lg-8">
<div id="projects">#{I18n.t('app.admin.settings.item_projects')}</div>
</div>
<div class="col-lg-4 m-t-lg">
<div id="twitter">#{I18n.t('app.admin.settings.item_twitter')}</div>
<div id="members">#{I18n.t('app.admin.settings.item_members')}</div>
</div>
</div>
<div class="row wrapper m-t-sm">
<div class="col-lg-12">
<div id="events">#{I18n.t('app.admin.settings.item_events')}</div>
</div>
</div>
</div>
HTML
setting.save
end
Setting.set('slot_duration', 60) unless Setting.find_by(name: 'slot_duration').try(:value)
Setting.set('spaces_module', false) unless Setting.find_by(name: 'spaces_module').try(:value)
Setting.set('plans_module', true) unless Setting.find_by(name: 'plans_module').try(:value)
Setting.set('invoicing_module', true) unless Setting.find_by(name: 'invoicing_module').try(:value)
Setting.set('feature_tour_display', 'once') unless Setting.find_by(name: 'feature_tour_display').try(:value)
Setting.set('email_from', 'noreply@fab-manager.com') unless Setting.find_by(name: 'email_from').try(:value)
Setting.set('online_payment_module', false) unless Setting.find_by(name: 'online_payment_module').try(:value)
Setting.set('openlab_default', true) unless Setting.find_by(name: 'openlab_default').try(:value)
unless Setting.find_by(name: 'allowed_cad_extensions').try(:value)
Setting.set(
'allowed_cad_extensions',
'pdf ai eps cad math svg stl dxf dwg obj step iges igs 3dm 3dmf doc docx png ino scad fcad skp sldprt sldasm slddrw' \
'slddrt tex latex ps fcstd fcstd1'
)
end
unless Setting.find_by(name: 'allowed_cad_mime_types').try(:value)
Setting.set(
'allowed_cad_mime_types',
'application/pdf application/postscript application/illustrator image/x-eps image/svg+xml application/sla application/dxf ' \
'application/acad application/dwg application/octet-stream application/step application/iges model/iges x-world/x-3dmf ' \
'application/vnd.openxmlformats-officedocument.wordprocessingml.document image/png text/x-arduino text/plain application/scad ' \
'application/vnd.sketchup.skp application/x-koan application/vnd-koan koan/x-skm application/vnd.koan application/x-tex ' \
'application/x-latex application/x-extension-fcstd'
)
end
Setting.set('stripe_currency', 'EUR') unless Setting.find_by(name: 'stripe_currency').try(:value)
Setting.set('invoice_prefix', 'FabManager_invoice') unless Setting.find_by(name: 'invoice_prefix').try(:value)
Setting.set('payment_schedule_prefix', 'FabManager_paymentSchedule') unless Setting.find_by(name: 'payment_schedule_prefix').try(:value)
Setting.set('confirmation_required', false) unless Setting.find_by(name: 'confirmation_required').try(:value)
Setting.set('user_validation_required', false) unless Setting.find_by(name: 'user_validation_required').try(:value)
Setting.set('user_validation_required_list', '') unless Setting.find_by(name: 'user_validation_required_list').try(:value)
Setting.set('wallet_module', true) unless Setting.find_by(name: 'wallet_module').try(:value)
Setting.set('statistics_module', true) unless Setting.find_by(name: 'statistics_module').try(:value)
Setting.set('machines_module', true) unless Setting.find_by(name: 'machines_module').try(:value)
Setting.set('upcoming_events_shown', 'until_start') unless Setting.find_by(name: 'upcoming_events_shown').try(:value)
Setting.set('trainings_module', true) unless Setting.find_by(name: 'trainings_module').try(:value)
Setting.set('public_agenda_module', true) unless Setting.find_by(name: 'public_agenda_module').try(:value)
Setting.set('renew_pack_threshold', 0.2) unless Setting.find_by(name: 'renew_pack_threshold').try(:value)
Setting.set('pack_only_for_subscription', true) unless Setting.find_by(name: 'pack_only_for_subscription').try(:value)
Setting.set('public_registrations', true) unless Setting.find_by(name: 'public_registrations').try(:value)
Setting.set('user_change_group', true) unless Setting.find_by(name: 'user_change_group').try(:value)
Setting.set('invoice_VAT-name', I18n.t('invoices.VAT')) unless Setting.find_by(name: 'invoice_VAT-name').try(:value)
unless Setting.find_by(name: 'overlapping_categories').try(:value)
Setting.set('overlapping_categories', 'training_reservations,machine_reservations,space_reservations,events_reservations')
end
Setting.set('extended_prices_in_same_day', false) unless Setting.find_by(name: 'extended_prices_in_same_day').try(:value)
Setting.set('show_username_in_admin_list', false) unless Setting.find_by(name: 'show_username_in_admin_list').try(:value)
Setting.set('store_module', false) unless Setting.find_by(name: 'store_module').try(:value)
Setting.set('store_hidden', true) unless Setting.find_by(name: 'store_hidden').try(:value)
Setting.set('advanced_accounting', false) unless Setting.find_by(name: 'advanced_accounting').try(:value)
Setting.set('accounting_sales_journal_code', 'SALES') unless Setting.find_by(name: 'accounting_sales_journal_code').try(:value)
Setting.set('accounting_payment_card_code', '5801') unless Setting.find_by(name: 'accounting_payment_card_code').try(:value)
Setting.set('accounting_payment_card_label', 'Cards payments') unless Setting.find_by(name: 'accounting_payment_card_label').try(:value)
Setting.set('accounting_payment_card_journal_code', 'CA01') unless Setting.find_by(name: 'accounting_payment_card_journal_code').try(:value)
Setting.set('accounting_payment_wallet_code', '5802') unless Setting.find_by(name: 'accounting_payment_wallet_code').try(:value)
Setting.set('accounting_payment_wallet_label', 'Wallet payments') unless Setting.find_by(name: 'accounting_payment_wallet_label').try(:value)
Setting.set('accounting_payment_wallet_journal_code', 'WA01') unless Setting.find_by(name: 'accounting_payment_wallet_journal_code').try(:value)
Setting.set('accounting_payment_other_code', '5803') unless Setting.find_by(name: 'accounting_payment_other_code').try(:value)
Setting.set('accounting_payment_other_label', 'Payments on site') unless Setting.find_by(name: 'accounting_payment_other_label').try(:value)
Setting.set('accounting_payment_other_journal_code', 'SI01') unless Setting.find_by(name: 'accounting_payment_other_journal_code').try(:value)
Setting.set('accounting_wallet_code', '4191') unless Setting.find_by(name: 'accounting_wallet_code').try(:value)
Setting.set('accounting_wallet_label', 'Wallet credit') unless Setting.find_by(name: 'accounting_wallet_label').try(:value)
Setting.set('accounting_wallet_journal_code', 'WC01') unless Setting.find_by(name: 'accounting_wallet_journal_code').try(:value)
Setting.set('accounting_VAT_code', '4457') unless Setting.find_by(name: 'accounting_VAT_code').try(:value)
Setting.set('accounting_VAT_label', 'Collected VAT') unless Setting.find_by(name: 'accounting_VAT_label').try(:value)
Setting.set('accounting_VAT_journal_code', 'VAT1') unless Setting.find_by(name: 'accounting_VAT_journal_code').try(:value)
Setting.set('accounting_subscription_code', '7061') unless Setting.find_by(name: 'accounting_subscription_code').try(:value)
Setting.set('accounting_subscription_label', 'Subscriptions') unless Setting.find_by(name: 'accounting_subscription_label').try(:value)
Setting.set('accounting_Machine_code', '7602') unless Setting.find_by(name: 'accounting_Machine_code').try(:value)
Setting.set('accounting_Machine_label', 'Machines reservations') unless Setting.find_by(name: 'accounting_Machine_label').try(:value)
Setting.set('accounting_Training_code', '7063') unless Setting.find_by(name: 'accounting_Training_code').try(:value)
Setting.set('accounting_Training_label', 'Trainings reservations') unless Setting.find_by(name: 'accounting_Training_label').try(:value)
Setting.set('accounting_Event_code', '7064') unless Setting.find_by(name: 'accounting_Event_code').try(:value)
Setting.set('accounting_Event_label', 'Events reservations') unless Setting.find_by(name: 'accounting_Event_label').try(:value)
Setting.set('accounting_Space_code', '7065') unless Setting.find_by(name: 'accounting_Space_code').try(:value)
Setting.set('accounting_Space_label', 'Spaces reservations') unless Setting.find_by(name: 'accounting_Space_label').try(:value)
Setting.set('accounting_Pack_code', '7066') unless Setting.find_by(name: 'accounting_Pack_code').try(:value)
Setting.set('accounting_Pack_label', 'Prepaid-packs selling') unless Setting.find_by(name: 'accounting_Pack_label').try(:value)
Setting.set('accounting_Product_code', '7071') unless Setting.find_by(name: 'accounting_Product_code').try(:value)
Setting.set('accounting_Product_label', 'Merchandise selling') unless Setting.find_by(name: 'accounting_Product_label').try(:value)
Setting.set('accounting_Error_code', 'ERROR') unless Setting.find_by(name: 'accounting_Error_code').try(:value)
Setting.set('accounting_Error_label', 'Erroneous invoices to refund') unless Setting.find_by(name: 'accounting_Error_label').try(:value)
Setting.set('external_id', false) unless Setting.find_by(name: 'external_id').try(:value)
if StatisticCustomAggregation.count.zero?
# available reservations hours for machines
machine_hours = StatisticType.find_by(key: 'hour', statistic_index_id: 2)
available_hours = StatisticCustomAggregation.new(
statistic_type_id: machine_hours.id,
es_index: 'fablab',
es_type: 'availabilities',
field: 'available_hours',
query: '{"size":0, "aggregations":{"%<aggs_name>s":{"sum":{"field":"bookable_hours"}}}, "query":{"bool":{"must":[{"range":' \
'{"start_at":{"gte":"%<start_date>s", "lte":"%<end_date>s"}}}, {"match":{"available_type":"machines"}}]}}}'
)
available_hours.save!
# available training tickets
training_bookings = StatisticType.find_by(key: 'booking', statistic_index_id: 3)
available_tickets = StatisticCustomAggregation.new(
statistic_type_id: training_bookings.id,
es_index: 'fablab',
es_type: 'availabilities',
field: 'available_tickets',
query: '{"size":0, "aggregations":{"%<aggs_name>s":{"sum":{"field":"nb_total_places"}}}, "query":{"bool":{"must":[{"range":' \
'{"start_at":{"gte":"%<start_date>s", "lte":"%<end_date>s"}}}, {"match":{"available_type":"training"}}]}}}'
)
available_tickets.save!
end
unless StatisticIndex.find_by(es_type_key: 'space')
index = StatisticIndex.create!(es_type_key: 'space', label: I18n.t('statistics.spaces'))
StatisticType.create!([
{ statistic_index_id: index.id, key: 'booking', label: I18n.t('statistics.bookings'),
graph: true, simple: true },
{ statistic_index_id: index.id, key: 'hour', label: I18n.t('statistics.hours_number'),
graph: true, simple: false }
])
end
unless StatisticIndex.find_by(es_type_key: 'order')
index = StatisticIndex.create!(es_type_key: 'order', label: I18n.t('statistics.orders'))
type = StatisticType.create!({ statistic_index_id: index.id, key: 'store', label: I18n.t('statistics.store'), graph: true, simple: true })
StatisticSubType.create!([
{ key: 'paid-processed', label: I18n.t('statistics.paid-processed'), statistic_types: [type] },
{ key: 'aborted', label: I18n.t('statistics.aborted'), statistic_types: [type] }
])
# average cart price for orders
average_cart = StatisticCustomAggregation.new(
statistic_type_id: type.id,
es_index: 'stats',
es_type: 'order',
field: 'average_cart',
query: '{"size":0, "aggregations":{"%<aggs_name>s":{"avg":{"field":"ca", ' \
'"script":"BigDecimal.valueOf(_value).setScale(1, RoundingMode.HALF_UP)", "missing": 0}}}, ' \
'"query":{"bool":{"must":[{"range": {"date":{"gte":"%<start_date>s", "lte":"%<end_date>s"}}}]}}}'
)
average_cart.save!
end
ProfileCustomField.find_or_create_by(label: 'N° SIRET')
ProfileCustomField.find_or_create_by(label: 'Code NAF')
ProfileCustomField.find_or_create_by(label: 'N° TVA intracommunautaire')

722
db/seeds/settings.rb Normal file
View File

@ -0,0 +1,722 @@
# frozen_string_literal: true
# default values for settings
unless Setting.find_by(name: 'about_body').try(:value)
setting = Setting.find_or_initialize_by(name: 'about_body')
setting.value = <<~HTML
<p>
<a href="http://fab-manager.com" target="_blank">Fab-manager</a> est outil de gestion des atelier de fabrication
numérique, permettant de réserver des machines de découpe, des imprimantes 3D, etc. tout en gérant simplement
les aspect financier, comptable et statistiques de votre espace.
</p>
<p>
<a href="http://fab-manager.com" target="_blank">Fab-manager</a> est un projet libre : ouvert à tous, il offre la
possibilité de contribuer soi-même au code, de télécharger le logiciel, de l'étudier et de le redistribuer. Vous
n'êtes pas technicien ? Vous pouvez quand même participer à <a href="https://translate.fab-manager.com/">traduire
Fab-manager dans votre langue</a>.
</p>
<p>
Fab-manager favorise le partage de connaissances grâce au réseau OpenLab : les projets que vous documentez sont
partagés avec l'ensemble du réseau des Fab-managers.
</p>
HTML
setting.save
end
Setting.set('about_title', 'Imaginer, Fabriquer, <br>Partager avec Fab-manager') unless Setting.find_by(name: 'about_title').try(:value)
unless Setting.find_by(name: 'about_contacts').try(:value)
setting = Setting.find_or_initialize_by(name: 'about_contacts')
setting.value = <<~HTML
<dl>
<dt>Support technique :</dt>
<dd><a href="https://forum.fab-manager.com">Forum</a></dd>
<dd><a href="https://feedback.fab-manager.com">Feedback</a></dd>
<dd><a href="https://github.com/sleede/fab-manager/">GitHub</a></dd>
</dl>
<br><br>
<p><a href='http://fab-manager.com'>Visitez le site de Fab-manager</a></p>
HTML
setting.save
end
Setting.set('twitter_name', 'Fab_Manager') unless Setting.find_by(name: 'twitter_name').try(:value)
unless Setting.find_by(name: 'machine_explications_alert').try(:value)
setting = Setting.find_or_initialize_by(name: 'machine_explications_alert')
setting.value = 'Tout achat de créneau machine est définitif. Aucune ' \
'annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez en ' \
"modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais, " \
'aucun changement ne pourra être effectué.'
setting.save
end
unless Setting.find_by(name: 'training_explications_alert').try(:value)
setting = Setting.find_or_initialize_by(name: 'training_explications_alert')
setting.value = 'Toute réservation de formation est définitive. ' \
'Aucune annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez ' \
"en modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais, " \
'aucun changement ne pourra être effectué.'
setting.save
end
unless Setting.find_by(name: 'subscription_explications_alert').try(:value)
setting = Setting.find_or_initialize_by(name: 'subscription_explications_alert')
setting.value = <<~HTML
<p><b>Règle sur la date de début des abonnements</b></p>
<ul>
<li><span style=\"font-size: 1.6rem; line-height: 2.4rem;\">Si vous êtes un nouvel utilisateur - i.e aucune
formation d'enregistrée sur le site - votre abonnement débutera à la date de réservation de votre première
formation.</span></li>
<li><span style="font-size: 1.6rem; line-height: 2.4rem;">Si vous avez déjà une formation ou plus de validée,
votre abonnement débutera à la date de votre achat d'abonnement.</span></li>
</ul>
<p>Merci de bien prendre ses informations en compte, et merci de votre compréhension. L'équipe du Fab Lab.<br>
</p>
HTML
setting.save
end
unless Setting.find_by(name: 'invoice_logo').try(:value)
setting = Setting.find_or_initialize_by(name: 'invoice_logo')
setting.value = <<~BASE64
iVBORw0KGgoAAAANSUhEUgAAAG0AAABZCAYAAAA0E6rtAAAACXBIWXMAAAsTAAALEwEAmpwYAAA57WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94
cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIg
eDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogICA8cmRmOlJERiB4
bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91
dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8v
cHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8x
LjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9
Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFk
b2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHht
cDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVE
YXRlPjIwMTctMDEtMDNUMTE6MTg6MTgrMDE6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNy0wNi0wNlQxNTo1
NjoxMiswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTctMDYtMDZUMTU6NTY6MTIrMDI6MDA8L3htcDpN
ZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8
L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6MmYwMTE5MTMtODI5NS0zOTQ0LWJmZjYtMTY5ZTNh
ZTQ5OThlPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6ZGU3ZGE1MmYtNGFi
Zi0xMWU3LTljODAtYWJjY2ZlM2JkNzdmPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6
YTE5NTAzOTAtOGQwOS0zMzQ3LWFkNGQtMzkyNDQ2YjRiNWJiPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5
PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAg
ICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmEx
OTUwMzkwLThkMDktMzM0Ny1hZDRkLTM5MjQ0NmI0YjViYjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAx
Ny0wMS0wM1QxMToxODoxOCswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9z
aG9wIENDIDIwMTcgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJk
ZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAg
ICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDoyZjAxMTkxMy04Mjk1LTM5NDQtYmZmNi0xNjllM2FlNDk5OGU8L3N0RXZ0Omlu
c3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTctMDYtMDZUMTU6NTY6MTIrMDI6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAg
ICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE3IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4K
ICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAg
IDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgog
ICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcy
MDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAg
ICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTA5PC9leGlm
OlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjg5PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6
RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAog
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBh
Y2tldCBlbmQ9InciPz7jSvdMAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAACL8SURBVHja7J15nB5Ftfe/VdXLsy8z
k5lM9hASsrDKImgiuyCL7ILgq4KKu9flivuCiKjoFeWqCCoKQpTLIsiOrBqI5Bo2IQsJ2ZPJZPZn7ae7q94/+kkyQzIhExKSwVufT08mz3RX91Onzjm/
86tTp4Vh+9oKYCFQA/YlThaHB+jlBmxuIcdyesmQQVAixELjYOPRSo25KDoJMdQ4mjTLKNFInBUENOGzEoc4vphEYnwVe4KNPdmgJoMeKxAjDSYnEAnA
BgSgo0cxZQNdINYJ9CqfcJmAxQaWpulZW0GZEI9RJHgcRYDmEKCIxQbKOLhoYF9COrDoJsQGRpNhPj20U+Xs+g0Ha712jKXpRhwdsrObhcAIQ61apeZ7
xJXiQa+IxRvQNo5yWP/dABpDI8nRAn/mQcTfHmJN82GqTTjGECLw61fp+tn9ezObfhcIQAIKGwlIA2JlmRELfbz5LvajFeSTEJR0/ezh3qw3QmA1DApD
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
BASE64
setting.save
end
Setting.set('invoice_reference', 'YYMMmmmX[/VL]R[/A]S[/E]') unless Setting.find_by(name: 'invoice_reference').try(:value)
Setting.set('invoice_code-active', true) unless Setting.find_by(name: 'invoice_code-active').try(:value)
Setting.set('invoice_code-value', 'FABMGRFABLAB') unless Setting.find_by(name: 'invoice_code-value').try(:value)
Setting.set('invoice_order-nb', 'nnnnnn-MM-YY') unless Setting.find_by(name: 'invoice_order-nb').try(:value)
Setting.set('invoice_VAT-active', false) unless Setting.find_by(name: 'invoice_VAT-active').try(:value)
Setting.set('invoice_VAT-rate', 20.0) unless Setting.find_by(name: 'invoice_VAT-rate').try(:value)
Setting.set('invoice_text', I18n.t('invoices.invoice_text_example')) unless Setting.find_by(name: 'invoice_text').try(:value)
unless Setting.find_by(name: 'invoice_legals').try(:value)
setting = Setting.find_or_initialize_by(name: 'invoice_legals')
setting.value = 'Fab-manager<br/>' \
'41 rue du Colonel Moutarde, 21000 DIJON France<br/>' \
'Tél. : +33 1 23 45 67 98<br/>' \
'Fax. : +33 1 23 45 67 98<br/>' \
'SIRET : 237 082 474 00006 - APE 913 E'
setting.save
end
Setting.set('booking_window_start', '1970-01-01 08:00:00') unless Setting.find_by(name: 'booking_window_start').try(:value)
Setting.set('booking_window_end', '1970-01-01 23:59:59') unless Setting.find_by(name: 'booking_window_end').try(:value)
Setting.set('booking_move_enable', true) unless Setting.find_by(name: 'booking_move_enable').try(:value)
Setting.set('booking_move_delay', 24) unless Setting.find_by(name: 'booking_move_delay').try(:value)
Setting.set('booking_cancel_enable', false) unless Setting.find_by(name: 'booking_cancel_enable').try(:value)
Setting.set('booking_cancel_delay', 24) unless Setting.find_by(name: 'booking_cancel_delay').try(:value)
Setting.set('main_color', '#cb1117') unless Setting.find_by(name: 'main_color').try(:value)
Setting.set('secondary_color', '#ffdd00') unless Setting.find_by(name: 'secondary_color').try(:value)
unless Setting.find_by(name: 'training_information_message').try(:value)
setting = Setting.find_or_initialize_by(name: 'training_information_message')
setting.value = "Avant de réserver une formation, nous vous conseillons de consulter nos offres d'abonnement qui " \
'proposent des conditions avantageuses sur le prix des formations et les créneaux machines.'
setting.save
end
Setting.set('fablab_name', 'Fab-manager') unless Setting.find_by(name: 'fablab_name').try(:value)
Setting.set('name_genre', 'male') unless Setting.find_by(name: 'name_genre').try(:value)
Setting.set('reminder_enable', true) unless Setting.find_by(name: 'reminder_enable').try(:value)
Setting.set('reminder_delay', 24) unless Setting.find_by(name: 'reminder_delay').try(:value)
Setting.set('visibility_yearly', 3) unless Setting.find_by(name: 'visibility_yearly').try(:value)
Setting.set('visibility_others', 1) unless Setting.find_by(name: 'visibility_others').try(:value)
Setting.set('reservation_deadline', 0) unless Setting.find_by(name: 'reservation_deadline').try(:value)
Setting.set('display_name_enable', false) unless Setting.find_by(name: 'display_name_enable').try(:value)
Setting.set('machines_sort_by', 'default') unless Setting.find_by(name: 'machines_sort_by').try(:value)
unless Setting.find_by(name: 'privacy_draft').try(:value)
setting = Setting.find_or_initialize_by(name: 'privacy_draft')
setting.value = <<~HTML
<p>La présente politique de confidentialité définit et vous informe de la manière dont _________ utilise et protège les
informations que vous nous transmettez, le cas échéant, lorsque vous utilisez le présent site accessible à partir de lURL suivante :
_________ (ci-après le « Site »).</p><p>Veuillez noter que cette politique de confidentialité est susceptible dêtre modifiée ou
complétée à tout moment par _________, notamment en vue de se conformer à toute évolution législative, réglementaire, jurisprudentielle
ou technologique. Dans un tel cas, la date de sa mise à jour sera clairement identifiée en tête de la présente politique et l'Utilisateur
sera informé par courriel. Ces modifications engagent lUtilisateur dès leur mise en ligne. Il convient par conséquent que lUtilisateur
consulte régulièrement la présente politique de confidentialité et dutilisation des cookies afin de prendre connaissance de ses
éventuelles modifications.</p><h3>I. DONNÉES PERSONNELLES</h3><p>Dune manière générale, il vous est possible de visiter le site de
_________ sans communiquer aucune information personnelle vous concernant. En toute hypothèse, vous nêtes en aucune manière obligé de
transmettre ces informations à _________.</p><p>Néanmoins, en cas de refus, il se peut que vous ne puissiez pas bénéficier de
certaines informations ou services que vous avez demandés. À ce titre en effet, _________ peut être amené dans certains cas à vous
demander de renseigner votre nom, prénom, pseudonyme, sexe, adresse mail, numéro de téléphone, entreprise et date de naissance (ci-après
vos « Informations Personnelles »). En fournissant ces informations, vous acceptez expressément quelles soient traitées par
_________, aux fins indiquées au point 2 ci-dessous.</p><p>Conformément au Règlement Général sur la Protection des Données (General
Data Protection Regulation) adopté par le Parlement européen le 14 avril 2016, et à la Loi Informatique et Libertés du 6 janvier 1978
modifiée, _________ vous informe des points suivants :</p><h4>1. Identité du responsable du traitement</h4><p>Le responsable du
traitement est (la société/l'association) _________ (adresse) _________, (code postal) _________ (ville)&nbsp;_________ (Pays)
_________ .</p><h4>2. Finalités du traitement</h4><p>_________ est susceptible de traiter vos Informations Personnelles :</p><p>(a)
aux fins de vous fournir les informations ou les services que vous avez demandés (notamment : l'envoi de notifications relatives à
vos activités sur le Site, lenvoi de la Newsletter, la correspondance par email, lenvoi dinformations commerciales, livres
blancs ou encore lévaluation de votre niveau de satisfaction quant aux services proposés) ;</p><p>(b) aux fins de recueillir des
informations nous permettant daméliorer notre Site, nos produits et services (notamment par le biais de cookies) ;</p><p>(c)
aux fins de pouvoir vous contacter à propos de différents événements relatifs à _________, incluant notamment la mise à jour des
produits et le support client.</p><h4>3. Destinataires</h4><p>Seul _________ est destinataire de vos Informations Personnelles.
Celles-ci, que ce soit sous forme individuelle ou agrégée, ne sont jamais transmises à un tiers, nonobstant les sous-traitants
auxquels _________ fait appel (vous trouverez de plus amples informations à leur sujet au point 7 ci-dessous). Ni _________,
ni lun quelconque de ses sous-traitants, ne procèdent à la commercialisation des données personnelles des visiteurs et Utilisateurs de
son Site.</p><h4>4. Durée de conservation</h4><p>Vos Informations Personnelles sont conservées par _________ uniquement pour le temps
correspondant à la finalité de la collecte tel quindiqué en 2 ci-dessus qui ne saurait en tout état de cause excéder 36 mois.</p><h4>5.
Droits Informatique et Libertés</h4><p>Vous disposez des droits suivants concernant vos Informations Personnelles, que vous pouvez exercer
en nous écrivant à ladresse postale mentionnée au point 1 ou en contactant le délégué à la protection des données, dont l'adresse est
mentionnée ci-contre.</p><p><b>o Droit daccès et de communication des données</b></p><p>Vous avez la faculté daccéder aux Informations
Personnelles qui vous concernent.</p><p>Cependant, en raison de lobligation de sécurité et de confidentialité dans le traitement des
données à caractère personnel qui incombe à _________, vous êtes informé que votre demande sera traitée sous réserve que vous apportiez la
preuve de votre identité, notamment par la production dun scan de votre titre didentité valide (en cas de demande par voie électronique)
ou dune photocopie signée de votre titre didentité valide (en cas de demande adressée par écrit).</p><p>_________ vous informe quil
sera en droit, le cas échéant, de sopposer aux demandes manifestement abusives (de par leur nombre, leur caractère répétitif ou
systématique).</p><p>Pour vous aider dans votre démarche, notamment si vous désirez exercer votre droit daccès par le biais dune
demande écrite à ladresse postale mentionnée au point 1, vous trouverez en cliquant sur le <a
href="https://www.cnil.fr/fr/modele/courrier/exercer-son-droit-dacces">lien</a> suivant un modèle de courrier élaboré par la Commission
Nationale de lInformatique et des Libertés (la « CNIL »).</p><p><b>o Droit de rectification des données</b></p><p>Au titre de ce droit,
la législation vous habilite à demander la rectification, la mise à jour, le verrouillage ou encore leffacement des données vous
concernant qui peuvent savérer le cas échéant inexactes, erronées, incomplètes ou obsolètes.</p><p>Egalement, vous pouvez définir des
directives générales et particulières relatives au sort des données à caractère personnel après votre décès. Le cas échéant, les héritiers
dune personne décédée peuvent exiger de prendre en considération le décès de leur proche et/ou de procéder aux mises à jour nécessaires.
</p><p>Pour vous aider dans votre démarche, notamment si vous désirez exercer, pour votre propre compte ou pour le compte de lun de vos
proches défunt, votre droit de rectification par le biais dune demande écrite à ladresse postale mentionnée au point 1, vous trouverez
en cliquant sur le <a href="https://www.cnil.fr/fr/modele/courrier/rectifier-des-donnees-inexactes-obsoletes-ou-perimees">lien</a>
suivant un modèle de courrier élaboré par la CNIL.</p><p><b>o Droit dopposition</b></p><p>Lexercice de ce droit nest possible que dans
lune des deux situations suivantes :</p><p>Lorsque lexercice de ce droit est fondé sur des motifs légitimes ; ou</p><p>Lorsque
lexercice de ce droit vise à faire obstacle à ce que les données recueillies soient utilisées à des fins de prospection commerciale.</p>
<p>Pour vous aider dans votre démarche, notamment si vous désirez exercer votre droit dopposition par le biais dune demande écrite
adressée à ladresse postale indiquée au point 1, vous trouverez en cliquant sur le <a
href="https://www.cnil.fr/fr/modele/courrier/supprimer-des-informations-vous-concernant-dun-site-internet">lien</a> suivant un modèle de
courrier élaboré par la CNIL.</p><h4>6. Délais de réponse</h4><p> _________ sengage à répondre à votre demande daccès, de rectification
ou dopposition ou toute autre demande complémentaire dinformations dans un délai raisonnable qui ne saurait dépasser 1 mois à compter
de la réception de votre demande.</p><h4>7. Prestataires habilités et transfert vers un pays tiers de lUnion Européenne</h4><p>_________
vous informe quil a recours à ses prestataires habilités pour faciliter le recueil et le traitement des données que vous nous avez
communiquées. Ces prestataires peuvent être situés en dehors de lUnion Européenne et ont communication des données recueillies par le
biais des divers formulaires présents sur le Site.</p><p>_________ sest préalablement assuré de la mise en œuvre par ses prestataires de
garanties adéquates et du respect de conditions strictes en matière de confidentialité, dusage et de protection des données. Tout
particulièrement, la vigilance sest portée sur lexistence dun fondement légal pour effectuer un quelconque transfert de données vers un
pays tiers. A ce titre, lun de nos prestataires est soumis à (nom de la règle) _________ approuvées par la (nom de l'autorité) _________
en (année d'approbation)&nbsp;_________.</p><h4>8. Plainte auprès de lautorité compétente</h4><p>Si vous considérez que _________ ne
respecte pas ses obligations au regard de vos Informations Personnelles, vous pouvez adresser une plainte ou une demande auprès de
lautorité compétente. En France, lautorité compétente est la CNIL à laquelle vous pouvez adresser une demande par voie électronique en
cliquant sur le lien suivant : <a href="https://www.cnil.fr/fr/plaintes/internet">https://www.cnil.fr/fr/plaintes/internet</a>.</p>
<h3>II. POLITIQUE RELATIVE AUX COOKIES</h3><p>Lors de votre première connexion sur le site web de _________, vous êtes avertis par un
bandeau en bas de votre écran que des informations relatives à votre navigation sont susceptibles dêtre enregistrées dans des fichiers
dénommés « cookies ». Notre politique dutilisation des cookies vous permet de mieux comprendre les dispositions que nous mettons en œuvre
en matière de navigation sur notre site web. Elle vous informe notamment sur lensemble des cookies présents sur notre site web, leur
finalité (partie I.) et vous donne la marche à suivre pour les paramétrer (partie II.)</p><h4>1. Informations générales sur les cookies
présents sur le site de _________</h4><p>_________, en tant quéditeur du présent site web, pourra procéder à limplantation dun cookie
sur le disque dur de votre terminal (ordinateur, tablette, mobile etc.) afin de vous garantir une navigation fluide et optimale sur notre
site Internet.</p><p>Les « cookies » (ou témoins de connexion) sont des petits fichiers texte de taille limitée qui nous permettent de
reconnaître votre ordinateur, votre tablette ou votre mobile aux fins de personnaliser les services que nous vous proposons.</p><p>Les
informations recueillies par le biais des cookies ne permettent en aucune manière de vous identifier nominativement. Elles sont utilisées
exclusivement pour nos besoins propres afin daméliorer linteractivité et la performance de notre site web et de vous adresser des
contenus adaptés à vos centres dintérêts. Aucune de ces informations ne fait lobjet dune communication auprès de tiers sauf lorsque
_________ a obtenu au préalable votre consentement ou bien lorsque la divulgation de ces informations est requise par la loi, sur ordre
dun tribunal ou toute autorité administrative ou judiciaire habilitée à en connaître.</p><p>Pour mieux vous éclairer sur les informations
que les cookies identifient, vous trouverez ci-dessous un tableau listant les différents types de cookies susceptibles dêtre utilisés sur
le site web de _________, leur nom, leur finalité ainsi que leur durée de conservation.</p><h4>2. Configuration de vos préférences sur les
cookies</h4><p>Vous pouvez accepter ou refuser le dépôt de cookies à tout moment.</p><p>Lors de votre première connexion sur le site web
de _________, une bannière présentant brièvement des informations relatives au dépôt de cookies et de technologies similaires apparaît en
bas de votre écran. Cette bannière vous demande de choisir explicitement d'accepter ou non le dépôt de cookies sur votre terminal.
</p><p>Après avoir fait votre choix, vous pouvez le modifier ultérieurement&nbsp; en vous connectant à votre compte utilisateur puis en
naviguant dans la section intitulée « mes paramètres&nbsp;», accessible via un clic sur votre nom, en haut à droite de l'écran.</p>
<p>Selon le type de cookie en cause, le recueil de votre consentement au dépôt et à la lecture de cookies sur votre terminal peut être
impératif.</p><h4>a. Les cookies exemptés de consentement</h4><p>Conformément aux recommandations de la Commission Nationale de
lInformatique et des Libertés (CNIL), certains cookies sont dispensés du recueil préalable de votre consentement dans la mesure ils
sont strictement nécessaires au fonctionnement du site internet ou ont pour finalité exclusive de permettre ou faciliter la communication
par voie électronique. Il sagit des cookies suivants :</p><p><b>o Identifiant de session</b> et&nbsp;<b>d'authentification</b> sur l'API de
Fab-manager.</p><p><b>o Identifiant de panier d'achat</b></b>, permettant de sauvegarder le contenu de votre panier d'achat, même lorsque
vous n'êtes pas connecté.</p>
<p><em>Les cookies ci-dessus sont intégralement soumis à la présente politique dans la mesure ils sont émis et gérés par _________.</em></p>
<p><b>o Stripe</b>, permettant de gérer les paiements par carte bancaire et dont la politique de confidentialité est accessible sur ce
<a href="https://stripe.com/fr/privacy">lien</a>.</p><p><b>o Disqus</b>, permettant de poster des commentaires sur les fiches projet et
dont la politique de confidentialité est accessible sur ce <a href="https://help.disqus.com/articles/1717103-disqus-privacy-policy">lien
</a>.</p><h4>b. Les cookies nécessitant le recueil préalable de votre consentement</h4><p>Cette
exigence concerne les cookies émis par des tiers et qui sont qualifiés de « persistants » dans la mesure ils demeurent dans votre
terminal jusquà leur effacement ou leur date dexpiration.</p><p>De tels cookies étant émis par des tiers, leur utilisation et leur dépôt
sont soumis à leurs propres politiques de confidentialité dont vous trouverez un lien ci-dessous. Cette famille de cookie comprend les
cookies de mesure daudience (Google Analytics).</p><p>Les cookies de mesure daudience établissent des statistiques concernant la
fréquentation et lutilisation de divers éléments du site web (comme les contenus/pages que vous avez visité).
Ces données participent à lamélioration de lergonomie du site web de _________. Un outil de mesure daudience est utilisé sur le
présent site internet :</p><p><b>o Google Analytics</b> pour gérer les statistiques de visites dont la politique de
confidentialité est disponible (uniquement en anglais) à partir du <a href="https://policies.google.com/privacy?hl=fr&amp;gl=ZZ">lien
</a> suivant. </p><h4>c. Vous disposez de divers outils de paramétrage des cookies</h4><p>La plupart
des navigateurs Internet sont configurés par défaut de façon à ce que le dépôt de cookies soit autorisé. Votre navigateur vous offre
lopportunité de modifier ces paramètres standards de manière que lensemble des cookies soit rejeté systématiquement ou bien à ce
quune partie seulement des cookies soit acceptée ou refusée en fonction de leur émetteur.</p><p><b>ATTENTION</b> : Nous attirons votre
attention sur le fait que le refus du dépôt de cookies sur votre terminal est néanmoins susceptible daltérer votre expérience
dutilisateur ainsi que votre accès à certains services ou fonctionnalités du présent site web. Le cas échéant, _________ décline toute
responsabilité concernant les conséquences liées à la dégradation de vos conditions de navigation qui interviennent en raison de votre
choix de refuser, supprimer ou bloquer les cookies nécessaires au fonctionnement du site.
Ces conséquences ne sauraient constituer un dommage et vous ne pourrez prétendre à aucune indemnité de ce fait.</p>
<p>Votre navigateur vous permet également de supprimer les cookies existants sur votre
terminal ou encore de vous signaler lorsque de nouveaux cookies sont susceptibles dêtre déposés sur votre terminal. Ces paramètres nont
pas dincidence sur votre navigation, mais vous font perdre tout le bénéfice apporté par le cookie.</p><p>Veuillez ci-dessous prendre
connaissance des multiples outils mis à votre disposition afin que vous puissiez paramétrer les cookies déposés sur votre terminal.</p>
<h4>d. Le paramétrage de votre navigateur Internet</h4><p>Chaque navigateur Internet propose ses propres paramètres de gestion des
cookies. Pour savoir de quelle manière modifier vos préférences en matière de cookies, vous trouverez ci-dessous les liens vers laide
nécessaire pour accéder au menu de votre navigateur prévu à cet effet :</p>
<ul>
<li><a href="https://support.google.com/chrome/answer/95647?hl=fr">Chrome</a></li>
<li><a href="https://mzl.la/3BX2oBb">Firefox</a></li>
<li><a href="https://support.microsoft.com/fr-fr/microsoft-edge/supprimer-les-cookies-dans-microsoft-edge-63947406-40ac-c3b8-57b9-2a946a29ae09">
Microsoft Edge</a></li>
<li><a href="https://help.opera.com/en/latest/web-preferences/#cookies">Opera</a></li>
<li><a href="https://support.apple.com/fr-fr/HT201265">Safari</a></li>
</ul>
<p>Pour de plus amples informations concernant les outils de maîtrise des cookies, vous pouvez consulter le
<a href="https://www.cnil.fr/fr/cookies-et-autres-traceurs/comment-se-proteger/maitriser-votre-navigateur">site internet</a> de la CNIL.</p>
HTML
setting.save
end
Setting.set('fab_analytics', true) unless Setting.find_by(name: 'fab_analytics').try(:value)
unless Setting.find_by(name: 'link_name').try(:value)
include ApplicationHelper # rubocop:disable Style/MixinUsage
name = Setting.get('fablab_name')
gender = Setting.get('name_genre')
setting = Setting.find_or_initialize_by(name: 'link_name')
setting.value = _t('app.public.common.about_the_fablab', NAME: name, GENDER: gender)
setting.save
end
unless Setting.find_by(name: 'home_content').try(:value)
setting = Setting.find_or_initialize_by(name: 'home_content')
setting.value = <<~HTML
<div>
<div class="m-sm">
<div id="news">#{I18n.t('app.admin.settings.item_news')}</div>
</div>
<div class="row wrapper">
<div class="col-lg-8">
<div id="projects">#{I18n.t('app.admin.settings.item_projects')}</div>
</div>
<div class="col-lg-4 m-t-lg">
<div id="twitter">#{I18n.t('app.admin.settings.item_twitter')}</div>
<div id="members">#{I18n.t('app.admin.settings.item_members')}</div>
</div>
</div>
<div class="row wrapper m-t-sm">
<div class="col-lg-12">
<div id="events">#{I18n.t('app.admin.settings.item_events')}</div>
</div>
</div>
</div>
HTML
setting.save
end
Setting.set('slot_duration', 60) unless Setting.find_by(name: 'slot_duration').try(:value)
Setting.set('spaces_module', false) unless Setting.find_by(name: 'spaces_module').try(:value)
Setting.set('plans_module', true) unless Setting.find_by(name: 'plans_module').try(:value)
Setting.set('invoicing_module', true) unless Setting.find_by(name: 'invoicing_module').try(:value)
Setting.set('feature_tour_display', 'once') unless Setting.find_by(name: 'feature_tour_display').try(:value)
Setting.set('email_from', 'noreply@fab-manager.com') unless Setting.find_by(name: 'email_from').try(:value)
Setting.set('online_payment_module', false) unless Setting.find_by(name: 'online_payment_module').try(:value)
Setting.set('openlab_default', true) unless Setting.find_by(name: 'openlab_default').try(:value)
unless Setting.find_by(name: 'allowed_cad_extensions').try(:value)
Setting.set(
'allowed_cad_extensions',
'pdf ai eps cad math svg stl dxf dwg obj step iges igs 3dm 3dmf doc docx png ino scad fcad skp sldprt sldasm slddrw' \
'slddrt tex latex ps fcstd fcstd1'
)
end
unless Setting.find_by(name: 'allowed_cad_mime_types').try(:value)
Setting.set(
'allowed_cad_mime_types',
'application/pdf application/postscript application/illustrator image/x-eps image/svg+xml application/sla application/dxf ' \
'application/acad application/dwg application/octet-stream application/step application/iges model/iges x-world/x-3dmf ' \
'application/vnd.openxmlformats-officedocument.wordprocessingml.document image/png text/x-arduino text/plain application/scad ' \
'application/vnd.sketchup.skp application/x-koan application/vnd-koan koan/x-skm application/vnd.koan application/x-tex ' \
'application/x-latex application/x-extension-fcstd'
)
end
Setting.set('stripe_currency', 'EUR') unless Setting.find_by(name: 'stripe_currency').try(:value)
Setting.set('invoice_prefix', 'FabManager_invoice') unless Setting.find_by(name: 'invoice_prefix').try(:value)
Setting.set('payment_schedule_prefix', 'FabManager_paymentSchedule') unless Setting.find_by(name: 'payment_schedule_prefix').try(:value)
Setting.set('confirmation_required', false) unless Setting.find_by(name: 'confirmation_required').try(:value)
Setting.set('user_validation_required', false) unless Setting.find_by(name: 'user_validation_required').try(:value)
Setting.set('user_validation_required_list', '') unless Setting.find_by(name: 'user_validation_required_list').try(:value)
Setting.set('wallet_module', true) unless Setting.find_by(name: 'wallet_module').try(:value)
Setting.set('statistics_module', true) unless Setting.find_by(name: 'statistics_module').try(:value)
Setting.set('machines_module', true) unless Setting.find_by(name: 'machines_module').try(:value)
Setting.set('upcoming_events_shown', 'until_start') unless Setting.find_by(name: 'upcoming_events_shown').try(:value)
Setting.set('trainings_module', true) unless Setting.find_by(name: 'trainings_module').try(:value)
Setting.set('public_agenda_module', true) unless Setting.find_by(name: 'public_agenda_module').try(:value)
Setting.set('renew_pack_threshold', 0.2) unless Setting.find_by(name: 'renew_pack_threshold').try(:value)
Setting.set('pack_only_for_subscription', true) unless Setting.find_by(name: 'pack_only_for_subscription').try(:value)
Setting.set('public_registrations', true) unless Setting.find_by(name: 'public_registrations').try(:value)
Setting.set('user_change_group', true) unless Setting.find_by(name: 'user_change_group').try(:value)
Setting.set('invoice_VAT-name', I18n.t('invoices.VAT')) unless Setting.find_by(name: 'invoice_VAT-name').try(:value)
unless Setting.find_by(name: 'overlapping_categories').try(:value)
Setting.set('overlapping_categories', 'training_reservations,machine_reservations,space_reservations,events_reservations')
end
Setting.set('extended_prices_in_same_day', false) unless Setting.find_by(name: 'extended_prices_in_same_day').try(:value)
Setting.set('show_username_in_admin_list', false) unless Setting.find_by(name: 'show_username_in_admin_list').try(:value)
Setting.set('store_module', false) unless Setting.find_by(name: 'store_module').try(:value)
Setting.set('store_hidden', true) unless Setting.find_by(name: 'store_hidden').try(:value)
Setting.set('advanced_accounting', false) unless Setting.find_by(name: 'advanced_accounting').try(:value)
Setting.set('accounting_sales_journal_code', 'SALES') unless Setting.find_by(name: 'accounting_sales_journal_code').try(:value)
Setting.set('accounting_payment_card_code', '5801') unless Setting.find_by(name: 'accounting_payment_card_code').try(:value)
Setting.set('accounting_payment_card_label', 'Cards payments') unless Setting.find_by(name: 'accounting_payment_card_label').try(:value)
Setting.set('accounting_payment_card_journal_code', 'CA01') unless Setting.find_by(name: 'accounting_payment_card_journal_code').try(:value)
Setting.set('accounting_payment_wallet_code', '5802') unless Setting.find_by(name: 'accounting_payment_wallet_code').try(:value)
Setting.set('accounting_payment_wallet_label', 'Wallet payments') unless Setting.find_by(name: 'accounting_payment_wallet_label').try(:value)
Setting.set('accounting_payment_wallet_journal_code', 'WA01') unless Setting.find_by(name: 'accounting_payment_wallet_journal_code').try(:value)
Setting.set('accounting_payment_other_code', '5803') unless Setting.find_by(name: 'accounting_payment_other_code').try(:value)
Setting.set('accounting_payment_other_label', 'Payments on site') unless Setting.find_by(name: 'accounting_payment_other_label').try(:value)
Setting.set('accounting_payment_other_journal_code', 'SI01') unless Setting.find_by(name: 'accounting_payment_other_journal_code').try(:value)
Setting.set('accounting_wallet_code', '4191') unless Setting.find_by(name: 'accounting_wallet_code').try(:value)
Setting.set('accounting_wallet_label', 'Wallet credit') unless Setting.find_by(name: 'accounting_wallet_label').try(:value)
Setting.set('accounting_wallet_journal_code', 'WC01') unless Setting.find_by(name: 'accounting_wallet_journal_code').try(:value)
Setting.set('accounting_VAT_code', '4457') unless Setting.find_by(name: 'accounting_VAT_code').try(:value)
Setting.set('accounting_VAT_label', 'Collected VAT') unless Setting.find_by(name: 'accounting_VAT_label').try(:value)
Setting.set('accounting_VAT_journal_code', 'VAT1') unless Setting.find_by(name: 'accounting_VAT_journal_code').try(:value)
Setting.set('accounting_subscription_code', '7061') unless Setting.find_by(name: 'accounting_subscription_code').try(:value)
Setting.set('accounting_subscription_label', 'Subscriptions') unless Setting.find_by(name: 'accounting_subscription_label').try(:value)
Setting.set('accounting_Machine_code', '7602') unless Setting.find_by(name: 'accounting_Machine_code').try(:value)
Setting.set('accounting_Machine_label', 'Machines reservations') unless Setting.find_by(name: 'accounting_Machine_label').try(:value)
Setting.set('accounting_Training_code', '7063') unless Setting.find_by(name: 'accounting_Training_code').try(:value)
Setting.set('accounting_Training_label', 'Trainings reservations') unless Setting.find_by(name: 'accounting_Training_label').try(:value)
Setting.set('accounting_Event_code', '7064') unless Setting.find_by(name: 'accounting_Event_code').try(:value)
Setting.set('accounting_Event_label', 'Events reservations') unless Setting.find_by(name: 'accounting_Event_label').try(:value)
Setting.set('accounting_Space_code', '7065') unless Setting.find_by(name: 'accounting_Space_code').try(:value)
Setting.set('accounting_Space_label', 'Spaces reservations') unless Setting.find_by(name: 'accounting_Space_label').try(:value)
Setting.set('accounting_Pack_code', '7066') unless Setting.find_by(name: 'accounting_Pack_code').try(:value)
Setting.set('accounting_Pack_label', 'Prepaid-packs selling') unless Setting.find_by(name: 'accounting_Pack_label').try(:value)
Setting.set('accounting_Product_code', '7071') unless Setting.find_by(name: 'accounting_Product_code').try(:value)
Setting.set('accounting_Product_label', 'Merchandise selling') unless Setting.find_by(name: 'accounting_Product_label').try(:value)
Setting.set('accounting_Error_code', 'ERROR') unless Setting.find_by(name: 'accounting_Error_code').try(:value)
Setting.set('accounting_Error_label', 'Erroneous invoices to refund') unless Setting.find_by(name: 'accounting_Error_label').try(:value)
Setting.set('external_id', false) unless Setting.find_by(name: 'external_id').try(:value)

206
db/seeds/statistics.rb Normal file
View File

@ -0,0 +1,206 @@
# frozen_string_literal: true
require_relative '../../lib/database/sequence'
# statistic_indices
unless StatisticIndex.find_by(es_type_key: 'subscription')
StatisticIndex.create!({ id: 1, es_type_key: 'subscription', label: I18n.t('statistics.subscriptions') })
end
unless StatisticIndex.find_by(es_type_key: 'machine')
StatisticIndex.create!({ id: 2, es_type_key: 'machine', label: I18n.t('statistics.machines_hours') })
end
unless StatisticIndex.find_by(es_type_key: 'training')
StatisticIndex.create!({ id: 3, es_type_key: 'training', label: I18n.t('statistics.trainings') })
end
StatisticIndex.create!({ id: 4, es_type_key: 'event', label: I18n.t('statistics.events') }) unless StatisticIndex.find_by(es_type_key: 'event')
unless StatisticIndex.find_by(es_type_key: 'account')
StatisticIndex.create!({ id: 5, es_type_key: 'account', label: I18n.t('statistics.registrations'), ca: false })
end
unless StatisticIndex.find_by(es_type_key: 'project')
StatisticIndex.create!({ id: 6, es_type_key: 'project', label: I18n.t('statistics.projects'), ca: false })
end
unless StatisticIndex.find_by(es_type_key: 'user')
StatisticIndex.create!({ id: 7, es_type_key: 'user', label: I18n.t('statistics.users'), table: false, ca: false })
end
Database::Sequence.update_id_seq(StatisticIndex.table_name)
StatisticIndex.create!({ es_type_key: 'space', label: I18n.t('statistics.spaces') }) unless StatisticIndex.find_by(es_type_key: 'space')
StatisticIndex.create!({ es_type_key: 'order', label: I18n.t('statistics.orders') }) unless StatisticIndex.find_by(es_type_key: 'order')
statistic_index_space = StatisticIndex.find_by(es_type_key: 'space')
statistic_index_order = StatisticIndex.find_by(es_type_key: 'order')
# statistic_fields
unless StatisticField.find_by(key: 'spaceDates')
StatisticField.create!({ key: 'spaceDates', label: I18n.t('statistics.space_dates'),
statistic_index_id: statistic_index_space.id, data_type: 'list' })
end
unless StatisticField.find_by(key: 'machineDates')
StatisticField.create!({ key: 'machineDates', label: I18n.t('statistics.machine_dates'), statistic_index_id: 2, data_type: 'list' })
end
unless StatisticField.find_by(key: 'trainingId')
StatisticField.create!({ key: 'trainingId', label: I18n.t('statistics.training_id'), statistic_index_id: 3, data_type: 'index' })
end
unless StatisticField.find_by(key: 'trainingDate')
StatisticField.create!({ key: 'trainingDate', label: I18n.t('statistics.training_date'), statistic_index_id: 3, data_type: 'date' })
end
unless StatisticField.find_by(key: 'eventId')
StatisticField.create!({ key: 'eventId', label: I18n.t('statistics.event_id'), statistic_index_id: 4, data_type: 'index' })
end
unless StatisticField.find_by(key: 'eventDate')
StatisticField.create!({ key: 'eventDate', label: I18n.t('statistics.event_date'), statistic_index_id: 4, data_type: 'date' })
end
unless StatisticField.find_by(key: 'themes')
StatisticField.create!({ key: 'themes', label: I18n.t('statistics.themes'), statistic_index_id: 6, data_type: 'list' })
end
unless StatisticField.find_by(key: 'components')
StatisticField.create!({ key: 'components', label: I18n.t('statistics.components'), statistic_index_id: 6, data_type: 'list' })
end
unless StatisticField.find_by(key: 'machines')
StatisticField.create!({ key: 'machines', label: I18n.t('statistics.machines'), statistic_index_id: 6, data_type: 'list' })
end
unless StatisticField.find_by(key: 'name')
StatisticField.create!({ key: 'name', label: I18n.t('statistics.event_name'), statistic_index_id: 4, data_type: 'text' })
end
unless StatisticField.find_by(key: 'userId')
StatisticField.create!({ key: 'userId', label: I18n.t('statistics.user_id'), statistic_index_id: 7, data_type: 'index' })
end
unless StatisticField.find_by(key: 'eventTheme')
StatisticField.create!({ key: 'eventTheme', label: I18n.t('statistics.event_theme'), statistic_index_id: 4, data_type: 'text' })
end
unless StatisticField.find_by(key: 'ageRange')
StatisticField.create!({ key: 'ageRange', label: I18n.t('statistics.age_range'), statistic_index_id: 4, data_type: 'text' })
end
unless StatisticField.find_by(key: 'groupName')
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: 1, data_type: 'text' })
end
# statistic_types
unless StatisticType.find_by(key: 'booking', statistic_index_id: 2)
StatisticType.create!({ statistic_index_id: 2, key: 'booking', label: I18n.t('statistics.bookings'), graph: true, simple: true })
end
unless StatisticType.find_by(key: 'hour', statistic_index_id: 2)
StatisticType.create!({ statistic_index_id: 2, key: 'hour', label: I18n.t('statistics.hours_number'), graph: true, simple: false })
end
unless StatisticType.find_by(key: 'booking', statistic_index_id: 3)
StatisticType.create!({ statistic_index_id: 3, key: 'booking', label: I18n.t('statistics.bookings'), graph: false, simple: true })
end
unless StatisticType.find_by(key: 'hour', statistic_index_id: 3)
StatisticType.create!({ statistic_index_id: 3, key: 'hour', label: I18n.t('statistics.hours_number'), graph: false, simple: false })
end
unless StatisticType.find_by(key: 'booking', statistic_index_id: 4)
StatisticType.create!({ statistic_index_id: 4, key: 'booking', label: I18n.t('statistics.tickets_number'), graph: false, simple: false })
end
unless StatisticType.find_by(key: 'hour', statistic_index_id: 4)
StatisticType.create!({ statistic_index_id: 4, key: 'hour', label: I18n.t('statistics.hours_number'), graph: false, simple: false })
end
unless StatisticType.find_by(key: 'member', statistic_index_id: 5)
StatisticType.create!({ statistic_index_id: 5, key: 'member', label: I18n.t('statistics.users'), graph: true, simple: true })
end
unless StatisticType.find_by(key: 'project', statistic_index_id: 6)
StatisticType.create!({ statistic_index_id: 6, key: 'project', label: I18n.t('statistics.projects'), graph: false, simple: true })
end
unless StatisticType.find_by(key: 'revenue', statistic_index_id: 7)
StatisticType.create!({ statistic_index_id: 7, key: 'revenue', label: I18n.t('statistics.revenue'), graph: false, simple: false })
end
unless StatisticType.find_by(key: 'booking', statistic_index_id: statistic_index_space.id)
StatisticType.create!({ statistic_index_id: statistic_index_space.id, key: 'booking', label: I18n.t('statistics.bookings'),
graph: true, simple: true })
end
unless StatisticType.find_by(key: 'hour', statistic_index_id: statistic_index_space.id)
StatisticType.create!({ statistic_index_id: statistic_index_space.id, key: 'hour', label: I18n.t('statistics.hours_number'),
graph: true, simple: false })
end
unless StatisticType.find_by(key: 'store', statistic_index_id: statistic_index_order.id)
StatisticType.create!({ statistic_index_id: statistic_index_order.id, key: 'store', label: I18n.t('statistics.store'),
graph: true, simple: true })
end
Plan.find_each do |plan|
if plan.find_statistic_type.nil?
StatisticType.create!(
statistic_index_id: 1,
key: plan.duration.to_i,
label: "#{I18n.t('statistics.duration')} : #{plan.human_readable_duration}",
graph: true,
simple: true
)
end
end
# statistic_sub_types
unless StatisticSubType.find_by(key: 'created')
StatisticSubType.create!({ key: 'created', label: I18n.t('statistics.account_creation'),
statistic_types: StatisticIndex.find_by(es_type_key: 'account').statistic_types })
end
unless StatisticSubType.find_by(key: 'published')
StatisticSubType.create!({ key: 'published', label: I18n.t('statistics.project_publication'),
statistic_types: StatisticIndex.find_by(es_type_key: 'project').statistic_types })
end
unless StatisticSubType.find_by(key: 'paid-processed')
StatisticSubType.create!({ key: 'paid-processed', label: I18n.t('statistics.paid-processed'),
statistic_types: statistic_index_order.statistic_types })
end
unless StatisticSubType.find_by(key: 'aborted')
StatisticSubType.create!({ key: 'aborted', label: I18n.t('statistics.aborted'), statistic_types: statistic_index_order.statistic_types })
end
Plan.find_each do |plan|
type = plan.find_statistic_type
subtype = if StatisticSubType.find_by(key: plan.slug).nil?
plan.create_statistic_subtype
else
StatisticSubType.find_by(key: plan.slug)
end
if StatisticTypeSubType.find_by(statistic_type: type, statistic_sub_type: subtype).nil?
StatisticTypeSubType.create!(statistic_type: type, statistic_sub_type: subtype)
end
end
# statistic_graphs
StatisticGraph.create!({ statistic_index_id: 1, chart_type: 'stackedAreaChart', limit: 0 }) unless StatisticGraph.find_by(statistic_index_id: 1)
StatisticGraph.create!({ statistic_index_id: 2, chart_type: 'stackedAreaChart', limit: 0 }) unless StatisticGraph.find_by(statistic_index_id: 2)
StatisticGraph.create!({ statistic_index_id: 3, chart_type: 'discreteBarChart', limit: 10 }) unless StatisticGraph.find_by(statistic_index_id: 3)
StatisticGraph.create!({ statistic_index_id: 4, chart_type: 'discreteBarChart', limit: 10 }) unless StatisticGraph.find_by(statistic_index_id: 4)
StatisticGraph.create!({ statistic_index_id: 5, chart_type: 'lineChart', limit: 0 }) unless StatisticGraph.find_by(statistic_index_id: 5)
StatisticGraph.create!({ statistic_index_id: 7, chart_type: 'discreteBarChart', limit: 10 }) unless StatisticGraph.find_by(statistic_index_id: 7)
# statistic_custom_aggregations
unless StatisticCustomAggregation.find_by(es_type: 'availabilities', field: 'available_hours')
# available reservations hours for machines
machine_hours = StatisticType.find_by(key: 'hour', statistic_index_id: 2)
StatisticCustomAggregation.create!(
statistic_type_id: machine_hours.id,
es_index: 'fablab',
es_type: 'availabilities',
field: 'available_hours',
query: '{"size":0, "aggregations":{"%<aggs_name>s":{"sum":{"field":"bookable_hours"}}}, "query":{"bool":{"must":[{"range":' \
'{"start_at":{"gte":"%<start_date>s", "lte":"%<end_date>s"}}}, {"match":{"available_type":"machines"}}]}}}'
)
end
unless StatisticCustomAggregation.find_by(es_type: 'availabilities', field: 'available_tickets')
# available training tickets
training_bookings = StatisticType.find_by(key: 'booking', statistic_index_id: 3)
StatisticCustomAggregation.create!(
statistic_type_id: training_bookings.id,
es_index: 'fablab',
es_type: 'availabilities',
field: 'available_tickets',
query: '{"size":0, "aggregations":{"%<aggs_name>s":{"sum":{"field":"nb_total_places"}}}, "query":{"bool":{"must":[{"range":' \
'{"start_at":{"gte":"%<start_date>s", "lte":"%<end_date>s"}}}, {"match":{"available_type":"training"}}]}}}'
)
end
unless StatisticCustomAggregation.find_by(es_type: 'order', field: 'average_cart')
# available training tickets
order_store = StatisticType.find_by(key: 'store', statistic_index_id: statistic_index_order.id)
# average cart price for orders
StatisticCustomAggregation.create!(
statistic_type_id: order_store.id,
es_index: 'stats',
es_type: 'order',
field: 'average_cart',
query: '{"size":0, "aggregations":{"%<aggs_name>s":{"avg":{"field":"ca", ' \
'"script":"BigDecimal.valueOf(_value).setScale(1, RoundingMode.HALF_UP)", "missing": 0}}}, ' \
'"query":{"bool":{"must":[{"range": {"date":{"gte":"%<start_date>s", "lte":"%<end_date>s"}}}]}}}'
)
end

View File

@ -37,3 +37,7 @@ Unable to decode ID token
This issue may occur if the ID Token signature algorithm is not set to `RSxxx` on your IDP.
Especially, this is not the default option when using LemonLDAP::NG, which uses `HSxxx` as the default algorithm, but you can configure it in `OpenID Connect Relaying Parties` > `my-fab-manager` > `Options` > `Security` > `ID Token signature algorithm`.
Using Keycloak, you can configure it in `Clients` > `my-fab-manager` > `Settings` > `Fine Grain OpenID Connect Configuration` > `ID Token Signature Algorithm`.
```
Issuer mismatch
```
Check that your configured issuer URL ends with a trailing slash.

23
lib/database/sequence.rb Normal file
View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
# Database helpers
module Database; end
# Manage sequences
class Database::Sequence
class << self
# update the ID sequence for the given table
# @param table_name [String]
def update_id_seq(table_name)
return unless ActiveRecord::Base.connection.instance_values['config'][:adapter] == 'postgresql'
ActiveRecord::Base.connection.execute <<~SQL.squish
WITH max_id AS (
SELECT max(id) as max FROM #{table_name}
)
SELECT setval('#{table_name}_id_seq', max_id.max)
FROM max_id;
SQL
end
end
end

View File

@ -9,16 +9,18 @@ namespace :fablab do
create_stats_index
create_stats_mappings
add_event_filters
add_machine_filters
add_space_filters
end
def delete_stats_index
puts 'DELETE stats'
`curl -XDELETE http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats`
`curl -XDELETE http://#{ENV.fetch('ELASTICSEARCH_HOST')}:9200/stats`
end
def create_stats_index
puts 'PUT index stats'
`curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats -d'
`curl -XPUT http://#{ENV.fetch('ELASTICSEARCH_HOST')}:9200/stats -d'
{
"settings" : {
"index" : {
@ -32,7 +34,7 @@ namespace :fablab do
def create_stats_mappings
%w[account event machine project subscription training user space].each do |stat|
puts "PUT Mapping stats/#{stat}"
`curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats/#{stat}/_mapping -d '
`curl -XPUT http://#{ENV.fetch('ELASTICSEARCH_HOST')}:9200/stats/#{stat}/_mapping -d '
{
"properties": {
"type": {
@ -61,7 +63,7 @@ namespace :fablab do
end
def add_event_filters
`curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats/event/_mapping -d '
`curl -XPUT http://#{ENV.fetch('ELASTICSEARCH_HOST')}:9200/stats/event/_mapping -d '
{
"properties": {
"ageRange": {
@ -76,10 +78,35 @@ namespace :fablab do
}';`
end
def add_machine_filters
`curl -XPUT http://#{ENV.fetch('ELASTICSEARCH_HOST')}:9200/stats/machine/_mapping -d '
{
"properties": {
"machineDates": {
"properties": {
"type": "date",
}
}
}
}';`
end
def add_space_filters
`curl -XPUT http://#{ENV.fetch('ELASTICSEARCH_HOST')}:9200/stats/space/_mapping -d '
{
"properties": {
"spaceDates": {
"properties": {
"type": "date",
}
}
}
}';`
end
desc 'add spaces reservations to statistics'
task add_spaces: :environment do
`curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats/space/_mapping -d '
`curl -XPUT http://#{ENV.fetch('ELASTICSEARCH_HOST')}:9200/stats/space/_mapping -d '
{
"properties": {
"type": {
@ -129,19 +156,18 @@ namespace :fablab do
end
else
puts "[ElasticSearch] An error occurred while creating #{Availability.index_name}/#{Availability.document_type}. " \
'Please check your ElasticSearch configuration.'
'Please check your ElasticSearch configuration.'
puts "\nCancelling..."
end
end
desc '(re)generate statistics in ElasticSearch for the past period. Use 0 to generate for today'
task :generate_stats, [:period] => :environment do |_task, args|
raise 'FATAL ERROR: You must pass a number of days (=> past period) OR a date to generate statistics' unless args.period
unless Setting.get('statistics_module')
print 'Statistics are disabled. Do you still want to generate? (y/N) '
confirm = STDIN.gets.chomp
confirm = $stdin.gets.chomp
raise 'Interrupted by user' unless confirm == 'y'
end

View File

@ -1,6 +1,6 @@
{
"name": "fab-manager",
"version": "5.6.8",
"version": "5.6.9",
"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",
@ -45,7 +45,7 @@
"react-refresh": "^0.11.0",
"react-select-event": "^5.5.1",
"react-test-renderer": "^17.0.2",
"webpack-dev-server": "^4.7.4"
"webpack-dev-server": "^4.9.0"
},
"dependencies": {
"@babel/core": "^7.20.2",
@ -57,7 +57,7 @@
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.12.1",
"@babel/preset-typescript": "^7.16.7",
"@babel/runtime": "^7.17.2",
"@babel/runtime": "^7.17.9",
"@claviska/jquery-minicolors": "^2.3.6",
"@dnd-kit/core": "^6.0.5",
"@dnd-kit/modifiers": "^6.0.0",
@ -118,7 +118,7 @@
"angular-xeditable": "0.10",
"assert": "^2.0.0",
"axios": "^0.21.2",
"babel-loader": "^8.2.3",
"babel-loader": "^9.1.2",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"bootstrap-sass": "3.4.3",
@ -151,8 +151,8 @@
"ngUpload": "0.5",
"ngtemplate-loader": "^2.1.0",
"nvd3": "1.8",
"object-to-formdata-tz": "4.4.3",
"object-to-formdata": "npm:object-to-formdata-tz@4.4.3",
"object-to-formdata-tz": "4.4.3",
"phosphor-react": "^1.4.0",
"process": "^0.11.10",
"prop-types": "^15.7.2",
@ -172,7 +172,7 @@
"resolve-url-loader": "^4.0.0",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"shakapacker": "6.2.0",
"shakapacker": "6.5.5",
"slugify": "^1.6.5",
"sortablejs": "^1.15.0",
"style-loader": "^3.3.1",
@ -183,7 +183,7 @@
"ui-select": "0.19",
"underscore": "1.12",
"use-immer": "^0.5.1",
"webpack": "5",
"webpack": "5.72.0",
"webpack-assets-manifest": "5",
"webpack-cli": "4",
"webpack-merge": "5",

View File

@ -42,6 +42,7 @@ OPENLAB_BASE_URI=https://openprojects.fab-manager.com
OPENLAB_SSL_VERIFY=true
LOG_LEVEL=debug
RAILS_LOG_TO_STDOUT=true
DISK_SPACE_MB_ALERT=1024
ADMINSYS_EMAIL=
ALLOW_INSECURE_HTTP=false

BIN
test/fixtures/files/event/Party.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -8,11 +8,16 @@ describe('FormatLib', () => {
const str = FormatLib.date(new Date('2023-01-12T12:00:00+0100'));
expect(str).toBe('12/01/2023');
});
test('format an iso8601 short date', () => {
test('format an iso8601 short date in french format', () => {
Fablab.intl_locale = 'fr-FR';
const str = FormatLib.date('2023-01-12');
expect(str).toBe('12/01/2023');
});
test('format an iso8601 short date in canadian format', () => {
Fablab.intl_locale = 'fr-CA';
const str = FormatLib.date('2023-02-27');
expect(str).toBe('2023-02-27');
});
test('format an iso8601 date', () => {
Fablab.intl_locale = 'fr-CA';
const str = FormatLib.date('2023-01-12T23:59:14-0500');

View File

@ -73,4 +73,49 @@ class Events::RecurrenceTest < ActionDispatch::IntegrationTest
assert(db_events.all? { |event| event.advanced_accounting.code == '706300' })
assert(db_events.all? { |event| event.advanced_accounting.analytical_section == '9A54C' })
end
test 'create a simple recurrent event' do
name = 'Fablab party'
post '/api/events',
params: {
event: {
title: name,
event_image_attributes: {
attachment: fixture_file_upload('/files/event/Party.jpg')
},
description: 'Come party tonight at the fablab...',
start_date: 2.weeks.from_now.utc,
end_date: 2.weeks.from_now.utc,
all_day: false,
start_time: '18:00',
end_time: '23:29',
amount: 20,
category_id: 2,
recurrence: 'month',
recurrence_end_at: 3.months.from_now.utc + 2.weeks
}
},
headers: upload_headers
# Check response format & status
assert_equal 201, response.status, response.body
assert_equal Mime[:json], response.content_type
# Check the events were correctly created
db_events = Event.where(title: name)
assert_equal 4, db_events.count
assert(db_events.all? { |event| !event.event_image.attachment.nil? })
assert(db_events.all? { |event| !event.description.empty? })
assert(db_events.all? { |event| event.availability.start_at.to_date >= 2.weeks.from_now.to_date })
assert(db_events.all? { |event| event.availability.start_at.to_date <= 3.months.from_now.end_of_day.to_date + 2.weeks })
assert(db_events.all? { |event| event.availability.end_at.to_date >= 2.weeks.from_now.to_date })
assert(db_events.all? { |event| event.availability.end_at.to_date <= 3.months.from_now.end_of_day.to_date + 2.weeks })
assert(db_events.none?(&:all_day?))
assert(db_events.all? { |event| event.amount == 2000 })
assert(db_events.all? { |event| event.event_theme_ids.empty? })
assert(db_events.all? { |event| event.category_id == 2 })
assert(db_events.all? { |event| event.age_range_id.nil? })
assert(db_events.all? { |event| event.event_files.count.zero? })
assert(db_events.all? { |event| event.event_price_categories.count.zero? })
end
end

View File

@ -8,28 +8,26 @@ class CreatePlanTest < ActionDispatch::IntegrationTest
login_as(admin, scope: :user)
end
test 'create a plan' do
test 'create a transversal partner plan' do
plans_count = Plan.count
post '/api/plans',
params: {
plan: {
base_name: 'Abonnement test',
type: 'Plan',
group_id: 1,
type: 'PartnerPlan',
group_id: 'all',
plan_category_id: nil,
interval: 'week',
interval_count: 2,
amount: 10,
ui_weight: 0,
is_rolling: true,
monthly_payment: false,
monthly_payment: true,
description: 'lorem ipsum dolor sit amet',
partner_id: '',
partner_id: 6,
plan_file_attributes: {
id: nil,
_destroy: nil,
attachment: nil
attachment: fixture_file_upload('/files/document.pdf')
}
}
}.to_json,
@ -39,9 +37,50 @@ class CreatePlanTest < ActionDispatch::IntegrationTest
assert_equal 201, response.status, response.body
assert_equal Mime[:json], response.content_type
# Check the created plans
res = json_response(response.body)
assert_equal 2, res[:plan_ids].count
assert_equal plans_count + 2, Plan.count
plans = Plan.where(name: 'Abonnement test')
assert(plans.all? { |plan| !plan.plan_file.attachment.nil? })
assert(plans.all? { |plan| plan.type == 'PartnerPlan' })
assert(plans.all? { |plan| plan.partner_id == 6 })
assert(plans.all?(&:is_rolling))
end
test 'create a simple plan' do
plans_count = Plan.count
post '/api/plans',
params: {
plan: {
base_name: 'Abonnement simple',
type: 'Plan',
group_id: 1,
plan_category_id: nil,
interval: 'month',
interval_count: 1,
amount: 40
}
}.to_json,
headers: default_headers
# Check response format & status
assert_equal 201, response.status, response.body
assert_equal Mime[:json], response.content_type
# Check the created plan
plan = json_response(response.body)
assert_equal Plan.last.id, plan[:plan_ids][0]
res = json_response(response.body)
assert_equal plans_count + 1, Plan.count
plan = Plan.find(res[:plan_ids][0])
assert_not_nil plan
assert_equal 'Abonnement simple', plan.base_name
assert_not plan.is_rolling
assert_equal 1, plan.group_id
assert_equal 'month', plan.interval
assert_equal 1, plan.interval_count
assert_equal 4000, plan.amount
end
end

View File

@ -16,7 +16,7 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
test 'build stats' do
# Create a reservation to generate an invoice (2 days ago)
machine = Machine.find(1)
slot = Availability.find(19).slots.first
machine_slot = Availability.find(19).slots.first
travel_to(2.days.ago)
post '/api/local_payment/confirm_payment', params: {
customer_id: @user.id,
@ -27,7 +27,7 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
reservable_type: machine.class.name,
slots_reservations_attributes: [
{
slot_id: slot.id
slot_id: machine_slot.id
}
]
}
@ -72,8 +72,8 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
}.to_json, headers: default_headers
travel_back
# Crate another machine reservation (today)
slot = Availability.find(19).slots.last
# Create another machine reservation (today)
machine_slot2 = Availability.find(19).slots.last
post '/api/local_payment/confirm_payment', params: {
customer_id: @user.id,
items: [
@ -83,7 +83,7 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
reservable_type: machine.class.name,
slots_reservations_attributes: [
{
slot_id: slot.id
slot_id: machine_slot2.id
}
]
}
@ -106,6 +106,7 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
{ term: { type: 'booking' } }] } }).first
assert_not_nil stat_booking
assert_equal machine.friendly_id, stat_booking['subType']
assert_equal 1, stat_booking['stat']
check_statistics_on_user(stat_booking)
stat_hour = Stats::Machine.search(query: { bool: { must: [{ term: { date: 2.days.ago.to_date.iso8601 } },
@ -113,6 +114,8 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
assert_not_nil stat_hour
assert_equal machine.friendly_id, stat_hour['subType']
assert_equal (machine_slot.duration.to_i / 3600.0).to_i, stat_hour['stat']
assert_includes stat_hour['machineDates'], { 'name' => machine_slot.start_at.to_date.iso8601 }
check_statistics_on_user(stat_hour)
# second machine reservation (today)
@ -120,6 +123,7 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
{ term: { type: 'booking' } }] } }).first
assert_not_nil stat_booking
assert_equal machine.friendly_id, stat_booking['subType']
assert_equal 1, stat_booking['stat']
check_statistics_on_user(stat_booking)
stat_hour = Stats::Machine.search(query: { bool: { must: [{ term: { date: DateTime.current.to_date.iso8601 } },
@ -127,6 +131,8 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
assert_not_nil stat_hour
assert_equal machine.friendly_id, stat_hour['subType']
assert_equal (machine_slot2.duration.to_i / 3600.0).to_i, stat_hour['stat']
assert_includes stat_hour['machineDates'], { 'name' => machine_slot2.start_at.to_date.iso8601 }
check_statistics_on_user(stat_hour)
# training
@ -136,6 +142,7 @@ class ReservationSubscriptionStatisticServiceTest < ActionDispatch::IntegrationT
{ term: { type: 'booking' } }] } }).first
assert_not_nil stat_training
assert_equal training.friendly_id, stat_training['subType']
assert_equal tr_slot.start_at.to_date.iso8601, stat_training['trainingDate']
check_statistics_on_user(stat_training)
# subscription

341
yarn.lock
View File

@ -1996,13 +1996,20 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2":
"@babel/runtime@^7.12.5":
version "7.17.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.17.9":
version "7.20.13"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b"
integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.7.2":
version "7.18.3"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4"
@ -2658,6 +2665,11 @@
"@jridgewell/resolve-uri" "3.1.0"
"@jridgewell/sourcemap-codec" "1.4.14"
"@leichtgewicht/ip-codec@^2.0.1":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
"@lyracom/embedded-form-glue@^0.3.3":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@lyracom/embedded-form-glue/-/embedded-form-glue-0.3.3.tgz#e1f1450a67678526da03500f13743fd4d749c734"
@ -3328,11 +3340,6 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
"@types/json-schema@^7.0.5":
version "7.0.7"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@ -3350,6 +3357,11 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6"
integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==
"@types/mime@*":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
"@types/mime@^1":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
@ -3464,6 +3476,14 @@
"@types/mime" "^1"
"@types/node" "*"
"@types/serve-static@^1.13.10":
version "1.15.0"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155"
integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==
dependencies:
"@types/mime" "*"
"@types/node" "*"
"@types/set-cookie-parser@^2.4.0":
version "2.4.2"
resolved "https://registry.yarnpkg.com/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz#b6a955219b54151bfebd4521170723df5e13caad"
@ -3500,10 +3520,10 @@
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397"
integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==
"@types/ws@^8.2.2":
version "8.5.2"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.2.tgz#77e0c2e360e9579da930ffcfa53c5975ea3bdd26"
integrity sha512-VXI82ykONr5tacHEojnErTQk+KQSoYbW1NB6iz6wUwrNd+BqfkfggQNoNdCqhJSzbNumShPERbM+Pc5zpfhlbw==
"@types/ws@^8.5.1":
version "8.5.4"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==
dependencies:
"@types/node" "*"
@ -3922,14 +3942,6 @@ agent-base@6:
dependencies:
debug "4"
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
dependencies:
clean-stack "^2.0.0"
indent-string "^4.0.0"
ajv-formats@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
@ -4159,11 +4171,6 @@ ansi-regex@^5.0.1:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-regex@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@ -4223,7 +4230,7 @@ array-flatten@1.1.1:
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
array-flatten@^2.1.0:
array-flatten@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
@ -4283,13 +4290,6 @@ assert@^2.0.0:
object-is "^1.0.1"
util "^0.12.0"
async@^2.6.2:
version "2.6.4"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
dependencies:
lodash "^4.17.14"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@ -4320,15 +4320,13 @@ babel-jest@^29.3.1:
graceful-fs "^4.2.9"
slash "^3.0.0"
babel-loader@^8.2.3:
version "8.2.3"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d"
integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==
babel-loader@^9.1.2:
version "9.1.2"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.2.tgz#a16a080de52d08854ee14570469905a5fc00d39c"
integrity sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==
dependencies:
find-cache-dir "^3.3.1"
loader-utils "^1.4.0"
make-dir "^3.1.0"
schema-utils "^2.6.5"
find-cache-dir "^3.3.2"
schema-utils "^4.0.0"
babel-plugin-dynamic-import-node@^2.3.3:
version "2.3.3"
@ -4507,17 +4505,15 @@ body-parser@1.20.1:
type-is "~1.6.18"
unpipe "1.0.0"
bonjour@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5"
integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU=
bonjour-service@^1.0.11:
version "1.1.0"
resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.0.tgz#424170268d68af26ff83a5c640b95def01803a13"
integrity sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==
dependencies:
array-flatten "^2.1.0"
deep-equal "^1.0.1"
array-flatten "^2.1.2"
dns-equal "^1.0.0"
dns-txt "^2.0.2"
multicast-dns "^6.0.1"
multicast-dns-service-types "^1.1.0"
fast-deep-equal "^3.1.3"
multicast-dns "^7.2.5"
boolbase@^1.0.0:
version "1.0.0"
@ -4609,11 +4605,6 @@ buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer-indexof@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
@ -4773,11 +4764,6 @@ clean-css@^4.2.3:
dependencies:
source-map "~0.6.0"
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
cli-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
@ -4942,10 +4928,10 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
connect-history-api-fallback@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
connect-history-api-fallback@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8"
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
content-disposition@0.5.4:
version "0.5.4"
@ -5240,7 +5226,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
dependencies:
ms "2.1.2"
debug@^3.1.1, debug@^3.2.7:
debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@ -5257,18 +5243,6 @@ dedent@^0.7.0:
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==
deep-equal@^1.0.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
dependencies:
is-arguments "^1.0.4"
is-date-object "^1.0.1"
is-regex "^1.0.4"
object-is "^1.0.1"
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
deep-equal@^2.0.5:
version "2.1.0"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.1.0.tgz#5ba60402cf44ab92c2c07f3f3312c3d857a0e1dd"
@ -5334,20 +5308,6 @@ define-properties@^1.1.4:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
del@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952"
integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==
dependencies:
globby "^11.0.1"
graceful-fs "^4.2.4"
is-glob "^4.0.1"
is-path-cwd "^2.2.0"
is-path-inside "^3.0.2"
p-map "^4.0.0"
rimraf "^3.0.2"
slash "^3.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@ -5395,20 +5355,12 @@ dns-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
dns-packet@^1.3.1:
version "1.3.4"
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f"
integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==
dns-packet@^5.2.2:
version "5.4.0"
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b"
integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==
dependencies:
ip "^1.1.0"
safe-buffer "^5.0.1"
dns-txt@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6"
integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=
dependencies:
buffer-indexof "^1.0.0"
"@leichtgewicht/ip-codec" "^2.0.1"
doctrine@^2.1.0:
version "2.1.0"
@ -6035,7 +5987,7 @@ expect@^29.0.0, expect@^29.3.1:
jest-message-util "^29.3.1"
jest-util "^29.3.1"
express@^4.17.1:
express@^4.17.3:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@ -6167,10 +6119,10 @@ finalhandler@1.2.0:
statuses "2.0.1"
unpipe "~1.0.0"
find-cache-dir@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==
find-cache-dir@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b"
integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==
dependencies:
commondir "^1.0.1"
make-dir "^3.0.2"
@ -6413,7 +6365,7 @@ globals@^13.19.0:
dependencies:
type-fest "^0.20.2"
globby@^11.0.1, globby@^11.0.4, globby@^11.1.0:
globby@^11.0.4, globby@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
@ -6637,10 +6589,10 @@ http-proxy-agent@^5.0.0:
agent-base "6"
debug "4"
http-proxy-middleware@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz#5df04f69a89f530c2284cd71eeaa51ba52243289"
integrity sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==
http-proxy-middleware@^2.0.3:
version "2.0.6"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f"
integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==
dependencies:
"@types/http-proxy" "^1.17.8"
http-proxy "^1.18.1"
@ -6822,11 +6774,6 @@ intl-messageformat@^9.11.4:
"@formatjs/icu-messageformat-parser" "2.0.18"
tslib "^2.1.0"
ip@^1.1.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
@ -7001,12 +6948,7 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-path-cwd@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
is-path-inside@^3.0.2, is-path-inside@^3.0.3:
is-path-inside@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
@ -7028,7 +6970,7 @@ is-potential-custom-element-name@^1.0.1:
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
is-regex@^1.0.4, is-regex@^1.1.3:
is-regex@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f"
integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==
@ -7771,7 +7713,7 @@ loader-runner@^4.2.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.4.0:
loader-utils@^1.0.2, loader-utils@^1.1.0:
version "1.4.2"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3"
integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==
@ -7858,7 +7800,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4:
lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@ -7897,7 +7839,7 @@ lz-string@^1.4.4:
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==
make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0:
make-dir@^3.0.0, make-dir@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@ -8059,18 +8001,11 @@ minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatc
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
minimist@^1.2.0, minimist@^1.2.6:
version "1.2.7"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
mkdirp@^0.5.5:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
dependencies:
minimist "^1.2.5"
moment-timezone@0.5:
version "0.5.35"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.35.tgz#6fa2631bdbe8ff04f6b8753f7199516be6dc9839"
@ -8123,17 +8058,12 @@ msw@^0.49.0:
type-fest "^2.19.0"
yargs "^17.3.1"
multicast-dns-service-types@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=
multicast-dns@^6.0.1:
version "6.2.3"
resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229"
integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==
multicast-dns@^7.2.5:
version "7.2.5"
resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced"
integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==
dependencies:
dns-packet "^1.3.1"
dns-packet "^5.2.2"
thunky "^1.0.2"
mute-stream@0.0.8:
@ -8207,10 +8137,10 @@ node-fetch@2.6.7, node-fetch@^2.6.7:
dependencies:
whatwg-url "^5.0.0"
node-forge@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2"
integrity sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==
node-forge@^1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
node-int64@^0.4.0:
version "0.4.0"
@ -8507,13 +8437,6 @@ p-locate@^5.0.0:
dependencies:
p-limit "^3.0.2"
p-map@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"
integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==
dependencies:
aggregate-error "^3.0.0"
p-retry@^4.5.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c"
@ -8654,15 +8577,6 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"
portfinder@^1.0.28:
version "1.0.28"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==
dependencies:
async "^2.6.2"
debug "^3.1.1"
mkdirp "^0.5.5"
postcss-calc@^8.2.3:
version "8.2.4"
resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5"
@ -9389,14 +9303,6 @@ regex-parser@^2.2.11:
resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58"
integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==
regexp.prototype.flags@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
regexp.prototype.flags@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307"
@ -9633,7 +9539,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@ -9675,15 +9581,6 @@ scheduler@^0.20.2:
loose-envify "^1.1.0"
object-assign "^4.1.1"
schema-utils@^2.6.5:
version "2.7.1"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7"
integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==
dependencies:
"@types/json-schema" "^7.0.5"
ajv "^6.12.4"
ajv-keywords "^3.5.2"
schema-utils@^3.0, schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281"
@ -9708,12 +9605,12 @@ select-hose@^2.0.0:
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
selfsigned@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b"
integrity sha512-cUdFiCbKoa1mZ6osuJs2uDHrs0k0oprsKveFiiaBKCNq3SYyb5gs2HxhQyDNLCmL51ZZThqi4YNDpCK6GOP1iQ==
selfsigned@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61"
integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==
dependencies:
node-forge "^1.2.0"
node-forge "^1"
semver@7.0.0:
version "7.0.0"
@ -9803,10 +9700,10 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
shakapacker@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/shakapacker/-/shakapacker-6.2.0.tgz#4f3cb0f99b8c7ff63e676fbf253331643388bd22"
integrity sha512-n9QAJGInUK7+Brn4JSaGGD9mWUdFAD60vP19qn9JlcqG3zAev0oKenUsLUcWFyKBFbpZMbGdWURuWYcp1iayog==
shakapacker@6.5.5:
version "6.5.5"
resolved "https://registry.yarnpkg.com/shakapacker/-/shakapacker-6.5.5.tgz#34c027b3d3b34b8241a946d4af256df81c0c04f7"
integrity sha512-KsDhjihjmkJVpdnuDvHj70RzRjreXcnMQtePp+TkHzi4sXO8gwt0btoTNrwuLrgxOfac7UQadDFYFGzJwoPz5w==
dependencies:
glob "^7.2.0"
js-yaml "^4.1.0"
@ -9865,13 +9762,13 @@ slugify@^1.6.5:
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.6.5.tgz#c8f5c072bf2135b80703589b39a3d41451fbe8c8"
integrity sha512-8mo9bslnBO3tr5PEVFzMPIWwWnipGS0xVbYf65zxDqfNwmzYn1LpiKNrR6DlClusuvo+hDHd1zKpmfAe83NQSQ==
sockjs@^0.3.21:
version "0.3.21"
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==
sockjs@^0.3.24:
version "0.3.24"
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce"
integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==
dependencies:
faye-websocket "^0.11.3"
uuid "^3.4.0"
uuid "^8.3.2"
websocket-driver "^0.7.4"
sortablejs@^1.15.0:
@ -10045,13 +9942,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==
dependencies:
ansi-regex "^6.0.1"
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
@ -10521,10 +10411,10 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
uuid@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-to-istanbul@^9.0.1:
version "9.0.1"
@ -10654,39 +10544,38 @@ webpack-dev-middleware@^5.3.1:
range-parser "^1.2.1"
schema-utils "^4.0.0"
webpack-dev-server@^4.7.4:
version "4.7.4"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz#d0ef7da78224578384e795ac228d8efb63d5f945"
integrity sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A==
webpack-dev-server@^4.9.0:
version "4.11.1"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5"
integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==
dependencies:
"@types/bonjour" "^3.5.9"
"@types/connect-history-api-fallback" "^1.3.5"
"@types/express" "^4.17.13"
"@types/serve-index" "^1.9.1"
"@types/serve-static" "^1.13.10"
"@types/sockjs" "^0.3.33"
"@types/ws" "^8.2.2"
"@types/ws" "^8.5.1"
ansi-html-community "^0.0.8"
bonjour "^3.5.0"
bonjour-service "^1.0.11"
chokidar "^3.5.3"
colorette "^2.0.10"
compression "^1.7.4"
connect-history-api-fallback "^1.6.0"
connect-history-api-fallback "^2.0.0"
default-gateway "^6.0.3"
del "^6.0.0"
express "^4.17.1"
express "^4.17.3"
graceful-fs "^4.2.6"
html-entities "^2.3.2"
http-proxy-middleware "^2.0.0"
http-proxy-middleware "^2.0.3"
ipaddr.js "^2.0.1"
open "^8.0.9"
p-retry "^4.5.0"
portfinder "^1.0.28"
rimraf "^3.0.2"
schema-utils "^4.0.0"
selfsigned "^2.0.0"
selfsigned "^2.1.1"
serve-index "^1.9.1"
sockjs "^0.3.21"
sockjs "^0.3.24"
spdy "^4.0.2"
strip-ansi "^7.0.0"
webpack-dev-middleware "^5.3.1"
ws "^8.4.2"
@ -10703,10 +10592,10 @@ webpack-sources@^3.2.3:
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
webpack@5:
version "5.70.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.70.0.tgz#3461e6287a72b5e6e2f4872700bc8de0d7500e6d"
integrity sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw==
webpack@5.72.0:
version "5.72.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.72.0.tgz#f8bc40d9c6bb489a4b7a8a685101d6022b8b6e28"
integrity sha512-qmSmbspI0Qo5ld49htys8GY9XhS9CGqFoHTsOVAnjBdg0Zn79y135R+k4IR4rKK6+eKaabMhJwiVB7xw0SJu5w==
dependencies:
"@types/eslint-scope" "^3.7.3"
"@types/estree" "^0.0.51"