Skip to content

Commit

Permalink
Merge branch 'dev' for release 6.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
nflorentin committed Nov 3, 2023
2 parents 60da6a8 + cba3805 commit 75ced8f
Show file tree
Hide file tree
Showing 35 changed files with 320 additions and 161 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,6 @@ yarn-debug.log*
/yarn-error.log
yarn-debug.log*
.yarn-integrity

*.sql
*.tar.gz
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog Fab-manager

## v6.3.0 2023 November 3

- Fix a bug: fix all failing tasks of rake task file chain.rake
- Fix a bug: file_size_validator.rb was broken since ruby v3, see https://github.com/rails/rails/issues/41270
- improvement: pre-registration event reservations ilimit places
- improvement: add including_deleted_users param for open api users
- decreases sidekiq concurrency from 25 to 5, 25 is too much and consumes memory for nothing
- do not log Notifications#polling action anymore, by default, can be enable via env variable ENABLE_NOTIFICATIONS_POLLING_LOGGING=true
- Fix a bug: api/products/index bug when sorting by amount
- adds a rake task to regenerate invoices by ids (see maintenance.rake)
- Fix a bug: replaces custom ServerLocale middleware with sidekiq i18n middleware
- adds a rake task to erase all reservations and invoices (fablab:maintenance:delete_all_reservations_and_invoices)
- improvement: dynamic label (i18n) for stats structure tables

## v6.2.0 2023 October 13

- Fix a bug: fix ReservationReminderWorker, was sending reservation reminder to users with a event reservation not validated by admin + adds tests for all scenarios
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,4 @@ gem 'sentry-ruby'
gem "reverse_markdown"

gem "ancestry"
gem 'silencer', require: false
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ GEM
concurrent-ruby (~> 1.0, >= 1.0.5)
sidekiq (>= 5.0, < 8.0)
thor (>= 0.20, < 3.0)
silencer (2.0.0)
simplecov (0.19.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
Expand Down Expand Up @@ -611,6 +612,7 @@ DEPENDENCIES
sidekiq (>= 6.0.7)
sidekiq-scheduler
sidekiq-unique-jobs (~> 7.1.23)
silencer
spring (~> 4)
spring-watcher-listen (~> 2.1.0)
stripe (= 5.29.0)
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/api/notifications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ def last_unread

def polling
@notifications = current_user.notifications
.with_valid_notification_type
.where('notifications.is_read = false AND notifications.created_at >= :date', date: params[:last_poll])
.order('notifications.created_at DESC')
.with_valid_notification_type
.where('notifications.is_read = false AND notifications.created_at >= :date', date: params[:last_poll])
.order('notifications.created_at DESC')
@totals = {
total: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).count,
unread: current_user.notifications.with_valid_notification_type.delivered_in_system(current_user).where(is_read: false).count
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/open_api/v1/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ class OpenAPI::V1::UsersController < OpenAPI::V1::BaseController
expose_doc

def index
@users = User.order(created_at: :desc).includes(:group, :profile, :invoicing_profile)
@users = InvoicingProfile.order(created_at: :desc).includes(user: %i[group profile statistic_profile])

@users = @users.where.not(user_id: nil) if params[:including_deleted_users].blank?

if params[:email].present?
email_param = params[:email].is_a?(String) ? params[:email].downcase : params[:email].map(&:downcase)
Expand Down
1 change: 1 addition & 0 deletions app/doc/open_api/v1/users_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class OpenAPI::V1::UsersDoc < OpenAPI::V1::BaseDoc
param :email, [String, Array], optional: true, desc: 'Filter users by *email* using strict matching.'
param :user_id, [Integer, Array], optional: true, desc: 'Filter users by *id* using strict matching.'
param :created_after, DateTime, optional: true, desc: 'Filter users to accounts created after the given date.'
param :including_deleted_users, [true, false], optional: true, desc: 'Filter users to accounts deleted or not.'
example <<-USERS
# /open_api/v1/users?page=1&per_page=4
{
Expand Down
3 changes: 0 additions & 3 deletions app/frontend/src/javascript/controllers/events.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -1023,9 +1023,6 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
});
resetEventReserve();
});
if ($scope.currentUser.role === 'admin') {
return $scope.ctrl.member = null;
}
};

/**
Expand Down
2 changes: 1 addition & 1 deletion app/frontend/templates/admin/events/reservations.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h1>{{ 'app.admin.event_reservations.the_reservations' | translate }} {{event.ti
<div ng-if="!isCancelled(reservation) && !reservation.is_paid">
<label class="m-r-sm">
<span translate>{{ 'app.admin.event_reservations.negative' }}</span>
<input type="radio" name="invalidate-{{reservation.id}}" ng-value="false" ng-click="invalidateReservation(reservation)" ng-model="reservation.slots_reservations_attributes[0].is_valid" ng-disabled="reservation.total_booked_seats > event.nb_free_places && !reservation.slots_reservations_attributes[0].is_valid">
<input type="radio" name="invalidate-{{reservation.id}}" ng-value="false" ng-click="invalidateReservation(reservation)" ng-model="reservation.slots_reservations_attributes[0].is_valid" ng-disabled="reservation.slots_reservations_attributes[0].is_valid === 'false'">
</label>
<label>
<span translate>{{ 'app.admin.event_reservations.affirmative' }}</span>
Expand Down
1 change: 0 additions & 1 deletion app/models/chained_element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
class ChainedElement < ApplicationRecord
belongs_to :element, polymorphic: true
belongs_to :previous, class_name: 'ChainedElement'
has_one :next, class_name: 'ChainedElement', inverse_of: :previous, dependent: :restrict_with_exception

before_create :set_content, :chain_record

Expand Down
9 changes: 9 additions & 0 deletions app/models/concerns/label_i18n_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module LabelI18nConcern
extend ActiveSupport::Concern

def label
super.present? ? super : I18n.t(label_i18n_path)
end
end
2 changes: 1 addition & 1 deletion app/models/slots_reservation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def update_places_cache(operation, target_slot = slot)
Slots::PlacesCacheService.change_places(target_slot,
reservation.reservable_type,
reservation.reservable_id,
reservation.total_booked_seats,
reservation.reservable.pre_registration ? 0 : reservation.total_booked_seats,
operation)
else
Slots::PlacesCacheService.change_places(target_slot, reservation.reservable_type, reservation.reservable_id, 1, operation)
Expand Down
2 changes: 2 additions & 0 deletions app/models/statistic_field.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
class StatisticField < ApplicationRecord
include LabelI18nConcern

has_one :statistic_index
end
2 changes: 2 additions & 0 deletions app/models/statistic_index.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class StatisticIndex < ApplicationRecord
include LabelI18nConcern

has_many :statistic_types
has_many :statistic_fields
has_one :statistic_graph
Expand Down
2 changes: 2 additions & 0 deletions app/models/statistic_sub_type.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class StatisticSubType < ApplicationRecord
include LabelI18nConcern

has_many :statistic_type_sub_types, dependent: :destroy
has_many :statistic_types, through: :statistic_type_sub_types
end
2 changes: 2 additions & 0 deletions app/models/statistic_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Allows splinting a StatisticIndex into multiple types.
# e.g. The StatisticIndex "subscriptions" may have types like "1 month", "1 year", etc.
class StatisticType < ApplicationRecord
include LabelI18nConcern

belongs_to :statistic_index
has_many :statistic_type_sub_types, dependent: :destroy
has_many :statistic_sub_types, through: :statistic_type_sub_types
Expand Down
2 changes: 1 addition & 1 deletion app/services/product_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def products_ordering(products, filters)
order ||= 'desc'

if key == 'amount'
products.order("COALESCE(amount, 0) #{order.upcase}")
products.order(Arel.sql("COALESCE(amount, 0) #{order.upcase}"))
else
products.order(key => order)
end
Expand Down
2 changes: 1 addition & 1 deletion app/views/open_api/v1/reservations/index.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ json.reservations @reservations do |reservation|
json.user_id reservation.statistic_profile.user_id
unless reservation.statistic_profile.user.nil?
json.user do
json.partial! 'open_api/v1/users/user', user: reservation.statistic_profile.user
json.partial! 'open_api/v1/users/user', user: reservation.statistic_profile.user.invoicing_profile
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/views/open_api/v1/user_trainings/index.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ json.user_trainings @user_trainings do |user_training|
json.user_id user_training.statistic_profile.user_id
unless user_training.statistic_profile.user.nil?
json.user do
json.partial! 'open_api/v1/users/user', user: user_training.statistic_profile.user
json.partial! 'open_api/v1/users/user', user: user_training.statistic_profile.user.invoicing_profile
end
end
end
Expand Down
26 changes: 14 additions & 12 deletions app/views/open_api/v1/users/_user.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
# frozen_string_literal: true

json.extract! user, :id, :email, :created_at
json.extract! user.profile, :full_name, :first_name, :last_name if user.association(:profile).loaded?
json.gender user.statistic_profile.gender ? 'man' : 'woman'

if user.association(:invoicing_profile).loaded?
json.invoicing_profile_id user.invoicing_profile.id
json.external_id user.invoicing_profile.external_id
json.organization !user.invoicing_profile.organization.nil?
json.address user.invoicing_profile.invoicing_address
json.id user.user_id || user.id
json.extract! user, :email, :full_name, :first_name, :last_name, :created_at
if user.user
json.gender user.user.statistic_profile.gender ? 'man' : 'woman'
else
json.gender 'man'
end

if user.association(:group).loaded?
json.invoicing_profile_id user.id
json.external_id user.external_id
json.organization !user.organization.nil?
json.address user.invoicing_address

if user&.user&.group
json.group do
if user.group_id?
json.extract! user.group, :id, :name, :slug
if user.user.group_id?
json.extract! user.user.group, :id, :name, :slug
else
json.nil!
end
Expand Down
11 changes: 7 additions & 4 deletions config/initializers/sidekiq.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@
require 'sidekiq'
require 'sidekiq-scheduler'
require 'sidekiq/middleware/i18n'
require 'sidekiq/server_locale'

redis_host = ENV.fetch('REDIS_HOST', 'localhost')
redis_url = "redis://#{redis_host}:6379"

Sidekiq.configure_server do |config|
config.redis = { url: redis_url }

# client_middleware is also configured in configure_server block
# because jobs running in the Sidekiq server can themselves push
# new jobs to Sidekiq, thus acting as clients
# see https://github.com/sidekiq/sidekiq/wiki/Middleware for more details
config.client_middleware do |chain|
chain.add Sidekiq::Middleware::I18n::Client
chain.add SidekiqUniqueJobs::Middleware::Client
end

config.server_middleware do |chain|
chain.add Sidekiq::Middleware::I18n::Server
chain.add SidekiqUniqueJobs::Middleware::Server
end

Expand All @@ -36,11 +41,9 @@
config.redis = { url: redis_url }

config.client_middleware do |chain|
chain.add Sidekiq::Middleware::I18n::Client
chain.add SidekiqUniqueJobs::Middleware::Client
end
config.server_middleware do |chain|
chain.add FabManager::Middleware::ServerLocale
end
end

# Quieting logging in the test environment
Expand Down
13 changes: 13 additions & 0 deletions config/initializers/silencer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'silencer/rails/logger'

silenced_actions = []
silenced_actions << "/api/notifications/polling" unless Rails.application.secrets.enable_notifications_polling_logging

Rails.application.configure do
config.middleware.swap(
Rails::Rack::Logger,
Silencer::Logger,
config.log_tags,
silence: silenced_actions
)
end
16 changes: 8 additions & 8 deletions config/locales/app.admin.es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ es:
description: "Descripción"
name: "Nombre"
illustration: "Ilustración"
illustration_recommendation: "Maximum display size: 932 * 700 px (unconstrained ratio). The image may be cropped in list view. Only the description page displays the full image."
illustration_recommendation: "Tamaño máximo: 932 * 700 px (ratio sin restricciones). La imagen puede ser recortada en la vista de lista. Sólo la página de descripción muestra la imagen completa."
technical_specifications: "Especificaciones técnicas"
category: "Categoría"
attachments: "Adjuntos"
Expand All @@ -67,8 +67,8 @@ es:
dont_forget_to_change_them_before_creating_slots_for_this_training: "No olvide cambiarlos antes de crear franjas horarias para esta formación."
description: "Descripción"
name: "Nombre"
illustration: "Visual"
illustration_recommendation: "Maximum display size: 932 * 700 px (unconstrained ratio). The image may be cropped in list view. Only the description page displays the full image."
illustration: "Ilustración"
illustration_recommendation: "Tamaño máximo: 932 * 700 px (ratio sin restricciones). La imagen puede ser recortada en la vista de lista. Sólo la página de descripción muestra la imagen completa."
add_a_new_training: "Añadir una nueva formación"
validate_your_training: "Valide su formación"
settings: "Configuración"
Expand Down Expand Up @@ -100,8 +100,8 @@ es:
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 a 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."
name: "Nombre"
illustration: "Visual"
illustration_recommendation: "Maximum display size: 932 * 700 px (unconstrained ratio). The image may be cropped in list view. Only the description page displays the full image."
illustration: "Ilustración"
illustration_recommendation: "Tamaño máximo: 932 * 700 px (ratio sin restricciones). La imagen puede ser recortada en la vista de lista. Sólo la página de descripción muestra la imagen completa."
description: "Descripción"
characteristics: "Características"
attachments: "Adjuntos"
Expand All @@ -121,8 +121,8 @@ es:
event_form:
ACTION_title: "{ACTION, select, create{Nuevo} other{Actualiza el}} evento"
title: "Título"
illustration: "Visual"
illustration_recommendation: "Maximum display size: 932 * 700 px (unconstrained ratio). The image may be cropped in list view. Only the description page displays the full image."
illustration: "Ilustración"
illustration_recommendation: "Tamaño máximo: 932 * 700 px (ratio sin restricciones). La imagen puede ser recortada en la vista de lista. Sólo la página de descripción muestra la imagen completa."
description: "Descripción"
attachments: "Adjuntos"
attached_files_pdf: "Archivos adjuntos (pdf)"
Expand Down Expand Up @@ -1668,7 +1668,7 @@ es:
secondary_colour: "Color secundario:"
secondary: "Secundario"
background_picture_of_the_profile_banner: "Imagen de fondo de la bandera del perfil"
background_picture_recommendation: "Only .png file. Recommended size: 4/1 ratio, 1600*400 px."
background_picture_recommendation: "Sólo archivo .png. Tamaño recomendado: 4/1, 1600*400 px."
change_the_profile_banner: "Cambiar la bandera del perfil"
home_page: "Página de inicio"
news_of_the_home_page: "Noticias de la página principal:"
Expand Down
6 changes: 3 additions & 3 deletions config/locales/app.logged.es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ es:
notify_admin_member_create_reservation: "Un miembro hace una reserva"
notify_admin_slot_is_modified: "Una franja de reserva ha sido modificada"
notify_admin_slot_is_canceled: "Una reserva ha sido cancelada"
notify_admin_reservation_validated: "A reservation has been validated"
notify_admin_reservation_invalidated: "A reservation has been invalidated"
notify_admin_member_pre_booked_reservation: "A pre-booking has been made"
notify_admin_reservation_validated: "Una reserva ha sido validada"
notify_admin_reservation_invalidated: "Una reserva ha sido invalidada"
notify_admin_member_pre_booked_reservation: "Se ha hecho una pre-reserva"
notify_admin_subscribed_plan: "Se ha adquirido una suscripción"
notify_admin_subscription_will_expire_in_7_days: "Una suscripción de miembro caduca en 7 días"
notify_admin_subscription_is_expired: "La suscripción de un miembro ha expirado"
Expand Down
2 changes: 1 addition & 1 deletion config/locales/app.shared.es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ es:
name: "Nombre"
name_is_required: "Se requiere un nombre."
illustration: "Ilustración"
illustration_recommendation: "Maximum display size: 932 * 700 px (unconstrained ratio)."
illustration_recommendation: "Tamaño máximo: 932 * 700 px (ratio sin restricciones)."
add_an_illustration: "Añadir una ilustración"
CAD_file: "Fichero CAD"
CAD_files: "Archivos CAD"
Expand Down
4 changes: 4 additions & 0 deletions config/secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ development:
adminsys_email: <%= ENV["ADMINSYS_EMAIL"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>
enable_notifications_polling_logging: <%= ENV.fetch("ENABLE_NOTIFICATIONS_POLLING_LOGGING", false) %>

test:
secret_key_base: 83daf5e7b80d990f037407bab78dff9904aaf3c195a50f84fa8695a22287e707dfbd9524b403b1dcf116ae1d8c06844c3d7ed942564e5b46be6ae3ead93a9d30
Expand Down Expand Up @@ -75,6 +76,7 @@ test:
adminsys_email: <%= ENV["ADMINSYS_EMAIL"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>
enable_notifications_polling_logging: <%= ENV.fetch("ENABLE_NOTIFICATIONS_POLLING_LOGGING", false) %>

staging:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Expand Down Expand Up @@ -117,6 +119,7 @@ staging:
enable_in_context_translation: <%= ENV["ENABLE_IN_CONTEXT_TRANSLATION"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>
enable_notifications_polling_logging: <%= ENV.fetch("ENABLE_NOTIFICATIONS_POLLING_LOGGING", false) %>

# Do not keep production secrets in the repository,
# instead read values from the environment.
Expand Down Expand Up @@ -162,3 +165,4 @@ production:
adminsys_email: <%= ENV["ADMINSYS_EMAIL"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>
enable_notifications_polling_logging: <%= ENV.fetch("ENABLE_NOTIFICATIONS_POLLING_LOGGING", false) %>
2 changes: 1 addition & 1 deletion config/sidekiq.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# configuration file for Sidekiq
:verbose: true
:logfile: ./log/sidekiq.log
:concurrency: 25
:concurrency: 5
:queues:
- [stripe, 7]
- [default, 5]
Expand Down
Loading

0 comments on commit 75ced8f

Please sign in to comment.