Ë
    ð(j?"  ã            
      ó  — U d Z ddlmZ ddlmZm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 ddlmZmZ dd	lmZ dd
lmZmZ ej.                  dej0                  dej2                  dej4                  dej6                  diZded<   dZd(d„Zd)d„Z d*d„Z!d+d„Z"ddddœ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d,d„Z#d-d„Z$d.d„Z%d/d„Z&d.d„Z'd0d„Z(d.d „Z)d1d!„Z*d2d"„Z+dd#œ	 	 	 	 	 	 	 	 	 d3d$„Z,d4d%„Z-	 	 	 	 	 	 	 	 	 	 	 	 d5d&„Z.	 	 	 	 	 	 	 	 	 	 	 	 d6d'„Z/y)7zJAdmin inbox notifications for member activity (claims, tracks, community).é    )Úannotations)ÚdatetimeÚtimezone)ÚZoneInfo)ÚHTTPExceptionÚstatus)ÚinspectÚtext)ÚEngine)ÚSessionÚ
joinedload)ÚUser)ÚAdminNotificationÚAdminNotificationTypezReward claimzTrack submittedzCommunity likezCommunity commentzCommunity sharez dict[AdminNotificationType, str]Ú_ADMIN_NOTIFICATION_TYPE_LABELSaÀ  
CREATE TABLE IF NOT EXISTS admin_notifications (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    notification_type VARCHAR(64) NOT NULL,
    title VARCHAR(255) NOT NULL,
    message TEXT NOT NULL,
    reference_type VARCHAR(64),
    reference_id INTEGER,
    is_read BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_admin_notifications_user_id ON admin_notifications (user_id);
CREATE INDEX IF NOT EXISTS ix_admin_notifications_notification_type ON admin_notifications (notification_type);
CREATE INDEX IF NOT EXISTS ix_admin_notifications_id ON admin_notifications (id);
c                ó–  — | j                   j                  dk(  }	 t        | «      }d|j                  «       v }|s:|r8| j                  «       5 }|j                  t        t        «      «       d d d «       y |s7ddl	m
} ddlm} |j                  j                  d   j                  | d¬«       y y # t        $ r d}Y Œƒw xY w# 1 sw Y   y xY w)	NÚ
postgresqlÚadmin_notificationsFr   )Úmodels_admin)ÚBaseT)ÚbindÚ
checkfirst)ÚdialectÚnamer	   Úget_table_namesÚ	ExceptionÚbeginÚexecuter
   Ú_CREATE_ADMIN_NOTIFICATIONS_PGÚappr   Úapp.databaser   ÚmetadataÚtablesÚcreate)ÚengineÚis_pgÚinspÚtable_existsÚconnr   r   s          úL/var/www/html/kelly/kelly-backend/app/services/admin_notification_service.pyÚsync_admin_notifications_schemar+   *   s²   € Ø�N‰N×Ñ <Ñ/€EðÜ�v‹ˆØ,°×0DÑ0DÓ0FÐFˆñ ™EØ�\‰\Œ^˜tØ�L‰LœÔ<Ó=Ô>÷ ˆ^áÝ$Ý%à�‰×ÑÐ2Ñ3×:Ñ:ÀÐSWÐ:ÕXð	 øô ò ØŠðú÷ ˆ^ús   ›B. ÁB?Â.B<Â;B<Â?Cc                óÐ   — | €y | j                   € | j                  t        j                  ¬«      } | j	                  t        d«      «      j                  d«      j                  d«      S )N)ÚtzinfozEurope/Londonz%d %b, %Y %I:%M %pÚ0)r-   Úreplacer   ÚutcÚ
astimezoner   ÚstrftimeÚlstrip)Údts    r*   Ú_format_notification_datetimer5   <   sT   € Ø	€zØØ	‡y�yÐØ�Z‰ZœxŸ|™|ˆZÓ,ˆØ�=‰=œ /Ó2Ó3×<Ñ<Ð=QÓR×YÑYÐZ]Ó^Ð^ó    c                ó†   — 	 t         t        | «         S # t        $ r# | j                  dd«      j	                  «       cY S w xY w)NÚ_Ú )r   r   Ú
ValueErrorr/   Útitle)Únotification_types    r*   Ú_type_labelr=   D   sD   € ð;Ü.Ô/DÐEVÓ/WÑXÐXøÜò ;Ø ×(Ñ(¨¨cÓ2×8Ñ8Ó:Ò:ð;ús   ‚ ”)A ¿A c                ó  — | j                   r:| j                   j                  r$| j                   j                  j                  «       nd }|s"| j                   r| j                   j                  }|sd| j                  › �}| j
                  | j                  ||| j                  t        | j                  «      | j                  | j                  | j                  | j                  | j                  | j                  t        | j                  «      dœS )NzUser #)ÚidÚuser_idÚ	user_nameÚmember_namer<   Ú
type_labelr;   ÚmessageÚreference_typeÚreference_idÚis_readÚ
created_atÚcreated_at_label)ÚuserÚ	full_nameÚstripÚemailr@   r?   r<   r=   r;   rD   rE   rF   rG   rH   r5   )ÚrowrA   s     r*   Úserialize_admin_notificationrO   K   sÇ   € Ø.1¯hªh¸3¿8¹8×;MÒ;M�—‘×"Ñ"×(Ñ(Ô*ÐSW€IÙ˜ŸšØ—H‘H—N‘Nˆ	ÙØ˜SŸ[™[˜MÐ*ˆ	à�f‰fØ—;‘;ØØ Ø ×2Ñ2Ü! #×"7Ñ"7Ó8Ø—‘Ø—;‘;Ø×,Ñ,Ø×(Ñ(Ø—;‘;Ø—n‘nÜ9¸#¿.¹.ÓIñð r6   NT)rE   rF   Úcommitc               óÞ  — t        |t        «      r|n/t        t        |«      j                  «       j	                  «       «      }|j                  «       }	|j                  «       }
|	r|
st        t        j                  d¬«      ‚t        |j                  |j                  |	|
||¬«      }| j                  |«       |r#| j                  «        | j                  |«       |S | j                  «        |S )Nz+Notification title and message are required)Ústatus_codeÚdetail)r@   r<   r;   rD   rE   rF   )Ú
isinstancer   ÚstrrL   Úlowerr   r   ÚHTTP_400_BAD_REQUESTr   r?   ÚvalueÚaddrP   ÚrefreshÚflush)ÚdbrJ   r<   r;   rD   rE   rF   rP   ÚntypeÚcleaned_titleÚcleaned_messagerN   s               r*   Úcreate_admin_notificationr`   b   sÑ   € ô Ð'Ô)>Ô?ñ 	ä"¤3Ð'8Ó#9×#?Ñ#?Ó#A×#GÑ#GÓ#IÓJð 
ð
 —K‘K“M€MØ—m‘m“o€OÙ¡ÜÜ×3Ñ3Ø@ô
ð 	
ô
 Ø—‘ØŸ+™+ØØØ%Ø!ô€Cð ‡F�Fˆ3„KÙØ
�	‰	ŒØ
�
‰
�3Œð €Jð 	�‰Œ
Ø€Jr6   c                ó$  — | j                  t        «      j                  t        t        j                  «      «      j                  t        j                  j                  «       t        j                  j                  «       «      j                  «       S )N)
Úqueryr   Úoptionsr   rJ   Úorder_byrH   Údescr?   Úall©r\   s    r*   Úlist_admin_notificationsrh   ‹   s]   € à
�‰Ô"Ó#ß	‰”Ô-×2Ñ2Ó3Ó	4ß	‰Ô#×.Ñ.×3Ñ3Ó5Ô7H×7KÑ7K×7PÑ7PÓ7RÓ	Sß	‰‹ð	r6   c                ó    — | j                  t        «      j                  t        j                  j	                  d«      «      j                  «       S )NF)rb   r   ÚfilterrG   Úis_Úcountrg   s    r*   Ú count_unread_admin_notificationsrm   ”   s8   € Ø�8‰8Ô%Ó&×-Ñ-Ô.?×.GÑ.G×.KÑ.KÈEÓ.RÓS×YÑYÓ[Ð[r6   c                óˆ   — | j                  t        |«      }|sy d|_        | j                  «        | j	                  |«       |S )NT)Úgetr   rG   rP   rZ   ©r\   Únotification_idrN   s      r*   Úmark_admin_notification_readrr   ˜   s9   € Ø
�&‰&Ô" OÓ
4€CÙØØ€C„KØ‡I�I„KØ‡J�Jˆs„OØ€Jr6   c                óê   — | j                  t        «      j                  t        j                  j	                  d«      «      j                  t        j                  did¬«      }| j                  «        |S )NFT©Úsynchronize_session)rb   r   rj   rG   rk   ÚupdaterP   ©r\   rl   s     r*   Ú!mark_all_admin_notifications_readrx   ¢   sZ   € à
�‰Ô"Ó#ß	‰Ô!×)Ñ)×-Ñ-¨eÓ4Ó	5ß	‰Ô"×*Ñ*¨DÐ1ÀuˆÓ	Mð 
ð
 ‡I�I„KØ€Lr6   c                óx   — | j                  t        |«      }|sy| j                  |«       | j                  «        y)NFT)ro   r   ÚdeleterP   rp   s      r*   Údelete_admin_notificationr{   ¬   s0   € Ø
�&‰&Ô" OÓ
4€CÙØØ‡I�Iˆc„NØ‡I�I„KØr6   c                óº   — | j                  t        «      j                  «       }|r5| j                  t        «      j                  d¬«       | j	                  «        |S )NFrt   )rb   r   rl   rz   rP   rw   s     r*   Úclear_all_admin_notificationsr}   µ   sF   € Ø�H‰HÔ&Ó'×-Ñ-Ó/€EÙØ
�‰Ô"Ó#×*Ñ*¸uÐ*ÔEØ
�	‰	ŒØ€Lr6   c                óZ   — | j                   xs dj                  «       xs | j                  S )NÚ )rK   rL   rM   )rJ   s    r*   Ú_member_display_namer€   ½   s#   € Ø�N‰NÒ ˜b×'Ñ'Ó)Ò7¨T¯Z©ZÐ7r6   c               ól   — t        |«      }t        | |t        j                  d|› d|› d|› d�d|¬«       y )NzNew reward claimz submitted a reward claim for z (z	 points).Úreward_claim©rJ   r<   r;   rD   rE   rF   )r€   r`   r   r‚   )r\   rJ   Úproduct_nameÚpointsÚclaim_idr   s         r*   Únotify_admin_reward_claimr‡   Á   sC   € Ü Ó%€DÜØ
ØÜ/×<Ñ<Ø Ø�&Ð6°|°nÀBÀvÀhÈiÐXØ%Øör6   )rF   c          
     óf   — t        |«      }t        | |t        j                  d|› d|› d�d|¬«       y )NzTrack progress submittedz completed a track step: Ú.Útrackrƒ   )r€   r`   r   Útrack_submit)r\   rJ   Ú
step_labelrF   r   s        r*   Únotify_admin_track_submitr�   Î   s?   € ô   Ó%€DÜØ
ØÜ/×<Ñ<Ø(Ø�&Ð1°*°¸QÐ?ØØ!ör6   c          
     óœ   — t        |«      }|xs dj                  «       xs d|› �}t        | |t        j                  d|› d|› d�d|¬«       y )Nr   úPost #zCommunity post likedz liked "z".Úcommunity_postrƒ   )r€   rL   r`   r   Úcommunity_like)r\   rJ   Úpost_idÚ
post_titler   r;   s         r*   Únotify_admin_community_liker”   á   s[   € Ü Ó%€DØÒ˜2×$Ñ$Ó&Ò<¨F°7°)Ð*<€EÜØ
ØÜ/×>Ñ>Ø$Ø�&˜   rÐ*Ø'Øör6   c               óì   — t        |«      }|xs dj                  «       xs d|› �}|j                  «       }t        |«      dkD  r|d d › d�}t        | |t        j
                  d|› d|› d|› �d	|¬
«       y )Nr   r�   éx   éu   z...zNew community commentz commented on "z": r�   rƒ   )r€   rL   Úlenr`   r   Úcommunity_comment)r\   rJ   r’   r“   Úcomment_previewr   r;   Úpreviews           r*   Únotify_admin_community_commentrœ   ï   s�   € ô   Ó%€DØÒ˜2×$Ñ$Ó&Ò<¨F°7°)Ð*<€EØ×#Ñ#Ó%€GÜ
ˆ7ƒ|�cÒØ˜T˜c�]�O 3Ð'ˆÜØ
ØÜ/×AÑAØ%Ø�&˜¨ w¨c°'°Ð;Ø'Øör6   c               ó¢   — t        |«      }|xs dj                  «       xs d|› �}t        | |t        j                  d|› d|› d|› d�d|¬«       y )	Nr   r�   zCommunity post sharedz	 shared "z" on r‰   r�   rƒ   )r€   rL   r`   r   Úcommunity_share)r\   rJ   r’   r“   Úplatformr   r;   s          r*   Únotify_admin_community_sharer      sc   € ô   Ó%€DØÒ˜2×$Ñ$Ó&Ò<¨F°7°)Ð*<€EÜØ
ØÜ/×?Ñ?Ø%Ø�&˜	 % ¨¨h¨Z°qÐ9Ø'Øör6   )r%   r   ÚreturnÚNone)r4   zdatetime | Noner¡   ú
str | None)r<   rU   r¡   rU   )rN   r   r¡   Údict)r\   r   rJ   r   r<   zAdminNotificationType | strr;   rU   rD   rU   rE   r£   rF   ú
int | NonerP   Úboolr¡   r   )r\   r   r¡   zlist[AdminNotification])r\   r   r¡   Úint)r\   r   rq   r§   r¡   zAdminNotification | None)r\   r   rq   r§   r¡   r¦   )rJ   r   r¡   rU   )r\   r   rJ   r   r„   rU   r…   r§   r†   r§   r¡   r¢   )
r\   r   rJ   r   rŒ   rU   rF   r¥   r¡   r¢   )
r\   r   rJ   r   r’   r§   r“   rU   r¡   r¢   )r\   r   rJ   r   r’   r§   r“   rU   rš   rU   r¡   r¢   )r\   r   rJ   r   r’   r§   r“   rU   rŸ   rU   r¡   r¢   )0Ú__doc__Ú
__future__r   r   r   Úzoneinfor   Úfastapir   r   Ú
sqlalchemyr	   r
   Úsqlalchemy.enginer   Úsqlalchemy.ormr   r   Ú
app.modelsr   Úapp.models_adminr   r   r‚   r‹   r‘   r™   rž   r   Ú__annotations__r   r+   r5   r=   rO   r`   rh   rm   rr   rx   r{   r}   r€   r‡   r�   r”   rœ   r    © r6   r*   Ú<module>r³      sÈ  ðÚ På "ç 'Ý ç )ß $Ý $ß .å ß Eð ×&Ñ&¨Ø×&Ñ&Ð(9Ø×(Ñ(Ð*:Ø×+Ñ+Ð-@Ø×)Ñ)Ð+<ðEÐ Ð!Aó ð"Ð ó$Yó$_ó;óð< "&Ø#Øñ&Øð&ð ð&ð 3ð	&ð
 ð&ð ð&ð ð&ð ð&ð ð&ð ó&óRó\óóóóó8ó
ð$  $ñØðà
ðð ð	ð
 ðð 
óó&ðØðØðØ),ðØ:=ðØPSðà	óð&ØðØðØ),ðØ:=ðØILðà	ôr6   