|
class CourseTransfer |
|
attr_reader :course, :from_organization, :to_organization, :options, :logger |
|
|
|
# options |
|
# - transfer_delegations: Boolean |
|
# - transfer_assignments: Boolean |
|
# - transfer_completions: Boolean |
|
# - owner_group_id: Integer |
|
def initialize(course, options = {}) |
|
@course = course |
|
@from_organization = options.fetch(:from_organization) |
|
@to_organization = options.fetch(:to_organization) |
|
@options = options |
|
@logger = options.fetch(:logger) { Logger.new(STDOUT) } |
|
end |
|
|
|
def call |
|
ActiveRecord::Base.transaction do |
|
store_course_previous_state |
|
|
|
update_categories |
|
transfer_course! |
|
transfer_badge! |
|
transfer_delegations! |
|
transfer_assignments! |
|
transfer_chapter_completions! |
|
|
|
check_course_integrity |
|
end |
|
end |
|
|
|
def store_course_previous_state |
|
pp @original_state = { |
|
categories: course.categories.count, |
|
approver: course.approver&.full_name, |
|
editors: course.editors.count, |
|
assignments: course.assignments.count, |
|
badge: course.badge.title, |
|
scope: course.organization.name |
|
} |
|
end |
|
|
|
def check_course_integrity |
|
course.reload |
|
|
|
pp new_state = { |
|
categories: course.categories.count, |
|
approver: course.approver&.full_name, |
|
editors: course.editors.count, |
|
assignments: course.assignments.count, |
|
badge: course.badge.title, |
|
scope: course.organization.name |
|
} |
|
|
|
success =( |
|
@original_state[:categories] == new_state[:categories] && |
|
@original_state[:badge] == new_state[:badge] && |
|
true |
|
) |
|
|
|
raise 'Error!' unless success |
|
end |
|
|
|
private |
|
|
|
def update_categories |
|
new_categories = course.categories.map { |category| to_organization.training_categories.find_or_create_by(title: category.title) } |
|
course.update!(categories: new_categories) |
|
logger.info ">>> set new categories #{new_categories.map(&:title)}" |
|
end |
|
|
|
def transfer_course! |
|
update_params = { |
|
scope_id: to_organization.id, |
|
owner_id: options.fetch(:owner_group_id) |
|
} |
|
course.update!(update_params) |
|
logger.info ">>> transfer course #{course.id}" |
|
end |
|
|
|
def transfer_badge! |
|
new_badge = to_organization.training_badges.find_by!( |
|
title: course.badge.title |
|
) |
|
course.update!(badge_id: new_badge.id) |
|
logger.info ">>> sync badge #{new_badge.id}" |
|
end |
|
|
|
def transfer_assignments! |
|
assignments = Training::Course::Assignment.where(course_id: course.id) |
|
if options.fetch(:transfer_assignments, true) |
|
assignments.each(&method(:transfer_assignment!)) |
|
else |
|
logger.info ">>>>>> destroying assignments #{assignments.pluck(:id)}" |
|
assignments.destroy_all |
|
end |
|
end |
|
|
|
def transfer_assignment!(assignment) |
|
assignment.group_assignments.each do |ga| |
|
new_group = to_organization.groups.find_by!(import_id: ga.group.import_id) |
|
|
|
ga.update!(group_id: new_group.id) |
|
end |
|
|
|
assignment.position_assignments.each do |pa| |
|
position_name = "#{from_organization.name} #{pa.position.name}".gsub(/OLD /, '').gsub(/Old-/, '') |
|
puts ">>> #{position_name}" |
|
if position_name =~ /All Positions/ |
|
new_position = to_organization.default_position |
|
else |
|
new_position = to_organization.positions.find_by!(name: position_name) |
|
end |
|
|
|
pa.update!(position_id: new_position.id) |
|
end |
|
logger.info ">>>>>> assigment #{assignment.id} transfered" |
|
end |
|
|
|
def transfer_delegations! |
|
if options.fetch(:transfer_delegations, true) |
|
course.delegations.each do |delegation| |
|
new_user = to_organization.users.find_by!( |
|
employee_number: delegation.user.employee_number |
|
) |
|
delegation.update!(user_id: new_user.id) |
|
end |
|
else |
|
logger.info ">>>> destroying delegations #{course.delegations.pluck(:id)}" |
|
course.delegations.destroy_all |
|
end |
|
end |
|
|
|
def transfer_chapter_completions! |
|
from_chapter_ids = Training::Course::Chapter.where(course: course).pluck(:id) |
|
|
|
chapter_completions = Training::Course::Chapter::Completion.where(chapter_id: from_chapter_ids) |
|
|
|
if options.fetch(:transfer_completions, false) |
|
chapter_completions.each(&method(:transfer_chapter_completion!)) |
|
logger.info ">>>> transfering #{chapter_completions.count} completions" |
|
else |
|
chapter_completions.destroy_all |
|
logger.info ">>>> destroying #{chapter_completions.count} completions" |
|
end |
|
end |
|
|
|
def transfer_chapter_completion!(completion) |
|
completion.update!( |
|
user_id: to_organization.users.find_by!( |
|
employee_number: completion.user.employee_number |
|
).id |
|
) |
|
end |
|
|
|
end |
|
|
|
def transfer_courses(from_organization:, to_organization:, course_ids: nil) |
|
course_ids ||= from_organization.training_courses.pluck(:id) |
|
|
|
options = { |
|
transfer_completions: true, |
|
transfer_delegations: true, |
|
transfer_assignments: true, |
|
course_ids: course_ids, |
|
from_organization: from_organization, |
|
to_organization: to_organization, |
|
owner_group_id: from_organization.default_group.id |
|
} |
|
|
|
success = 0 |
|
|
|
begin |
|
courses = from_organization.training_courses.find(options[:course_ids]) |
|
puts ">>> courses to transfer #{courses.count}" |
|
|
|
courses.each do |course| |
|
transfer = CourseTransfer.new(course, options) |
|
begin |
|
transfer.call |
|
success += 1 |
|
rescue => e |
|
puts e.message |
|
pp e.backtrace |
|
end |
|
end |
|
rescue ActiveRecord::RecordNotFound |
|
puts ">>> no courses found in organization #{from_organization.name} "\ |
|
"with ID #{course_ids}" |
|
end |
|
|
|
puts ">>>> #{success} courses transfered" |
|
end |
|
|
|
varner = find_organization('varner') |
|
cubus = UsersSystem::Organization.with_identifier_name('old-cubus') |
|
dressmann = UsersSystem::Organization.with_identifier_name('old-dressmann') |
|
|
|
# transfer_courses(from_organization: cubus, to_organization: varner) |
|
# transfer_courses(from_organization: dressmann, to_organization: varner) |