§
    éƒtjý*  ã                  ó$  — U d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
mZ ddlmZmZmZ ddlmZmZ  ej        ¦   «         Zi Zd	ed
<   i Zded<   e
dz  dz  Zd.d„Zd/d„Zd0d„Zd1d„Zd2d„Zd3d"„Zd4d#„Zd5d%„Z d6d'„Z!d7d(„Z"d8d)„Z#d*d+œd9d-„Z$dS ):zÂIn-memory PDF calculation jobs (confirm-before-calc).

By default user PDFs and extracted content are kept in process memory only
and are never written to disk (see Settings.persist_user_data).
é    )ÚannotationsN)ÚPath)ÚAny)ÚBASE_DIRÚget_settings)Ú	calculateÚformat_job_contextÚvalidate_rows)ÚExtractionResultÚextract_pdfzdict[str, dict[str, Any]]Ú_JOBSzdict[str, str]Ú_SESSION_JOBSÚdataÚpdf_uploadsÚreturnÚboolc                 óB   — t          t          ¦   «         j        ¦  «        S ©N)r   r   Úpersist_user_data© ó    ú)/var/www/html/CA-Chatbot/app/pdf/store.pyÚ_persist_enabledr      s   € Ý•‘”Ô0Ñ1Ô1Ð1r   r   c                 óH   — t                                dd¬¦  «         t           S )NT)ÚparentsÚexist_ok)Ú_UPLOAD_DIRÚmkdirr   r   r   Ú_ensure_upload_dirr      s!   € Ý×Ò˜d¨TÐÑ2Ô2Ð2ÝÐr   Úrowsú	list[Any]úlist[dict[str, Any]]c                ó$  — g }| D ]Š}t          |d¦  «        rVt          |t          ¦  «        sA|                     |j        |j        |j        |j        |j        |j	        |j
        dœ¦  «         Œh|                     t          |¦  «        ¦  «         Œ‹|S )NÚ__dict__©ÚdescriptionÚdebitÚcreditÚamountÚdateÚaccountÚraw)ÚhasattrÚ
isinstanceÚdictÚappendr&   r'   r(   r)   r*   r+   r,   )r    ÚoutÚrs      r   Ú_serialize_rowsr3   !   s£   € Ø
€CØð  ð  ˆÝ�1�jÑ!Ô!ð 	 ­*°Q½Ñ*=Ô*=ð 	 Ø�JŠJà#$¤=ØœWØœhØœhØœFØ œyØœ5ðð ñ
ô 
ð 
ð 
ð �JŠJ•t˜A‘w”wÑÔÐÐØ€Jr   Újobúdict[str, Any]ÚNonec                óò   — t          ¦   «         sdS t          ¦   «          t          | d         › d�z  }|                     t	          j        d„ |                      ¦   «         D ¦   «         d¬¦  «        ¦  «         dS )u5   Optional durable copy â€” off by default for privacy.NÚjob_idú.jsonc                ó&   — i | ]\  }}|d k    ¯||“ŒS )Ú	file_pathr   )Ú.0ÚkÚvs      r   ú
<dictcomp>z"_save_job_disk.<locals>.<dictcomp><   s(   € ÐEÐEÐE™T˜Q °A¸Ò4DÐ4D�A�qÐ4DÐ4DÐ4Dr   é   )Úindent)r   r   r   Ú
write_textÚjsonÚdumpsÚitems)r4   Ú	meta_paths     r   Ú_save_job_diskrG   5   sƒ   € åÑÔð ØˆÝÑÔÐÝ  X¤Ð5Ð5Ð5Ñ5€IØ×ÒÝŒ
ÐEÐE S§Y¢Y¡[¤[ÐEÑEÔEÈaÐPÑPÔPñô ð ð ð r   Ú
saved_pathÚfilenameÚstrc                óÈ  — t          | |¬¦  «        }t          |dd ¦  «        pd}t          t          |j        ¦  «        |¬¦  «        }||_        |j        r|                     d¦  «        rd}d}d}nd}d}d	}d|_        d|_        i d
|j	        “d|j
        “d|j        “d|“d|“d	|“dd“d|“dt          |j        ¦  «        “d|j        “d|j        p|j        “d|j        “d|“d|j        “dt!          ¦   «         rt#          | ¦  «        nd “dd “dt          |dd ¦  «        pi “}t$          5  |t&          |j	        <   d d d ¦  «         n# 1 swxY w Y   t)          |¦  «         |S )N)rI   Údocument_kindÚunknown©rL   ÚokFTÚreadyÚneeds_confirmr8   rI   Úsource_typeÚtrustedÚ	confirmedÚstatusr    Útext_previewÚdocument_textÚwarningsÚ
validationÚocr_usedr;   ÚcalculationÚstatement_totals)r   Úgetattrr
   r3   r    rY   rS   ÚgetrQ   r8   rI   rR   rV   rW   rX   rZ   r   rJ   Ú_LOCKr   rG   )	rH   rI   ÚresultÚkindrY   rQ   rS   rU   r4   s	            r   Úcreate_job_from_uploadrb   @   s4  € Ý*¨:ÀÐIÑIÔI€FÝ�6˜?¨DÑ1Ô1Ð>°Y€DÝ�¨v¬{Ñ;Ô;È4ÐPÑPÔP€JØ"€FÔð „~ð 	$˜*Ÿ.š.¨Ñ.Ô.ð 	$ØˆØˆØˆˆàˆØˆØ ˆØˆŒØ#ˆÔðØ�&”-ðà�F”Oðð 	�vÔ)ðð 	˜ð	ð
 	�7ðð 	˜ðð 	�Uðð 	�&ðð 	• ¤Ñ,Ô,ðð 	˜Ô+ðð 	˜Ô-ÐD°Ô1Dðð 	�F”Oðð 	�jðð 	�F”Oðð 	Õ(8Ñ(:Ô(:ÐD•S˜‘_”_�_Àðð  	�tð!ð" 	�G FÐ,>ÀÑEÔEÐKÈð#€Cõ( 
ð #ð #Ø"�ˆfŒmÑð#ð #ð #ñ #ô #ð #ð #ð #ð #ð #ð #øøøð #ð #ð #ð #õ �3ÑÔÐØ€Js   Ä,EÅEÅEr8   údict[str, Any] | Nonec                ó„  — t           5  t                               | ¦  «        }d d d ¦  «         n# 1 swxY w Y   |r|S t          ¦   «         sd S t          | › d�z  }|                     ¦   «         rQt          j        |                     ¦   «         ¦  «        }t           5  |t          | <   d d d ¦  «         n# 1 swxY w Y   |S d S )Nr9   )	r_   r   r^   r   r   ÚexistsrC   ÚloadsÚ	read_text)r8   r4   rF   r   s       r   Úget_jobrh   m   s>  € Ý	ð  ð  Ý�iŠi˜ÑÔˆð ð  ð  ñ  ô  ð  ð  ð  ð  ð  ð  øøøð  ð  ð  ð  à
ð Øˆ
ÝÑÔð ØˆtÝ Ð.Ð.Ð.Ñ.€IØ×ÒÑÔð ÝŒz˜)×-Ò-Ñ/Ô/Ñ0Ô0ˆÝð 	!ð 	!Ø �E�&‰Mð	!ð 	!ð 	!ñ 	!ô 	!ð 	!ð 	!ð 	!ð 	!ð 	!ð 	!øøøð 	!ð 	!ð 	!ð 	!àˆØˆ4s   ˆ/¯3¶3ÂB3Â3B7Â:B7c                ó   — t          | ¦  «        }|st          d¦  «        ‚g }|D ]Ç}|                     t          |                     d¦  «        pd¦  «                             ¦   «         |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d	¦  «        pdd
œ¦  «         ŒÈt          ||                     d¦  «        pd¬¦  «        }||d<   ||d<   d|d<   d|d<   t          |                     d¦  «        ¦  «        |d<   |                     d¦  «        rdnd|d<   t          |                     d¦  «        pg ¦  «        |d<   |                     d¦  «        s"|d         |                     dg ¦  «        z   |d<   t          5  |t          | <   d d d ¦  «         n# 1 swxY w Y   t          |¦  «         |S )NúJob not foundr&   Ú r'   r(   r)   r*   r+   r,   r%   rL   rM   rN   r    rY   TrT   FrQ   rO   rS   ÚinvalidrU   rX   Úissues)rh   ÚKeyErrorr0   rJ   r^   Ústripr
   r   Úlistr_   r   rG   )r8   r    r4   Úcleanedr2   rY   s         r   Úconfirm_jobrr   }   s/  € Ý
�&‰/Œ/€CØð (Ý�Ñ'Ô'Ð'à€GØð 
ð 
ˆØ�Šå" 1§5¢5¨Ñ#7Ô#7Ð#=¸2Ñ>Ô>×DÒDÑFÔFØŸš˜w™œØŸ%š% ™/œ/ØŸ%š% ™/œ/ØŸš˜f™œØŸ5š5 Ñ+Ô+Ø—u’u˜U‘|”|Ð) rðð ñ
	
ô 
	
ð 
	
ð 
	
õ ˜w°c·g²g¸oÑ6NÔ6NÐ6[ÐR[Ð\Ñ\Ô\€JØ€Cˆ�KØ"€CˆÑØ€CˆÑØ €CˆÑÝ˜*Ÿ.š.¨Ñ.Ô.Ñ/Ô/€Cˆ	�NØ#-§>¢>°$Ñ#7Ô#7ÐF�K�K¸Y€Cˆ�MÝ˜3Ÿ7š7 :Ñ.Ô.Ð4°"Ñ5Ô5€Cˆ
�OØ�>Š>˜$ÑÔð IØ˜jœ/¨J¯NªN¸8ÀRÑ,HÔ,HÑHˆˆJ‰å	ð ð Ø�ˆf‰ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð å�3ÑÔÐØ€Js   ÇG$Ç$G(Ç+G(Ú
session_idc                óÜ   — | sd S t           5  t                               | ¦  «        }|t          | <   |r!||k    rt                               |d ¦  «         d d d ¦  «         d S # 1 swxY w Y   d S r   )r_   r   r^   r   Úpop)rs   r8   Úprevs      r   Úattach_job_to_sessionrw   ¡   sº   € Øð ØˆÝ	ð "ð "å× Ò  Ñ,Ô,ˆØ$*��jÑ!Øð 	"�D˜F’N�NÝ�IŠI�d˜DÑ!Ô!Ð!ð"ð "ð "ñ "ô "ð "ð "ð "ð "ð "ð "ð "øøøð "ð "ð "ð "ð "ð "s   ŒAA!Á!A%Á(A%ú
str | Nonec                ó¢   — | sd S t           5  t                               | ¦  «        }d d d ¦  «         n# 1 swxY w Y   |sd S t          |¦  «        S r   )r_   r   r^   rh   )rs   r8   s     r   Úget_session_jobrz   ¬   s–   € Øð ØˆtÝ	ð /ð /Ý×"Ò" :Ñ.Ô.ˆð/ð /ð /ñ /ô /ð /ð /ð /ð /ð /ð /øøøð /ð /ð /ð /àð ØˆtÝ�6‰?Œ?Ðs   Œ3³7º7c                ó  — | sd S t           5  t                               | d ¦  «        }|rt                               |d ¦  «         d d d ¦  «         n# 1 swxY w Y   	 ddlm}  || ¦  «         d S # t          $ r Y d S w xY w)Nr   )Úclear_session_history)r_   r   ru   r   Úapp.rag.chainr|   Ú	Exception)rs   r8   r|   s      r   Úclear_session_jobr   ¶   së   € Øð ØˆÝ	ð $ð $Ý×"Ò" :¨tÑ4Ô4ˆØð 	$Ý�IŠI�f˜dÑ#Ô#Ð#ð$ð $ð $ñ $ô $ð $ð $ð $ð $ð $ð $øøøð $ð $ð $ð $ð
Ø7Ð7Ð7Ð7Ð7Ð7àÐ˜jÑ)Ô)Ð)Ð)Ð)øÝð ð ð Øˆˆðøøøs#   Œ9AÁAÁAÁA0 Á0
A>Á=A>c           
     ó   — t          | |¦  «        }|                     d¦  «        pg }|sM|                     d¦  «        s8|                     d¦  «        s#d|› d�|d<   |rt          ||d         ¦  «         |S |                     d¦  «        pi }|                     d	¦  «        €|                     d¦  «        ��\|                     d¦  «        pd}|dk    rd}||d<   	 |r,t          |d         |¦  «        }t	          |d         ¦  «        }nhd|d<   d|d<   d|d<   ddlm}  ||g ¬¦  «        |d<   d|d<   t          5  |t          |d         <   d
d
d
¦  «         n# 1 swxY w Y   t          |¦  «         nt# t          $ rg}t          t                               t          |                     d¦  «        pg ¦  «        t          |¦  «        gz   ¦  «        ¦  «        |d<   Y d
}~nd
}~ww xY w|rt          ||d         ¦  «         t          |¦  «        |d<   |S |rÍt          |d         |¦  «        }	 t	          |d         ¦  «        }n # t          $ r“}t          t                               t          |                     d¦  «        pg ¦  «        t          |¦  «        gz   ¦  «        ¦  «        |d<   |rt          ||d         ¦  «         t          |¦  «        |d<   |cY d
}~S d
}~ww xY w|rt          ||d         ¦  «         t          |¦  «        |d<   |S )uN   Extract â†’ auto-confirm â†’ calculate â†’ bind to chat session (memory only).r    rW   rV   u&   Could not read usable content from â€œu   â€�.Úerrorr8   r\   Ú	money_outNÚmoney_inrL   Úbank_statementrM   TrT   FrQ   rS   r   )Úcalculate_from_statement_totals)r    r[   Ú
calculatedrU   rX   Úcontext_block)rb   r^   rw   rr   Úcalculate_jobÚapp.pdf.calcr…   r_   r   rG   r~   rp   r/   ÚfromkeysrJ   r	   )	rH   rI   rs   r4   r    Úheaderra   r…   Úexcs	            r   Úingest_pdf_for_chatr�   Æ   s©  € å
  ¨XÑ
6Ô
6€CØ�7Š7�6‰?Œ?Ð ˜b€DØð ˜Ÿš Ñ1Ô1ð °S·W²W¸^Ñ5LÔ5Lð ØNÀÐNÐNÐNˆˆG‰Øð 	=Ý! *¨c°(¬mÑ<Ô<Ð<Øˆ
ð �WŠWÐ'Ñ(Ô(Ð.¨B€FØ‡z‚z�+ÑÔÐ*¨f¯jªj¸Ñ.DÔ.DÑ.PØ�wŠw�Ñ'Ô'Ð;Ð+;ˆØ�9ÒÐØ#ˆDØ#'ˆC�Ñ ð	`Øð $Ý! # h¤-°Ñ6Ô6�Ý# C¨¤MÑ2Ô2��à#'��KÑ Ø',��OÑ$Ø!%��I‘ØHÐHÐHÐHÐHÐHà%DÐ%DÀVÐRTÐ%UÑ%UÔ%U��MÑ"Ø ,��H‘Ýð /ð /Ø+.•E˜#˜hœ-Ñ(ð/ð /ð /ñ /ô /ð /ð /ð /ð /ð /ð /øøøð /ð /ð /ð /å˜sÑ#Ô#Ð#øøÝð 	`ð 	`ð 	`Ý"¥4§=¢=µ°c·g²g¸jÑ6IÔ6IÐ6OÈRÑ1PÔ1PÕTWÐX[ÑT\ÔT\ÐS]Ñ1]Ñ#^Ô#^Ñ_Ô_ˆC�
‰OˆOˆOˆOˆOˆOøøøøð	`øøøàð 	=Ý! *¨c°(¬mÑ<Ô<Ð<Ý1°#Ñ6Ô6ˆˆOÑØˆ
àð 	Ý˜#˜hœ-¨Ñ.Ô.ˆð	Ý  H¤Ñ.Ô.ˆCˆCøÝð 	ð 	ð 	Ý"¥4§=¢=µ°c·g²g¸jÑ6IÔ6IÐ6OÈRÑ1PÔ1PÕTWÐX[ÑT\ÔT\ÐS]Ñ1]Ñ#^Ô#^Ñ_Ô_ˆC�
‰OØð AÝ% j°#°h´-Ñ@Ô@Ð@Ý#5°cÑ#:Ô#:ˆC�Ñ ØˆJˆJˆJˆJˆJˆJøøøøð	øøøð ð 9Ý˜j¨#¨h¬-Ñ8Ô8Ð8å-¨cÑ2Ô2€CˆÑØ€Js]   ÃAE5 Ä=EÅE5 ÅEÅE5 Å!EÅ"E5 Å5
G&Å?AG!Ç!G&È.I É
K!ÉBKËK!ËK!T)Úallow_unbalancedrŽ   c          	     óê  — t          | ¦  «        }|st          d¦  «        ‚|                     d¦  «        s*|                     d¦  «        s|                     d¦  «        s$|                     d¦  «        st          d¦  «        ‚|                     d¦  «        pg }|                     d¦  «        pd	}|                     d
¦  «        pi }|s9|                     d¦  «        €$|                     d¦  «        €t	          d¦  «        ‚|rt          ||¬¦  «        n	dg dddd |dœ}||d<   d„ |                     d¦  «        pg D ¦   «         }|r%t	          dd                     |¦  «        z   ¦  «        ‚|                     d
¦  «        pi                      d¦  «        sfddlm}  ||                     d¦  «        p|                     d¦  «        pd¦  «        }	|	r)|	|d
<   |	}|                     d¦  «        pd	d	k    rd|d<   d}t          |||pd ¬¦  «        }
|dk    r½|                     d¦  «        du r¦d|
d<   d|
d <   |                     d¦  «        pg }|
                     d!d¦  «        d"z   d                     |¦  «        z   d#z   |
d!<   t          t                               t          |                     d$¦  «        pg ¦  «        |z   ¦  «        ¦  «        |d$<   nW|dk    rQ|                     d¦  «        s<|s:t	          dd                     |                     d¦  «        pg ¦  «        z   ¦  «        ‚|
|d%<   ||d<   d&|d'<   t          5  |t          | <   d d d ¦  «         n# 1 swxY w Y   t          |¦  «         |S )(Nrj   rZ   rQ   rS   rT   uZ   Confirm extracted amounts before calculating. Click â€œConfirm amountsâ€�, then Calculate.r    rL   rM   r\   r‚   rƒ   z6No line items to calculate. Add or confirm rows first.rN   Tr   )rO   rm   Ú	row_countÚdebit_totalÚcredit_totalÚbalancedrL   rY   c                ó>   — g | ]}d |                      ¦   «         v ¯|‘ŒS )zno numeric amount)Úlower)r<   Úis     r   ú
<listcomp>z!calculate_job.<locals>.<listcomp>  s0   € ÐcÐcÐc˜ÐBUÐYZ×Y`ÒY`ÑYbÔYbÐBbÐBb�1ÐBbÐBbÐBbr   rm   zValidation failed: z; )Úparse_statement_header_totalsrW   rV   rk   r„   )rL   r\   r“   FrO   Ú
imbalancedÚsummaryz/ | WARNING: debits and credits do not balance (ú)rX   r[   r†   rU   )rh   rn   r^   ÚPermissionErrorÚ
ValueErrorr
   ÚjoinÚapp.pdf.extractr˜   r   rp   r/   rŠ   r_   r   rG   )r8   rŽ   r4   r    ra   r‹   rY   Úhard_issuesr˜   Úparsedr`   rm   s               r   rˆ   rˆ   ÿ   s!  € Ý
�&‰/Œ/€CØð (Ý�Ñ'Ô'Ð'à
‡w‚wˆzÑÔð ˜cŸgšg oÑ6Ô6ð ¸c¿gºgÀiÑ>PÔ>Pð Ø�wŠw�{Ñ#Ô#ð 	Ý!ð?ñô ð ð
 �7Š7�6‰?Œ?Ð ˜b€DØ�7Š7�?Ñ#Ô#Ð0 y€DØ�WŠWÐ'Ñ(Ô(Ð.¨B€FØð SØ�
Š
�;ÑÔÐ+¨v¯zªz¸*Ñ/EÔ/EÐ/QåÐQÑRÔRÐRà<@ð •˜t°4Ð8Ñ8Ô8Ð8ØØØØØØØðGð G€Jð #€CˆÑàcÐc˜zŸ~š~¨hÑ7Ô7Ð=¸2ÐcÑcÔc€KØð IÝÐ.°·²¸;Ñ1GÔ1GÑGÑHÔHÐHð �GŠGÐ&Ñ'Ô'Ð-¨2×2Ò2°;Ñ?Ô?ð (ØAÐAÐAÐAÐAÐAà.Ð.Ø�GŠG�OÑ$Ô$ÐE¨¯ª°Ñ(?Ô(?ÐEÀ2ñ
ô 
ˆð ð 	(Ø&,ˆCÐ"Ñ#ØˆFØ—’˜Ñ(Ô(Ð5¨I¸)ÒCÐCØ'7��OÑ$Ø'�å�t¨4À&À.ÈDÐQÑQÔQ€FØÐÒÐ J§N¢N°:Ñ$>Ô$>À%Ð$GÐ$GØˆˆt‰Ø#ˆˆ|ÑØ—’ Ñ)Ô)Ð/¨Rˆà�JŠJ�y "Ñ%Ô%Ø?ñ@à�iŠi˜ÑÔñ ð ñð 	ˆyÑõ �tŸ}š}­T°#·'²'¸*Ñ2EÔ2EÐ2KÈÑ-LÔ-LÈvÑ-UÑVÔVÑWÔWˆˆJ‰ˆØ	Ð!Ò	!Ð	!¨*¯.ª.¸Ñ*>Ô*>Ð	!ÐGWÐ	!ÝÐ.°·²¸:¿>º>È(Ñ;SÔ;SÐ;YÐWYÑ1ZÔ1ZÑZÑ[Ô[Ð[à€CˆÑØ€CˆÑØ €Cˆ�MÝ	ð ð Ø�ˆf‰ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð å�3ÑÔÐØ€Js   ÍMÍMÍ M)r   r   )r   r   )r    r!   r   r"   )r4   r5   r   r6   )rH   r   rI   rJ   r   r5   )r8   rJ   r   rc   )r8   rJ   r    r"   r   r5   )rs   rJ   r8   rJ   r   r6   )rs   rx   r   rc   )rs   rx   r   r6   )rH   r   rI   rJ   rs   rx   r   r5   )r8   rJ   rŽ   r   r   r5   )%Ú__doc__Ú
__future__r   rC   Ú	threadingÚpathlibr   Útypingr   Ú
app.configr   r   r‰   r   r	   r
   rŸ   r   r   ÚLockr_   r   Ú__annotations__r   r   r   r   r3   rG   rb   rh   rr   rw   rz   r   r�   rˆ   r   r   r   ú<module>rª      s  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ø EÐ EÐ EÐ EÐ EÐ EÐ EÐ EÐ EÐ EØ 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9àˆ	ŒÑÔ€Ø#%€Ð %Ð %Ð %Ñ %Ø "€Ð "Ð "Ð "Ñ "Ø˜Ñ -Ñ/€ð2ð 2ð 2ð 2ðð ð ð ð
ð ð ð ð(ð ð ð ð*ð *ð *ð *ðZð ð ð ð !ð !ð !ð !ðH"ð "ð "ð "ðð ð ð ðð ð ð ð 6ð 6ð 6ð 6ðr <@ð Fð Fð Fð Fð Fð Fð Fð Fr   