mirror of
				https://github.com/scinote-eln/scinote-web.git
				synced 2025-11-04 03:59:08 +08:00 
			
		
		
		
	Fix assignment sync to new protocol drafts and deletion [SCI-8060]
This commit is contained in:
		
							parent
							
								
									73ed75a73a
								
							
						
					
					
						commit
						cfcb80f642
					
				
					 4 changed files with 56 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue