
    7>hA                     z   d dl mZ d dlmZmZ d dlmZmZmZmZ d dl	m
Z
mZmZmZ d dlZd dlZd dlmZmZmZ d dlmZ  ej,                  e      Zded	efd
Z e ej6                  dd             e ej6                  dd            dd e ej6                  dd             e ej6                  dd            dd e ej6                  dd             e ej6                  dd            dddZdeded	efdZdedej@                  ded	efdZ!dededejD                  ded	ef
d Z#deded	eeef   fd!Z$	 	 	 d/dedee   d"ee   d#ee   d	e
eeef      f
d$Z%deded	efd%Z&ded	eeef   fd&Z'ded'e
e   d(eeef   ded	eeef   f
d)Z(	 d0ded*ed+ee   d	e
eeef      fd,Z)ded-ed	e
eeef      fd.Z*y)1    )Session)HTTPExceptionstatus)datetimetime	timedeltadate)ListDictAnyOptionalN)AdvisorAdvisorScheduleUser)schemastime_strreturnc                 ^    t        t        | j                  d            \  }}t        ||      S )z0Parse time string in format HH:MM to time object:)mapintsplitr   )r   hoursminutess      O/var/www/html/DP/alpha_backend/app/advisor_service/services/schedule_service.py
parse_timer      s(    hnnS12NE7w    SHIFT_1_STARTz09:00SHIFT_1_ENDz17:00zMorning Shift)startendnameSHIFT_2_STARTSHIFT_2_ENDz01:00zEvening ShiftSHIFT_3_STARTSHIFT_3_ENDzNight Shift)SHIFT_1SHIFT_2SHIFT_3
advisor_iddbc                 H   	 t        j                         }|j                         }|j                         }|j	                  t
              j                  t
        j                  | k(  t
        j                  |k  t
        j                  |k\        j                         }|syt        j                  |j                        }|sy|d   }|d   }||kD  r||k\  xs ||k  S ||cxk  xr |k  S c S # t        $ r+}	t        j!                  dt#        |	              Y d}	~	yd}	~	ww xY w)z
    Check if an advisor is currently in their scheduled shift
    
    Args:
        advisor_id: ID of the advisor to check
        db: Database session
        
    Returns:
        bool: True if advisor is in shift, False otherwise
    Fr    r!   z'Error checking if advisor is in shift: N)r   nowr   r	   queryr   filterr*   shift_period_startshift_period_endfirstSHIFTSgetshift	Exceptionloggererrorstr)
r*   r+   r-   current_timecurrent_dateschedule
shift_infoshift_start	shift_endes
             r   is_advisor_in_shiftrA   $   s    llnxxzxxz 88O,33&&*4..,>,,<
 %'	 	  ZZ/
 )u%	 ";.K,)2KK,;);;;; >s1vhGHs0   BC-  !C- C- C- *C- -	D!6!DD!schedule_data
manager_idc                 $   | j                  t              j                  t        j                  |j                  k(        j                         }|st        dd      | j                  t              j                  t        j                  |j                  k(  t        j                  |j                  k  t        j                  |j                  k\        j                         }|r!| j                  |       | j                          t        |j                  ||j                  |j                  |j                  |j                        }| j                  |       | j                          | j                  |       t!        | |j                         |S )a(  
    Create a new schedule for an advisor
    If there's an overlapping schedule, it will be overridden
    
    Args:
        db: Database session
        schedule_data: Schedule data
        manager_id: ID of the manager creating the schedule
        
    Returns:
        Created schedule
      zAdvisor not foundstatus_codedetail)r*   shift_setup_byr0   r1   r5   advisor_status)r.   r   r/   idr*   r2   r   r   r0   r1   deletecommitr5   rJ   addrefreshupdate_advisor_status)r+   rB   rC   advisoroverlapping_scheduledb_schedules         r   create_advisor_schedulerT   Q   s;   $ hhw&&wzz]5M5M'MNTTVG4GHH 88O4;;""m&>&>>**m.L.LL((M,L,LL eg	  
		&'
		 " ++!(;;&77!!$33K FF;IIKJJ{ "m667r   schedule_idc                 @   | j                  t              j                  t        j                  |k(        j	                         }|st        dd      |j                  |j                  |_        |j                  |j                  |_        |j                  |j                  |_        |j                  |j                  |_	        ||_
        t        j                         |_        | j                          | j                  |       t!        | |j"                         |S )a#  
    Update an existing advisor schedule
    
    Args:
        db: Database session
        schedule_id: ID of the schedule to update
        schedule_data: Updated schedule data
        manager_id: ID of the manager updating the schedule
        
    Returns:
        Updated schedule
    rE   Schedule not foundrF   )r.   r   r/   rK   r2   r   r0   r1   r5   rJ   rI   r   utcnow
updated_onrM   rO   rP   r*   )r+   rU   rB   rC   rS   s        r   update_advisor_schedulerZ      s    & ((?+22?3E3E3TU[[]K4HII ''3)6)I)I&%%1'4'E'E$&)//##/%2%A%A" ",K%__.KIIKJJ{ "k445r   c                     | j                  t              j                  t        j                  |k(        j	                         }|st        dd      |j                  }| j                  |       | j                          t        | |       ddiS )z
    Delete an advisor schedule
    
    Args:
        db: Database session
        schedule_id: ID of the schedule to delete
        
    Returns:
        Success message
    rE   rW   rF   messagezSchedule deleted successfully)
r.   r   r/   rK   r2   r   r*   rL   rM   rP   )r+   rU   rS   r*   s       r   delete_advisor_scheduler]      s|     ((?+22?3E3E3TU[[]K4HII''J IIkIIK "j)677r   
start_dateend_datec                    | j                  t              j                  t        t        j                  t        j
                  k(  d      j                  t        j                  j                  d      t        j                  j                  d            }|r"|j                  t        j                  |k(        }|r"|j                  t        j                  |k\        }|r"|j                  t        j                  |k        }|j                  t        j                        }g }|j                         D ]  }|d   }|j                  }|j                   }	|j#                  |j
                  |j                  ||	|j                  |j                  |j$                  |j&                  |j(                  |j*                  d
        |S )af  
    Get advisor schedules with optional filtering, including advisor details
    
    Args:
        db: Database session
        advisor_id: Optional advisor ID to filter by
        start_date: Optional start date to filter by
        end_date: Optional end date to filter by
        
    Returns:
        List of advisor schedules with advisor details
    T)isouteradvisor_nameadvisor_typer   )
rK   r*   rb   rc   r0   r1   rJ   r5   
created_atrY   )r.   r   joinr   r*   rK   add_columns	full_namelabeltyper/   r1   r0   order_byallrb   rc   appendrJ   r5   rd   rY   )
r+   r*   r^   r_   r.   resultsrowr<   rb   rc   s
             r   get_advisor_schedulesro      sr   & 	!	&&'**4 
 


 
##N3LL~.

 
 _77:EF_==KL_??8KL NN?==>E Gyy{q6''''++"--(("*"="= ( 9 9&55^^"--"--
 	 $ Nr   c                     	 t        ||       }| j                  t              j                  t        j                  |k(        j                         }|st        j                  d| d       y|r| j                  t              j                  t        j                  |k(  t        j                  t        j                         j                         k  t        j                  t        j                         j                         k\        j                         }|r|j                  rd|_        nd|_        nd|_        |j"                  r`| j                  t$              j                  t$        j                  |j"                  k(        j                         }|r|j                   |_        | j'                          |S # t(        $ r;}t        j                  dt+        |              | j-                          Y d}~yd}~ww xY w)z
    Update an advisor's status based on their current schedule
    
    Args:
        db: Database session
        advisor_id: ID of the advisor to update
        
    Returns:
        bool: True if advisor is in shift, False otherwise
    zAdvisor with ID z
 not foundF10zError updating advisor status: N)rA   r.   r   r/   rK   r2   r7   r8   r   r*   r0   r   r-   r	   r1   rJ   r   user_idr   rM   r6   r9   rollback)r+   r*   in_shiftrQ   r<   userr@   s          r   rP   rP     sw   &&z26 ((7#**7::+CDJJLLL+J<zBC xx077**j822hlln6I6I6KK00HLLN4G4G4II eg	  H33!$!$ GN ??88D>((GOO)CDJJLD%nn
		 6s1vh?@
s   A*F9 -EF9 9	G=1G88G=c                 x   	 | j                  t              j                         }d}d}d}|D ]*  }t        | |j                        }|dz  }|r|dz  }&|dz  }, d|||dS # t
        $ rO}t        j                  dt        |              | j                          t        ddt        |             d	}~ww xY w)
z
    Refresh the status of all advisors based on their schedules
    
    Args:
        db: Database session
        
    Returns:
        Summary of updates
    r      zAll advisor statuses refreshed)r\   total_updatedonlineofflinez'Error refreshing all advisor statuses: i  z#Error refreshing advisor statuses: rF   N)r.   r   rk   rP   rK   r6   r7   r8   r9   rt   r   )r+   advisorsupdated_countonline_countoffline_countrQ   ru   r@   s           r   refresh_all_advisor_statusesr   F  s    
88G$((*G,R<HQM!"   8*"$	
 	
  
>s1vhGH
8QA
 	

s   AA! !	B9*A
B44B9advisor_idsbase_schedulec                 "   g g d}|D ]N  }	 i |d|i}t        j                  di |}t        | ||      }|d   j                  ||j                  d       P |S # t
        $ r*}	|d   j                  |t        |	      d       Y d}	~	d}	~	ww xY w)	aD  
    Create schedules for multiple advisors at once
    
    Args:
        db: Database session
        advisor_ids: List of advisor IDs
        base_schedule: Base schedule data (without advisor_id)
        manager_id: ID of the manager creating the schedules
        
    Returns:
        Summary of created schedules
    )successfailedr*   r   )r*   rU   r   )r*   r8   N )r   AdvisorScheduleCreaterT   rl   rK   r6   r9   )
r+   r   r   rC   rm   r*   rB   schedule_creater<   r@   s
             r   create_bulk_advisor_schedulesr   p  s    & G
 "
	G}GlJGM%;;LmLO /r?JOH I%%('{{'  ", N  	H$$(Q&  	s   AA	B$ B		Br5   
check_datec                 @   |"t        j                         j                         }t        j                  |t         j                  j                               }| j                  t              j                  t        j                  |k(  t        j                  |k  t        j                  |k\  t        j                  dk(        j                         }g }|D ]  }| j                  t              j                  t        j                  |j                   k(        j#                         }|sS|j%                  |j                  |j&                  |j(                  |j*                  |j,                  |j                  |j                  |j                  |j                  d	        |S )a(  
    Get all advisors scheduled for a specific shift on a given date
    
    Args:
        db: Database session
        shift: Shift identifier (e.g., "SHIFT_1")
        check_date: Date to check (defaults to today)
        
    Returns:
        List of advisors with their schedule details
    T)	r*   rg   emailphone_numberr   rU   r5   r0   r1   )r   r-   r	   combineminr   r.   r   r/   r5   r0   r1   rJ   rk   r   rK   r*   r2   rl   rg   r   r   r   )r+   r5   r   check_datetime	schedulesresultr<   rQ   s           r   get_advisors_by_shiftr     sH   " \\^((*
 %%j(,,2C2C2EFN )00&**n<((N:&&$.	
 
ce  F((7#**JJ(---

%' 	 MM%jj$..  ' 4 4!..'{{!&.&A&A$,$=$=
 
 $ Mr   r   c           
      6   |j                         }|j                         }d}t        j                         D ]5  \  }}|d   }|d   }||k  r||k\  s||k  s |} n||cxk  r|k  s0n 3|} n |sg S | j	                  t
              j                  t
        j                  |k(  t
        j                  |k  t
        j                  |k\  t
        j                  dk(        j                         }	g }
|	D ]  }| j	                  t              j                  t        j                  |j                  k(        j                         }|sS|
j!                  |j                  |j"                  |j$                  |j&                  |j                  |j                  d        |
S )z
    Get advisors available at a specific date and time
    
    Args:
        db: Database session
        check_datetime: Datetime to check availability
        
    Returns:
        List of advisors with their IDs and statuses
    Nr    r!   T)r*   rg   r   current_statusr5   rU   )r	   r   r3   itemsr.   r   r/   r5   r0   r1   rJ   rk   r   rK   r*   r2   rl   rg   r   r   )r+   r   r   
check_timetarget_shift	shift_keyr=   r>   r?   r   r   r<   rQ   s                r   "get_available_advisors_at_datetimer     s     $$&J$$&J L!'	: )u%	 {"[(J),C( j5I5( "0  	 )00-**j8((J6&&$.	
 
ce  F((7#**JJ(---

%' 	 MM%jj$.. ")..!'{{   Mr   )NNN)N)+sqlalchemy.ormr   fastapir   r   r   r   r   r	   typingr
   r   r   r   osloggingapp.common.modelsr   r   r   
app.commonr   	getLogger__name__r7   r9   r   getenvr3   r   boolrA   r   rT   AdvisorScheduleUpdaterZ   r]   ro   rP   r   r   r   r   r   r   r   <module>r      s   " ) 4 4 , , 	  < < 			8	$      IBIIow?@)"))M7;< IBIIow?@)"))M7;< IBIIow?@)"))M7;<
$+C +W + +Z33003 3 	3j... 00. 	.
 .`8 8c 8d38n 8: !%%)#'	@@@ "@ x 	@
 
$sCx.@D1g 13 14 1f(
W (
c3h (
T--c- S>- 	-
 
#s(^-d "&333 3 
$sCx.	3j@@@ 
$sCx.@r   