mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-22 11:52:21 +01:00
Merge branch 'dev' into staging
This commit is contained in:
commit
19b6bd8d8a
@ -2,9 +2,16 @@
|
|||||||
|
|
||||||
## next deploy
|
## next deploy
|
||||||
|
|
||||||
|
- improves api/notification controller to avoid failing when there is a notification with wrong notification_type in db
|
||||||
|
- Add extra_authorize_params to OpenIdConnect config
|
||||||
|
- Improvement : add a notification to remind users to upload their supporting documents
|
||||||
|
|
||||||
|
## v6.0.14 2023 September 6
|
||||||
|
|
||||||
- Fix a bug: for project categories, if there is no category : do not show categories panel in show view, do not show categories input field in edit view
|
- Fix a bug: for project categories, if there is no category : do not show categories panel in show view, do not show categories input field in edit view
|
||||||
- Fix a bug: unable to update status to paid for latest payment schedule item
|
- Fix a bug: unable to update status to paid for latest payment schedule item
|
||||||
- Fix a bug: unable to generate statistic
|
- Fix a bug: unable to generate statistic
|
||||||
|
- Fix a bug: unable to update user profile by admin
|
||||||
- Feature: add a filter in members list (admin) to show only "not validated" members
|
- Feature: add a filter in members list (admin) to show only "not validated" members
|
||||||
- Concerning statistics:
|
- Concerning statistics:
|
||||||
- removes age and type column from all statistics tabs (only in web, not in xlsx export file)
|
- removes age and type column from all statistics tabs (only in web, not in xlsx export file)
|
||||||
|
@ -99,7 +99,7 @@ class API::AuthProvidersController < API::APIController
|
|||||||
providable_attributes: [:id, :issuer, :discovery, :client_auth_method, :prompt, :send_scope_to_token_endpoint,
|
providable_attributes: [:id, :issuer, :discovery, :client_auth_method, :prompt, :send_scope_to_token_endpoint,
|
||||||
:client__identifier, :client__secret, :client__authorization_endpoint, :client__token_endpoint,
|
:client__identifier, :client__secret, :client__authorization_endpoint, :client__token_endpoint,
|
||||||
:client__userinfo_endpoint, :client__jwks_uri, :client__end_session_endpoint, :profile_url,
|
:client__userinfo_endpoint, :client__jwks_uri, :client__end_session_endpoint, :profile_url,
|
||||||
{ scope: [] }],
|
:extra_authorize_params, { scope: [] }],
|
||||||
auth_provider_mappings_attributes: [:id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type,
|
auth_provider_mappings_attributes: [:id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type,
|
||||||
:_destroy, { transformation: [:type, :format, :true_value, :false_value,
|
:_destroy, { transformation: [:type, :format, :true_value, :false_value,
|
||||||
{ mapping: %i[from to] }] }])
|
{ mapping: %i[from to] }] }])
|
||||||
|
@ -15,6 +15,7 @@ class API::NotificationsController < API::APIController
|
|||||||
def index
|
def index
|
||||||
loop do
|
loop do
|
||||||
@notifications = current_user.notifications
|
@notifications = current_user.notifications
|
||||||
|
.with_valid_notification_type
|
||||||
.delivered_in_system(current_user)
|
.delivered_in_system(current_user)
|
||||||
.includes(:attached_object)
|
.includes(:attached_object)
|
||||||
.page(params[:page])
|
.page(params[:page])
|
||||||
@ -24,8 +25,8 @@ class API::NotificationsController < API::APIController
|
|||||||
break unless delete_obsoletes(@notifications)
|
break unless delete_obsoletes(@notifications)
|
||||||
end
|
end
|
||||||
@totals = {
|
@totals = {
|
||||||
total: current_user.notifications.delivered_in_system(current_user).count,
|
total: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).count,
|
||||||
unread: current_user.notifications.delivered_in_system(current_user).where(is_read: false).count
|
unread: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).where(is_read: false).count
|
||||||
}
|
}
|
||||||
render :index
|
render :index
|
||||||
end
|
end
|
||||||
@ -33,6 +34,7 @@ class API::NotificationsController < API::APIController
|
|||||||
def last_unread
|
def last_unread
|
||||||
loop do
|
loop do
|
||||||
@notifications = current_user.notifications
|
@notifications = current_user.notifications
|
||||||
|
.with_valid_notification_type
|
||||||
.delivered_in_system(current_user)
|
.delivered_in_system(current_user)
|
||||||
.includes(:attached_object)
|
.includes(:attached_object)
|
||||||
.where(is_read: false)
|
.where(is_read: false)
|
||||||
@ -42,19 +44,20 @@ class API::NotificationsController < API::APIController
|
|||||||
break unless delete_obsoletes(@notifications)
|
break unless delete_obsoletes(@notifications)
|
||||||
end
|
end
|
||||||
@totals = {
|
@totals = {
|
||||||
total: current_user.notifications.delivered_in_system(current_user).count,
|
total: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).count,
|
||||||
unread: current_user.notifications.delivered_in_system(current_user).where(is_read: false).count
|
unread: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).where(is_read: false).count
|
||||||
}
|
}
|
||||||
render :index
|
render :index
|
||||||
end
|
end
|
||||||
|
|
||||||
def polling
|
def polling
|
||||||
@notifications = current_user.notifications
|
@notifications = current_user.notifications
|
||||||
.where('is_read = false AND created_at >= :date', date: params[:last_poll])
|
.with_valid_notification_type
|
||||||
.order('created_at DESC')
|
.where('notifications.is_read = false AND notifications.created_at >= :date', date: params[:last_poll])
|
||||||
|
.order('notifications.created_at DESC')
|
||||||
@totals = {
|
@totals = {
|
||||||
total: current_user.notifications.delivered_in_system(current_user).count,
|
total: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).count,
|
||||||
unread: current_user.notifications.delivered_in_system(current_user).where(is_read: false).count
|
unread: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).where(is_read: false).count
|
||||||
}
|
}
|
||||||
render :index
|
render :index
|
||||||
end
|
end
|
||||||
|
@ -34,6 +34,15 @@ export const OpenidConnectForm = <TFieldValues extends FieldValues, TContext ext
|
|||||||
// this is a workaround for https://github.com/JedWatson/react-select/issues/1879
|
// this is a workaround for https://github.com/JedWatson/react-select/issues/1879
|
||||||
const [selectKey, setSelectKey] = useState<number>(0);
|
const [selectKey, setSelectKey] = useState<number>(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!currentFormValues?.extra_authorize_params) {
|
||||||
|
setValue(
|
||||||
|
'providable_attributes.extra_authorize_params' as Path<TFieldValues>,
|
||||||
|
'{}' as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
// when we have detected a discovery endpoint, we mark it as available
|
// when we have detected a discovery endpoint, we mark it as available
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValue(
|
setValue(
|
||||||
@ -160,6 +169,12 @@ export const OpenidConnectForm = <TFieldValues extends FieldValues, TContext ext
|
|||||||
tooltip={t('app.admin.authentication.openid_connect_form.profile_edition_url_help')}
|
tooltip={t('app.admin.authentication.openid_connect_form.profile_edition_url_help')}
|
||||||
rules={{ required: false, pattern: ValidationLib.urlRegex }}
|
rules={{ required: false, pattern: ValidationLib.urlRegex }}
|
||||||
formState={formState} />
|
formState={formState} />
|
||||||
|
<FormInput id="providable_attributes.extra_authorize_params"
|
||||||
|
register={register}
|
||||||
|
label={t('app.admin.authentication.openid_connect_form.extra_authorize_params')}
|
||||||
|
tooltip={t('app.admin.authentication.openid_connect_form.extra_authorize_params_help')}
|
||||||
|
rules={{ required: false }}
|
||||||
|
formState={formState} />
|
||||||
<h4>{t('app.admin.authentication.openid_connect_form.client_options')}</h4>
|
<h4>{t('app.admin.authentication.openid_connect_form.client_options')}</h4>
|
||||||
<FormInput id="providable_attributes.client__identifier"
|
<FormInput id="providable_attributes.client__identifier"
|
||||||
label={t('app.admin.authentication.openid_connect_form.client__identifier')}
|
label={t('app.admin.authentication.openid_connect_form.client__identifier')}
|
||||||
|
@ -136,6 +136,7 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return handleSubmit((data: User) => {
|
return handleSubmit((data: User) => {
|
||||||
|
['events_reservations', 'space_reservations', 'training_reservations', 'machine_reservations', 'all_projects', 'invoices', 'subscribed_plan', 'subscription'].forEach(key => delete data[key]);
|
||||||
MemberAPI[action](data)
|
MemberAPI[action](data)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
reset(res);
|
reset(res);
|
||||||
|
@ -61,7 +61,8 @@ export interface OpenIdConnectProvider {
|
|||||||
client__userinfo_endpoint?: string,
|
client__userinfo_endpoint?: string,
|
||||||
client__jwks_uri?: string,
|
client__jwks_uri?: string,
|
||||||
client__end_session_endpoint?: string,
|
client__end_session_endpoint?: string,
|
||||||
profile_url?: string
|
profile_url?: string,
|
||||||
|
extra_authorize_parameters?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MappingFields {
|
export interface MappingFields {
|
||||||
|
@ -74,6 +74,7 @@ export const notificationTypeNames = [
|
|||||||
'notify_user_is_validated',
|
'notify_user_is_validated',
|
||||||
'notify_user_is_invalidated',
|
'notify_user_is_invalidated',
|
||||||
'notify_user_supporting_document_refusal',
|
'notify_user_supporting_document_refusal',
|
||||||
|
'notify_user_supporting_document_reminder',
|
||||||
'notify_admin_user_supporting_document_refusal',
|
'notify_admin_user_supporting_document_refusal',
|
||||||
'notify_user_order_is_ready',
|
'notify_user_order_is_ready',
|
||||||
'notify_user_order_is_canceled',
|
'notify_user_order_is_canceled',
|
||||||
|
@ -989,6 +989,11 @@ p, .widget p {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-none {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-inline-start: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (min-width: $screen-lg-min) {
|
@media screen and (min-width: $screen-lg-min) {
|
||||||
.b-r-lg {
|
.b-r-lg {
|
||||||
border-right: 1px solid $border-color;
|
border-right: 1px solid $border-color;
|
||||||
|
@ -288,7 +288,7 @@
|
|||||||
<td ng-repeat="field in selectedIndex.additional_fields">
|
<td ng-repeat="field in selectedIndex.additional_fields">
|
||||||
<ng-switch on="field.data_type">
|
<ng-switch on="field.data_type">
|
||||||
<span ng-switch-when="date">{{formatDate(datum._source[field.key])}}</span>
|
<span ng-switch-when="date">{{formatDate(datum._source[field.key])}}</span>
|
||||||
<ul ng-switch-when="list">
|
<ul ng-switch-when="list" class="list-none">
|
||||||
<li ng-repeat="elem in uniq(datum._source[field.key])">{{elem.name}}</li>
|
<li ng-repeat="elem in uniq(datum._source[field.key])">{{elem.name}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<span ng-switch-default>{{datum._source[field.key]}}</span>
|
<span ng-switch-default>{{datum._source[field.key]}}</span>
|
||||||
|
@ -19,6 +19,8 @@ class Notification < ApplicationRecord
|
|||||||
SQL
|
SQL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope :with_valid_notification_type, -> { joins(:notification_type).where(notification_types: { name: NOTIFICATIONS_TYPES.map { |nt| nt[:name] } }) }
|
||||||
|
|
||||||
validates :receiver_id,
|
validates :receiver_id,
|
||||||
:receiver_type,
|
:receiver_type,
|
||||||
:attached_object_id,
|
:attached_object_id,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# NotificationType defines the different types of Notification.
|
# NotificationType defines the different types of Notification.
|
||||||
# To add a new notification type in db, you must add it in:
|
# To add a new notification type in db, you must add it in:
|
||||||
# - db/seeds/notification_types.rb
|
# - config/initializers/notification_types.rb
|
||||||
# - app/views/api/notifications/_XXXXXX.json.jbuilder
|
# - app/views/api/notifications/_XXXXXX.json.jbuilder
|
||||||
# - app/views/notifications_mailer/XXXXXX.html.erb
|
# - app/views/notifications_mailer/XXXXXX.html.erb
|
||||||
# - app/frontend/src/javascript/models/notification-type.ts
|
# - app/frontend/src/javascript/models/notification-type.ts
|
||||||
|
@ -93,6 +93,7 @@ class User < ApplicationRecord
|
|||||||
scope :not_confirmed, -> { where(confirmed_at: nil) }
|
scope :not_confirmed, -> { where(confirmed_at: nil) }
|
||||||
scope :inactive_for_3_years, -> { where('users.last_sign_in_at < ?', 3.years.ago) }
|
scope :inactive_for_3_years, -> { where('users.last_sign_in_at < ?', 3.years.ago) }
|
||||||
scope :not_validated, -> { where(validated_at: nil) }
|
scope :not_validated, -> { where(validated_at: nil) }
|
||||||
|
scope :supporting_documents_reminder_not_sent, -> { where(supporting_documents_reminder_sent_at: nil) }
|
||||||
|
|
||||||
def to_json(*)
|
def to_json(*)
|
||||||
ApplicationController.new.view_context.render(
|
ApplicationController.new.view_context.render(
|
||||||
|
@ -27,6 +27,7 @@ class Members::MembersService
|
|||||||
if @member.validated_at? && !(new_types - current_types).empty?
|
if @member.validated_at? && !(new_types - current_types).empty?
|
||||||
validated_at_changed = true
|
validated_at_changed = true
|
||||||
@member.validated_at = nil
|
@member.validated_at = nil
|
||||||
|
@member.supporting_documents_reminder_sent_at = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ class Statistics::FetcherService
|
|||||||
.eager_load(:slots, :slots_reservations, :invoice_items, :reservation_context, statistic_profile: [:group])
|
.eager_load(:slots, :slots_reservations, :invoice_items, :reservation_context, statistic_profile: [:group])
|
||||||
.find_each do |r|
|
.find_each do |r|
|
||||||
next unless r.reservable
|
next unless r.reservable
|
||||||
next unless r.original_invoice
|
|
||||||
next if r.slots.empty?
|
next if r.slots.empty?
|
||||||
|
|
||||||
profile = r.statistic_profile
|
profile = r.statistic_profile
|
||||||
@ -63,7 +62,7 @@ class Statistics::FetcherService
|
|||||||
nb_hours: (r.slots.map(&:duration).map(&:to_i).reduce(:+) / 3600.0).to_f,
|
nb_hours: (r.slots.map(&:duration).map(&:to_i).reduce(:+) / 3600.0).to_f,
|
||||||
ca: calcul_ca(r.original_invoice),
|
ca: calcul_ca(r.original_invoice),
|
||||||
reservation_context_id: r.reservation_context_id,
|
reservation_context_id: r.reservation_context_id,
|
||||||
coupon: r.original_invoice.coupon&.code }.merge(user_info(profile))
|
coupon: r&.original_invoice&.coupon&.code }.merge(user_info(profile))
|
||||||
yield result
|
yield result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -78,7 +77,6 @@ class Statistics::FetcherService
|
|||||||
.eager_load(:slots, :slots_reservations, :invoice_items, :reservation_context, statistic_profile: [:group])
|
.eager_load(:slots, :slots_reservations, :invoice_items, :reservation_context, statistic_profile: [:group])
|
||||||
.find_each do |r|
|
.find_each do |r|
|
||||||
next unless r.reservable
|
next unless r.reservable
|
||||||
next unless r.original_invoice
|
|
||||||
next if r.slots.empty?
|
next if r.slots.empty?
|
||||||
|
|
||||||
profile = r.statistic_profile
|
profile = r.statistic_profile
|
||||||
@ -91,7 +89,7 @@ class Statistics::FetcherService
|
|||||||
nb_hours: (r.slots.map(&:duration).map(&:to_i).reduce(:+) / 3600.0).to_f,
|
nb_hours: (r.slots.map(&:duration).map(&:to_i).reduce(:+) / 3600.0).to_f,
|
||||||
ca: calcul_ca(r.original_invoice),
|
ca: calcul_ca(r.original_invoice),
|
||||||
reservation_context_id: r.reservation_context_id,
|
reservation_context_id: r.reservation_context_id,
|
||||||
coupon: r.original_invoice.coupon&.code }.merge(user_info(profile))
|
coupon: r&.original_invoice&.coupon&.code }.merge(user_info(profile))
|
||||||
yield result
|
yield result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -106,7 +104,7 @@ class Statistics::FetcherService
|
|||||||
.eager_load(:slots, :slots_reservations, :invoice_items, :reservation_context, statistic_profile: [:group])
|
.eager_load(:slots, :slots_reservations, :invoice_items, :reservation_context, statistic_profile: [:group])
|
||||||
.find_each do |r|
|
.find_each do |r|
|
||||||
next unless r.reservable
|
next unless r.reservable
|
||||||
next unless r.original_invoice
|
next if r.slots.empty?
|
||||||
|
|
||||||
profile = r.statistic_profile
|
profile = r.statistic_profile
|
||||||
slot = r.slots.first
|
slot = r.slots.first
|
||||||
@ -119,7 +117,7 @@ class Statistics::FetcherService
|
|||||||
nb_hours: difference_in_hours(slot.start_at, slot.end_at),
|
nb_hours: difference_in_hours(slot.start_at, slot.end_at),
|
||||||
ca: calcul_ca(r.original_invoice),
|
ca: calcul_ca(r.original_invoice),
|
||||||
reservation_context_id: r.reservation_context_id,
|
reservation_context_id: r.reservation_context_id,
|
||||||
coupon: r.original_invoice&.coupon&.code }.merge(user_info(profile))
|
coupon: r&.original_invoice&.coupon&.code }.merge(user_info(profile))
|
||||||
yield result
|
yield result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -134,7 +132,7 @@ class Statistics::FetcherService
|
|||||||
.eager_load(:slots, :slots_reservations, :invoice_items, statistic_profile: [:group])
|
.eager_load(:slots, :slots_reservations, :invoice_items, statistic_profile: [:group])
|
||||||
.find_each do |r|
|
.find_each do |r|
|
||||||
next unless r.reservable
|
next unless r.reservable
|
||||||
next unless r.original_invoice
|
next if r.slots.empty?
|
||||||
|
|
||||||
profile = r.statistic_profile
|
profile = r.statistic_profile
|
||||||
slot = r.slots.first
|
slot = r.slots.first
|
||||||
@ -148,7 +146,7 @@ class Statistics::FetcherService
|
|||||||
age_range: (r.reservable.age_range_id ? r.reservable.age_range.name : ''),
|
age_range: (r.reservable.age_range_id ? r.reservable.age_range.name : ''),
|
||||||
nb_places: r.total_booked_seats,
|
nb_places: r.total_booked_seats,
|
||||||
nb_hours: difference_in_hours(slot.start_at, slot.end_at),
|
nb_hours: difference_in_hours(slot.start_at, slot.end_at),
|
||||||
coupon: r.original_invoice.coupon&.code,
|
coupon: r&.original_invoice&.coupon&.code,
|
||||||
ca: calcul_ca(r.original_invoice) }.merge(user_info(profile))
|
ca: calcul_ca(r.original_invoice) }.merge(user_info(profile))
|
||||||
yield result
|
yield result
|
||||||
end
|
end
|
||||||
|
@ -16,6 +16,6 @@ if @provider.providable_type == OpenIdConnectProvider.name
|
|||||||
:prompt, :send_scope_to_token_endpoint, :client__identifier, :client__secret, :client__authorization_endpoint,
|
:prompt, :send_scope_to_token_endpoint, :client__identifier, :client__secret, :client__authorization_endpoint,
|
||||||
:client__token_endpoint, :client__userinfo_endpoint, :client__jwks_uri, :client__end_session_endpoint, :profile_url
|
:client__token_endpoint, :client__userinfo_endpoint, :client__jwks_uri, :client__end_session_endpoint, :profile_url
|
||||||
json.scope @provider.providable[:scope]
|
json.scope @provider.providable[:scope]
|
||||||
|
json.extra_authorize_params @provider.providable[:extra_authorize_params]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
json.title notification.notification_type
|
||||||
|
json.description t('.reminder_message')
|
@ -16,7 +16,7 @@ if provider.providable_type == 'OpenIdConnectProvider'
|
|||||||
json.extract! provider.providable, :id, :issuer, :discovery, :client_auth_method, :scope, :response_type, :response_mode,
|
json.extract! provider.providable, :id, :issuer, :discovery, :client_auth_method, :scope, :response_type, :response_mode,
|
||||||
:display, :prompt, :send_scope_to_token_endpoint, :client__identifier, :client__secret, :client__authorization_endpoint,
|
:display, :prompt, :send_scope_to_token_endpoint, :client__identifier, :client__secret, :client__authorization_endpoint,
|
||||||
:client__token_endpoint, :client__userinfo_endpoint, :client__jwks_uri, :client__end_session_endpoint, :profile_url,
|
:client__token_endpoint, :client__userinfo_endpoint, :client__jwks_uri, :client__end_session_endpoint, :profile_url,
|
||||||
:post_logout_redirect_uri, :uid_field, :client__redirect_uri, :client__scheme, :client__host, :client__port
|
:post_logout_redirect_uri, :uid_field, :client__redirect_uri, :client__scheme, :client__host, :client__port,
|
||||||
|
:extra_authorize_params
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= t('.body.user_supporting_document_reminder') %>
|
||||||
|
</p>
|
27
app/workers/supporting_documents_reminder_worker.rb
Normal file
27
app/workers/supporting_documents_reminder_worker.rb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Send a notification to users who did not upload their supporting document files yet
|
||||||
|
class SupportingDocumentsReminderWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
|
||||||
|
def perform
|
||||||
|
users_to_notify = User.members
|
||||||
|
.supporting_documents_reminder_not_sent
|
||||||
|
.where("users.created_at < ?", 2.days.ago)
|
||||||
|
.left_outer_joins(supporting_document_files: { supporting_document_type: :groups })
|
||||||
|
.where("groups.id = users.group_id OR groups.id IS NULL")
|
||||||
|
.select("users.*, count(supporting_document_files.id)")
|
||||||
|
.group("users.id")
|
||||||
|
.having("(count(supporting_document_files.id)) < (SELECT count(supporting_document_types.id) "\
|
||||||
|
"FROM supporting_document_types "\
|
||||||
|
"INNER JOIN supporting_document_types_groups "\
|
||||||
|
"ON supporting_document_types_groups.supporting_document_type_id = supporting_document_types.id "\
|
||||||
|
"WHERE supporting_document_types_groups.group_id = users.group_id)")
|
||||||
|
users_to_notify.each do |user|
|
||||||
|
NotificationCenter.call type: 'notify_user_supporting_document_reminder',
|
||||||
|
receiver: user,
|
||||||
|
attached_object: user
|
||||||
|
user.update_column(:supporting_documents_reminder_sent_at, DateTime.current)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
81
config/initializers/notification_types.rb
Normal file
81
config/initializers/notification_types.rb
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
NOTIFICATIONS_TYPES = [
|
||||||
|
{ name: 'notify_admin_when_project_published', category: 'projects', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_project_collaborator_to_valid', category: 'projects', is_configurable: false },
|
||||||
|
{ name: 'notify_project_author_when_collaborator_valid', category: 'projects', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_user_training_valid', category: 'trainings', is_configurable: false },
|
||||||
|
{ name: 'notify_member_subscribed_plan', category: 'subscriptions', is_configurable: false },
|
||||||
|
{ name: 'notify_member_create_reservation', category: 'agenda', is_configurable: false },
|
||||||
|
{ name: 'notify_member_subscribed_plan_is_changed', category: 'deprecated', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_member_create_reservation', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_member_slot_is_modified', category: 'agenda', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_slot_is_modified', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
|
||||||
|
{ name: 'notify_admin_when_user_is_created', category: 'users_accounts', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_subscribed_plan', category: 'subscriptions', is_configurable: true, roles: ['admin'] },
|
||||||
|
{ name: 'notify_user_when_invoice_ready', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_member_subscription_will_expire_in_7_days', category: 'subscriptions', is_configurable: false },
|
||||||
|
{ name: 'notify_member_subscription_is_expired', category: 'subscriptions', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_subscription_will_expire_in_7_days', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_subscription_is_expired', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_subscription_canceled', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_member_subscription_canceled', category: 'subscriptions', is_configurable: false },
|
||||||
|
{ name: 'notify_user_when_avoir_ready', category: 'wallet', is_configurable: false },
|
||||||
|
|
||||||
|
{ name: 'notify_member_slot_is_canceled', category: 'agenda', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_slot_is_canceled', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_partner_subscribed_plan', category: 'subscriptions', is_configurable: false },
|
||||||
|
{ name: 'notify_member_subscription_extended', category: 'subscriptions', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_subscription_extended', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_user_group_changed', category: 'users_accounts', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_user_user_group_changed', category: 'users_accounts', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_when_user_is_imported', category: 'users_accounts', is_configurable: true, roles: ['admin'] },
|
||||||
|
{ name: 'notify_user_profile_complete', category: 'users_accounts', is_configurable: false },
|
||||||
|
{ name: 'notify_user_auth_migration', category: 'user', is_configurable: false },
|
||||||
|
|
||||||
|
{ name: 'notify_admin_user_merged', category: 'users_accounts', is_configurable: true, roles: ['admin'] },
|
||||||
|
{ name: 'notify_admin_profile_complete', category: 'users_accounts', is_configurable: true, roles: ['admin'] },
|
||||||
|
{ name: 'notify_admin_abuse_reported', category: 'projects', is_configurable: true, roles: ['admin'] },
|
||||||
|
{ name: 'notify_admin_invoicing_changed', category: 'deprecated', is_configurable: false },
|
||||||
|
{ name: 'notify_user_wallet_is_credited', category: 'wallet', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_user_wallet_is_credited', category: 'wallet', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_export_complete', category: 'exports', is_configurable: false },
|
||||||
|
{ name: 'notify_member_about_coupon', category: 'agenda', is_configurable: false },
|
||||||
|
{ name: 'notify_member_reservation_reminder', category: 'agenda', is_configurable: false },
|
||||||
|
|
||||||
|
{ name: 'notify_admin_free_disk_space', category: 'app_management', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_close_period_reminder', category: 'accountings', is_configurable: true, roles: ['admin'] },
|
||||||
|
{ name: 'notify_admin_archive_complete', category: 'accountings', is_configurable: true, roles: ['admin'] },
|
||||||
|
{ name: 'notify_privacy_policy_changed', category: 'app_management', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_import_complete', category: 'app_management', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_refund_created', category: 'wallet', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admins_role_update', category: 'users_accounts', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_user_role_update', category: 'users_accounts', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_objects_stripe_sync', category: 'payments', is_configurable: false },
|
||||||
|
{ name: 'notify_user_when_payment_schedule_ready', category: 'payments', is_configurable: false },
|
||||||
|
|
||||||
|
{ name: 'notify_admin_payment_schedule_failed', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_member_payment_schedule_failed', category: 'payments', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_payment_schedule_check_deadline', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_payment_schedule_transfer_deadline', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_payment_schedule_error', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_member_payment_schedule_error', category: 'payments', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_payment_schedule_gateway_canceled', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_member_payment_schedule_gateway_canceled', category: 'payments', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_user_supporting_document_files_created', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_user_supporting_document_files_updated', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
|
||||||
|
{ name: 'notify_user_is_validated', category: 'users_accounts', is_configurable: false },
|
||||||
|
{ name: 'notify_user_is_invalidated', category: 'users_accounts', is_configurable: false },
|
||||||
|
{ name: 'notify_user_supporting_document_refusal', category: 'supporting_documents', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_user_supporting_document_refusal', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_order_is_paid', category: 'shop', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_user_order_is_ready', category: 'shop', is_configurable: false },
|
||||||
|
{ name: 'notify_user_order_is_canceled', category: 'shop', is_configurable: false },
|
||||||
|
{ name: 'notify_user_order_is_refunded', category: 'shop', is_configurable: false },
|
||||||
|
{ name: 'notify_admin_low_stock_threshold', category: 'shop', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_admin_training_auto_cancelled', category: 'trainings', is_configurable: true, roles: ['admin', 'manager'] },
|
||||||
|
{ name: 'notify_member_training_auto_cancelled', category: 'trainings', is_configurable: false },
|
||||||
|
{ name: 'notify_user_supporting_document_reminder', category: 'supporting_documents', is_configurable: false }
|
||||||
|
].freeze
|
@ -111,6 +111,10 @@ de:
|
|||||||
save: "Speichern"
|
save: "Speichern"
|
||||||
create_success: "Der Raum wurde erfolgreich erstellt"
|
create_success: "Der Raum wurde erfolgreich erstellt"
|
||||||
update_success: "Der Raum wurde erfolgreich aktualisiert"
|
update_success: "Der Raum wurde erfolgreich aktualisiert"
|
||||||
|
associated_machines: "Included machines"
|
||||||
|
children_spaces: "Included spaces"
|
||||||
|
associated_objects: "Associated objects"
|
||||||
|
associated_objects_warning: "Only use these fields if you want interblocking reservation between spaces, child spaces and machines. If you want machine and space reservations to remain independent, please leave the following fields blank."
|
||||||
event_form:
|
event_form:
|
||||||
ACTION_title: "{ACTION, select, create{Neue} other{Aktualisiere die}} Veranstaltung"
|
ACTION_title: "{ACTION, select, create{Neue} other{Aktualisiere die}} Veranstaltung"
|
||||||
title: "Titel"
|
title: "Titel"
|
||||||
@ -1477,6 +1481,8 @@ de:
|
|||||||
client__jwks_uri: "JWKS URI"
|
client__jwks_uri: "JWKS URI"
|
||||||
client__end_session_endpoint: "End session endpoint"
|
client__end_session_endpoint: "End session endpoint"
|
||||||
client__end_session_endpoint_help: "The url to call to log the user out at the authorization server."
|
client__end_session_endpoint_help: "The url to call to log the user out at the authorization server."
|
||||||
|
extra_authorize_params: "Extra authorize parameters"
|
||||||
|
extra_authorize_params_help: "A hash of extra fixed parameters that will be merged to the authorization request"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "Name"
|
name: "Name"
|
||||||
authentication_type: "Authentifizierungsart"
|
authentication_type: "Authentifizierungsart"
|
||||||
|
@ -1544,6 +1544,8 @@ en:
|
|||||||
client__jwks_uri: "JWKS URI"
|
client__jwks_uri: "JWKS URI"
|
||||||
client__end_session_endpoint: "End session endpoint"
|
client__end_session_endpoint: "End session endpoint"
|
||||||
client__end_session_endpoint_help: "The url to call to log the user out at the authorization server."
|
client__end_session_endpoint_help: "The url to call to log the user out at the authorization server."
|
||||||
|
extra_authorize_params: "Extra authorize parameters"
|
||||||
|
extra_authorize_params_help: "A hash of extra fixed parameters that will be merged to the authorization request"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "Name"
|
name: "Name"
|
||||||
authentication_type: "Authentication type"
|
authentication_type: "Authentication type"
|
||||||
|
@ -111,6 +111,10 @@ es:
|
|||||||
save: "Guardar"
|
save: "Guardar"
|
||||||
create_success: "El espacio se ha creado correctamente"
|
create_success: "El espacio se ha creado correctamente"
|
||||||
update_success: "El espacio se ha actualizado correctamente"
|
update_success: "El espacio se ha actualizado correctamente"
|
||||||
|
associated_machines: "Included machines"
|
||||||
|
children_spaces: "Included spaces"
|
||||||
|
associated_objects: "Associated objects"
|
||||||
|
associated_objects_warning: "Only use these fields if you want interblocking reservation between spaces, child spaces and machines. If you want machine and space reservations to remain independent, please leave the following fields blank."
|
||||||
event_form:
|
event_form:
|
||||||
ACTION_title: "{ACTION, select, create{Nuevo} other{Actualiza el}} evento"
|
ACTION_title: "{ACTION, select, create{Nuevo} other{Actualiza el}} evento"
|
||||||
title: "Título"
|
title: "Título"
|
||||||
@ -1477,6 +1481,8 @@ es:
|
|||||||
client__jwks_uri: "JWKS URI"
|
client__jwks_uri: "JWKS URI"
|
||||||
client__end_session_endpoint: "Endpoint de fin de sesión"
|
client__end_session_endpoint: "Endpoint de fin de sesión"
|
||||||
client__end_session_endpoint_help: "La URL a llamar para cerrar la sesión del usuario en el servidor de autorización."
|
client__end_session_endpoint_help: "La URL a llamar para cerrar la sesión del usuario en el servidor de autorización."
|
||||||
|
extra_authorize_params: "Extra authorize parameters"
|
||||||
|
extra_authorize_params_help: "A hash of extra fixed parameters that will be merged to the authorization request"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "Nombre"
|
name: "Nombre"
|
||||||
authentication_type: "Tipo de autenticación"
|
authentication_type: "Tipo de autenticación"
|
||||||
|
@ -111,10 +111,10 @@ fr:
|
|||||||
save: "Enregistrer"
|
save: "Enregistrer"
|
||||||
create_success: "L'espace a bien été créé"
|
create_success: "L'espace a bien été créé"
|
||||||
update_success: "L'espace a bien été mis à jour"
|
update_success: "L'espace a bien été mis à jour"
|
||||||
associated_machines: "Machines"
|
associated_machines: "Machines incluses"
|
||||||
children_spaces: "Espaces"
|
children_spaces: "Espaces inclus"
|
||||||
associated_objects: "Machines et sous-espaces"
|
associated_objects: "Objet associé"
|
||||||
associated_objects_warning: "Utilisez ces champs uniquement si vous souhaitez que la réservation de l'espace bloque la réservation des machines associées et des sous-espaces (et vice-versa). Si vous souhaitez que les réservations restent indépendantes, veuillez laisser les champs suivants vides."
|
associated_objects_warning: "Utilisez uniquement ces champs si vous souhaitez une réservation d'interblocage entre les espaces, les sous-espaces et les machines. Si vous voulez que les réservations de machines et d'espaces restent indépendantes, veuillez laisser les champs suivants vides."
|
||||||
event_form:
|
event_form:
|
||||||
ACTION_title: "{ACTION, select, create{Nouvel } other{Mettre à jour l''}}événement"
|
ACTION_title: "{ACTION, select, create{Nouvel } other{Mettre à jour l''}}événement"
|
||||||
title: "Titre"
|
title: "Titre"
|
||||||
@ -1536,6 +1536,8 @@ fr:
|
|||||||
client__jwks_uri: "URI JWKS"
|
client__jwks_uri: "URI JWKS"
|
||||||
client__end_session_endpoint: "Point d'accès pour terminer la session"
|
client__end_session_endpoint: "Point d'accès pour terminer la session"
|
||||||
client__end_session_endpoint_help: "L'url à appeler pour déconnecter l'utilisateur sur le serveur d'autorisation."
|
client__end_session_endpoint_help: "L'url à appeler pour déconnecter l'utilisateur sur le serveur d'autorisation."
|
||||||
|
extra_authorize_params: "Paramètres d'autorisation supplémentaires"
|
||||||
|
extra_authorize_params_help: "Un hachage de paramètres supplémentaires fixes qui seront fusionnés à la demande d'autorisation"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "Nom"
|
name: "Nom"
|
||||||
authentication_type: "Type d'authentification"
|
authentication_type: "Type d'authentification"
|
||||||
|
@ -111,6 +111,10 @@ it:
|
|||||||
save: "Salva"
|
save: "Salva"
|
||||||
create_success: "Lo spazio è stato creato correttamente"
|
create_success: "Lo spazio è stato creato correttamente"
|
||||||
update_success: "Lo spazio è stato aggiornato correttamente"
|
update_success: "Lo spazio è stato aggiornato correttamente"
|
||||||
|
associated_machines: "Included machines"
|
||||||
|
children_spaces: "Included spaces"
|
||||||
|
associated_objects: "Associated objects"
|
||||||
|
associated_objects_warning: "Only use these fields if you want interblocking reservation between spaces, child spaces and machines. If you want machine and space reservations to remain independent, please leave the following fields blank."
|
||||||
event_form:
|
event_form:
|
||||||
ACTION_title: "{ACTION, select, create{Nuovo} other{Aggiorna}} evento"
|
ACTION_title: "{ACTION, select, create{Nuovo} other{Aggiorna}} evento"
|
||||||
title: "Titolo"
|
title: "Titolo"
|
||||||
@ -1477,6 +1481,8 @@ it:
|
|||||||
client__jwks_uri: "JWKS URI"
|
client__jwks_uri: "JWKS URI"
|
||||||
client__end_session_endpoint: "Endpoint di fine sessione"
|
client__end_session_endpoint: "Endpoint di fine sessione"
|
||||||
client__end_session_endpoint_help: "L'url da chiamare per effettuare il log out dell'utente al server di autorizzazione."
|
client__end_session_endpoint_help: "L'url da chiamare per effettuare il log out dell'utente al server di autorizzazione."
|
||||||
|
extra_authorize_params: "Extra authorize parameters"
|
||||||
|
extra_authorize_params_help: "A hash of extra fixed parameters that will be merged to the authorization request"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "Nome"
|
name: "Nome"
|
||||||
authentication_type: "Tipo di autenticazione"
|
authentication_type: "Tipo di autenticazione"
|
||||||
|
@ -111,6 +111,10 @@
|
|||||||
save: "Save"
|
save: "Save"
|
||||||
create_success: "The space was created successfully"
|
create_success: "The space was created successfully"
|
||||||
update_success: "The space was updated successfully"
|
update_success: "The space was updated successfully"
|
||||||
|
associated_machines: "Included machines"
|
||||||
|
children_spaces: "Included spaces"
|
||||||
|
associated_objects: "Associated objects"
|
||||||
|
associated_objects_warning: "Only use these fields if you want interblocking reservation between spaces, child spaces and machines. If you want machine and space reservations to remain independent, please leave the following fields blank."
|
||||||
event_form:
|
event_form:
|
||||||
ACTION_title: "{ACTION, select, create{New} other{Update the}} event"
|
ACTION_title: "{ACTION, select, create{New} other{Update the}} event"
|
||||||
title: "Title"
|
title: "Title"
|
||||||
@ -1477,6 +1481,8 @@
|
|||||||
client__jwks_uri: "JWKS URI"
|
client__jwks_uri: "JWKS URI"
|
||||||
client__end_session_endpoint: "End session endpoint"
|
client__end_session_endpoint: "End session endpoint"
|
||||||
client__end_session_endpoint_help: "The url to call to log the user out at the authorization server."
|
client__end_session_endpoint_help: "The url to call to log the user out at the authorization server."
|
||||||
|
extra_authorize_params: "Extra authorize parameters"
|
||||||
|
extra_authorize_params_help: "A hash of extra fixed parameters that will be merged to the authorization request"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "Name"
|
name: "Name"
|
||||||
authentication_type: "Authentication type"
|
authentication_type: "Authentication type"
|
||||||
|
@ -111,6 +111,10 @@ pt:
|
|||||||
save: "Save"
|
save: "Save"
|
||||||
create_success: "The space was created successfully"
|
create_success: "The space was created successfully"
|
||||||
update_success: "The space was updated successfully"
|
update_success: "The space was updated successfully"
|
||||||
|
associated_machines: "Included machines"
|
||||||
|
children_spaces: "Included spaces"
|
||||||
|
associated_objects: "Associated objects"
|
||||||
|
associated_objects_warning: "Only use these fields if you want interblocking reservation between spaces, child spaces and machines. If you want machine and space reservations to remain independent, please leave the following fields blank."
|
||||||
event_form:
|
event_form:
|
||||||
ACTION_title: "{ACTION, select, create{New} other{Update the}} event"
|
ACTION_title: "{ACTION, select, create{New} other{Update the}} event"
|
||||||
title: "Title"
|
title: "Title"
|
||||||
@ -1477,6 +1481,8 @@ pt:
|
|||||||
client__jwks_uri: "JWKS URI"
|
client__jwks_uri: "JWKS URI"
|
||||||
client__end_session_endpoint: "Endpoint de término de sessão"
|
client__end_session_endpoint: "Endpoint de término de sessão"
|
||||||
client__end_session_endpoint_help: "O Url para efetuar uma chamada para desconectar o usuário no servidor de autorização."
|
client__end_session_endpoint_help: "O Url para efetuar uma chamada para desconectar o usuário no servidor de autorização."
|
||||||
|
extra_authorize_params: "Extra authorize parameters"
|
||||||
|
extra_authorize_params_help: "A hash of extra fixed parameters that will be merged to the authorization request"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "Nome"
|
name: "Nome"
|
||||||
authentication_type: "Tipo de autenticação"
|
authentication_type: "Tipo de autenticação"
|
||||||
|
@ -111,6 +111,10 @@ zu:
|
|||||||
save: "crwdns36885:0crwdne36885:0"
|
save: "crwdns36885:0crwdne36885:0"
|
||||||
create_success: "crwdns31813:0crwdne31813:0"
|
create_success: "crwdns31813:0crwdne31813:0"
|
||||||
update_success: "crwdns31815:0crwdne31815:0"
|
update_success: "crwdns31815:0crwdne31815:0"
|
||||||
|
associated_machines: "crwdns37729:0crwdne37729:0"
|
||||||
|
children_spaces: "crwdns37731:0crwdne37731:0"
|
||||||
|
associated_objects: "crwdns37733:0crwdne37733:0"
|
||||||
|
associated_objects_warning: "crwdns37735:0crwdne37735:0"
|
||||||
event_form:
|
event_form:
|
||||||
ACTION_title: "crwdns36887:0ACTION={ACTION}crwdne36887:0"
|
ACTION_title: "crwdns36887:0ACTION={ACTION}crwdne36887:0"
|
||||||
title: "crwdns31817:0crwdne31817:0"
|
title: "crwdns31817:0crwdne31817:0"
|
||||||
@ -1477,6 +1481,8 @@ zu:
|
|||||||
client__jwks_uri: "crwdns26198:0crwdne26198:0"
|
client__jwks_uri: "crwdns26198:0crwdne26198:0"
|
||||||
client__end_session_endpoint: "crwdns26200:0crwdne26200:0"
|
client__end_session_endpoint: "crwdns26200:0crwdne26200:0"
|
||||||
client__end_session_endpoint_help: "crwdns26202:0crwdne26202:0"
|
client__end_session_endpoint_help: "crwdns26202:0crwdne26202:0"
|
||||||
|
extra_authorize_params: "crwdns37725:0crwdne37725:0"
|
||||||
|
extra_authorize_params_help: "crwdns37727:0crwdne37727:0"
|
||||||
provider_form:
|
provider_form:
|
||||||
name: "crwdns26204:0crwdne26204:0"
|
name: "crwdns26204:0crwdne26204:0"
|
||||||
authentication_type: "crwdns26206:0crwdne26206:0"
|
authentication_type: "crwdns26206:0crwdne26206:0"
|
||||||
|
@ -100,7 +100,7 @@ fr:
|
|||||||
_the_fablab_policy: "les conditions d'utilisation"
|
_the_fablab_policy: "les conditions d'utilisation"
|
||||||
field_required: "Champ requis"
|
field_required: "Champ requis"
|
||||||
profile_custom_field_is_required: "{FEILD} est requis"
|
profile_custom_field_is_required: "{FEILD} est requis"
|
||||||
user_supporting_documents_required: "Attention !<br>Vous avez déclarez être \"{GROUP}\", des pièces justificatives pourront vous être demandées."
|
user_supporting_documents_required: "Attention !<br>Vous avez déclaré être \"{GROUP}\", des pièces justificatives pourront vous être demandées."
|
||||||
unexpected_error_occurred: "Une erreur inattendue s'est produite. Veuillez réessayer ultérieurement."
|
unexpected_error_occurred: "Une erreur inattendue s'est produite. Veuillez réessayer ultérieurement."
|
||||||
used_for_statistics: "Cette donnée sera utilisée à des fins statistiques"
|
used_for_statistics: "Cette donnée sera utilisée à des fins statistiques"
|
||||||
used_for_invoicing: "Cette donnée sera utilisée à des fins de facturation"
|
used_for_invoicing: "Cette donnée sera utilisée à des fins de facturation"
|
||||||
|
@ -65,6 +65,7 @@ de:
|
|||||||
not_available: "Nicht verfügbar"
|
not_available: "Nicht verfügbar"
|
||||||
reserving: "Ich reserviere"
|
reserving: "Ich reserviere"
|
||||||
i_ve_reserved: "Ich reservierte"
|
i_ve_reserved: "Ich reservierte"
|
||||||
|
blocked: "Blocked"
|
||||||
length_must_be_slot_multiple: "muss mindestens %{MIN} Minuten nach dem Startdatum liegen"
|
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"
|
must_be_associated_with_at_least_1_machine: "muss mindestens einer Maschine zugeordnet sein"
|
||||||
deleted_user: "Gelöschte Benutzer"
|
deleted_user: "Gelöschte Benutzer"
|
||||||
@ -446,6 +447,8 @@ de:
|
|||||||
account_invalidated: "Dein Account ist ungültig."
|
account_invalidated: "Dein Account ist ungültig."
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "Your supporting documents were refused"
|
refusal: "Your supporting documents were refused"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
||||||
notify_user_order_is_ready:
|
notify_user_order_is_ready:
|
||||||
@ -538,6 +541,7 @@ de:
|
|||||||
space: "Dieser Space ist deaktiviert"
|
space: "Dieser Space ist deaktiviert"
|
||||||
machine: "Diese Maschine ist deaktiviert"
|
machine: "Diese Maschine ist deaktiviert"
|
||||||
reservable: "Diese Maschine ist nicht reservierbar"
|
reservable: "Diese Maschine ist nicht reservierbar"
|
||||||
|
blocked_by_another_reservation: "This slot is blocked by another reservation"
|
||||||
cart_validation:
|
cart_validation:
|
||||||
select_user: "Please select a user before continuing"
|
select_user: "Please select a user before continuing"
|
||||||
settings:
|
settings:
|
||||||
|
@ -462,6 +462,8 @@ en:
|
|||||||
child_invalidated: "Your account child is invalid."
|
child_invalidated: "Your account child is invalid."
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "Your supporting documents were refused"
|
refusal: "Your supporting documents were refused"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
||||||
notify_user_child_supporting_document_refusal:
|
notify_user_child_supporting_document_refusal:
|
||||||
|
@ -65,6 +65,7 @@ es:
|
|||||||
not_available: "No disponible"
|
not_available: "No disponible"
|
||||||
reserving: "Me reservo"
|
reserving: "Me reservo"
|
||||||
i_ve_reserved: "He reservado"
|
i_ve_reserved: "He reservado"
|
||||||
|
blocked: "Blocked"
|
||||||
length_must_be_slot_multiple: "Debe ser al menos %{MIN} minutos después de la fecha de inicio"
|
length_must_be_slot_multiple: "Debe ser al menos %{MIN} minutos después de la fecha de inicio"
|
||||||
must_be_associated_with_at_least_1_machine: "debe estar asociado con al menos 1 máquina"
|
must_be_associated_with_at_least_1_machine: "debe estar asociado con al menos 1 máquina"
|
||||||
deleted_user: "Usuario eliminado"
|
deleted_user: "Usuario eliminado"
|
||||||
@ -446,6 +447,8 @@ es:
|
|||||||
account_invalidated: "Su cuenta no es válida."
|
account_invalidated: "Su cuenta no es válida."
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "Sus justificantes han sido rechazados"
|
refusal: "Sus justificantes han sido rechazados"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "El justificante del afiliado <strong><em>%{NAME}</em></strong> ha sido rechazado."
|
refusal: "El justificante del afiliado <strong><em>%{NAME}</em></strong> ha sido rechazado."
|
||||||
notify_user_order_is_ready:
|
notify_user_order_is_ready:
|
||||||
@ -538,6 +541,7 @@ es:
|
|||||||
space: "Este espacio está desactivado"
|
space: "Este espacio está desactivado"
|
||||||
machine: "Esta máquina está desactivada"
|
machine: "Esta máquina está desactivada"
|
||||||
reservable: "Esta máquina no se puede reservar"
|
reservable: "Esta máquina no se puede reservar"
|
||||||
|
blocked_by_another_reservation: "This slot is blocked by another reservation"
|
||||||
cart_validation:
|
cart_validation:
|
||||||
select_user: "Por favor, seleccione un usuario antes de continuar"
|
select_user: "Por favor, seleccione un usuario antes de continuar"
|
||||||
settings:
|
settings:
|
||||||
|
@ -66,7 +66,7 @@ fr:
|
|||||||
not_available: "Non disponible"
|
not_available: "Non disponible"
|
||||||
reserving: "Je réserve"
|
reserving: "Je réserve"
|
||||||
i_ve_reserved: "J'ai réservé"
|
i_ve_reserved: "J'ai réservé"
|
||||||
blocked: "Bloquée"
|
blocked: "Bloqué"
|
||||||
length_must_be_slot_multiple: "doit être au moins %{MIN} minutes après la date de début"
|
length_must_be_slot_multiple: "doit être au moins %{MIN} minutes après la date de début"
|
||||||
must_be_associated_with_at_least_1_machine: "doit être associé avec au moins 1 machine"
|
must_be_associated_with_at_least_1_machine: "doit être associé avec au moins 1 machine"
|
||||||
deleted_user: "Utilisateur supprimé"
|
deleted_user: "Utilisateur supprimé"
|
||||||
@ -462,6 +462,8 @@ fr:
|
|||||||
child_invalidated: "Votre compte enfant est invalide."
|
child_invalidated: "Votre compte enfant est invalide."
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "Vos pièces justificatives ont été refusées"
|
refusal: "Vos pièces justificatives ont été refusées"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "Ceci est un rappel pour vous demander de télécharger vos documents justificatifs."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "Le justificatif du membre <strong><em>%{NAME}</strong></em> a été refusé."
|
refusal: "Le justificatif du membre <strong><em>%{NAME}</strong></em> a été refusé."
|
||||||
notify_user_child_supporting_document_refusal:
|
notify_user_child_supporting_document_refusal:
|
||||||
|
@ -65,6 +65,7 @@ it:
|
|||||||
not_available: "Non disponibile"
|
not_available: "Non disponibile"
|
||||||
reserving: "Sto prenotando"
|
reserving: "Sto prenotando"
|
||||||
i_ve_reserved: "Ho prenotato"
|
i_ve_reserved: "Ho prenotato"
|
||||||
|
blocked: "Blocked"
|
||||||
length_must_be_slot_multiple: "deve essere almeno %{MIN} minuti dopo la data di inizio"
|
length_must_be_slot_multiple: "deve essere almeno %{MIN} minuti dopo la data di inizio"
|
||||||
must_be_associated_with_at_least_1_machine: "deve essere associata ad almeno 1 macchina"
|
must_be_associated_with_at_least_1_machine: "deve essere associata ad almeno 1 macchina"
|
||||||
deleted_user: "Utente eliminato"
|
deleted_user: "Utente eliminato"
|
||||||
@ -446,6 +447,8 @@ it:
|
|||||||
account_invalidated: "Il tuo account non è valido."
|
account_invalidated: "Il tuo account non è valido."
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "I tuoi documenti aggiuntivi sono stati rifiutati"
|
refusal: "I tuoi documenti aggiuntivi sono stati rifiutati"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "Il documento aggiuntivo del membro <strong><em>%{NAME}</strong></em> è stato rifiutato."
|
refusal: "Il documento aggiuntivo del membro <strong><em>%{NAME}</strong></em> è stato rifiutato."
|
||||||
notify_user_order_is_ready:
|
notify_user_order_is_ready:
|
||||||
@ -538,6 +541,7 @@ it:
|
|||||||
space: "Questo spazio è disabilitato"
|
space: "Questo spazio è disabilitato"
|
||||||
machine: "Questa macchina è disabilitata"
|
machine: "Questa macchina è disabilitata"
|
||||||
reservable: "Questa macchina non è prenotabile"
|
reservable: "Questa macchina non è prenotabile"
|
||||||
|
blocked_by_another_reservation: "This slot is blocked by another reservation"
|
||||||
cart_validation:
|
cart_validation:
|
||||||
select_user: "Seleziona un utente prima di continuare"
|
select_user: "Seleziona un utente prima di continuare"
|
||||||
settings:
|
settings:
|
||||||
|
@ -402,6 +402,10 @@ de:
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "Your supporting documents were refused:"
|
user_supporting_document_files_refusal: "Your supporting documents were refused:"
|
||||||
action: "Please re-upload some new supporting documents."
|
action: "Please re-upload some new supporting documents."
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "Reminder to upload your supporting documents"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "A member's supporting documents were refused"
|
subject: "A member's supporting documents were refused"
|
||||||
body:
|
body:
|
||||||
|
@ -434,6 +434,10 @@ en:
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "Your supporting documents were refused:"
|
user_supporting_document_files_refusal: "Your supporting documents were refused:"
|
||||||
action: "Please re-upload some new supporting documents."
|
action: "Please re-upload some new supporting documents."
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "Reminder to upload your supporting documents"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "A member's supporting documents were refused"
|
subject: "A member's supporting documents were refused"
|
||||||
body:
|
body:
|
||||||
|
@ -402,6 +402,10 @@ es:
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "Sus justificantes han sido rechazados:"
|
user_supporting_document_files_refusal: "Sus justificantes han sido rechazados:"
|
||||||
action: "Por favor, vuelva a subir nuevos documentos justificativos."
|
action: "Por favor, vuelva a subir nuevos documentos justificativos."
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "Reminder to upload your supporting documents"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "Los justificantes del afiliado de un miembro han sido rechazados"
|
subject: "Los justificantes del afiliado de un miembro han sido rechazados"
|
||||||
body:
|
body:
|
||||||
|
@ -434,6 +434,10 @@ fr:
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "Vos pièces justificatives ont été refusées :"
|
user_supporting_document_files_refusal: "Vos pièces justificatives ont été refusées :"
|
||||||
action: "Veuillez téléverser de nouvelles pièces justificatives."
|
action: "Veuillez téléverser de nouvelles pièces justificatives."
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "Rappel de télécharger vos documents justificatifs"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "Ceci est un rappel pour vous demander de télécharger vos documents justificatifs."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "Les justificatifs d'un membre ont été refusés"
|
subject: "Les justificatifs d'un membre ont été refusés"
|
||||||
body:
|
body:
|
||||||
|
@ -402,6 +402,10 @@ it:
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "I tuoi documenti aggiuntivi sono stati rifiutati:"
|
user_supporting_document_files_refusal: "I tuoi documenti aggiuntivi sono stati rifiutati:"
|
||||||
action: "Si prega di ricaricare nuovi documenti di supporto."
|
action: "Si prega di ricaricare nuovi documenti di supporto."
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "Reminder to upload your supporting documents"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "I documenti aggiuntivi di un membro sono stati rifiutati"
|
subject: "I documenti aggiuntivi di un membro sono stati rifiutati"
|
||||||
body:
|
body:
|
||||||
|
@ -402,6 +402,10 @@
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "Your supporting documents were refused:"
|
user_supporting_document_files_refusal: "Your supporting documents were refused:"
|
||||||
action: "Please re-upload some new supporting documents."
|
action: "Please re-upload some new supporting documents."
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "Reminder to upload your supporting documents"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "A member's supporting documents were refused"
|
subject: "A member's supporting documents were refused"
|
||||||
body:
|
body:
|
||||||
|
@ -402,6 +402,10 @@ pt:
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "Os seus documentos de apoio foram recusados:"
|
user_supporting_document_files_refusal: "Os seus documentos de apoio foram recusados:"
|
||||||
action: "Por favor, recarregue novos documentos de apoio."
|
action: "Por favor, recarregue novos documentos de apoio."
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "Reminder to upload your supporting documents"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "Documentos de apoio de um membro foram recusados"
|
subject: "Documentos de apoio de um membro foram recusados"
|
||||||
body:
|
body:
|
||||||
|
@ -402,6 +402,10 @@ zu:
|
|||||||
body:
|
body:
|
||||||
user_supporting_document_files_refusal: "crwdns37363:0crwdne37363:0"
|
user_supporting_document_files_refusal: "crwdns37363:0crwdne37363:0"
|
||||||
action: "crwdns37365:0crwdne37365:0"
|
action: "crwdns37365:0crwdne37365:0"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
subject: "crwdns37743:0crwdne37743:0"
|
||||||
|
body:
|
||||||
|
user_supporting_document_reminder: "crwdns37745:0crwdne37745:0"
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
subject: "crwdns37367:0crwdne37367:0"
|
subject: "crwdns37367:0crwdne37367:0"
|
||||||
body:
|
body:
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
not_available: "Ikke tilgjengelig"
|
not_available: "Ikke tilgjengelig"
|
||||||
reserving: "I'm reserving"
|
reserving: "I'm reserving"
|
||||||
i_ve_reserved: "Jeg har reservert"
|
i_ve_reserved: "Jeg har reservert"
|
||||||
|
blocked: "Blocked"
|
||||||
length_must_be_slot_multiple: "må være minst %{MIN} minutter etter startdatoen"
|
length_must_be_slot_multiple: "må være minst %{MIN} minutter etter startdatoen"
|
||||||
must_be_associated_with_at_least_1_machine: "må være tilknyttet minst 1 maskin"
|
must_be_associated_with_at_least_1_machine: "må være tilknyttet minst 1 maskin"
|
||||||
deleted_user: "Deleted user"
|
deleted_user: "Deleted user"
|
||||||
@ -446,6 +447,8 @@
|
|||||||
account_invalidated: "Your account is invalid."
|
account_invalidated: "Your account is invalid."
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "Your supporting documents were refused"
|
refusal: "Your supporting documents were refused"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
||||||
notify_user_order_is_ready:
|
notify_user_order_is_ready:
|
||||||
@ -538,6 +541,7 @@
|
|||||||
space: "This space is disabled"
|
space: "This space is disabled"
|
||||||
machine: "This machine is disabled"
|
machine: "This machine is disabled"
|
||||||
reservable: "This machine is not reservable"
|
reservable: "This machine is not reservable"
|
||||||
|
blocked_by_another_reservation: "This slot is blocked by another reservation"
|
||||||
cart_validation:
|
cart_validation:
|
||||||
select_user: "Please select a user before continuing"
|
select_user: "Please select a user before continuing"
|
||||||
settings:
|
settings:
|
||||||
|
@ -65,6 +65,7 @@ pt:
|
|||||||
not_available: "Não disponível "
|
not_available: "Não disponível "
|
||||||
reserving: "I'm reserving"
|
reserving: "I'm reserving"
|
||||||
i_ve_reserved: "Eu reservei"
|
i_ve_reserved: "Eu reservei"
|
||||||
|
blocked: "Blocked"
|
||||||
length_must_be_slot_multiple: "deve ser pelo menos %{MIN} minutos após a data de início"
|
length_must_be_slot_multiple: "deve ser pelo menos %{MIN} minutos após a data de início"
|
||||||
must_be_associated_with_at_least_1_machine: "deve estar associada a pelo menos uma máquina"
|
must_be_associated_with_at_least_1_machine: "deve estar associada a pelo menos uma máquina"
|
||||||
deleted_user: "Usuário deletado"
|
deleted_user: "Usuário deletado"
|
||||||
@ -446,6 +447,8 @@ pt:
|
|||||||
account_invalidated: "Sua conta é inválida."
|
account_invalidated: "Sua conta é inválida."
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "Your supporting documents were refused"
|
refusal: "Your supporting documents were refused"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "This is a reminder for you to upload your supporting documents."
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
||||||
notify_user_order_is_ready:
|
notify_user_order_is_ready:
|
||||||
@ -538,6 +541,7 @@ pt:
|
|||||||
space: "Este espaço está desativado"
|
space: "Este espaço está desativado"
|
||||||
machine: "Esta máquina está desativada"
|
machine: "Esta máquina está desativada"
|
||||||
reservable: "Esta máquina não é reservável"
|
reservable: "Esta máquina não é reservável"
|
||||||
|
blocked_by_another_reservation: "This slot is blocked by another reservation"
|
||||||
cart_validation:
|
cart_validation:
|
||||||
select_user: "Por favor, selecione um usuário antes de continuar"
|
select_user: "Por favor, selecione um usuário antes de continuar"
|
||||||
settings:
|
settings:
|
||||||
|
@ -65,6 +65,7 @@ zu:
|
|||||||
not_available: "crwdns3267:0crwdne3267:0"
|
not_available: "crwdns3267:0crwdne3267:0"
|
||||||
reserving: "crwdns37199:0crwdne37199:0"
|
reserving: "crwdns37199:0crwdne37199:0"
|
||||||
i_ve_reserved: "crwdns3269:0crwdne3269:0"
|
i_ve_reserved: "crwdns3269:0crwdne3269:0"
|
||||||
|
blocked: "crwdns37737:0crwdne37737:0"
|
||||||
length_must_be_slot_multiple: "crwdns3271:0%{MIN}crwdne3271:0"
|
length_must_be_slot_multiple: "crwdns3271:0%{MIN}crwdne3271:0"
|
||||||
must_be_associated_with_at_least_1_machine: "crwdns3273:0crwdne3273:0"
|
must_be_associated_with_at_least_1_machine: "crwdns3273:0crwdne3273:0"
|
||||||
deleted_user: "crwdns22460:0crwdne22460:0"
|
deleted_user: "crwdns22460:0crwdne22460:0"
|
||||||
@ -446,6 +447,8 @@ zu:
|
|||||||
account_invalidated: "crwdns23006:0crwdne23006:0"
|
account_invalidated: "crwdns23006:0crwdne23006:0"
|
||||||
notify_user_supporting_document_refusal:
|
notify_user_supporting_document_refusal:
|
||||||
refusal: "crwdns37345:0crwdne37345:0"
|
refusal: "crwdns37345:0crwdne37345:0"
|
||||||
|
notify_user_supporting_document_reminder:
|
||||||
|
reminder_message: "crwdns37739:0crwdne37739:0"
|
||||||
notify_admin_user_supporting_document_refusal:
|
notify_admin_user_supporting_document_refusal:
|
||||||
refusal: "crwdns37347:0%{NAME}crwdne37347:0"
|
refusal: "crwdns37347:0%{NAME}crwdne37347:0"
|
||||||
notify_user_order_is_ready:
|
notify_user_order_is_ready:
|
||||||
@ -538,6 +541,7 @@ zu:
|
|||||||
space: "crwdns36283:0crwdne36283:0"
|
space: "crwdns36283:0crwdne36283:0"
|
||||||
machine: "crwdns36285:0crwdne36285:0"
|
machine: "crwdns36285:0crwdne36285:0"
|
||||||
reservable: "crwdns36287:0crwdne36287:0"
|
reservable: "crwdns36287:0crwdne36287:0"
|
||||||
|
blocked_by_another_reservation: "crwdns37741:0crwdne37741:0"
|
||||||
cart_validation:
|
cart_validation:
|
||||||
select_user: "crwdns37211:0crwdne37211:0"
|
select_user: "crwdns37211:0crwdne37211:0"
|
||||||
settings:
|
settings:
|
||||||
|
@ -62,6 +62,10 @@ auto_cancel_authorizations:
|
|||||||
class: TrainingAuthorizationWorker
|
class: TrainingAuthorizationWorker
|
||||||
queue: default
|
queue: default
|
||||||
|
|
||||||
|
supporting_documents_reminder_worker:
|
||||||
|
cron: "0 8 * * *" # every day, at 8
|
||||||
|
class: SupportingDocumentsReminderWorker
|
||||||
|
|
||||||
child_age_will_be_18:
|
child_age_will_be_18:
|
||||||
cron: "0 0 0 * * *" # every day, at midnight
|
cron: "0 0 0 * * *" # every day, at midnight
|
||||||
class: ChildAgeWorker
|
class: ChildAgeWorker
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddSupportingDocumentsReminderSentAtToUsers < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_column :users, :supporting_documents_reminder_sent_at, :datetime
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddExtraAuthorizeParamsToOpenIdConnectProvider < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_column :open_id_connect_providers, :extra_authorize_params, :jsonb, default: {}
|
||||||
|
end
|
||||||
|
end
|
@ -1,104 +1,5 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
NOTIFICATIONS_TYPES = [
|
|
||||||
{ name: 'notify_admin_when_project_published', category: 'projects', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_project_collaborator_to_valid', category: 'projects', is_configurable: false },
|
|
||||||
{ name: 'notify_project_author_when_collaborator_valid', category: 'projects', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_user_training_valid', category: 'trainings', is_configurable: false },
|
|
||||||
{ name: 'notify_member_subscribed_plan', category: 'subscriptions', is_configurable: false },
|
|
||||||
{ name: 'notify_member_create_reservation', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_member_subscribed_plan_is_changed', category: 'deprecated', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_member_create_reservation', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_slot_is_modified', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_slot_is_modified', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
|
|
||||||
{ name: 'notify_admin_when_user_is_created', category: 'users_accounts', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_subscribed_plan', category: 'subscriptions', is_configurable: true, roles: ['admin'] },
|
|
||||||
{ name: 'notify_user_when_invoice_ready', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_subscription_will_expire_in_7_days', category: 'subscriptions', is_configurable: false },
|
|
||||||
{ name: 'notify_member_subscription_is_expired', category: 'subscriptions', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_subscription_will_expire_in_7_days', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_subscription_is_expired', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_subscription_canceled', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_subscription_canceled', category: 'subscriptions', is_configurable: false },
|
|
||||||
{ name: 'notify_user_when_avoir_ready', category: 'wallet', is_configurable: false },
|
|
||||||
|
|
||||||
{ name: 'notify_member_slot_is_canceled', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_slot_is_canceled', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_partner_subscribed_plan', category: 'subscriptions', is_configurable: false },
|
|
||||||
{ name: 'notify_member_subscription_extended', category: 'subscriptions', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_subscription_extended', category: 'subscriptions', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_user_group_changed', category: 'users_accounts', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_user_user_group_changed', category: 'users_accounts', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_when_user_is_imported', category: 'users_accounts', is_configurable: true, roles: ['admin'] },
|
|
||||||
{ name: 'notify_user_profile_complete', category: 'users_accounts', is_configurable: false },
|
|
||||||
{ name: 'notify_user_auth_migration', category: 'user', is_configurable: false },
|
|
||||||
|
|
||||||
{ name: 'notify_admin_user_merged', category: 'users_accounts', is_configurable: true, roles: ['admin'] },
|
|
||||||
{ name: 'notify_admin_profile_complete', category: 'users_accounts', is_configurable: true, roles: ['admin'] },
|
|
||||||
{ name: 'notify_admin_abuse_reported', category: 'projects', is_configurable: true, roles: ['admin'] },
|
|
||||||
{ name: 'notify_admin_invoicing_changed', category: 'deprecated', is_configurable: false },
|
|
||||||
{ name: 'notify_user_wallet_is_credited', category: 'wallet', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_user_wallet_is_credited', category: 'wallet', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_export_complete', category: 'exports', is_configurable: false },
|
|
||||||
{ name: 'notify_member_about_coupon', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_member_reservation_reminder', category: 'agenda', is_configurable: false },
|
|
||||||
|
|
||||||
{ name: 'notify_admin_free_disk_space', category: 'app_management', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_close_period_reminder', category: 'accountings', is_configurable: true, roles: ['admin'] },
|
|
||||||
{ name: 'notify_admin_archive_complete', category: 'accountings', is_configurable: true, roles: ['admin'] },
|
|
||||||
{ name: 'notify_privacy_policy_changed', category: 'app_management', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_import_complete', category: 'app_management', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_refund_created', category: 'wallet', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admins_role_update', category: 'users_accounts', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_user_role_update', category: 'users_accounts', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_objects_stripe_sync', category: 'payments', is_configurable: false },
|
|
||||||
{ name: 'notify_user_when_payment_schedule_ready', category: 'payments', is_configurable: false },
|
|
||||||
|
|
||||||
{ name: 'notify_admin_payment_schedule_failed', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_payment_schedule_failed', category: 'payments', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_payment_schedule_check_deadline', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_payment_schedule_transfer_deadline', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_payment_schedule_error', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_payment_schedule_error', category: 'payments', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_payment_schedule_gateway_canceled', category: 'payments', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_payment_schedule_gateway_canceled', category: 'payments', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_user_supporting_document_files_created', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_user_supporting_document_files_updated', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
|
|
||||||
{ name: 'notify_user_is_validated', category: 'users_accounts', is_configurable: false },
|
|
||||||
{ name: 'notify_user_is_invalidated', category: 'users_accounts', is_configurable: false },
|
|
||||||
{ name: 'notify_user_supporting_document_refusal', category: 'supporting_documents', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_user_supporting_document_refusal', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_order_is_paid', category: 'shop', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_user_order_is_ready', category: 'shop', is_configurable: false },
|
|
||||||
{ name: 'notify_user_order_is_canceled', category: 'shop', is_configurable: false },
|
|
||||||
{ name: 'notify_user_order_is_refunded', category: 'shop', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_low_stock_threshold', category: 'shop', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_training_auto_cancelled', category: 'trainings', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_training_auto_cancelled', category: 'trainings', is_configurable: false },
|
|
||||||
|
|
||||||
{ name: 'notify_member_training_authorization_expired', category: 'trainings', is_configurable: false },
|
|
||||||
{ name: 'notify_member_training_invalidated', category: 'trainings', is_configurable: false },
|
|
||||||
{ name: 'notify_member_reservation_limit_reached', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_user_child_supporting_document_refusal', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_user_child_supporting_document_refusal', category: 'supporting_documents', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_child_created', category: 'users_accounts', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_user_child_is_validated', category: 'users_accounts', is_configurable: false },
|
|
||||||
{ name: 'notify_user_child_is_invalidated', category: 'users_accounts', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_user_child_supporting_document_files_updated', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_admin_user_child_supporting_document_files_created', category: 'supporting_documents', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
|
|
||||||
{ name: 'notify_member_reservation_validated', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_reservation_validated', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_pre_booked_reservation', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_member_pre_booked_reservation', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_member_reservation_invalidated', category: 'agenda', is_configurable: false },
|
|
||||||
{ name: 'notify_admin_reservation_invalidated', category: 'agenda', is_configurable: true, roles: ['admin', 'manager'] },
|
|
||||||
{ name: 'notify_user_when_child_age_will_be_18', category: 'users_accounts', is_configurable: false }
|
|
||||||
|
|
||||||
].freeze
|
|
||||||
|
|
||||||
NOTIFICATIONS_TYPES.each do |notification_type_attrs|
|
NOTIFICATIONS_TYPES.each do |notification_type_attrs|
|
||||||
notification_type = NotificationType.find_by(name: notification_type_attrs[:name])
|
notification_type = NotificationType.find_by(name: notification_type_attrs[:name])
|
||||||
|
|
||||||
|
@ -2039,7 +2039,8 @@ CREATE TABLE public.open_id_connect_providers (
|
|||||||
client__end_session_endpoint character varying,
|
client__end_session_endpoint character varying,
|
||||||
profile_url character varying,
|
profile_url character varying,
|
||||||
created_at timestamp without time zone NOT NULL,
|
created_at timestamp without time zone NOT NULL,
|
||||||
updated_at timestamp without time zone NOT NULL
|
updated_at timestamp without time zone NOT NULL,
|
||||||
|
extra_authorize_params jsonb DEFAULT '{}'::jsonb
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -4354,7 +4355,8 @@ CREATE TABLE public.users (
|
|||||||
current_sign_in_ip inet,
|
current_sign_in_ip inet,
|
||||||
last_sign_in_ip inet,
|
last_sign_in_ip inet,
|
||||||
validated_at timestamp without time zone,
|
validated_at timestamp without time zone,
|
||||||
mapped_from_sso character varying
|
mapped_from_sso character varying,
|
||||||
|
supporting_documents_reminder_sent_at timestamp(6) without time zone
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -9261,6 +9263,8 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||||||
('20230728090257'),
|
('20230728090257'),
|
||||||
('20230825101952'),
|
('20230825101952'),
|
||||||
('20230828073428'),
|
('20230828073428'),
|
||||||
('20230831103208');
|
('20230831103208'),
|
||||||
|
('20230901090637'),
|
||||||
|
('20230907124230');
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fab-manager",
|
"name": "fab-manager",
|
||||||
"version": "6.0.13",
|
"version": "6.0.14",
|
||||||
"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.",
|
"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": [
|
"keywords": [
|
||||||
"fablab",
|
"fablab",
|
||||||
|
8
test/fixtures/notification_types.yml
vendored
8
test/fixtures/notification_types.yml
vendored
@ -607,3 +607,11 @@ notification_type_72:
|
|||||||
is_configurable: false
|
is_configurable: false
|
||||||
created_at: 2023-02-16 10:42:39.143888000 Z
|
created_at: 2023-02-16 10:42:39.143888000 Z
|
||||||
updated_at: 2023-02-16 10:42:39.143888000 Z
|
updated_at: 2023-02-16 10:42:39.143888000 Z
|
||||||
|
|
||||||
|
notification_type_73:
|
||||||
|
id: 73
|
||||||
|
name: notify_user_supporting_document_reminder
|
||||||
|
category: supporting_documents
|
||||||
|
is_configurable: false
|
||||||
|
created_at: 2023-02-02 08:25:33.439078000 Z
|
||||||
|
updated_at: 2023-02-02 08:25:33.439078000 Z
|
@ -39,6 +39,21 @@ class NotificationsTest < ActionDispatch::IntegrationTest
|
|||||||
assert_equal (Notification.where(receiver_id: @admin.id).count - 1), notifications_total
|
assert_equal (Notification.where(receiver_id: @admin.id).count - 1), notifications_total
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'polling endpoint' do
|
||||||
|
@admin = User.find_by(username: 'admin')
|
||||||
|
login_as(@admin, scope: :user)
|
||||||
|
|
||||||
|
get '/api/notifications/polling', params: { last_poll: Notification.order(:created_at).pick(:created_at) }
|
||||||
|
|
||||||
|
# Check response format & status
|
||||||
|
assert_equal 200, response.status, response.body
|
||||||
|
assert_match Mime[:json].to_s, response.content_type
|
||||||
|
|
||||||
|
# Check the list items are ok
|
||||||
|
notifications_total = json_response(response.body)[:totals][:total]
|
||||||
|
assert_not_equal notifications.count, 0
|
||||||
|
end
|
||||||
|
|
||||||
test 'Last unread returns last 3 unread notifications' do
|
test 'Last unread returns last 3 unread notifications' do
|
||||||
@member = User.find(4)
|
@member = User.find(4)
|
||||||
login_as(@member, scope: :user)
|
login_as(@member, scope: :user)
|
||||||
|
83
test/workers/supporting_documents_reminder_worker_test.rb
Normal file
83
test/workers/supporting_documents_reminder_worker_test.rb
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
require 'minitest/autorun'
|
||||||
|
#require 'sidekiq/testing'
|
||||||
|
|
||||||
|
class SupportingDocumentsReminderWorkerTest < ActiveSupport::TestCase
|
||||||
|
include ActionMailer::TestHelper
|
||||||
|
setup do
|
||||||
|
@worker = SupportingDocumentsReminderWorker.new
|
||||||
|
|
||||||
|
group = groups(:group_1)
|
||||||
|
@users = User.where(group_id: group.id).members
|
||||||
|
@supporting_document_type_1 = SupportingDocumentType.create!(name: "doc1", groups: [group])
|
||||||
|
@supporting_document_type_2 = SupportingDocumentType.create!(name: "doc2", groups: [group])
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'do nothing if it concerns another group' do
|
||||||
|
group = Group.create!(name: 'test', slug: 'test')
|
||||||
|
SupportingDocumentType.destroy_all
|
||||||
|
supporting_document_type = SupportingDocumentType.create!(name: "doc3", groups: [group])
|
||||||
|
|
||||||
|
@users.each do |user|
|
||||||
|
assert_nil user.supporting_documents_reminder_sent_at
|
||||||
|
end
|
||||||
|
assert_enqueued_emails 0 do
|
||||||
|
@worker.perform
|
||||||
|
end
|
||||||
|
@users.reload.each do |user|
|
||||||
|
assert_nil user.supporting_documents_reminder_sent_at
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'notify every users who did not upload supporting document files' do
|
||||||
|
@users.each do |user|
|
||||||
|
assert_nil user.supporting_documents_reminder_sent_at
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_enqueued_emails @users.length do
|
||||||
|
@worker.perform
|
||||||
|
end
|
||||||
|
|
||||||
|
@users.reload.each do |user|
|
||||||
|
assert user.supporting_documents_reminder_sent_at
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_enqueued_emails 0 do
|
||||||
|
@worker.perform
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'notify users even if they have uploaded 1 document of the 2' do
|
||||||
|
@users.each do |user|
|
||||||
|
user.supporting_document_files.create!(supporting_document_type: @supporting_document_type_1,
|
||||||
|
attachment: fixture_file_upload('document.pdf'))
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_enqueued_emails @users.length do
|
||||||
|
@worker.perform
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'do not notify users if they have uploaded all documents' do
|
||||||
|
@users.each do |user|
|
||||||
|
user.supporting_document_files.create!(supporting_document_type: @supporting_document_type_1,
|
||||||
|
attachment: fixture_file_upload('document.pdf'))
|
||||||
|
user.supporting_document_files.create!(supporting_document_type: @supporting_document_type_2,
|
||||||
|
attachment: fixture_file_upload('document.pdf'))
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_enqueued_emails 0 do
|
||||||
|
@worker.perform
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'do not notify users if they were created too recently' do
|
||||||
|
@users.update_all(created_at: 2.minutes.ago)
|
||||||
|
|
||||||
|
assert_enqueued_emails 0 do
|
||||||
|
@worker.perform
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user