Ë
    KµCj¯  ã                   óz   — d Z ddlmZ ddlmZmZmZ ddlmZ ddl	m
Z
mZ  ee«      Zdddd	œZd
ededz  ddfd„Zy)u
  
Notification creation service (module 1.1.11).

This is called from the Celery task (app/workers/tasks.py) after a
successful analysis tied to a crop_plan_id, comparing the new
feasibility label against the plan's previous one. A change triggers
both an in-app Notification row and a best-effort email via
app/services/email_service.py.

Kept as a plain synchronous function (not async) since it's invoked
from the synchronous Celery task context â€” see sync_db_session usage
elsewhere in tasks.py for the same pattern.
é    )Ú
get_logger)ÚCropPlanÚNotificationÚUser)Úsync_db_session)Úbuild_feasibility_change_emailÚ
send_emailÚinfoÚwarningÚcritical)ÚsuitableÚriskyÚnot_suitableÚcrop_plan_idÚnew_feasibility_labelNÚreturnc                 ó\  — | r|sy	 t        «       5 }|j                  t        | «      }|€
	 ddd«       y|j                  t        |j                  «      }|€
	 ddd«       yddlm}m} ddlm	} |j                   ||«      j                  |j                  | k(  «      j                   ||j                  «      «      j                  d«      «      j!                  «       j#                  «       }t%        |«      dkD  r|d   j&                  nd}	t%        |«      dk  }
|	duxr |	|k7  }|
s|s
	 ddd«       yt(        j                  |d«      }|
r|j*                  j-                  «       › d�n|j*                  j-                  «       › d	�}d
|j.                  › d|j1                  dd«      › d�}t3        |j4                  ||||j4                  ¬«      }|j7                  |«       |j9                  «        t;        |j*                  |j<                  |	|«      \  }}}t?        |j@                  |||«      }||_!        tD        jG                  d|j4                  › d|j4                  › d| › d|› d�	«       ddd«       y# 1 sw Y   yxY w# tH        $ r'}tD        jK                  d| › d|› �d¬«       Y d}~yd}~ww xY w)u  
    Looks up the plan's previous latest analysis to determine the prior
    label, and creates a notification only if the label actually
    changed (or this is the plan's first analysis) â€” avoids spamming
    a notification on every re-run if nothing about the outlook changed.
    Nr   )ÚdescÚselect)ÚAnalysisRecordé   é   r
   z plan analyzedz plan status changedzYour 'z' plan is now classified as 'Ú_ú z'.)Úuser_idÚtitleÚmessageÚseverityÚrelated_crop_plan_idzCreated notification z for user_id=z crop_plan_id=z (email_sent=ú)z/Failed to create notification for crop_plan_id=z: T)Úexc_info)&r   Úgetr   r   r   Ú
sqlalchemyr   r   Úapp.db.modelsr   ÚexecuteÚwherer   Úorder_byÚ
created_atÚlimitÚscalarsÚallÚlenÚfeasibility_labelÚSEVERITY_FOR_LABELÚcropr   ÚnameÚreplacer   ÚidÚaddÚflushr   Úlocationr	   ÚemailÚ
email_sentÚloggerr
   Ú	ExceptionÚerror)r   r   ÚsessionÚplanÚuserr   r   r   Úprevious_recordsÚ	old_labelÚis_first_analysisÚlabel_changedr   r   r   ÚnotificationÚsubjectÚ	text_bodyÚ	html_bodyr7   Úexcs                        úNC:\Crop_Prediction\Backend\crop-ai-system\app\services\notification_service.pyÚ#notify_feasibility_change_if_neededrH      s¾  € ñ Ñ4ØðJ
ÜÓð A	 'Ø—;‘;œx¨Ó6ˆDØˆ|Ø÷A	ð A	ð
 —;‘;œt T§\¡\Ó2ˆDØˆ|Ø÷A	ð A	÷ 0å4ð —‘Ù˜>Ó*ß‘U˜>×6Ñ6¸,ÑFÓGß‘X™d >×#<Ñ#<Ó=Ó>ß‘U˜1“Xó	÷ ‘“ß‘“ð ô BEÐEUÓAVÐYZÒAZÐ(¨Ñ+×=Ò=Ð`dˆIä #Ð$4Ó 5¸Ñ :ÐØ%¨TÐ1ÒX°iÐCXÑ6XˆMá$©]Ø÷CA	ð A	ôF *×-Ñ-Ð.CÀVÓLˆHñ %ð —9‘9—?‘?Ó$Ð% ^Ñ4àŸ	™	Ÿ™Ó)Ð*Ð*>Ð?ð ð ˜Ÿ™˜ð $Ø)×1Ñ1°#°sÓ;Ð<¸Bð@ð ô
 (ØŸ™ØØØ!Ø%)§W¡WôˆLð �K‰K˜Ô%Ø�M‰MŒOä,JØ—	‘	˜4Ÿ=™=¨)Ð5Jó-Ñ)ˆG�Y 	ô $ D§J¡J°¸ÀIÓNˆJØ&0ˆLÔ#ä�K‰KØ'¨¯©Ð'8¸ÀdÇgÁgÀYð O Ø ,˜~¨]¸:¸,ÀaðIô÷}A	÷ A	ñ A	ûôD ò 
ô 	�‰Ø=¸l¸^È2ÈcÈUÐSØð 	÷ 	
ñ 	
ûð	
úsX   ‡
I; ‘I/«I; ´#I/ÁI; Á CI/Ä(I; Ä1D5I/É&I; É/I8É4I; É8I; É;	J+ÊJ&Ê&J+)Ú__doc__Úapp.core.logging_configr   r$   r   r   r   Úapp.db.sync_sessionr   Úapp.services.email_servicer   r	   Ú__name__r8   r.   ÚstrrH   © ó    rG   ú<module>rQ      s_   ðñõ /ß 6Ñ 6Ý /ß Qá	�HÓ	€ð ØØñÐ ðW
ØðW
à ™:ðW
ð 
ôW
rP   