
    	]j                     `   d Z ddlmZmZmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ  e
dddd       G d de             Z e
dddd       G d de             Z e
dddd       G d de             Z e
dddd       G d de             ZddZddZy) z
FSM Transitions for Project model.

This module defines declarative transitions for the Project entity,
replacing the previous signal-based approach with explicit, testable transitions.
    )AnyDictOptional)	load_func)settings)register_state_transition)ProjectStateChoices)get_or_infer_state)StateManager)ModelChangeTransitionTransitionContext)get_or_initialize_stateprojectproject_createdTF)triggers_on_createtriggers_on_updatec                   b    e Zd ZdZd	dee   defdZdedefdZ	dedefdZ
dedeeef   fdZy)
ProjectCreatedTransitionz
    Transition when a new project is created.

    This is the initial state transition that occurs when a project is
    first saved to the database.

    Trigger: Automatically on creation (triggers_on_create=True, triggers_on_update=False)
    Ncontextreturnc                 "    t         j                  S N)r	   CREATEDselfr   s     N/root/env/lib/python3.12/site-packages/label_studio/fsm/project_transitions.pyget_target_statez)ProjectCreatedTransition.get_target_state   s    "***    c                     | j                   S )z+Only execute on creation, never on updates.)is_creatingr   s     r   should_executez'ProjectCreatedTransition.should_execute"   s    r   c                      y)z,Return detailed reason for project creation.zProject created r   s     r   
get_reasonz#ProjectCreatedTransition.get_reason&   s     r   c                     |j                   }|j                  |j                  |j                  r|j                  ndt	        |j
                        dS )z
        Execute project creation transition.

        Args:
            context: Transition context containing project and user information

        Returns:
            Context data to store with the state record
        N)organization_idtitlecreated_by_idlabel_config_present)entityr&   r'   r(   boollabel_configr   r   r   s      r   
transitionz#ProjectCreatedTransition.transition*   sK     ..  '66]]6=6K6KW22QU$()=)=$>	
 	
r   r   )__name__
__module____qualname____doc__r   r   strr   r+   r!   r$   r   r   r.   r#   r   r   r   r      sd    +1B(C +s + &7  D  !"3 ! !
"3 
S#X 
r   r   project_in_progressc                   R    e Zd ZdZddee   defdZdedefdZdede	ee
f   fdZy)	ProjectInProgressTransitionz
    Transition when project moves to IN_PROGRESS state.

    Triggered when: First annotation is submitted on any task
    From: CREATED -> IN_PROGRESS
    Nr   r   c                 "    t         j                  S r   r	   IN_PROGRESSr   s     r   r   z,ProjectInProgressTransition.get_target_stateK       "...r   c                      y)Nz9Project moved to in progress - first annotation submittedr#   r   s     r   r$   z&ProjectInProgressTransition.get_reasonN   s    Jr   c                 h    |j                   }|j                  |j                  j                         dS N)r&   total_tasksr*   r&   taskscountr-   s      r   r.   z&ProjectInProgressTransition.transitionQ   .    ..&66"==..0
 	
r   r   r/   r0   r1   r2   r   r   r3   r   r$   r   r   r.   r#   r   r   r6   r6   B   sS    /1B(C /s /K"3 K K
"3 
S#X 
r   r6   project_completedc                   R    e Zd ZdZddee   defdZdedefdZdede	ee
f   fdZy)	ProjectCompletedTransitionz
    Transition when project moves to COMPLETED state.

    Triggered when: All tasks in project are COMPLETED
    From: IN_PROGRESS -> COMPLETED
    Nr   r   c                 "    t         j                  S r   )r	   	COMPLETEDr   s     r   r   z+ProjectCompletedTransition.get_target_stateb   s    ",,,r   c                      y)Nz'Project completed - all tasks completedr#   r   s     r   r$   z%ProjectCompletedTransition.get_reasone   s    8r   c                 h    |j                   }|j                  |j                  j                         dS r=   r?   r-   s      r   r.   z%ProjectCompletedTransition.transitionh   rB   r   r   rC   r#   r   r   rF   rF   Y   sP    -1B(C -s -9"3 9 9
"3 
S#X 
r   rF   "project_in_progress_from_completedc                   R    e Zd ZdZddee   defdZdedefdZdede	ee
f   fdZy)	(ProjectInProgressFromCompletedTransitionz
    Transition when project moves back to IN_PROGRESS from COMPLETED.

    Triggered when: Any task becomes not COMPLETED (e.g., annotations deleted)
    From: COMPLETED -> IN_PROGRESS
    Nr   r   c                 "    t         j                  S r   r8   r   s     r   r   z9ProjectInProgressFromCompletedTransition.get_target_state{   r:   r   c                      y)Nz:Project moved back to in progress - task became incompleter#   r   s     r   r$   z3ProjectInProgressFromCompletedTransition.get_reason~   s    Kr   c                 h    |j                   }|j                  |j                  j                         dS r=   r?   r-   s      r   r.   z3ProjectInProgressFromCompletedTransition.transition   rB   r   r   rC   r#   r   r   rM   rM   p   sS    /1B(C /s /L"3 L L
"3 
S#X 
r   rM   Nc                    t        j                  |       }t        |       }|t        | ||       y ||k7  r|t        j
                  k(  rY|t        j                  k(  rt        j                  | d|       y |t        j                  k(  rt        j                  | d|       y y |t        j                  k(  rt        j                  | d|       y y y )N)userinferred_stater4   )r*   transition_namerR   rK   rD   )	r   get_current_state_valuer
   r   r	   r9   r   execute_transitionrH   )r   rR   reasoncontext_datacurrent_staterS   s         r   sync_project_staterZ      s     88AM'0Nd>R&0<<< 3 ; ;;//wPelpq"5"?"??//"4X_c @ 2<<<++7L_fjk = 'r   c                 F    t        t        j                        } || |      S r   )r   r   FSM_SYNC_PROJECT_STATE)r   rR   update_funcs      r   &update_project_state_after_task_changer^      s    H;;<Kw%%r   )NNNr   )r2   typingr   r   r   core.utils.commonr   django.confr   fsm.registryr   fsm.state_choicesr	   fsm.state_inferencer
   fsm.state_managerr   fsm.transitionsr   r   	fsm.utilsr   r   r6   rF   rM   rZ   r^   r#   r   r   <module>rh      s    ' & '   2 1 2 * D - 9&7Dejk&
4 &
 l&
Z 9&;PUjop
"7 
 q
, 9&9ehmn
!6 
 o
, 3bg
/D 

,l*&r   