
    PkjjV&                        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
 d dlmZ d dlmZ d#dZd$dZd%dZd&dZddd'dZddd(d Zd)d!Zd)d"ZdS )*    )annotations)datedatetime)DecimalInvalidOperation)BytesIO)median)Any)load_workbookvaluer
   returnstrc                    d                     t          | pd                                                                                                                    S )N  )joinr   stripcasefoldsplit)r   s    8src/jarvis_finance/services/household_source_analysis.py_normr      sD    88C$$**,,5577==??@@@    Decimal | Nonec                    t          | pd                                                              dd                              dd          }|sd S d|v rqd|v rm|                    d          |                    d          k    r*|                    dd                              dd          n|                    dd          }nd|v r|                    dd          }	 t	          |          S # t
          $ r Y d S w xY w)Nr   'r   ,.)r   r   replacerfindr   r   )r   texts     r   _decimalr!      s   u{!!##++C44<<S"EED t
d{{sd{{:>**S//DJJWZOO:[:[t||C$$,,S#666aeamamnqsuavav	||C%%t}}   tts    C/ /
C=<C=
str | Nonec                   t          | t          t          f          rOt          | t                    r&|                                                                 n|                                 S t	          | pd                                          d d         }dD ]M}	 t          j        ||                                                                          c S # t          $ r Y Jw xY wd S )Nr   
   )z%Y-%m-%dz%d.%m.%Yz%d/%m/%Y)
isinstancer   r   	isoformatr   r   strptime
ValueError)r   r    fmts      r   _dater*      s    %(D)** ^+5eX+F+F]uzz||%%'''EOOL]L]]u{!!##CRC(D3  	$T3//4466@@BBBBB 	 	 	H	4s   8C
C$#C$rowslist[dict[str, Any]]c           	        g }| D ]O}t          |          }d |                                D             t          d |D             d          }t                              d          pd                                          }t          |          ot          fddD                        }|r|rt          d |d	         D             d          }d
                    d t          |d	                             |          pd                                          |fD                       |d	         |<   5|||<   |	                    |           Q|S )zFold provider continuation records before identity or classification.

    A continuation has descriptive text but no account, booking/value date or amount.
    It extends the preceding logical record and can never become an independent row.
    c                4    i | ]\  }}t          |          |S  r   .0keyr   s      r   
<dictcomp>z(fold_raiffeisen_rows.<locals>.<dictcomp>3   s$    @@@ZS%uSzz5@@@r   c              3  @   K   | ]}t          |          d k    |V  dS r    Nr0   r2   r3   s     r   	<genexpr>z'fold_raiffeisen_rows.<locals>.<genexpr>4   s2      EEc

f0D0D0D0D0D0DEEr   Textr    r   c              3     K   | ]:}t                              |          pd                                           V  ;dS )r   N)r   getr   )r2   r3   lows     r   r8   z'fold_raiffeisen_rows.<locals>.<genexpr>6   sZ       5
 5
 "##))++5
 5
 5
 5
 5
 5
r   )ibanz	booked atzvaluta datezcredit/debit amountc              3  @   K   | ]}t          |          d k    |V  dS r6   r0   r7   s     r   r8   z'fold_raiffeisen_rows.<locals>.<genexpr>;   s2       T TuSzzV?S?S?S?S?S?S T Tr   r   c              3     K   | ]}||V  	d S Nr/   )r2   parts     r   r8   z'fold_raiffeisen_rows.<locals>.<genexpr><   s<       1 1dh11 1 1 1 1 1r   )
dictitemsnextr   r;   r   boolanyr   append)	r+   logicalsourceitemtext_keydescriptioncontinuationprevious_keyr<   s	           @r   fold_raiffeisen_rowsrP   *   s    %'G  F||@@4::<<@@@EEEEEvNN#''&///R006688K(( 
 5
 5
 5
 5
R5
 5
 5
 2
 2
 .
  	G 	 T T T T TV\]]L(+ 1 1"%gbkool&C&C&Ir"J"J"P"P"R"RT_!`1 1 1 ) )GBK% $XtNr   N)has_balancerecordslist[list[str]]rQ   bool | Nonec          
        g }| D ]}d |D             }|rJ|d                                          s0|                                 |r|d                                          0|s^|d                                          sd                    d |dd         D                       }|r_|r]d                    t          |d         d                                                    |f                                           |d         d<   t	          |          d	k     r||nt	          |          d
k    }|rdnd}d                    d |d|          D                       }|                    |d                                          |d                                          |||rdnd                                          |r|d                                          nd|d                                          d           |S )a  Right-align malformed provider rows and fold their continuation lines.

    The provider emits unquoted commas inside descriptions. Amount, balance and
    value date are therefore recovered from the right edge before any identity
    or merchant logic runs.
    c                0    g | ]}t          |pd           S )r   )r   r2   r   s     r   
<listcomp>z5parse_raiffeisen_physical_records.<locals>.<listcomp>P   s$    999u#ekr""999r   r?   r   r   c              3  f   K   | ],}|                                 |                                 V  -d S rA   r   rW   s     r   r8   z4parse_raiffeisen_physical_records.<locals>.<genexpr>V   s7      #[#[eU[[]]#[EKKMM#[#[#[#[#[#[r      Nr9            z, c              3  f   K   | ],}|                                 |                                 V  -d S rA   rZ   rW   s     r   r8   z4parse_raiffeisen_physical_records.<locals>.<genexpr>`   s<      ee%W\WbWbWdWdeeeeeeer      r   )IBANz	Booked Atr9   zCredit/Debit AmountBalancezValuta Date)r   popr   r   lenrH   )	rR   rQ   rI   physicalvaluesrN   row_has_balanceright_columnsrM   s	            r   !parse_raiffeisen_physical_recordsrk   E   s$    %'G  99999 	VBZ--// 	JJLLL  	VBZ--// 	 	ay   	88#[#[vabbz#[#[#[[[L i i&)hhGBK4G0H0H0N0N0P0PR^/_&`&`&f&f&h&hF#v;;?? *5)@++c&kkUVFV,3!iiee6!]NBR;Seeeee1IOO%%**#)*G""R#H#N#N#P#P-<Dvbz'')))"!":++--
 
 	 	 	 	 Nr   as_ofdatabytesrm   dict[str, Any]c                  t          t          |           dd          }g }|j        D ]}d |                    d          D             }|rUt	          d |d         D                       s6|                    d           |rt	          d |d         D                       6|s}|d         }t          |          dk    rt          |d                   nd}|du }|rd	 |D             ng }	t          d
 t          |	          D             d          }
t          d t          |	          D             d          }t          d t          |	          D             d          }t          d t          |	          D             d          }|sd\  }
}}}|
|n|r
|dd         n|}|D ]}|
t          |          k    s|t          |          k    r*t          ||
         pd                                          }t          ||                   }|r|m|<|t          |          k     r)t          ||         pd                                          nd}|(|t          |          k     rt          ||                   n|}|                    |dd         t          |d          ||pdd           |                                 d |D             }dt          |          dt          |          dk    rt          t#          |                    ndt          t%          d |D             t'          d                    d          |dS )zHRead an AKB point-in-time workbook as balances only, never transactions.T)	read_only	data_onlyc                ,    g | ]}t          |          S r/   )tuple)r2   rows     r   rX   z0analyze_akb_balance_workbook.<locals>.<listcomp>u   s    LLL3E#JJLLLr   )values_onlyc              3     K   | ]}|d vV  	dS ))Nr   Nr/   rW   s     r   r8   z/analyze_akb_balance_workbook.<locals>.<genexpr>v   s'      "T"Tu5
#:"T"T"T"T"T"Tr   r   r`   Nc                ,    g | ]}t          |          S r/   r0   rW   s     r   rX   z0analyze_akb_balance_workbook.<locals>.<listcomp>   s    333E5<<333r   c              3  (   K   | ]\  }}|d v 	|V  dS )>   kontoaccountkontobezeichnungNr/   r2   ir   s      r   r8   z/analyze_akb_balance_workbook.<locals>.<genexpr>   s1      xxHAueOwFwFwaFwFwFwFwxxr   c              3  (   K   | ]\  }}|d v 	|V  dS )>   saldobalance
kontostandNr/   r~   s      r   r8   z/analyze_akb_balance_workbook.<locals>.<genexpr>   s1      rrHAueOqFqFqaFqFqFqFqrrr   c              3  (   K   | ]\  }}|d v 	|V  dS )>      währungcurrencywaehrungNr/   r~   s      r   r8   z/analyze_akb_balance_workbook.<locals>.<genexpr>   s1      uuXQuPtGtGtqGtGtGtGtuur   c              3  (   K   | ]\  }}|d v 	|V  dS )>   as ofdatumstichtagNr/   r~   s      r   r8   z/analyze_akb_balance_workbook.<locals>.<genexpr>   s1      ll(!UEMkDkDkADkDkDkDkllr   )r   r`   NNr   CHFx   .2f)account_labelr   r   rm   c                .    h | ]}|d          
|d          S rl   r/   r2   rK   s     r   	<setcomp>z/analyze_akb_balance_workbook.<locals>.<setcomp>   s%    BBBtDMBT']BBBr   account_balance_snapshotc              3  X   K   | ]%}|d          dk    t          |d                   V  &dS )r   r   r   Nr   r   s     r   r8   z/analyze_akb_balance_workbook.<locals>.<genexpr>   s@       m mdSWXbScglSlSli!9!9SlSlSlSl m mr   0)contractsnapshot_counttransaction_countrm   	total_chf	snapshots)r   r   
worksheets	iter_rowsrG   re   rf   r!   rE   	enumerater   r   upperr*   rH   formatcloseitersumr   )rn   rm   workbookr   sheetraw_rowsfirstfirst_balanceheader_modeheadersaccount_indexbalance_indexcurrency_indexas_of_indexsource_rowsrv   labelr   r   row_datedatess                        r   analyze_akb_balance_workbookr   p   s   WT]]ddKKKH&(I$ O OLL%//d/*K*KLLL 	s"T"TQR"T"T"TTT 	LLOOO  	s"T"TQR"T"T"TTT 	 	 /2%jj1nnq***$#t+7BJ33U3333xx	'0B0Bxxxz~rr	'0B0Brrrtxyyuu71C1Cuuuw{||lli.@.@lllnrss 	YHXEM=.+ M$9&1?hqrrllx 		O 		OCC((MSXX,E,EM*0b117799Es=122G GODRD^cqtwx{t|t|c|c|s3~.7%88>>@@@  CHH2=2Ik\_`c\d\dNdNduS-...joHuTcT{vgW\G]G]ks  G  M  KM  N  N  O  O  O  O		O NNBByBBBE.i..&)%jjAood5kk"""4C m mi m m movwzo{o{||  D  E  E  r   c                j   g }g }t                      }g }| D ]}d |                                D             }t          |                    d          p)|                    d          p|                    d                    }|dv rr|                    |           t          |                    d          p|                    d                    }|r|                    |           t          |                    d          pd	                                          }	|	r|                    |	           d
t          |                    d          p|                    d                    v rFt          |                    d                    }
|
"|                    t          |
                     t          |          |rt          |          nd |rt          |          nd t          |          t          |          t          t          |t!          d                    d          dS )Nc                4    i | ]\  }}t          |          |S r/   r0   r1   s      r   r4   z'summarize_visa_rows.<locals>.<dictcomp>   $    BBBZS%uSzz5BBBr   statustransactionstatusbookingstatus>   pendentpending
authorised
authorized
vorgemerktr   
valutadatetransactionidr   zihre zahlungmerchantnamedetailsamountr   r   )booked_transactionsperiod_start
period_endunique_transaction_idspayment_countpayment_total_chf)setrD   r   r;   rH   r*   r   r   addr!   absrf   minmaxr   r   r   )r+   bookedr   transaction_idspaymentsrJ   r<   r   parsed_datetransaction_idr   s              r   summarize_visa_rowsr      s   FE #O H - -BB6<<>>BBBswwx((dCGG4G,H,HdCGGTcLdLdeeUUUfCGGFOODsww|/D/DEE 	&LL%%%SWW_55;<<BBDD 	0///U377>#:#:#Pcggi>P>PQQQQcggh//00F!F,,,"6{{&+5E


$)3c%jjjt"%o"6"6X#C'#,,$?$?GG  r   c                f   i }| D ]}d |                                 D             d                    fddD                       }|                    |t                              d                    t          d          dd          }t                              d	                    }||d
xx         |z  cc<   |dxx         dz  cc<   d |                                D             }d |                                D             }t          |           t          |          |rt          |          nd |rt          |          nd t          |r)t          t          t          |                              nt          d          d          t          d |D                       dddS )Nc                4    i | ]\  }}t          |          |S r/   r0   r1   s      r   r4   z)summarize_migros_rows.<locals>.<dictcomp>   r   r   |c              3  \   K   | ]&}t                              |                    V  'd S rA   )r   r;   )r2   namer<   s     r   r8   z(summarize_migros_rows.<locals>.<genexpr>   s5      {{uSWWT]]++{{{{{{r   )r   zeitfilialekassennummertransaktionsnummerr   r   r   )r   totalr+   umsatzr   r+   r`   c                .    g | ]}|d          
|d          S )r   r/   r2   records     r   rX   z)summarize_migros_rows.<locals>.<listcomp>   s%    NNNvf~NVF^NNNr   c                8    g | ]}t          |d                    S )r   )r   r   s     r   rX   z)summarize_migros_rows.<locals>.<listcomp>   s$    CCCvc&/""CCCr   r   c              3  <   K   | ]}|t          d           k    V  dS )50Nr   )r2   r   s     r   r8   z(summarize_migros_rows.<locals>.<genexpr>   s-      #O#OuEWT]]$:#O#O#O#O#O#Or   )article_rowsreceipt_countr   r   median_receipt_chfreceipts_at_least_50amount_threshold_review_countduplicate_article_rows_removed)rD   r   
setdefaultr*   r;   r   r!   rh   rf   r   r   r   r   r	   r   )	r+   receiptsrJ   r3   r   r   r   totalsr<   s	           @r   summarize_migros_rowsr      s   *,H  BB6<<>>BBBhh{{{{8z{{{{{$$S59I9I3J3JU\]`UaUakl*m*mnn#''(++,,7OOOv%OOOv!NN(//*;*;NNNECC1B1BCCCFD		X&+5E


$)3c%jjjt$V%]WS-@-@%A%A%AQXY\Q]Q]_dee ##O#O#O#O#O O O)**+	 	 	r   )r   r
   r   r   )r   r
   r   r   )r   r
   r   r"   )r+   r,   r   r,   )rR   rS   rQ   rT   r   r,   )rn   ro   rm   r"   r   rp   )r+   r,   r   rp   )
__future__r   r   r   decimalr   r   ior   
statisticsr	   typingr
   openpyxlr   r   r!   r*   rP   rk   r   r   r   r/   r   r   <module>r      s`   " " " " " " # # # # # # # # - - - - - - - -                   " " " " " "A A A A   	 	 	 	   8 =A( ( ( ( ( (V FJ , , , , , ,^   >     r   