Skip to content

Instantly share code, notes, and snippets.

@fmundaca
Created May 17, 2021 16:54
Show Gist options
  • Save fmundaca/c9178041b8635f356c527b1ae27ea067 to your computer and use it in GitHub Desktop.
Save fmundaca/c9178041b8635f356c527b1ae27ea067 to your computer and use it in GitHub Desktop.
# Creado por: Rankmi
# Fecha: <b>24 enero 2016</b>
# Servicio que crea/actualiza un usuario con los datos básicos.
module ManageCollaborators
class CreateCollaborator < RankmiBaseService
include ::Concerns::ServiceHelper
include ::Concerns::FamilyGoalsAdministrable
attr_accessor :enterprise_area, :area_slug, :user_data, :direct_manager,
:user, :process, :survey, :survey_id, :from_master, :massive
def initialize(user:, process: nil, survey: nil, from_master: false)
@user = user
@process = process
@survey = survey
@survey_id = survey.nil? ? nil : survey.id
@from_master = from_master
@direct_manager = nil
end
# Crea un usuario con los parámetros básicos.
# <b>Área</b, <b>username</b> e <b>identificados</b> son requeridos
# Recibe como parámetro un hash que contiene los datos necesarios del usuario
# En caso de errores retornará los errores estándar con contexto apropiado para saber que puede estar pasando
def create(args = {}, massive = false)
@massive = massive
self.user_data = args
account = {}
unless from_master
return area_not_found(user_data[:area]) if user_data[:area].nil?
self.area_slug = user_data[:area].to_s.str_slug
end
valid_fields = validate_fields
return valid_fields if valid_fields.respond_to?(:missing_parameters?) ||
valid_fields.respond_to?(:malformed_field?)
unless from_master
load_enterprise_area
return area_not_found(user_data[:area]) if enterprise_area.nil?
end
ActiveRecord::Base.transaction(requires_new: true) do
user_identifier = user_data[:identifier].to_s.clean_identifier
@user_to_save = User.find_by(identifier: user_identifier)
is_new_user = @user_to_save.nil?
return forbidden_resource('Usuario pertenece a otra empresa') if !is_new_user && (@user_to_save.enterprise.id != user.enterprise.id)
if is_new_user
ActiveRecord::Base.transaction do
@user_to_save = user.enterprise.users.create!(identifier: user_identifier) if is_new_user
@user_to_save.save_account(args)
rescue
raise ActiveRecord::Rollback, "Call tech support!"
end
else
@user_to_save.save_account(args)
end
if !is_new_user && @user_to_save.account.present? && !@user_to_save.account.tokens.empty?
@user_to_save.account.update_attribute(:tokens, {})
end
if user_data.include?('manager_identifier')
is_valid_direct_manager = valid_direct_manager(manager_identifier: user_data[:manager_identifier],
identifier: user_data[:identifier])
return is_valid_direct_manager if is_valid_direct_manager.respond_to?(:malformed_field?)
@user_to_save.direct_manager = direct_manager
end
create_or_update_profile
create_or_update_email(is_new_user)
create_or_update_lang
create_or_update_birthdate
create_or_update_joiningdate
create_or_update_demographic
create_or_update_position
create_or_update_status
# RKM-5146 @jhony.acevedo: Add optional fields
update_from_master(user_data, from_master)
@user_to_save.exclude_search = user_data[:exclude_search].present?
begin
@user_to_save.save!
rescue StandardError
error_msg = @user_to_save.errors.full_messages.map(&:message).join(", ")
raise ActiveRecord::RecordNotSaved.new("Problem saving user: #{error_msg}")
end
# TODO: Tirar a background?
create_or_update_user_area(current_user: user,
user_to_save: @user_to_save) unless from_master
create_or_update_subdomain(is_new_user: is_new_user)
# TODO: Tirar a background?
create_family_competence
User.logger_info(user.id,
@user_to_save.id,
@user_to_save.previous_changes,
is_new_user ? UserChangesLog::USER_CREATE : UserChangesLog::USER_INFORMATION_CHANGE)
return ImmutableStruct.new(:user, :is_new_user).new(user: @user_to_save,
is_new_user: is_new_user)
end
error_on_save('user', @user_to_save.errors.full_messages)
rescue StandardError => e
process_exception(e)
end
def create_or_update_profile
profile = @user_to_save.profile || @user_to_save.build_profile
profile.assign_attributes(user_profile_attributes)
profile.save!
end
def user_profile_attributes
permit_user_data = user_data.is_a?(Hash) ? user_data : user_data.to_unsafe_hash
permit_user_data.with_indifferent_access.slice(*::UserProfile.attributes).compact
end
#
def is_datetime(d)
d.methods.include? :strftime
end
# @falvarado
# RKM-3596 => refactor the method to convert it into a class one. Sidekieable
def create_or_update_user_area(current_user:, user_to_save:)
user_to_save.enterprise_areas << enterprise_area && return if user_to_save.id.nil?
# RKM-3112
# @falvarado: instead of delete the user_areas for the current process/survey we'll try to
# replace the old enterprise_area_id update_user_area
if survey.nil? || survey.respond_to?(:survey_not_found)
current_area = user_to_save.enterprise_areas.find_by(enterprise_process_id: process.id)
else
current_area = user_to_save.enterprise_areas.find_by(survey_id: @survey_id)
end
if current_area.nil?
user_to_save.user_enterprise_areas.create(enterprise_area_id: enterprise_area.id)
else
current_user_enterprise_areas = user_to_save.user_enterprise_areas.find_by(enterprise_area_id: current_area.id)
current_user_enterprise_areas.enterprise_area_id = enterprise_area.id
current_user_enterprise_areas.save!
end
logger_change_area_user(current_user_id: current_user.id,
user_id: user_to_save.id)
enterprise_area.touch unless @massive
end
def logger_change_area_user(current_user_id:, user_id:)
current_user = User.find(current_user_id)
user = User.find(user_id)
enterprise_areas = if survey.respond_to?(:survey_not_found)
user.enterprise_areas.select(:id).where(enterprise_process_id: process.id)
else
user.enterprise_areas.select(:id).where(survey_id: @survey_id)
end
# logger cambio de area
return if enterprise_areas.include?(enterprise_area)
old_area = user.enterprise_areas.find_by(id: enterprise_areas)
old_area = old_area.present? ? old_area.name : nil
current_user.logger_info(user,
{ enterprise_area: [old_area, enterprise_area.name] },
UserChangesLog::USER_AREA_CHANGE,
process.id,
@survey_id)
end
private
def update_from_master(user_data, from_master)
return unless from_master
# if from_master
@user_to_save.area = user_data[:area] if user_data[:area].present?
@user_to_save.function = user_data[:function] if user_data[:function].present?
@user_to_save.unit = user_data[:unit] if user_data[:unit].present?
# end
end
def create_or_update_demographic
@user_to_save.name = user_data[:firstname] if user_data[:firstname].present?
@user_to_save.lastname = user_data[:lastname] if user_data[:lastname].present?
@user_to_save.middle_name = user_data[:middlename] if user_data[:middlename].present?
@user_to_save.mothers_name = user_data[:mothername] if user_data[:mothername].present?
@user_to_save.gender = user_data[:gender].to_s.downcase if user_data[:gender].present?
@user_to_save.phone = user_data[:phone].to_s.clean_identifier if user_data[:phone].present?
@user_to_save.address = user_data[:address] if user_data[:address].present?
@user_to_save.rut = user_data[:rut].to_s.clean_identifier if user_data[:rut].present?
end
def create_or_update_subdomain(is_new_user:)
return if user_data[:subdomain].nil? && !is_new_user
subdomain = user_data[:subdomain].present? ?
user.enterprise.enterprise_login_informations.find_by(custom_domain: user_data[:subdomain].to_s.downcase) :
user.enterprise.enterprise_login_informations.find_by(default: true)
# si el subdominio no es encontrado entonces se debe asignar el por defecto.
if subdomain.nil?
subdomain = user.enterprise.enterprise_login_informations.find_by(default: true)
end
user_enterprise_login = UserEnterpriseLogin.find_or_create_by(user: @user_to_save)
user_enterprise_login.enterprise_login_information = subdomain
user_enterprise_login.save
end
def create_or_update_email(is_new_user)
if is_new_user
if user_data[:email].blank?
subdomain = user_data[:subdomain].present? ?
user_data[:subdomain] :
user.enterprise.enterprise_login_informations.find_by(default: true)[:custom_domain]
@user_to_save.enable_fake_email(email: "#{user_data[:identifier]}@#{subdomain}.com")
else
@user_to_save.disable_fake_email(email: user_data[:email].to_s.downcase)
end
else
if (@user_to_save.email != user_data[:email]) && !user_data[:email].blank?
@user_to_save.disable_fake_email(email: user_data[:email].to_s.downcase)
elsif user_data[:email].blank? && @user_to_save.email.blank?
subdomain = user_data[:subdomain].present? ?
user_data[:subdomain] :
user.enterprise.enterprise_login_informations.find_by(default: true)[:custom_domain]
@user_to_save.enable_fake_email(email: "#{user_data[:identifier]}@#{subdomain}.com")
end
end
end
def create_family_competence
return unless user_data[:family_competence].present?
family_competence = user.enterprise.family_competences.find_by(id: user_data[:family_competence][:id])
user_family_competence = UserFamilyCompetence.find_or_create_by(user: @user_to_save,
enterprise_process: process)
user_family_competence.family_competence = family_competence
user_family_competence.save
end
def create_or_update_birthdate
return unless user_data[:birthdate].present?
@user_to_save.birthdate = user_data[:birthdate].is_a?(Numeric) ? Time.at(user_data[:birthdate].to_i) : user_data[:birthdate]
end
def create_or_update_joiningdate
return unless user_data[:joiningdate].present?
@user_to_save.joining_date = user_data[:joiningdate].is_a?(Numeric) ? Time.at(user_data[:joiningdate].to_i) : user_data[:joiningdate]
end
def create_or_update_lang
unless user_data[:idioma].nil?
@user_to_save.lang = user_data[:idioma].downcase
end
unless user_data[:lang].nil?
@user_to_save.lang = user_data[:lang].downcase
end
end
def create_or_update_position
return if user_data[:position].nil? && user_data[:position_id].nil?
@user_to_save.enterprise_position_id = if user_data[:position_id].present?
EnterprisePosition.find!(user_data[:position_id])
elsif user_data[:position].present?
position = EnterpriseServices::Positions::Create.new(enterprise: @user.enterprise,
params: { name: user_data[:position] }).perform
position.id
end
end
def load_enterprise_area
self.enterprise_area = user.enterprise.enterprise_areas.find_by(slug: self.area_slug,
enterprise_process_id: process.id,
survey_id: survey_id)
end
def validate_fields
missing_parameters('Área no puede estar vacío') if user_data[:area].nil? && !from_master
end
# RKM-5142 Jonathan Rojas 21-01-2019
def valid_direct_manager(identifier:, manager_identifier:)
if manager_identifier.blank?
self.direct_manager = nil
return
end
self.direct_manager = user.enterprise.users.find_by(identifier: manager_identifier.to_s.clean_identifier)
unless direct_manager.present?
malformed_field('manager_identifier', "El identificador del manager no existe: #{manager_identifier} ")
end
if manager_identifier.eql?(identifier)
malformed_field('manager_identifier', "No puede ser manager si mismo: #{manager_identifier} ")
end
end
def create_or_update_status
if user_data[:status].present?
status = change_status_value(user_data[:status].downcase.strip)
unless status.nil?
if @user_to_save.user_account.present?
@user_to_save.user_account.update!(active: status)
end
end
end
end
def change_status_value(status)
status === "desactivado" ? false : status === "activo" ? true : nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment