
    8j                       d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	m
Z
mZ ddlmZ dZ ej                  d	      Z ej                  d
ej"                        Z ej                  dej"                        Z ej                  dej"                        Z ej                  dej"                        Z ej                  dej"                        ZddZddZy)us  
Chase credit card statement parser — Story 9.7.

Tested against: Chase Amazon Prime Visa, account ending 4086, period 04/14/26–05/13/26.

Format (ACCOUNT ACTIVITY section):
  MM/DD  Description  Amount

Note: The "ACCOUNT ACTIVITY" header is in doubled-character format in some PDFs
(e.g. "AACCCCOOUUNNTT AACCTTIIVVIITTYY"). We detect sections by their normal-text
section headers (PAYMENTS AND OTHER CREDITS, PURCHASE, INTEREST CHARGED).

State machine:
  NONE → PAYMENTS  (on "PAYMENTS AND OTHER CREDITS")
  PAYMENTS → PURCHASES  (on "PURCHASE[S]?")
  PURCHASES → DONE  (on "INTEREST CHARGED" or "TOTAL INTEREST")
    )annotationsN)date)Decimal)StagedTransaction
ParseErrorcompute_dedup_hash)	normalizez2.0.0z<^(\d{2}/\d{2})\s+(.+?)\s+([-]?\d{1,3}(?:,\d{3})*\.\d{2})\s*$z^PAYMENTS AND OTHER CREDITS$z^PURCHASE[S]?$z^(INTEREST CHARGED|TOTAL INTEREST|FEES CHARGED|2\d{3} Totals|QUALIFIED PROMOTIONAL|IINNTTEERREESSTT|AACCCCOOUUNNTT(?! AACCTTIIVVIITTYY))z^(Order Number|Equal Pay applied|Date of|Transaction\s+Merchant|\$ Amount|Manage your account|Page \d+ of|www\.chase|SAYRE |0000001 |A50001)z)PURCHASE INTEREST CHARGE|CASH ADVANCE FEEc                D   	 ddl }g }g }	 |j	                  |       5 }g }t        |j                  d      D ]N  \  }}|j                         xs dj                  d      D ]#  }|j                  ||j                         f       % P 	 ddd       t              }	d}
|D ]  \  }}|s
t        j                  |      rd	}
"t        j                  |      r|
d
v rd}
>t        j                  |      r|
d
v rd}
Z|
d
vr_t         j                  |      rut"        j                  |      }|s|j%                  d      }|j%                  d      j                         }|j%                  d      }t&        j)                  |      r	 t+        |dd       t+        |dd       }}t-        |	||      }	 t3        |j5                  dd            }|t3        d      k  xs |
d	k(  }t9        |      }t;        |      }t=        |||      }|j                  t?        |||||d|d|	              	 ||fS # t        $ r g t        dddt              gfcY S w xY w# 1 sw Y   xY w# t.        $ r5}|j                  t        ||t1        |      t                     Y d}~d}~ww xY w# t6        $ r5}|j                  t        ||t1        |      t                     Y d}~8d}~ww xY w# t6        $ r7}|j                  t        dt1        |      dt                     Y d}~||fS d}~ww xY w)z(Parse a Chase credit card statement PDF.r   N zpdfplumber not installed   )start
nonepayments)r   	purchasesr   done      ,0chaseg?)	r   merchant_rawmerchant_normalizedamount	is_creditissuer
dedup_hashconfidence_scoreraw_textzFailed to open or read PDF) 
pdfplumberImportErrorr   _PARSER_VERSIONopen	enumeratepagesextract_textsplitappendstrip_extract_year_STARTS_PAYMENTSmatch_STARTS_PURCHASES_ENDS_TRANSACTIONS_SKIP_RE_TXN_REgroup_INTEREST_DESC_REsearchintr   
ValueErrorstrr   replace	Exceptionabsr	   r   r   )pdf_pathr    transactionserrorspdf	all_linespage_numpagelinestatement_yearstatemdate_strdescription
amount_strmonthdaytxn_dateexcr   r   
abs_amountnormr   s                           :/var/www/html/financials/app/services/pdf_parsers/chase.pyparserO   5   s2   T -/L!FR^__X& 	?#/1I"+CIIQ"? ?$!..06B==dC ?D$$h

%=>??	? 'y1 ' A	NHd  %%d+" &&t,55'E!''-55"E55 ~~d# d#AwwqzH''!***,KJ !''4 "1.HQRL0Ass;
 !3!3C!<=
 -D*1DIVJ[)D+D*hGJ 1($(!#%!%
! 
oA	L u  TJq"&@/RSSST	? 	?j  j4S?ST  j4S?ST*  ^jCH.JO\]]^s   H, K A+IC;K )I.J	AK ,IIIK 	J&*JK JK 	K'*KK KK 	L(*LLc                   ddl }| D ]  \  }}t        j                  d|t        j                        }|r<|j	                  d      }t        |      dk(  rt        |      c S dt        |      z   c S t        j                  d|t        j                        }|s|j	                  d      }t        |      dk(  rt        |      c S dt        |      z   c S  |j                   j                         j                  S )zGExtract statement year from 'Opening/Closing Date MM/DD/YY - MM/DD/YY'.r   Nz,Opening/Closing Date\s+\d{2}/\d{2}/(\d{2,4})r      i  z'Statement Date:\s+\d{2}/\d{2}/(\d{2,4}))	datetimerer3   Ir1   lenr4   nowyear)linesrR   _rA   rD   yrm2s          rN   r*   r*      s     	?4IIEtRTTRB!"gl3r7>s2w>YYA4N!B!"gl3r7>s2w>	?   "'''    )r:   r6   returnz0tuple[list[StagedTransaction], list[ParseError]])rX   zlist[tuple[int, str]]r]   r4   )__doc__
__future__r   rS   rR   r   decimalr   app.services.pdf_parsers.baser   r   r    app.services.merchant_normalizerr	   r"   compiler0   rT   r+   r-   r.   r/   r2   rO   r*    r\   rN   <module>re      s   " # 	   [ [ 6 "**C
  RZZ ?F RZZ 12448 RZZ ![\^\`\`b 
 2:: DD	 BJJKRTTR ^ B(r\   