
    5yj+)                         d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	m
Z
 ddlmZmZ g dZ G d d	ej                        Zy)
    N)http)AccessErrorValidationError)content_dispositionrequest   )HR_OFFICER_GROUP_leave_type_code)employee_nameleave_type_codeyearallocated_daysc                       e Zd Z ej                  ddd      d        Z ej                  ddddg      d	        Zed
        Zy)XenoLeaveBalanceImportz)/xeno_leave/leave_balance_import/templater   user)typeauthc                 8   t         j                  j                  j                  t              st        d      t         j                  d   j                  g       }t        j                         }|j                  }d|_
        |j                  t               |d   D ]N  }t        j                  j                  dd      |_        t        j                  j!                  dd	
      |_        P ddlm} t         j                  d   j                  dgd      }|d d }|j                  |r|j(                  nd|rt+        |      nd|j-                         j.                  dg       d}t        j                  j                  d      |j1                  |dd      _        g d}	t3        |	      D ]  \  }
}|j1                  ||
z   d|        dj5                  d |D              }|j1                  |t7        |	      z   dz   dd|        t9        dg d      D ]  \  }}||j:                  |   _         t?        j@                         }|jC                  |       |jE                  d       t        jF                  |jI                         ddtK        d       fg!      S )"N8Only Time Off Officers can use the Leave Balance import.hr.leave.typezLeave Balancesr   TFFFFFF)boldcolorsolid2563EB)fgColorr   )datehr.employee)active=Tlimitz
John SmithAL
      )r   zNOTES:)rowcolumnvalue)zemployee_name: must match an existing employee's full Name exactly (case-insensitive); if two employees share a name, the row will be skipped and reported so you can tell them apartzLleave_type_code: the code after the dot in the leave type name (e.g. AL, SL)z;year: the calendar year this balance applies to (e.g. 2026)zBallocated_days: the total days granted for that employee/type/yearzIf a balance already exists for the same employee + leave type + year, its allocated_days is revised instead of creating a duplicate.   , c              3   R   K   | ]  }t        |       d |j                   d ! yw) ()N)r
   name).0lts     K/home/susu/odoo-hr-migration/xeno_leave/controllers/leave_balance_import.py	<genexpr>zGXenoLeaveBalanceImport.leave_balance_import_template.<locals>.<genexpr>A   s(     VB-b12"RWWIQ?Vs   %'zAvailable leave type codes: ABCD)            )Content-TypezAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetzContent-Dispositionz"Leave_Balance_Import_Template.xlsxheaders)&r   envr   	has_groupr	   r   searchopenpyxlWorkbookr   titleappend_TEMPLATE_HEADERSstylesFontfontPatternFillfilldatetimer   r.   r
   todayr   cell	enumeratejoinlenzipcolumn_dimensionswidthioBytesIOsaveseekmake_responsereadr   )selfleave_typesworkbooksheetrJ   r   example_employeeexample_type	notes_rownotesinotecodescolrP   outputs                   r1   leave_balance_import_templatez4XenoLeaveBalanceImport.leave_balance_import_template   s^   {{))*:;XYYkk/299"=$$&&&'!H 	OD ,,$h,GDI 33GX3NDI	O 	"";;}5<<>S=T\]<^"2A%5!!<.:\*JJLr
 	 	CK??CWCW]aCWCb

y(
;@	
 !' 	@GAtJJ9q=$J?	@ 		V+VV

y3u:-1!7w? 	 	A fo6 	7JC16E##C(.	7 fA$$KKMV&(;<`(ab
 	
    z'/xeno_leave/leave_balance_import/uploadPOST)r   r   methodsc                 
  ' t         j                  j                  j                  t              st        d      	 t        j                  |d      }|j                  }|j                  d      }	 t        |      D cg c]  }t        |xs d      j                         ! }}t!        |      D 	ci c]  \  }}	|	|
 c}	}'t"        D 
cg c]	  }
|
'vs|
 }}
|r(| j                  d
dj%                  |       gddd      S d8'fd	}t         j                  d   j'                         j)                  d      }t         j                  d   j'                         }t         j                  d   j'                         }|j+                  g       }|D ci c]  }t-        |      | }}d}d}g }t!        |d      D ]~  \  }}|t/        d |D              rt         ||d            j                         }t         ||d            j                         j1                         } ||d      } ||d      }|s|j3                  d| d       |s|j3                  d| d       	 t5        |      }|dk  s|dkD  rt6        	 	 t;        |      }|dk  rt6        	 |j+                  d d!|fg      }|s|j3                  d| d"| d#       t=        |      d$kD  r5dj%                  d% |D              }|j3                  d| d&| d'| d(       U|} |j?                  |      }!|!s|j3                  d| d)| d#       | d*}"| d+}#	 t         j                  j@                  jC                         5  |j+                  d,d-| jD                  fd.d-|!jD                  fd/d-|"fgd$0      }$|$r|$jG                  d1|i       |d$z  }nq|j)                  ddd2      jI                  | jD                  |!jD                  |"|#||!jJ                   d3| d4d5      }%|%j'                         jM                          |d$z  }d d d         | j                  |||d7      S # t        $ r | j                  dgddd      cY S w xY wc c}w # t        $ r | j                  d	gddd      cY S w xY wc c}	}w c c}
w c c}w # t8        t6        f$ r |j3                  d| d       Y w xY w# t8        t6        f$ r |j3                  d| d       Y Hw xY w# 1 sw Y   xY w# tN        $ r=}&|j3                  d| d6|&jP                  r|&jP                  d   n|&        Y d }&~&d }&~&wt        $ r"}&|j3                  d| d6|&        Y d }&~&d }&~&ww xY w)9Nr   T)	data_onlyz7Could not read this file -- please upload a .xlsx file.r   )errorsimportedupdated)values_only zThe file is empty.zMissing required column(s): r*   c                 ^    j                  |      }||t        |       k\  s| |   |S | |   S N)getrM   )r&   r.   defaultr_   col_idxs       r1   rJ   z@XenoLeaveBalanceImport.leave_balance_import_upload.<locals>.celll   s6    D!AyASMSV^q6Mre   r   F)active_testr   zhr.leave.allocationr)   )startc              3   $   K   | ]  }|d u  
 y wrp    )r/   vs     r1   r2   zEXenoLeaveBalanceImport.leave_balance_import_upload.<locals>.<genexpr>   s     !9!t)!9s   r   r   r   r   zRow z: employee_name is required.z: leave_type_code is required.i  i4  z(: year must be a valid year (e.g. 2026).z/: allocated_days must be a non-negative number.r.   z=ilikez: Employee 'z' not found.r   c              3   V   K   | ]!  }|j                   xs d |j                    # yw)zid N)xeno_employee_codeid)r/   ms     r1   r2   zEXenoLeaveBalanceImport.leave_balance_import_upload.<locals>.<genexpr>   s(     !X1!"6"6"FCv,"F!Xs   ')z: 'z"' matches more than one employee (z#) -- can't tell which one, skipped.z: Leave type code 'z-01-01z-12-31employee_idr    holiday_status_id	date_fromr!   number_of_days)import_filemail_create_nosubscribetracking_disabler,   z day(s)))r}   r~   r   date_tor   r.   z: )rk   rl   rj   )rn   ))r   r;   r   r<   r	   r   r>   load_workbook	Exception_json_responser   	iter_rowsnextstrstripStopIterationrK   rB   rL   sudowith_contextr=   r
   allupperrA   int
ValueError	TypeErrorfloatrM   rq   cr	savepointr{   writecreater.   action_approver   args)(rW   ufilekwargsrY   rZ   	rows_iterhheaderr_   r.   cmissingrJ   Employee	LeaveType
AllocationrX   r0   type_by_coderk   rl   rj   row_numr&   emp_name	type_codeyear_rawdays_rawr   r   matchesra   employee
leave_typer   r   existing
allocationers   s(                                          @r1   leave_balance_import_uploadz2XenoLeaveBalanceImport.leave_balance_import_uploadT   s   {{))*:;XYY	G--etDH
 OOO5		h48ODqc!'rl((*DFD +4F*;<wq$47</D1G3C1DD&&9$))G:L9MNO!(- . .	 ;;}-224AAeATKK0557	[[!67<<>
&&r*;FGR(,b0GG%iq9 [	LGS{c!9S!994_56<<>HD&789??AGGIIC(HC!12HWI-IJKWI-KLM8}$;$+$$ #.
!&x!A%$$ & oo('C&DEGWI\(<PQ7|a		!XPW!XX7)3xj 1wACD H%)))4JWI-@<XY&IfoG)[[^^--/ "&)00&X[[9,c:==A$c952 	  1   H
   !(8.'IJ1%/%<%<(,d-1 &= & !&+3;;1;)2'..<'1&7r.9I$R"  #( #)88: AE"&g[	z ""WX^#_``E  	G&&3l2m561(F G G	G E 	h&&3G2HVWde'fgg	h =D( H0 z* WI-UVW z* WI-\]^2"& "&F # WIRQVVq	/KLM WIRs34s   Q 1Q< >$Q7"Q< 2R!	R'R'R,(R1S
(T2C T2TQ43Q47Q< <RR1$SS$TTT	T	V2UV U==Vc                 X    t        j                  t        j                  |       dg      S )N)r8   zapplication/jsonr9   )r   rU   jsondumps)payloads    r1   r   z%XenoLeaveBalanceImport._json_response   s)    $$JJw*N)OQ 	Qre   N)	__name__
__module____qualname__r   routerd   r   staticmethodr   rw   re   r1   r   r      sl    TZZ;&vV6
 W6
p TZZ9V^d]efGa gGaR Q Qre   r   )rQ   r   r>   odoor   odoo.exceptionsr   r   	odoo.httpr   r   leave_importr	   r
   rB   
Controllerr   rw   re   r1   <module>r      s7    	    8 2 < S HQT__ HQre   