Ë
    ö–j   ã            
       ó¨   — d dl Z d dlZd dlmZ  e j                  d«      Zd„ Zdad„ Zdde	de
dz  de
dz  fd	„Zd
efd„Zdde
de	de
dz  de
dz  fd„Zy)é    N)ÚsettingsÚapic                 ó  — d}t        j                  || z
  «      }t        j                  ||z
  «      }t        j                  |dz  «      dz  t        j                  t        j                  | «      «      t        j                  t        j                  |«      «      z  t        j                  |dz  «      dz  z  z   }dt        j                  t        j
                  |«      t        j
                  d|z
  «      «      z  }||z  S )Ng     ã¸@é   é   )ÚmathÚradiansÚsinÚcosÚatan2Úsqrt)	Úlat1Úlon1Úlat2Úlon2Úr_kmÚdlatÚdlonÚaÚcs	            ú$/var/www/html/truck-me/api/notify.pyÚ_haversine_kmr   	   sÇ   € Ø€DÜ�<‰<˜˜t™Ó$€DÜ�<‰<˜˜t™Ó$€Dä�‰�˜‘Ó˜aÑÜ
�(‰(”4—<‘< Ó%Ó
&¬¯©´$·,±,¸tÓ2DÓ)EÑ
EÌÏÉÐQUÐXYÑQYÓHZÐ^_ÑH_Ñ
_ñ	`ð ð 	
ŒD�J‰J”t—y‘y “|¤T§Y¡Y¨q°1©uÓ%5Ó6Ñ6€AØ�!‰8€Oó    c                  óH  — t         �t        j                  d«       t         S t        t        dd«      xs d} | st        j                  d«       y 	 dd l}ddlm} 	 |j                  «       a t        j                  d«       t         S # t        $ r t        j                  d«       Y y w xY w# t        $ r Y nw xY w	 |j                  | «      }|j                  |«      a t        j                  d	| «       t         S # t        $ r }t        j                  d
|«       Y d }~y d }~ww xY w)Nz#FCM firebase app ready source=cacheÚFIREBASE_CREDENTIALS_PATHÚ z5FCM firebase disabled reason=missing_credentials_pathr   )Úcredentialsz,firebase_admin not installed; push disabled.z%FCM firebase app ready source=get_appz+FCM firebase app initialized credentials=%szFirebase init failed: %s)Ú_firebase_appÚloggerÚinfoÚgetattrr   ÚwarningÚfirebase_adminr   ÚImportErrorÚget_appÚ
ValueErrorÚCertificateÚinitialize_appÚ	ExceptionÚ	exception)Úpathr#   r   ÚcredÚexcs        r   Ú_ensure_firebaser.      s	  € äÐ Ü�‰Ð9Ô:ÜÐÜ”8Ð8¸"Ó=ÒCÀ€DÙÜ�‰ÐNÔOØðÛÝ.ðØ&×.Ñ.Ó0ˆÜ�‰Ð;Ô<ÜÐøô ò Ü�‰ÐEÔFÙðûô ò ÙðúðØ×&Ñ& tÓ,ˆØ&×5Ñ5°dÓ;ˆÜ�‰ÐAÀ4ÔHô Ðøô ò Ü×ÑÐ3°SÔ9Üûðús<   Á
B Á*B* ÂB'Â&B'Â*	B6Â5B6Â:8C8 Ã8	D!ÄDÄD!ÚdataÚtitleÚbodyc                 ó®  — t         j                  d| j                  t        |j	                  dd«      «      t        |j                  «       D �cg c]  }t        |«      ‘Œ c}«      t        |«      t        |«      «       t        «       }|s!t         j                  d| j                  «       y	 ddl
m} ddlm} d}	 |j                  j!                  | ¬
«      j#                  «       }	|	r|	j$                  r|	j$                  }|s!t         j                  d| j                  «       yt         j                  d| j                  |dd «       |j)                  «       D ��
ci c]  \  }}
t        |«      |
€dn
t        |
«      “Œ  }}}
|rd|vrt        |«      |d<   |rd|vrt        |«      |d<   |j+                  |||s|r|j-                  ||¬«      nd|j/                  d¬«      |j1                  ddi¬«      ¬«      }	 |j3                  ||¬«      }t         j                  d| j                  |dd |j	                  dd«      |«       yc c}w # t        $ r# t         j                  d	| j                  «       Y yw xY w# t&        $ r Y �Œ‚w xY wc c}
}w # t&        $ r@}t         j                  d| j                  |dd |j	                  dd«      |«       Y d}~yd}~ww xY w)z|
    Send FCM using the user's token from UserPushDevice (1:1).
    `data` values must be strings for FCM data payload.
    zHFCM flow start user=%s event=%s payload_keys=%s has_title=%s has_body=%sÚ
event_typer   z,FCM skip user=%s reason=firebase_unavailableFr   )ÚUserPushDevice)Ú	messagingz$FCM skip user=%s reason=import_error)Úuserz FCM skip user=%s reason=no_tokenz(FCM token loaded user=%s token_prefix=%sNé   r0   r1   ©r0   r1   Úhigh)Úpriorityzapns-priorityÚ10)Úheaders)Útokenr/   ÚnotificationÚandroidÚapns)Úappz3FCM sent user=%s token_prefix=%s event=%s msg_id=%sTz9FCM send failed user=%s token_prefix=%s event=%s error=%s)r   r    ÚidÚstrÚgetÚsortedÚkeysÚboolr.   r"   Úaccounts.modelsr4   r#   r5   r$   ÚobjectsÚfilterÚfirstÚ	fcm_tokenr)   ÚitemsÚMessageÚNotificationÚAndroidConfigÚ
APNSConfigÚsend)r6   r/   r0   r1   ÚkrA   r4   r5   r=   ÚdevÚvÚstr_dataÚmessageÚmsg_idr-   s                  r   Úsend_fcm_data_to_userrY   6   s“  € ô
 ‡K�KØRØ�‰ÜˆD�H‰H�\ 2Ó&Ó'Ü §	¡	£Ö,˜1”�A•Ò,Ó-ÜˆU‹ÜˆT‹
ôô Ó
€CÙÜ�‰ÐEÀtÇwÁwÔOØðÝ2Ý,ð €EðØ×$Ñ$×+Ñ+°Ð+Ó6×<Ñ<Ó>ˆÙ�3—=’=Ø—M‘MˆEñ Ü�‰Ð6¸¿¹Ô@ØÜ
‡K�KÐ:¸D¿G¹GÀUÈ3ÈBÀZÔPØ@DÇ
Á
Ã×M¹¸¸1”�A“˜a˜i™¬S°«VÑ3ÐM€HÑMñ � Ñ(Ü ›Jˆ�ÑÙ�˜hÑ&Ü˜t›9ˆ�ÑØ×ÑØØÙGLÑPT�Y×+Ñ+°%¸dÐ+ÔCÐZ^Ø×'Ñ'°Ð'Ó8Ø×!Ñ!¨?¸DÐ*AÐ!ÓBð  ó €GðØ—‘ ¨S�Ó1ˆÜ�‰ØAØ�G‰GØ�#�2ˆJØ�L‰L˜ rÓ*Øô	
ð ùòa -øô ò Ü�‰Ð=¸t¿w¹wÔGÙðûô ò Úðüó Nøô0 ò Ü�‰ØGØ�G‰GØ�#�2ˆJØ�L‰L˜ rÓ*Øô	
ô ûðúsJ   ÁIÂ,I Â;AI5 Å#JÇ7A	J É)I2É1I2É5	JÊJÊ	KÊ6KËKÚreturnc           
      óL  — ddl m}m} ddlm}m} | j                  �| j                  €y	 t        | j                  «      }t        | j                  «      }t        t        t        dd«      «      }t        t        t        dd«      «      }	  |«       }	g }|j"                  j%                  d	«      j'                  |j(                  j*                  d
¬«      j-                  d
¬«      j-                  d¬«      dd }|j/                  «       D ]¨  }t1        |j2                  «      }|	j5                  |«      }|s	  ||j2                  «      }|j5                  d«      |j5                  d«      }}|�|€Œe	 t9        t        |«      t        |«      ||«      }||k  sŒŒ|j;                  ||j6                  f«       Œª |j=                  d„ ¬«       d}|d| D ]D  \  }}t?        |gdt1        | j@                  «      t1        |«      t1        |«      dœdd¬«       |dz  }ŒF |S # t        t        f$ r Y yw xY w# t        $ r#}
t        j!                  d|
«       i }	Y d}
~
�Œ¿d}
~
ww xY w# t        $ r,}
t        j!                  d|j6                  |
«       Y d}
~
�Œ‚d}
~
ww xY w# t        t        f$ r Y �Œœw xY w)z�
    FCM NEARBY_LOAD to transporters with Traccar position within radius of pickup (capped).
    Returns number of notifications attempted.
    r   )ÚTransporterProfileÚUserRole)Úget_latest_device_positionÚget_latest_positions_mapNÚNEARBY_LOAD_NOTIFY_RADIUS_KMé2   ÚNEARBY_PUBLISH_NOTIFY_MAXz&Traccar bulk positions unavailable: %sr6   T)Úuser__role__roleÚdocuments_verified)Útc_id__isnullr   )Útc_idiô  z!Traccar position skip user=%s: %sÚlatitudeÚ	longitudec                 ó   — | d   S )Nr   © )Úxs    r   ú<lambda>z9notify_nearby_transporters_new_shipment.<locals>.<lambda>®   s
   €  ! A¡$€ r   )ÚkeyÚNEARBY_LOAD)Úshipment_idÚ
pickup_latÚ
pickup_lonzNew load nearbyz?A published load is available near your last reported position.r8   r   )!rH   r\   r]   Úapi.traccarr^   r_   rp   rq   ÚfloatÚ	TypeErrorr&   r!   r   Úintr)   r   ÚdebugrI   Úselect_relatedrJ   ÚRoleÚTRANSPORTERÚexcludeÚiteratorrC   rf   rD   Úuser_idr   ÚappendÚsortÚnotify_usersrB   )Úshipmentr\   r]   r^   r_   ÚplatÚplonÚradiusÚcapÚpositions_mapr-   Ú
candidatesÚqsÚprofilerf   ÚposÚlatÚlonÚdÚnÚ_Úuids                         r   Ú'notify_nearby_transporters_new_shipmentr�   {   s�  € ÷
 =ßPà×ÑÐ" h×&9Ñ&9Ð&AØðÜ�X×(Ñ(Ó)ˆÜ�X×(Ñ(Ó)ˆô ”7œ8Ð%CÀRÓHÓI€FÜ
Œg”hÐ ;¸RÓ@Ó
A€CðÙ0Ó2ˆð
 €Jà×"Ñ"×1Ñ1°&Ó9ß	‰ §¡×!:Ñ!:ÈtˆÓ	Tß	‰˜tˆÓ	$ß	‰�rˆÓ	Ø
€sð
€Bð —;‘;“=ò 4ˆÜ�G—M‘MÓ"ˆØ×Ñ Ó&ˆÙðÙ0°·±Ó?�ð —7‘7˜:Ó&¨¯©°Ó(<ˆSˆØˆ;˜#˜+Øð	Üœe C›j¬%°«*°d¸DÓAˆAð �‹;Ø×Ñ˜q '§/¡/Ð2Õ3ð#4ð& ‡O�O™€OÔ'Ø	€AØ˜T˜cÐ"ò ‰ˆˆ3ÜØˆEØä" 8§;¡;Ó/Ü! $›iÜ! $›iñð
 $ØRõ
	
ð 	
ˆQ‰‰ðð €Høôk ”zÐ"ò Ùðûô ò Ü�‰Ð=¸sÔCØŽûðûô" ò Ü—‘Ð@À'Ç/Á/ÐSVÔWÝûðûô œ:Ð&ò 	Úð	úsS   «*H Â
H) Ä2IÅ, JÈH&È%H&È)	IÈ2IÉIÉ	JÉ!!JÊJÊJ#Ê"J#r3   Úpayloadc                 ó~  — ddl m} ddlm}  |«       }d|i|¥}|xs dj	                  «       j                  «       }	|xs dj	                  «       xs d}
|xs dj	                  «       xs |
}| D �cg c]  }|sŒ|‘Œ	 }}t        j                  d||t        |xs i j                  «       D �cg c]  }t        |«      ‘Œ c}«      |
«       | D ]º  }|st        j                  d|«       Œ	 |j                  j                  |¬	«      }|j                  j                  |
||	||xs d d¬«      }t        j                  d||j                   |j                   «       t#        ||||¬«      }t        j                  d||j                   |«       Œ¼ y c c}w c c}w # |j                  $ r t        j                  d
||«       Y Œðw xY w)Nr   )Úget_user_model)rO   r3   r   rO   z@Notify pipeline start event=%s users=%s payload_keys=%s title=%sz2Notify pipeline skip event=%s reason=empty_user_id)Úpkz;Notify pipeline skip event=%s user=%s reason=user_not_foundF)r0   rW   Útyper6   r/   Úseenz5Notify DB created event=%s user=%s notification_id=%sr8   z+Notify push result event=%s user=%s sent=%s)Údjango.contrib.authr“   Úcore.modelsrO   ÚstripÚlowerr   r    rE   rF   rC   r"   rI   rD   ÚDoesNotExistÚcreaterB   rY   )Úuser_idsr3   r‘   r0   r1   r“   rO   ÚUserÚbaseÚ
notif_typeÚnotif_titleÚnotif_messager�   Úsafe_user_idsrS   ÚuÚnotifÚsents                     r   r   r   À   s´  € Ý2Ý(ÙÓ€DØ˜*Ð0¨Ð0€DØÒ" ×)Ñ)Ó+×1Ñ1Ó3€JØ’;˜B×%Ñ%Ó'Ò9¨>€KØ’Z˜R×&Ñ&Ó(Ò7¨K€MØ$,Ö4˜S²’SÐ4€MÐ4Ü
‡K�KØJØØÜ ¢¨B× 4Ñ 4Ó 6Ö7˜1”�A•Ò7Ó8Øôð ò [ˆÙÜ�N‰NÐOÐQ[Ô\Øð	Ø—‘× Ñ  CÐ Ó(ˆAð ×$Ñ$×+Ñ+ØØ!ØØØ’˜DØð ,ó 
ˆô 	�‰ÐKÈZÐYZ×Y]ÑY]Ð_d×_gÑ_gÔhÜ$ Q¨°EÀÔEˆÜ�‰ÐAÀ:ÈqÏtÉtÐUYÕZñ'[ùò 5ùò
 8øð × Ñ ò 	Ü�N‰NÐXÐZdÐfiÔjÙð	ús$   Á0F	Á8F	Â+FÃ(FÆ&F<Æ;F<)NN)Úloggingr   Údjango.confr   Ú	getLoggerr   r   r   r.   ÚdictrC   rY   ru   r�   r   rj   r   r   ú<module>r«      s™   ðÛ Û å  à	ˆ×	Ñ	˜5Ó	!€ò	ð €òñ>B dð B°3¸±:ð BÈCÐRVÉJó BðJB¸ó BñJ#[ sð #[°Tð #[À#ÈÁ*ð #[Ð[^ÐaeÑ[eô #[r   