§
    É‰¬jC,  ã            
      ó  — d dl mZ d dlZd dlmZ d dlmZmZ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mZmZ  ej        d¦  «        Z e¦   «         Ze                     dd¬¦  «         e eg d¢¦  «        ¦  «        fdJd„¦   «         Ze                     dd¬¦  «         e eg d¢¦  «        ¦  «        fdKd„¦   «         Ze                     dd¬¦  «         e eg d¢¦  «        ¦  «        fdLd„¦   «         Ze                     dd¬¦  «         e eg d¢¦  «        ¦  «        fdLd „¦   «         Z e                     d!d"¬¦  «         e eg d¢¦  «        ¦  «        fdMd$„¦   «         Z!e                     d%d&¬¦  «         e	dd'¬(¦  «         e	dd)¬(¦  «         e	d*d+¬(¦  «         e eg d¢¦  «        ¦  «        fdNd1„¦   «         Z"e                     d2d3e
j#        ¬4¦  «         e eg d¢¦  «        ¦  «        fdOd6„¦   «         Z$e                     d7d8¬¦  «         e eg d¢¦  «        ¦  «        fdPd:„¦   «         Z%e                     d;d<¬¦  «         e eg d¢¦  «        ¦  «        fdLd=„¦   «         Z&e                     d>d?¬¦  «         e eg d¢¦  «        ¦  «        fdQd@„¦   «         Z'e                     dA¦  «        dB„ ¦   «         Z(e                     dC¦  «        dRdF„¦   «         Z)e                     dG¦  «        dSdI„¦   «         Z*dS )Té    )ÚannotationsN)ÚAny)Ú	APIRouterÚDependsÚHTTPExceptionÚQueryÚstatus)ÚStreamingResponse)Úrequire_role)ÚErpDatabaseClient)Úget_drawing_takeoff_serviceé   )ÚApplyChatCorrectionsRequestÚChatTrainRequestÚLearnedRuleCreateRequestzdscons.api.takeoff.chatz/{takeoff_id}/chat-trainuM   TrÃ² chuyá»‡n & Huáº¥n luyá»‡n Trá»±c tiáº¿p AI Quá»³nh QS khi bÃ³c tÃ¡ch sai)Úsummary)Ú
superadminÚdirectorÚmanagerÚengineerÚstaffÚ
takeoff_idÚstrÚreqr   Úcurrent_userúdict[str, Any]Úreturnc              ƒ  ó:  K  — |                      ¦   «         }|st          dd¬¦  «        ‚t          ¦   «         }|j        p+|                     d¦  «        p|                     d¦  «        pd}	 |                     | |||                     ¦   «         ¬¦  «        ƒ d{V —†}t          |¦  «        |d	<   |S # t          $ r#}t          d
t          |¦  «        ¬¦  «        ‚d}~wt          $ r4}t                               d|¦  «         t          dd|›�¬¦  «        ‚d}~ww xY w)uÈ   Gá»­i pháº£n há»“i, chá»‰ Ä‘áº¡o lá»—i sai cho AI Quá»³nh QS. AI Quá»³nh sáº½ tiáº¿p thu, Ä‘á»� xuáº¥t danh má»¥c hiá»‡u chá»‰nh vÃ  tá»± Ä‘á»™ng Ä‘Ãºc káº¿t Quy táº¯c rÃºt kinh nghiá»‡m vÄ©nh viá»…n.é�  õ:   Vui lÃ²ng nháº­p ná»™i dung chá»‰ Ä‘áº¡o / huáº¥n luyá»‡n.©Ústatus_codeÚdetailÚ	full_nameÚusernameõ   Ká»¹ SÆ° TrÆ°á»Ÿng QS©r   Úuser_messageÚcurrent_user_nameÚ
auto_applyNÚdataé”  u-   [TAKEOFF] Lá»—i huáº¥n luyá»‡n AI Quá»³nh: %séô  u%   Lá»—i khi huáº¥n luyá»‡n AI Quá»³nh: )Úget_messager   r   Úsender_roleÚgetÚchat_train_ai_quynhÚshould_auto_applyÚdictÚ
ValueErrorr   Ú	ExceptionÚloggerÚerror)	r   r   r   Úuser_msgÚserviceÚuser_displayÚresÚval_errÚexcs	            úHC:\Projects\DSCons\app\modules\takeoff\presentation\chat_train_routes.pyÚchat_train_ai_quynh_endpointr?      s  è è € ð �ŠÑ Ô €HØð 
ÝØÐ$`ð
ñ 
ô 
ð 	
õ *Ñ+Ô+€GàŒð 	#Ø×Ò˜KÑ(Ô(ð	#à×Ò˜JÑ'Ô'ð	#ð #ð	 ð
Ø×/Ò/Ø!Ø!Ø*Ø×,Ò,Ñ.Ô.ð	 0ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆõ ˜3‘i”iˆˆF‰Øˆ
øÝð Bð Bð BÝ¨µC¸±L´LÐAÑAÔAÐAøøøøÝð 
ð 
ð 
Ý�ŠÐDÀcÑJÔJÐJÝØÐ$SÈCÐ$SÐ$Sð
ñ 
ô 
ð 	
øøøøð
øøøs%   Á,AB1 Â1
DÂ;CÃDÃ&/DÄDz/{takeoff_id}/chat-train-streamuN   Pháº£n há»“i Trá»±c tiáº¿p Thá»�i Gian Thá»±c (SSE Stream) cá»§a AI Quá»³nh QSc           	   ƒ  óT  K  — |                      ¦   «         }|st          dd¬¦  «        ‚t          ¦   «         }|j        p+|                     d¦  «        p|                     d¦  «        pd}t          |                     | |||                     ¦   «         ¬¦  «        dd	d
ddœ¬¦  «        S )ur   Gá»­i chá»‰ Ä‘áº¡o vÃ  nháº­n pháº£n há»“i SSE Realtime Streaming tá»« AI Quá»³nh tá»«ng token khÃ´ng Ä‘á»™ trá»….r   r    r!   r$   r%   r&   r'   ztext/event-streamzno-cachez
keep-aliveÚno)zCache-ControlÚ
ConnectionzX-Accel-Buffering)Ú
media_typeÚheaders)r.   r   r   r/   r0   r
   Úchat_train_ai_quynh_streamr2   )r   r   r   r8   r9   r:   s         r>   Ú#chat_train_ai_quynh_stream_endpointrF   J   sê   è è € ð �ŠÑ Ô €HØð 
ÝØÐ$`ð
ñ 
ô 
ð 	
õ *Ñ+Ô+€GàŒð 	#Ø×Ò˜KÑ(Ô(ð	#à×Ò˜JÑ'Ô'ð	#ð #ð	 õ Ø×*Ò*Ø!Ø!Ø*Ø×,Ò,Ñ.Ô.ð	 	+ñ 	
ô 	
ð 'à'Ø&Ø!%ð
ð 
ðñ ô ð ó    z/{takeoff_id}/chat-historyuS   Láº¥y ToÃ n Bá»™ Lá»‹ch Sá»­ Há»™i Thoáº¡i Huáº¥n Luyá»‡n cá»§a Há»“ SÆ¡ Báº£n Váº½c                ór   — t          ¦   «         }|                     | ¦  «        }d| ||t          |¦  «        dœS )u[   Láº¥y danh sÃ¡ch tin nháº¯n há»™i thoáº¡i huáº¥n luyá»‡n giá»¯a Ká»¹ sÆ° QS vÃ  AI Quá»³nh.Úsuccess)r	   r   r+   ÚmessagesÚcount)r   Úlist_takeoff_chat_messagesÚlen)r   r   ÚclientrJ   s       r>   Úget_takeoff_chat_historyrO   v   sF   € õ Ñ Ô €FØ×0Ò0°Ñ<Ô<€HàØ ØØÝ�X‘”ðð ð rG   uK   LÃ m Má»›i / XÃ³a Lá»‹ch Sá»­ Há»™i Thoáº¡i Huáº¥n Luyá»‡n cá»§a Báº£n Váº½)r   r   r   r   c                óR   — t          ¦   «         }|                     | ¦  «         dddœS )uL   XÃ³a sáº¡ch lá»‹ch sá»­ chat Ä‘á»ƒ báº¯t Ä‘áº§u phiÃªn huáº¥n luyá»‡n má»›i.rI   u@   Ä�Ã£ lÃ m má»›i khung há»™i thoáº¡i huáº¥n luyá»‡n thÃ nh cÃ´ng.©r	   Úmessage)r   Úclear_takeoff_chat_history)r   r   rN   s      r>   Ú#clear_takeoff_chat_history_endpointrT   Ž   s8   € õ Ñ Ô €FØ
×%Ò% jÑ1Ô1Ð1àØUðð ð rG   z$/{takeoff_id}/apply-chat-correctionsuW   1-Click Ã�p Dá»¥ng Danh Má»¥c BoQ Hiá»‡u Chá»‰nh Tá»« AI Quá»³nh vÃ o Báº£ng Dá»± ToÃ¡nr   c                óª   — |                      ¦   «         }|st          dd¬¦  «        ‚t          ¦   «         }|                     | ||j        ¬¦  «        }|S )u^   Cáº­p nháº­t cÃ¡c dÃ²ng BoQ Ä‘á»� xuáº¥t tá»« AI Quá»³nh vÃ o báº£ng bÃ³c tÃ¡ch chÃ­nh thá»©c.r   u.   KhÃ´ng cÃ³ háº¡ng má»¥c nÃ o Ä‘á»ƒ Ã¡p dá»¥ng.r!   )r   Úsuggested_itemsÚ
message_id)Ú	get_itemsr   r   Ú apply_chat_suggested_correctionsrW   )r   r   r   ÚitemsrN   r;   s         r>   Úapply_chat_corrections_endpointr[   ¡   se   € ð �MŠM‰OŒO€EØð fÝ¨Ð4dÐeÑeÔeÐeåÑ Ô €FØ
×
1Ò
1ØØØ”>ð 2ñ ô €Cð
 €JrG   z/learned-rules/listuQ   Danh SÃ¡ch ToÃ n Bá»™ Quy Táº¯c RÃºt Kinh Nghiá»‡m Ä�Ã£ Há»�c Cá»§a AI Quá»³nh QSu   Lá»�c theo loáº¡i cÃ´ng trÃ¬nh)Údescriptionu   Lá»�c theo nhÃ³m cÃ´ng tÃ¡cTu(   Chá»‰ láº¥y quy táº¯c Ä‘ang kÃ­ch hoáº¡tÚdrawing_typeú
str | NoneÚcategoryÚ	is_activeÚboolc                óv   — t          ¦   «         }|                     | ||¬¦  «        }d||t          |¦  «        dœS )ug   Xem danh sÃ¡ch cÃ¡c quy táº¯c rÃºt kinh nghiá»‡m mÃ  AI Quá»³nh Ä‘Ã£ há»�c Ä‘Æ°á»£c tá»« cÃ¡c ká»¹ sÆ°.)r]   r_   r`   rI   )r	   r+   ÚrulesrK   )r   Úlist_takeoff_learned_rulesrM   )r]   r_   r`   r   rN   rc   s         r>   Úlist_learned_rules_endpointre   º   sS   € õ Ñ Ô €FØ×-Ò-Ø!¨HÀ	ð .ñ ô €Eð ØØÝ�U‘”ð	ð ð rG   z/learned-rules/createu=   ThÃªm Thá»§ CÃ´ng Quy Táº¯c RÃºt Kinh Nghiá»‡m Cho AI Quá»³nh)r   r"   r   c                óH  — t          ¦   «         }| j        p+|                     d¦  «        p|                     d¦  «        pd}|                     | j        |                      ¦   «         |                      ¦   «         |                      ¦   «         || j        ¬¦  «        }dd||dœS )u`   ThÃªm má»™t quy táº¯c Ä‘á»‹nh má»©c hoáº·c kinh nghiá»‡m má»›i vÃ o bá»™ nhá»› cá»§a AI Quá»³nh.r$   r%   r&   )r]   r_   Úerror_patternÚcorrection_ruleÚlearned_from_userÚconfidence_weightrI   uD   Ä�Ã£ thÃªm quy táº¯c rÃºt kinh nghiá»‡m thÃ nh cÃ´ng cho AI Quá»³nh!)r	   rR   r+   Úrule)	r   Úcreated_by_roler0   Úsave_takeoff_learned_ruler]   Úget_categoryÚget_error_patternÚget_correction_rulerj   )r   r   rN   r:   Úcreateds        r>   Úcreate_learned_rule_endpointrr   Õ   sÅ   € õ Ñ Ô €FàÔð 	#Ø×Ò˜KÑ(Ô(ð	#à×Ò˜JÑ'Ô'ð	#ð #ð	 ð ×.Ò.ØÔ%Ø×!Ò!Ñ#Ô#Ø×+Ò+Ñ-Ô-Ø×/Ò/Ñ1Ô1Ø&ØÔ/ð /ñ ô €Gð ØYØØð	ð ð rG   z/learned-rules/{rule_id}uD   XÃ³a Quy Táº¯c RÃºt Kinh Nghiá»‡m Khá»�i Bá»™ Nhá»› Cá»§a AI Quá»³nhÚrule_idc                óx   — t          ¦   «         }|                     | ¦  «        }|st          dd¬¦  «        ‚dddœS )u"   XÃ³a quy táº¯c rÃºt kinh nghiá»‡m.r,   u(   KhÃ´ng tÃ¬m tháº¥y quy táº¯c Ä‘á»ƒ xÃ³a.r!   rI   u4   Ä�Ã£ xÃ³a quy táº¯c rÃºt kinh nghiá»‡m thÃ nh cÃ´ng.rQ   )r   Údelete_takeoff_learned_ruler   )rs   r   rN   Úoks       r>   Údelete_learned_rule_endpointrw   ø   sT   € õ Ñ Ô €FØ	×	+Ò	+¨GÑ	4Ô	4€BØð `Ý¨Ð4^Ð_Ñ_Ô_Ð_àØIðð ð rG   z&/{takeoff_id}/reapply-rules-and-pricesub   1-Click TÃ¡i Ã�p Dá»¥ng ToÃ n Bá»™ Quy Táº¯c RÃºt Kinh Nghiá»‡m & Ä�Æ¡n GiÃ¡ Sá»Ÿ XÃ¢y Dá»±ng 2026c                ó&  — t          ¦   «         }	 |                     | ¦  «        }|S # t          $ r#}t          dt	          |¦  «        ¬¦  «        ‚d}~wt
          $ r4}t                               d|¦  «         t          dd|›�¬¦  «        ‚d}~ww xY w)uƒ   TÃ¡i Ã¡p dá»¥ng quy táº¯c rÃºt kinh nghiá»‡m Ä‘Ã£ há»�c vÃ  Ä‘á»“ng bá»™ láº¡i Ä‘Æ¡n giÃ¡ SXD má»›i nháº¥t cho há»“ sÆ¡ bÃ³c tÃ¡ch.r,   r!   Nu>   [TAKEOFF] Lá»—i khi tÃ¡i Ã¡p dá»¥ng quy táº¯c & Ä‘Æ¡n giÃ¡: %sr-   u%   Lá»—i khi tÃ¡i Ã¡p dá»¥ng quy táº¯c: )r   Ú)reapply_rules_and_state_prices_to_takeoffr4   r   r   r5   r6   r7   )r   r   r9   r;   r<   r=   s         r>   Ú!reapply_rules_and_prices_endpointrz     s¸   € õ *Ñ+Ô+€Gð	
Ø×?Ò?À
ÑKÔKˆØˆ
øÝð Bð Bð BÝ¨µC¸±L´LÐAÑAÔAÐAøøøøÝð 
ð 
ð 
Ý�ŠÐUÐWZÑ[Ô[Ð[ÝØÐ$SÈCÐ$SÐ$Sð
ñ 
ô 
ð 	
øøøøð
øøøs    �' §
B±AÁBÁ/BÂBz/learned-rules/deduplicateuG   Gá»™p vÃ  Tá»‘i Æ¯u HÃ³a Bá»™ Nhá»› Tri Thá»©c (Deduplicate & Clean up)c                ó°   — t          ¦   «         }|                     ¦   «         }dd|                     dd¦  «        › d|                     dd¦  «        › d�|dœS )	u|   Tá»± Ä‘á»™ng rÃ  soÃ¡t, gá»™p cÃ¡c quy táº¯c trÃ¹ng láº·p vÃ  cá»™ng dá»“n sá»‘ láº§n Ã¡p dá»¥ng/ghi nhá»› cá»§a AI Quá»³nh.rI   u   Ä�Ã£ gá»™p thÃ nh cÃ´ng Úduplicate_groups_mergedr   u.    nhÃ³m quy táº¯c trÃ¹ng láº·p vÃ  dá»�n dáº¹p Údeleted_duplicate_rulesu    báº£n ghi thá»«a.)r	   rR   r+   )r   Ú!deduplicate_takeoff_learned_rulesr0   )r   rN   r;   s      r>   Ú"deduplicate_learned_rules_endpointr   %  sœ   € õ Ñ Ô €FØ
×
2Ò
2Ñ
4Ô
4€Càð }¨c¯gªgÐ6OÐQRÑ.SÔ.Sð  }ð  }ð  DG÷  DKò  DKð  Leð  ghñ  Diô  Dið  }ð  }ð  }Øðð ð rG   z/training/drillsc               ƒ  ó   K  — ddigS )NÚdrill_idzDRILL-NVH-DAITHANG-2026© r‚   rG   r>   Ú
get_drillsrƒ   8  s   è è € àÐ2Ð3Ð4Ð4rG   z/training/run-drillr+   r3   c              ƒ  ó:   K  — d|                       dd¦  «        ddœS )NÚ	completedr�   Ú r   )r	   r�   Útotal_ground_truth_items)r0   )r+   s    r>   Ú	run_drillrˆ   <  s%   è è € à!¨t¯xªx¸
ÀBÑ/GÔ/GÐefÐgÐgÐgrG   z/training/scorecardr�   c              ƒ  ó   K  — d| dœS )Né_   )Úscorer�   r‚   )r�   s    r>   Úget_scorecardrŒ   @  s   è è € à XÐ.Ð.Ð.rG   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )
r]   r^   r_   r^   r`   ra   r   r   r   r   )r   r   r   r   r   r   )rs   r   r   r   r   r   )r   r   r   r   )r+   r3   )r�   r   )+Ú
__future__r   ÚloggingÚtypingr   Úfastapir   r   r   r   r	   Úfastapi.responsesr
   Ú"app.modules.auth.presentation.authr   Úapp.core.postgres.erp_clientr   Ú7app.modules.takeoff.application.drawing_takeoff_servicer   Úschemasr   r   r   Ú	getLoggerr6   ÚrouterÚpostr?   rF   r0   rO   ÚdeleterT   r[   re   ÚHTTP_201_CREATEDrr   rw   rz   r   rƒ   rˆ   rŒ   r‚   rG   r>   ú<module>r›      sô  ðØ "Ð "Ð "Ð "Ð "Ð "à €€€Ø Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð 0Ð /Ð /Ð /Ð /Ð /à ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø :Ð :Ð :Ð :Ð :Ð :Ø _Ð _Ð _Ð _Ð _Ð _ðð ð ð ð ð ð ð ð ð ð 
ˆÔ	Ð4Ñ	5Ô	5€Ø	ˆ‰Œ€ð ‡‚ØØ[ð ñ ô ð $+ 7ØˆØFÐFÐFñ	
ô 	
ñ$ô $ð&
ð &
ð &
ð &
ñ	ô ð&
ðR ‡‚Ø%Ø\ð ñ ô ð $+ 7ØˆØFÐFÐFñ	
ô 	
ñ$ô $ð%ð %ð %ð %ñ	ô ð%ðP ‡‚Ø Øað ñ ô ð $+ 7ØˆØFÐFÐFñ	
ô 	
ñ$ô $ðð ð ð ñ	ô ðð( ‡‚Ø ØYð ñ ô ð $+ 7ØˆÐFÐFÐFÑGÔGñ$ô $ðð ð ð ñ	ô ðð ‡‚Ø*Øeð ñ ô ð $+ 7ØˆÐFÐFÐFÑGÔGñ$ô $ðð ð ð ñ	ô ðð* ‡‚ØØ_ð ñ ô ð
  %˜u TÐ7WÐXÑXÔXØ ˜5 Ð3PÐQÑQÔQØ�e˜DÐ.XÐYÑYÔYØ#* 7ØˆØFÐFÐFñ	
ô 	
ñ$ô $ð	ð ð ð ñ	ô ðð. ‡‚ØØKØÔ'ð ñ ô ð $+ 7ØˆÐFÐFÐFÑGÔGñ$ô $ðð ð ð ñô ð
ð< ‡‚ØØRð ñ ô ð $+ 7ØˆÐFÐFÐFÑGÔGñ$ô $ðð ð ð ñ	ô ðð" ‡‚Ø,Øpð ñ ô ð $+ 7ØˆÐFÐFÐFÑGÔGñ$ô $ð
ð 
ð 
ð 
ñ	ô ð
ð( ‡‚Ø ØUð ñ ô ð
 $+ 7ØˆÐFÐFÐFÑGÔGñ$ô $ðð ð ð ñ	ô ðð ‡‚ÐÑÔð5ð 5ñ  Ôð5ð ‡‚Ð"Ñ#Ô#ðhð hð hñ $Ô#ðhð ‡‚Ð!Ñ"Ô"ð/ð /ð /ñ #Ô"ð/ð /ð /rG   