2020-01-27 17:10:29 +01:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
# Settings are saved in two database tables: Settings and HistoryValues.
|
|
|
|
# Due to the way the controller updates the settings, we cannot safely use ActiveRecord's callbacks (eg. after_update, after_commit...)
|
|
|
|
# so this service provides a wrapper around these operations.
|
|
|
|
class SettingService
|
2022-11-04 09:44:17 +01:00
|
|
|
class << self
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param setting [Setting]
|
2022-11-22 17:43:19 +01:00
|
|
|
def update_allowed?(setting)
|
2022-11-04 09:44:17 +01:00
|
|
|
return false if Rails.application.secrets.locked_settings.include? setting.name
|
2020-06-15 13:20:48 +02:00
|
|
|
|
2022-11-04 09:44:17 +01:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2023-02-17 16:56:17 +01:00
|
|
|
# @param setting [Hash{Symbol->String}]
|
|
|
|
# @return [StandardError,NilClass]
|
|
|
|
def check_before_update(setting)
|
|
|
|
check_home_scss(setting)
|
|
|
|
end
|
|
|
|
|
2023-02-20 17:12:38 +01:00
|
|
|
# @param setting [Setting]
|
|
|
|
# @param value [String]
|
|
|
|
# @param operator [User]
|
|
|
|
def save_and_update(setting, value, operator)
|
|
|
|
return false unless setting.save
|
|
|
|
|
|
|
|
val = parse_value(setting.name, value)
|
|
|
|
setting.history_values.create(value: val, invoicing_profile: operator.invoicing_profile)
|
|
|
|
end
|
|
|
|
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def run_after_update(settings)
|
|
|
|
update_theme_stylesheet(settings)
|
|
|
|
update_home_stylesheet(settings)
|
|
|
|
notify_privacy_update(settings)
|
|
|
|
sync_stripe_objects(settings)
|
|
|
|
build_stats(settings)
|
|
|
|
export_projects_to_openlab(settings)
|
|
|
|
validate_admins(settings)
|
|
|
|
update_accounting_line(settings)
|
2023-01-24 16:48:05 +01:00
|
|
|
update_trainings_auto_cancel(settings)
|
2023-01-27 17:31:16 +01:00
|
|
|
update_trainings_authorization(settings)
|
|
|
|
update_trainings_invalidation(settings)
|
2022-11-04 09:44:17 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
2020-06-15 13:20:48 +02:00
|
|
|
|
2023-02-20 17:12:38 +01:00
|
|
|
# @param setting [String]
|
|
|
|
# @param value [String]
|
|
|
|
def parse_value(setting, value)
|
|
|
|
return value unless %w[booking_window_start booking_window_end].include?(setting)
|
|
|
|
|
|
|
|
Time.zone.parse(value)
|
|
|
|
end
|
|
|
|
|
2022-11-04 09:44:17 +01:00
|
|
|
# rebuild the theme stylesheet
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def update_theme_stylesheet(settings)
|
|
|
|
return unless (%w[main_color secondary_color] & settings.map(&:name)).count.positive?
|
2022-11-04 09:44:17 +01:00
|
|
|
|
|
|
|
Stylesheet.theme&.rebuild!
|
|
|
|
end
|
|
|
|
|
2023-02-17 16:56:17 +01:00
|
|
|
# validate that the provided SCSS has a valid syntax
|
2023-02-20 17:12:38 +01:00
|
|
|
# @param setting [Hash{Symbol->String}]
|
2023-02-17 16:56:17 +01:00
|
|
|
def check_home_scss(setting)
|
|
|
|
return nil unless setting[:name] == 'home_css'
|
|
|
|
|
|
|
|
engine = SassC::Engine.new(".home-page { #{setting[:value]} }", style: :compressed)
|
|
|
|
engine.render
|
|
|
|
nil
|
|
|
|
rescue StandardError => e
|
|
|
|
e
|
|
|
|
end
|
|
|
|
|
2022-11-04 09:44:17 +01:00
|
|
|
# rebuild the home page stylesheet
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def update_home_stylesheet(settings)
|
|
|
|
return unless settings.any? { |s| s.name == 'home_css' }
|
2022-11-04 09:44:17 +01:00
|
|
|
|
|
|
|
Stylesheet.home_page&.rebuild!
|
|
|
|
end
|
2020-01-27 17:10:29 +01:00
|
|
|
|
|
|
|
# notify about a change in privacy policy
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def notify_privacy_update(settings)
|
|
|
|
return unless settings.any? { |s| s.name == 'privacy_body' }
|
2022-11-04 09:44:17 +01:00
|
|
|
|
2023-01-03 10:36:45 +01:00
|
|
|
setting = settings.find { |s| s.name == 'privacy_body' }
|
2022-11-04 09:44:17 +01:00
|
|
|
NotifyPrivacyUpdateWorker.perform_async(setting.id)
|
|
|
|
end
|
2020-06-09 14:27:18 +02:00
|
|
|
|
2021-06-04 18:26:20 +02:00
|
|
|
# sync all objects on stripe
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def sync_stripe_objects(settings)
|
|
|
|
return unless (%w[stripe_secret_key online_payment_module] & settings.map(&:name)).count.positive?
|
2022-11-04 09:44:17 +01:00
|
|
|
|
2023-01-03 10:36:45 +01:00
|
|
|
setting = settings.find { |s| s.name == 'stripe_secret_key' }
|
2022-11-04 09:44:17 +01:00
|
|
|
SyncObjectsOnStripeWorker.perform_async(setting.history_values.last&.invoicing_profile&.user&.id)
|
|
|
|
end
|
|
|
|
|
|
|
|
# generate the statistics since the last update
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def build_stats(settings)
|
|
|
|
return unless settings.any? { |s| s.name == 'statistics_module' && s.value == 'true' }
|
2020-06-17 12:20:51 +02:00
|
|
|
|
2023-01-03 10:36:45 +01:00
|
|
|
setting = settings.find { |s| s.name == 'statistics_module' }
|
2022-11-04 09:44:17 +01:00
|
|
|
PeriodStatisticsWorker.perform_async(setting.previous_update)
|
|
|
|
end
|
2022-04-20 17:43:38 +02:00
|
|
|
|
|
|
|
# export projects to openlab
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def export_projects_to_openlab(settings)
|
|
|
|
return unless (%w[openlab_app_id openlab_app_secret] & settings.map(&:name)).count.positive? &&
|
2022-11-04 09:44:17 +01:00
|
|
|
Setting.get('openlab_app_id').present? && Setting.get('openlab_app_secret').present?
|
|
|
|
|
2023-03-22 16:05:25 +01:00
|
|
|
Project.find_each(&:openlab_create)
|
2022-11-04 09:44:17 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# automatically validate the admins
|
2023-01-24 16:48:05 +01:00
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def validate_admins(settings)
|
|
|
|
return unless settings.any? { |s| s.name == 'user_validation_required' && s.value == 'true' }
|
2022-11-04 09:44:17 +01:00
|
|
|
|
2023-02-14 13:10:58 +01:00
|
|
|
User.admins.each { |admin| admin.update(validated_at: Time.current) if admin.validated_at.nil? }
|
2022-04-20 17:43:38 +02:00
|
|
|
end
|
2022-11-22 17:43:19 +01:00
|
|
|
|
2023-01-24 16:48:05 +01:00
|
|
|
# rebuild accounting lines
|
|
|
|
# @param settings [Array<Setting>]
|
2022-11-22 17:43:19 +01:00
|
|
|
def update_accounting_line(settings)
|
|
|
|
return unless settings.any? { |s| s.name.match(/^accounting_/) || s.name == 'advanced_accounting' }
|
|
|
|
|
|
|
|
AccountingWorker.perform_async(:all)
|
|
|
|
end
|
2023-01-24 16:48:05 +01:00
|
|
|
|
|
|
|
# update tranings auto_cancel parameters
|
|
|
|
# @param settings [Array<Setting>]
|
|
|
|
def update_trainings_auto_cancel(settings)
|
|
|
|
return unless settings.any? { |s| s.name.match(/^trainings_auto_cancel/) }
|
|
|
|
|
|
|
|
tac = settings.find { |s| s.name == 'trainings_auto_cancel' }
|
|
|
|
threshold = settings.find { |s| s.name == 'trainings_auto_cancel_threshold' }
|
|
|
|
deadline = settings.find { |s| s.name == 'trainings_auto_cancel_deadline' }
|
|
|
|
|
|
|
|
Training.find_each do |t|
|
2023-01-26 14:11:14 +01:00
|
|
|
Trainings::AutoCancelService.update_auto_cancel(t, tac, threshold, deadline)
|
2023-01-24 16:48:05 +01:00
|
|
|
end
|
|
|
|
end
|
2023-01-27 17:31:16 +01:00
|
|
|
|
|
|
|
# update trainings authorization parameters
|
|
|
|
# @param settings [Array<Setting>]
|
|
|
|
def update_trainings_authorization(settings)
|
|
|
|
return unless settings.any? { |s| s.name.match(/^trainings_authorization_validity/) }
|
|
|
|
|
|
|
|
authorization = settings.find { |s| s.name == 'trainings_authorization_validity' }
|
|
|
|
duration = settings.find { |s| s.name == 'trainings_authorization_validity_duration' }
|
|
|
|
|
|
|
|
Training.find_each do |t|
|
|
|
|
Trainings::AuthorizationService.update_authorization(t, authorization, duration)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# update trainings invalidation parameters
|
|
|
|
# @param settings [Array<Setting>]
|
|
|
|
def update_trainings_invalidation(settings)
|
|
|
|
return unless settings.any? { |s| s.name.match(/^trainings_invalidation_rule/) }
|
|
|
|
|
|
|
|
invalidation = settings.find { |s| s.name == 'trainings_invalidation_rule' }
|
|
|
|
duration = settings.find { |s| s.name == 'trainings_invalidation_rule_period' }
|
|
|
|
|
|
|
|
Training.find_each do |t|
|
|
|
|
Trainings::InvalidationService.update_invalidation(t, invalidation, duration)
|
|
|
|
end
|
|
|
|
end
|
2020-01-27 17:10:29 +01:00
|
|
|
end
|
|
|
|
end
|