Fix assignment sync to new protocol drafts and deletion [SCI-8060]

This commit is contained in:
Martin Artnik 2023-03-06 16:06:38 +01:00
parent 73ed75a73a
commit cfcb80f642
4 changed files with 56 additions and 31 deletions

View file

@ -46,6 +46,16 @@ module UserAssignments
end
def assign_users_to_protocol(protocol)
if protocol.parent_id && protocol.in_repository_draft?
Protocol.transaction(requires_new: true) do
protocol.parent.user_assignments.find_each do |user_assignment|
protocol.parent.sync_child_protocol_user_assignment(user_assignment, protocol.id)
end
end
return
end
return unless protocol.visible?
protocol.create_public_user_assignments!(@assigned_by)

View file

@ -58,13 +58,13 @@ module Assignable
self.class.name.in?(Extends::TOP_LEVEL_ASSIGNABLES)
end
def after_user_assignment_save
# Optional, redefine in the assignable model.
# Will be called when an assignment is saved for the assignable model.
end
private
def after_user_assignment_changed(user_assignment = nil)
# Optional, redefine in the assignable model.
# Will be called when an assignment is changed (save/destroy) for the assignable model.
end
def create_users_assignments
return if skip_user_assignments

View file

@ -17,7 +17,6 @@ class Protocol < ApplicationRecord
include TinyMceImages
after_create :auto_assign_protocol_members, if: :visible?
after_create :sync_child_protocol_user_assignments, unless: -> { parent_id }
after_destroy :decrement_linked_children
after_save :update_user_assignments, if: -> { saved_change_to_visibility? && in_repository? }
after_save :update_linked_children
@ -685,33 +684,48 @@ class Protocol < ApplicationRecord
end
end
def after_user_assignment_save
sync_child_protocol_user_assignments
def child_version_protocols
published_versions.or(Protocol.where(id: draft&.id))
end
def sync_child_protocol_user_assignment(user_assignment, child_protocol_id = nil)
# Copy user assignments to child protocol(s)
Protocol.transaction(requires_new: true) do
# Reload to ensure a potential new draft is also included in child versions
reload
(
# all or single child version protocol
child_protocol_id ? child_version_protocols.where(id: child_protocol_id) : child_version_protocols
).find_each do |child_protocol|
child_assignment = child_protocol.user_assignments.find_or_initialize_by(
user: user_assignment.user
)
if user_assignment.destroyed?
child_assignment.destroy! if child_assignment.persisted?
next
end
child_assignment.update!(
user_assignment.attributes.slice(
'user_role_id',
'assigned',
'assigned_by_id',
'team_id'
)
)
end
end
end
private
def sync_child_protocol_user_assignments
# Copy user assignments to child protocols
def after_user_assignment_changed(user_assignment)
return unless in_repository_published_original?
return if parent_id
Protocol.transaction do
user_assignments.find_each do |user_assignment|
linked_children.find_each do |child_protocol|
child_protocol.user_assignments.find_or_initialize_by(
user: user_assignment.user
).update!(
user_assignment.attributes.slice(
'user_role_id',
'assigned',
'assigned_by_id',
'team_id'
)
)
end
end
end
sync_child_protocol_user_assignment(user_assignment)
end
def auto_assign_protocol_members

View file

@ -7,7 +7,8 @@ class UserAssignment < ApplicationRecord
after_create :assign_team_child_objects, if: -> { assignable.is_a?(Team) }
after_update :update_team_children_assignments, if: -> { assignable.is_a?(Team) && saved_change_to_user_role_id? }
before_destroy :unassign_team_child_objects, if: -> { assignable.is_a?(Team) }
after_save :call_user_assignment_save_hook
after_destroy :call_user_assignment_changed_hook
after_save :call_user_assignment_changed_hook
belongs_to :assignable, polymorphic: true, touch: true
belongs_to :user_role
@ -25,8 +26,8 @@ class UserAssignment < ApplicationRecord
private
def call_user_assignment_save_hook
assignable.after_user_assignment_save
def call_user_assignment_changed_hook
assignable.__send__(:after_user_assignment_changed, self)
end
def assign_team_child_objects