o
    dBjÀ5  ã                   @  s<  U d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
mZmZmZ e e¡ZdZdZdd	d
dd
d
dd
dd
d
dddddddœdœZded< dIdd„ZdJdd„ZdKdd„ZdLdd „Zdd!œdMd#d$„ZdNdOd(d)„ZdPd/d0„ZdQd2d3„ZdRd5d6„ZdSd8d9„Zddd:œdTd=d>„ZdUdBdC„Z dVdEdF„Z!dWdGdH„Z"dS )XzLConfigurable email notifications for support tickets (SMTP, off by default).é    )ÚannotationsN)ÚEmailMessage)ÚAnyÚDictÚListÚOptionalÚticket_emailz********FÚsmtpÚ éK  TúPCA Support)Úticket_createdÚticket_assignedÚticket_resolvedÚcustomer_replyÚstaff_replyÚstaff_login)ÚenabledÚproviderÚ	smtp_hostÚ	smtp_portÚ	smtp_userÚsmtp_passwordÚsmtp_use_tlsÚ
from_emailÚ	from_nameÚsupport_inbox_emailÚreply_to_emailÚeventsúDict[str, Any]ÚDEFAULT_CONFIGÚ
table_nameÚstrÚreturnÚboolc                 C  s   |   d|f¡ |  ¡ d uS )Nz}
        SELECT 1 FROM information_schema.tables
        WHERE table_schema = DATABASE() AND table_name = %s LIMIT 1
        )ÚexecuteÚfetchone)Úcursorr!   © r(   úF/home/aiteam/pcaa-dev/dashboard-backend/ticket_notification_service.pyÚ_table_exists(   s
   ûr*   ÚNonec                 C  s   |   d¡ d S )Nav  
        CREATE TABLE IF NOT EXISTS pcaa_notification_settings (
            setting_key VARCHAR(64) NOT NULL PRIMARY KEY,
            config_json JSON NOT NULL,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            updated_by VARCHAR(100) NULL
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
        )r%   )r'   r(   r(   r)   Ú#ensure_notification_settings_schema3   s   ÿr,   ÚrawúOptional[Dict[str, Any]]c                 C  sX   t  t  t¡¡}| s|S |  ¡ D ]\}}|dkr%t|tƒr%|d  |¡ q|||< q|S )Nr   )ÚjsonÚloadsÚdumpsr    ÚitemsÚ
isinstanceÚdictÚupdate)r-   ÚbaseÚkeyÚvaluer(   r(   r)   Ú_merge_defaults@   s   
r9   c                  C  sê   t t dd¡pdƒ ¡ } | si S t t dd¡ƒ ¡ dv | tt dd¡p$dƒt t dd¡p-dƒ ¡ t t d	d¡p8dƒ ¡ t t d
d¡ƒ ¡ dvt t dd¡pNdƒ ¡ t t dd¡pYdƒ ¡ t t dd¡pddƒ ¡ t t dd¡podƒ ¡ dœ
S )NÚTICKET_SMTP_HOSTr
   ÚTICKET_EMAIL_ENABLED)Ú1ÚtrueÚyesÚTICKET_SMTP_PORTÚ587r   ÚTICKET_SMTP_USERÚTICKET_SMTP_PASSWORDÚTICKET_SMTP_USE_TLSr=   )Ú0ÚfalseÚnoÚTICKET_FROM_EMAILÚTICKET_FROM_NAMEr   ÚTICKET_SUPPORT_INBOXÚTICKET_REPLY_TO)
r   r   r   r   r   r   r   r   r   r   )r"   ÚosÚgetenvÚstripÚlowerÚint)Úhostr(   r(   r)   Ú_env_fallbackL   s   örQ   ©Úinclude_secretsrS   c          
      C  sÎ   t | ƒ i }t| dƒr-|  dtf¡ |  ¡ }|r-| d¡r-|d }t|tƒr(|nt 	|¡}t
|ƒ}tƒ }| ¡ D ]\}}|dvrI| |¡sI|||< q8|rN|S t|ƒ}	|	 d¡rat|	d< d|	d< |	S d|	d< |	S )	NÚpcaa_notification_settingszQSELECT config_json FROM pcaa_notification_settings WHERE setting_key = %s LIMIT 1Úconfig_json)Nr
   Fr   TÚhas_smtp_passwordF)r,   r*   r%   ÚSETTING_KEYr&   Úgetr3   r4   r/   r0   r9   rQ   r2   ÚPASSWORD_MASK)
r'   rS   ÚstoredÚrowr-   ÚconfigÚenvr7   r8   Úmaskedr(   r(   r)   Úget_ticket_email_config^   s4   
þ€
ÿr_   ÚpayloadÚ
updated_byúOptional[str]c           	        sÐ   t | ƒ t| dd}t|pi ƒ}t| d¡pdƒ ¡ }|r!|tkr*| d¡p'd|d< t|ƒ}| d¡rVt| d¡p:i ƒ‰ d}t‡ fdd	„|D ƒƒsV|D ]}dˆ |< qKˆ |d< |  	d
t
t |¡|f¡ t| ddS )NTrR   r   r
   r   r   )r   r   r   r   c                 3  s    | ]}ˆ   |¡V  qd S ©N)rX   )Ú.0r7   ©r   r(   r)   Ú	<genexpr>Š   s   € z+save_ticket_email_config.<locals>.<genexpr>zÞ
        INSERT INTO pcaa_notification_settings (setting_key, config_json, updated_by)
        VALUES (%s, %s, %s)
        ON DUPLICATE KEY UPDATE config_json = VALUES(config_json), updated_by = VALUES(updated_by)
        F)r,   r_   r9   r"   rX   rM   rY   r4   Úanyr%   rW   r/   r1   )	r'   r`   ra   ÚcurrentÚincomingÚpasswordr\   Úrecommendedr7   r(   re   r)   Úsave_ticket_email_config}   s&   

úrl   r\   Úto_addrsú	List[str]ÚsubjectÚbodyc                 C  sŠ  dd„ |D ƒ}|st dƒ‚t|  d¡pdƒ ¡ }|st dƒ‚t|  d¡p%dƒ}t|  d	¡p.dƒ ¡ }t|  d
¡p9dƒ ¡ }t|  dd¡ƒ}	t|  d¡pN|pNdƒ ¡ }
|
sXt dƒ‚t|  d¡p_dƒ ¡ }t|  d¡pjdƒ ¡ }tƒ }||d< |r|› d|
› dn|
|d< d |¡|d< |r||d< | |¡ t	j
||dd}|	r¤| ¡  |r®|r®| ||¡ | |¡ W d   ƒ d S 1 s¾w   Y  d S )Nc                 S  s(   g | ]}t |pd ƒ ¡ rt |ƒ ¡ ‘qS )r
   )r"   rM   )rd   Úar(   r(   r)   Ú
<listcomp>š   s   ( z_smtp_send.<locals>.<listcomp>zNo recipientsr   r
   zSMTP host is not configuredr   r   r   r   r   Tr   zFrom email is not configuredr   r   r   ÚSubjectz <Ú>ÚFromz, ÚTozReply-Toé   )Útimeout)Ú
ValueErrorr"   rX   rM   rO   r$   r   ÚjoinÚset_contentÚsmtplibÚSMTPÚstarttlsÚloginÚsend_message)r\   rm   ro   rp   Ú
recipientsrP   ÚportÚuserrj   Úuse_tlsr   r   Úreply_toÚmsgr	   r(   r(   r)   Ú
_smtp_send™   s:   
"ûr‡   Úto_emailc                 C  s8   t | dd}| d¡stdƒ‚t||gddƒ d|dœS )NTrR   r   z;Ticket email notifications are disabled. Enable them first.u   PCA Support â€” test emailzEThis is a test email from the PCA support ticket notification system.)ÚsuccessÚsent_to)r_   rX   ry   r‡   )r'   rˆ   r\   r(   r(   r)   Úsend_test_email½   s   
ü
r‹   Úeventc                 C  s*   |   d¡sdS |   d¡pi }t|  |¡ƒS )Nr   Fr   )rX   r$   )r\   rŒ   r   r(   r(   r)   Ú_event_enabledÊ   s   
r   Úticketc                 C  s   t |  d¡pd|  d¡› ƒS )NÚticket_numberú#Úid)r"   rX   )rŽ   r(   r(   r)   Ú_ticket_labelÑ   s   r’   )Úassignee_emailÚmessage_previewr“   r”   c             
   C  sú  z\t | dd}t||ƒsW d S t|ƒ}| d¡}| d¡p$| d¡p$d}d|› d|› d	| d
¡p3d› d|› d| d¡› g}	| d¡rR|	 d| d¡› ¡ | d¡rb|	 d| d¡› ¡ |rp|	 ddt|ƒ ¡ g¡ d |	¡}
d| 	dd¡ 
¡ › d	|› }|dkr“d|› }d|
› d}
n|dkr¢d|› }d|
› d}
g }|dkrÄt| d ¡p¯dƒ ¡ }|r»| |¡ nxt d!|¡ W d S |dkrát|pÌdƒ ¡ }|rØ| |¡ n[t d"|¡ W d S |d#krøt| d$¡pìdƒ ¡ }|r÷| |¡ n;|d%krt| d ¡pdƒ ¡ }|r| |¡ |r| |¡ n|d&kr3t| d$¡p'dƒ ¡ }|r3| |¡ tt d'd(„ |D ƒ¡ƒ}|sLt d)||¡ W d S t||||
ƒ t d*|||¡ W d S  ty| } zt d+|| d,¡|¡ W Y d }~d S d }~ww )-NTrR   Úbusiness_idro   Ú
issue_textzSupport ticketzTicket: z
Business: u    â€” Úbusiness_namer
   z	Subject: zStatus: ÚstatusÚassigned_tozAssigned to: Údue_atzDue: zMessage:Ú
z[PCA] Ú_Ú r   u   [PCA] New support ticket â€” z)A customer raised a new support ticket.

u6   

Open PCA Master â†’ Support to review and assign it.r   u   [PCA] New assignment â€” z*You have been assigned a support ticket.

uA   

Open PCA Master â†’ Support â†’ My assigned tickets to view it.r   zQticket email skipped event=ticket_created ticket=%s (support_inbox_email not set)zLticket email skipped event=ticket_assigned ticket=%s (assignee has no email)r   Ú
user_emailr   r   c                 S  s   g | ]}|r|‘qS r(   r(   )rd   Úrr(   r(   r)   rr   '  s    z)try_send_ticket_email.<locals>.<listcomp>z7ticket email skipped event=%s ticket=%s (no recipients)z*ticket email sent event=%s ticket=%s to=%sz*ticket email failed event=%s ticket=%s: %sr‘   )r_   r   r’   rX   ÚappendÚextendr"   rM   rz   ÚreplaceÚtitleÚloggerÚinfoÚlistr4   Úfromkeysr‡   Ú	ExceptionÚwarning)r'   rŒ   rŽ   r“   r”   r\   ÚlabelÚbidro   Ú
body_linesrp   Úmail_subjectr   ÚinboxÚemailÚcustomerÚexcr(   r(   r)   Útry_send_ticket_emailÕ   sš   

ü



ÿÿ
ÿÿþþ
€


€

$€ÿr²   Úuser_idrO   úList[Dict[str, Any]]c                 C  s"   |   dt|ƒf¡ t|  ¡ pg ƒS )Na
  
        SELECT ticket_number, business_id, subject, issue_text, status, due_at
        FROM reported_issues
        WHERE assigned_to_user_id = %s
          AND status IN ('open', 'in_progress')
        ORDER BY due_at ASC, created_at DESC
        LIMIT 25
        )r%   rO   r¦   Úfetchall)r'   r³   r(   r(   r)   Ú_assigned_active_tickets2  s
   ÷r¶   rƒ   c                 C  sN   | sdS |   d¡dv rdS |   d¡dvrdS t|   d¡pdƒ ¡  ¡ }|dv S )	NFÚ	is_master)Té   r<   TÚhas_master_panelÚ
staff_teamr
   )Ú	developerÚsupport)rX   r"   rM   rN   )rƒ   Úteamr(   r(   r)   Ú_is_staff_login_email_targetA  s   r¾   c              
   C  sô  zÜt |ƒsW dS t| d¡pdƒ ¡ }| d¡}|r|sW dS t| dd}t|dƒs-W dS t| d¡p4dƒ ¡ pDt| d	¡p?dƒ ¡ pDd
}t| t|ƒƒ}d|› ddddg}|r°| dt	|ƒ› d¡ | d¡ |D ]D}| d¡prd}	| d¡p~| d¡p~d}
t|
ƒ ¡  
dd¡dd… }
| d¡}|r™d|› nd}| d|	› d| d¡› d|
› |› ¡ qjn| d¡ | ddg¡ d |¡}dt	|ƒ› d }t||g||ƒ t d!|t	|ƒ¡ W dS  tyù } zt d"| d¡|¡ W Y d}~dS d}~ww )#zDEmail developer/support staff their assigned ticket digest on login.Nr¯   r
   r‘   TrR   r   Ú	full_nameÚusernameÚtherezHello ú,z&You logged in to the PCA master panel.z	You have z assigned ticket(s) open:r   ÚTicketro   r–   r›   r   éd   rš   u    Â· due z- u    Â· BID r•   u    Â· z,You have no open assigned tickets right now.u   â€” PCA Supportu   [PCA] Login digest â€” z assigned ticket(s)z)staff login email sent to %s (%s tickets)z(staff login email failed for user %s: %s)r¾   r"   rX   rM   r_   r   r¶   rO   r    Úlenr¢   r¡   rz   r‡   r¤   r¥   r¨   r©   )r'   rƒ   r¯   r³   r\   rÀ   ÚticketsÚlinesr[   rª   ÚsubjÚdueÚdue_txtrp   ro   r±   r(   r(   r)   Útry_send_staff_login_emailL  sT   

ÿý
ü

(ú

"€ÿrË   )r!   r"   r#   r$   )r#   r+   )r-   r.   r#   r   )r#   r   )rS   r$   r#   r   rc   )r`   r   ra   rb   r#   r   )
r\   r   rm   rn   ro   r"   rp   r"   r#   r+   )rˆ   r"   r#   r   )r\   r   rŒ   r"   r#   r$   )rŽ   r   r#   r"   )
rŒ   r"   rŽ   r   r“   rb   r”   rb   r#   r+   )r³   rO   r#   r´   )rƒ   r   r#   r$   )rƒ   r   r#   r+   )#Ú__doc__Ú
__future__r   r/   ÚloggingrK   r|   Úemail.messager   Útypingr   r   r   r   Ú	getLoggerÚ__name__r¤   rW   rY   r    Ú__annotations__r*   r,   r9   rQ   r_   rl   r‡   r‹   r   r’   r²   r¶   r¾   rË   r(   r(   r(   r)   Ú<module>   s\    
úô





$

	ú
]
