
    bkj7                        d dl mZ d dlZd dlmZ d dlmZ d dlZd dlm	Z	m
Z
mZmZ d dlmZ d dlmZ d dlmZ d	Zd
 Zd%d&dZd'dZd(dZd Zd Zd Zd Zd Zd Zd Zd Z d  Z!d! Z"d" Z#d# Z$d$ Z%dS ))    )annotationsN)Decimal)sha256)TrueWealthCashTrueWealthPositionTrueWealthStatementparse_truewealth_text)truewealth_service)connect_memory)apply_migrationsaccount_truewealth_testc                    t                      } t          |            |                     d           |                     dt          f           |                     dt          f           |                                  | S )NzINSERT INTO platforms(platform_id,name,platform_type,country,default_currency,is_active,created_at) VALUES('p','True Wealth','robo','CH','CHF',1,'2026-01-01')zINSERT INTO accounts(account_id,platform_id,account_name,account_type,currency,performance_included,is_active,created_at,portfolio_bucket)
           VALUES(?,'p','Manual Portfolio','managed_portfolio','CHF',0,1,'2026-01-01','truewealth')a  INSERT INTO account_value_snapshots(snapshot_id,account_id,valuation_date,total_value_chf,currency,source_type,quality_status,notes,created_at)
           VALUES('legacy_manual',?,'2026-06-30','10000','CHF','manual_total_value','ok','historical','2026-06-30T12:00:00Z'))r   r   executeTEST_ACCOUNT_IDcommit)conns    !tests/test_truewealth_sprint12.py	make_connr      s    DTLL 	i   	LL	g	  
 	LL	A	  
 	KKMMMK    
2026-07-2712000rawbytesdatestrtotalreturnr   c                   t          |d|t          |          t          dddt          d          dt          d          t          d                    t          d	d
dt          d          dt          d          t          d                    ft          ddt          d          d t          d                    ft	          |                                           d          S )Nz
2026-01-01zposition:CH0000000001zSynthetic ETF ACH0000000001100CHF505000zposition:US0000000002zSynthetic ETF BUS0000000002202004000zcash:CHF3000   )statement_dateperiod_from	period_tosource_total_chf	positionscashfile_sha256
page_count)r   r   r   r   r   	hexdigest)r   r   r   s      r   	statementr3   *   s     68I>[bch[i[ikpryz~rr  BI  JP  BQ  BQ  R  R68I>[bcg[h[hjoqxy~qq  BI  JP  BQ  BQ  R  R
 ZwvWWY3KK))++   r   dict[str, str]c                `    t           dt          j        |                                           dS )Nzofficial.pdf)
account_id	file_namecontent_base64)r   base64	b64encodedecode)r   s    r   import_requestr<   :   s1    %# *3//6688  r   c                    t          |          }t          j        | |          }t          j        | i ||d         |d         dd          S )N
preview_idconfirmation_idTr>   r?   confirm)r<   servicepreview_truewealth_importconfirm_truewealth_import)r   r   requestpreviews       r   confirm_importrG   B   s\    S!!G/g>>G,x7x',"7GTeLfswxxx  r   c                 *   d} t          | dd          }|j        dk    sJ |j        t          d          k    sJ |j        d         j        dk    sJ |j        d         j        t          d	          k    sJ |j        t          d
          k    sJ d S )Nuy  
True Wealth AG
Periode 01.01.2026 - 27.07.2026
Steuerauszug in CHF 27.07.2026
Total Steuerwert der A, B, DA-1 und USA-Werte am 27.07.2026
12’000 0 0 0
CHF (Synthetic Custodian AG)
27.07.2026 Steuerwert / Ertrag CHF 7’000.00 7’000.00 0.00
0000000 CH0000000001 - Synthetic ETF A, CH
27.07.2026 Bestand / Steuerwert / Ertrag 100.00 CHF 50.00 5’000.00 0.00
True Wealth AG
	synthetic   )r0   r1   r   r   r   r   z7000.0012000.00)	r	   r*   r-   r   r.   isinr/   amount_originalcomponents_total_chf)textparseds     r   @test_text_parser_extracts_official_rows_without_inventing_valuesrQ   K   s    D #4[QOOOF L0000"gg&6&66666A#~5555;q>)WY-?-?????&'**=*=======r   c                    t                      } t          j        |           }|d         dk    sJ |d         du sJ d|d                                         v sJ |d         du sJ t          j        | d	dd
dd           t          j        |           }|d         J t          d |d         D                       sJ d S )Ncurrent_source_typemanual_total_valuecurrent_is_manual_provisionalTmanuellcurrent_labelallocation_performance_usableFlegacy_manual
reversibleactivenoterA   current_value_chfc              3  F   K   | ]}|d          dk    o|d         dk    V  dS )snapshot_idrY   	is_activer   N ).0rows     r   	<genexpr>zItest_legacy_manual_value_is_never_labelled_as_official.<locals>.<genexpr>j   s<      nnSVs=!_4N[9IQ9Nnnnnnnr   history)r   rB   get_truewealth_summarylower"set_manual_truewealth_value_activeany)r   summarydisableds      r   6test_legacy_manual_value_is_never_labelled_as_officialrm   `   s    ;;D,T22G()-AAAAA23t;;;;06688888823u<<<<.t_QV`ly}F~F~-d33H'(000nnZbclZmnnnnnnnnnnr   c                t   t                      }|                    d           |                    d           |                                 d}|                     t          dd            t	          j        |t          |                    }|d         dk    sJ t	          j        |          d         J d S )	Nz<UPDATE platforms SET name='TrueWealth' WHERE platform_id='p'z#DELETE FROM account_value_snapshotss   %PDF-synthetic-bootstrapparse_truewealth_tax_statementc                     t          |           S Nr3   values    r   <lambda>zRtest_platform_spelling_without_space_and_empty_account_bootstrap.<locals>.<lambda>s       QZ[`QaQa r   reconciliation_statusmatchedr^   )r   r   r   setattrrB   rC   r<   rg   )monkeypatchr   r   rF   s       r   @test_platform_spelling_without_space_and_empty_account_bootstrapr{   m   s    ;;DLLOPPPLL6777KKMMM
%C!ACaCabbb/nS6I6IJJG*+y8888)$//0CDLLLLLr   c                   t                      }d}|                     dt          |                     |                     t          dd            t          ||          }t          ||          }t	          j        |          }|d         du sJ |d         du sJ |d         |d         k    sJ |d	         d
k    sJ |d         dk    sJ |d         du sJ t          |d                   dk    sJ |                    d          	                                d         dk    sJ |                    d          	                                d         dk    sJ |                    dt          f          	                                }t          |          dk    sJ |                    dt          f          	                                d         dk    sJ |dz  dz  dz  t          |                                           dz  }|                                |k    sJ |                                j        dz  dk    sJ d S )Ns   %PDF-1.7 official-aJARVIS_FINANCE_RUNTIME_DIRro   c                     t          |           S rq   rr   rs   s    r   ru   zStest_official_confirm_is_idempotent_preserves_legacy_and_archives.<locals>.<lambda>}   rv   r   
idempotentFTbatch_idr^   rK   rS   truewealth_official_importrX   r.      zNSELECT COUNT(*) FROM account_value_snapshots WHERE snapshot_id='legacy_manual'r   rJ   .SELECT COUNT(*) FROM truewealth_import_batcheszySELECT included,classification_role,decision_version
           FROM performance_scope_classifications WHERE account_id=?)rJ    canonical_truewealth_total_valueinvestment_performance_scope_v1znSELECT COUNT(*) FROM audit_log
           WHERE entity_type='performance_scope_classification' AND entity_id=?imports
truewealtharchivez.pdfi  i  )r   setenvr   ry   rB   rG   rg   lenr   fetchoner   tupler   r2   
read_bytesstatst_mode)	rz   tmp_pathr   r   firstsecondrk   classificationarchiveds	            r   Atest_official_confirm_is_idempotent_preserves_legacy_and_archivesr   y   s   ;;D
 C3S]]CCC!ACaCabbb4%%ED#&&F,T22G%'''',4''''*z!22222&':5555()-IIIII23t;;;;w{#$$))))<<hiirrttuvw{|||||<<HIIRRTTUVW[\\\\\\\	H	  hjj	 
   $nnnnn<<	S	  hjj	 	   
 )#l2Y>F3KKDYDYD[D[AaAaAaaH  C''''==??"U*e333333r   c                   t                      }d}|                     dt          |                     |                     t          dd            t          ||           dddd}t	          j        ||          }t	          j        |i ||d	         |d
         dd          t	          j        |          }|d         dk    sJ |d         du sJ |d         dk    sJ |d         du sJ |d         du sJ t          |d                   dk    sJ t	          j
        |d         dddd           t	          j        |          }|d         dk    sJ |d         dk    sJ t          fd|d         D                       sJ t	          j
        |d         dddd           t	          j        |          d         dk    sJ d S ) Ns   %PDF-1.7 official-br}   ro   c                     t          |           S rq   rr   rs   s    r   ru   z]test_newer_manual_value_wins_without_changing_positions_and_can_be_reversed.<locals>.<lambda>   rv   r   125002026-07-28T08:00:00Zzportal viewtotal_value_chfvaluation_atr]   r>   r?   Tr@   r^   12500.00rU   positions_snapshot_dater   mixed_as_ofrX   Fr.   r   r`   revertr[   rK   rS   r   c              3  T   K   | ]"}|d          d          k    o|d         dk    V  #dS )r`   ra   r   Nrb   )rc   rd   results     r   re   z^test_newer_manual_value_wins_without_changing_positions_and_can_be_reversed.<locals>.<genexpr>   sC      ttY\s=!VM%::Ts;?OST?Tttttttr   rf   
reactivate)r   r   r   ry   rB   rG   preview_manual_truewealth_valueconfirm_manual_truewealth_valuerg   r   ri   rj   )	rz   r   r   r   payloadrF   rk   restoredr   s	           @r   Ktest_newer_manual_value_wins_without_changing_positions_and_can_be_reversedr      sc   ;;D
 C3S]]CCC!ACaCabbb4");Q[hiiG5dGDDG4x7x',"7GTeLfswxxx F ,T22G&':555523t;;;;,-=====!T))))23u<<<<w{#$$)))).tVM5JW\fn{  MA  MA  B  B  B-d33H'(J6666)*.JJJJJtttt`hir`stttttttt.tVM5JW[eq  C  MD  MD  E  E  E)$//0CD
RRRRRRr   c                   t                      }|                     dt          |                     dd}|                     t          dfd           t          |           dddd	}t	          j        ||          }t	          j        |i ||d
         |d         dd           t          ||           t	          j        |          }|d         dk    sJ |d         dk    sJ d S )Nr}   s   %PDF-1.7 official-news   %PDF-1.7 official-oldro   c                4    t          | | k    rdnd          S )Nr   z
2026-07-20rr   )rt   
newest_raws    r   ru   zItest_older_official_import_cannot_displace_newer_manual.<locals>.<lambda>   s>    QZ[`rw  |F  sF  sFbnbn  LX  RY  RY r   r   r   znewer manualr   r>   r?   Tr@   r^   r   r   r   )	r   r   r   ry   rB   rG   r   r   rg   )rz   r   r   old_rawr   rF   rk   r   s          @r   7test_older_official_import_cannot_displace_newer_manualr      sP   ;;D3S]]CCC)J&G!A  DY  DY  DY  DY  Z  Z  Z4$$$");Q[ijjG5dGDDG+D  3cW  3cGT`Lav}  P  wQ  ^b  3c  3c  3c  d  d  d4!!!,T22G&':5555,-======r   c                   t                      }|                     dt          |                     dddd}t          j        ||          }t          j        |i ||d         |d         dd	           d
}|                     t          dd            t          ||           t          j        |          d         dk    sJ d S )Nr}   11500z2026-07-27T22:00:00Zzsame dayr   r>   r?   Tr@   s   %PDF-1.7 same-dayro   c                     t          |           S rq   rr   rs   s    r   ru   zAtest_same_day_official_has_priority_over_manual.<locals>.<lambda>   rv   r   rS   r   )	r   r   r   rB   r   r   ry   rG   rg   )rz   r   r   r   rF   r   s         r   /test_same_day_official_has_priority_over_manualr      s    ;;D3S]]CCC");Q[effG5dGDDG+D  3cW  3cGT`Lav}  P  wQ  ^b  3c  3c  3c  d  d  d
C!ACaCabbb4)$//0EFJfffffffr   c                    t                      }d}|                     t          dd            |j        }t          j        |t          |                     t          j        |           |j        |k    sJ d S )Ns   %PDF-1.7 preview-onlyro   c                     t          |           S rq   rr   rs   s    r   ru   z;test_preview_and_get_are_side_effect_free.<locals>.<lambda>   rv   r   )r   ry   rB   total_changesrC   r<   rg   )rz   r   r   befores       r   )test_preview_and_get_are_side_effect_freer      s{    ;;D
"C!ACaCabbbF%dN3,?,?@@@"4(((''''''r   c                   t                      }d}|                     dt          |                     |                     t          dd            t          ||          }t          j        t          d          5  |	                    d|d         f           d d d            n# 1 swxY w Y   t          j        t          d	          5  |	                    d
|d         f           d d d            d S # 1 swxY w Y   d S )Ns   %PDF-1.7 immutabler}   ro   c                     t          |           S rq   rr   rs   s    r   ru   zGtest_immutable_source_tables_reject_update_and_delete.<locals>.<lambda>   rv   r   	immutablematchzHUPDATE truewealth_snapshots SET source_total_chf='0' WHERE snapshot_id=?r`   cannot be deletedz4DELETE FROM truewealth_snapshots WHERE snapshot_id=?)
r   r   r   ry   rB   rG   pytestraises	Exceptionr   )rz   r   r   r   r   s        r   5test_immutable_source_tables_reject_update_and_deleter      s   ;;D
C3S]]CCC!ACaCabbbD#&&F	y	4	4	4 { {_bhivbwayzzz{ { { { { { { { { { { { { { {	y(;	<	<	< g gKfUbNcMefffg g g g g g g g g g g g g g g g g gs$   <B&&B*-B*C77C;>C;c           	        t                      }|                     dt          |                     d|                     t          dfd           t                    }t	          j        ||          }|                    d           t          j	        t          d          5  t	          j        |i ||d         |d	         d
d           d d d            n# 1 swxY w Y   t          |dz  dz  dz                      d                    rJ |                    d                                          d         dk    sJ d S )Nr}   s   %PDF-synthetic-rollbackro   c                "    t                    S rq   rr   )_rawr   s    r   ru   z;test_confirm_rollback_removes_new_archive.<locals>.<lambda>   s    PYZ]P^P^ r   z{CREATE TRIGGER force_truewealth_failure BEFORE INSERT ON truewealth_import_batches BEGIN SELECT RAISE(ABORT, 'forced'); END
conflictedr   r>   r?   Tr@   r   r   r   z*.pdfr   r   )r   r   r   ry   rB   r<   rC   r   r   r   
ValueErrorrD   listglobr   )rz   r   r   rE   rF   r   s        @r   )test_confirm_rollback_removes_new_archiver      s   ;;D3S]]CCC
$C!AC^C^C^C^___S!!G/g>>GLL	3   
z	6	6	6 
 
)|w|gl&;PWXiPjw{|||	
 	
 	

 
 
 
 
 
 
 
 
 
 
 
 
 
 

 X	)L89DJJ7SSTTTTT<<HIIRRTTUVW[\\\\\\\s   (*CC"%C"c           	     @   t                      }|                     dt          |                     |                     t          dd            t          |d           t          d          }t	          j        ||          }|d         du sJ t          j	        t          d	          5  t	          j        |i ||d
         |d         dd           d d d            n# 1 swxY w Y   |                    d                                          d         dk    sJ d S )Nr}   ro   c                     t          |           S rq   rr   rs   s    r   ru   zEtest_same_date_different_official_source_is_blocked.<locals>.<lambda>  rv   r   s   %PDF-1.7 source-ones   %PDF-1.7 source-twoconflictTz$different official TrueWealth sourcer   r>   r?   r@   r   r   rJ   )r   r   r   ry   rB   rG   r<   rC   r   r   r   rD   r   r   )rz   r   r   r   rF   s        r   3test_same_date_different_official_source_is_blockedr      sk   ;;D3S]]CCC!ACaCabbb4/000233F/f==G:$&&&&	z)O	P	P	P 
 
){v{W\%:wWhOivz{{{	
 	
 	

 
 
 
 
 
 
 
 
 
 
 
 
 
 

 <<HIIRRTTUVW[\\\\\\\s   **C  C$'C$c            	         t                      } dD ]N}t          j        t          d          5  t	          j        | |ddd           d d d            n# 1 swxY w Y   Od S )N)NaNInfinityz	-Infinityzpositive finiter   r    r   )r   r   r   r   rB   r   )r   rt   s     r   *test_manual_non_finite_values_are_rejectedr     s    ;;D1  ]:->??? 	 	3$);Q[]^^  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 s   AA	A	c                    t                      } dddd}t          j        | |          }t          j        | i ||d         |d         dd          }t	          j        t          d	
          5  |                     d|d         f           d d d            n# 1 swxY w Y   t	          j        t          d
          5  |                     d|d         f           d d d            d S # 1 swxY w Y   d S )Nr   r   zimmutable valuer   r>   r?   Tr@   zfields are immutabler   zJUPDATE account_value_snapshots SET total_value_chf='1' WHERE snapshot_id=?r`   r   z7DELETE FROM account_value_snapshots WHERE snapshot_id=?)r   rB   r   r   r   r   r   r   )r   r   rF   r   s       r   4test_manual_value_is_not_hard_deleted_or_overwrittenr     s   ;;D");Q[lmmG5dGDDG4x7x',"7GTeLfswxxx F 
y(>	?	?	? } }adjkxdyc{|||} } } } } } } } } } } } } } }	y(;	<	<	< j jNQWXeQfPhiiij j j j j j j j j j j j j j j j j js$   .BBB>C))C-0C-)r   r   )r   r   r   r   r   r   r   r   )r   r   r   r4   )r   r   )&
__future__r   r9   decimalr   hashlibr   r   /jarvis_finance.imports.truewealth_tax_statementr   r   r   r	   jarvis_finance.servicesr
   rB   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r   r3   r<   rG   rQ   rm   r{   r   r   r   r   r   r   r   r   r   r   rb   r   r   <module>r      s   " " " " " "                          B A A A A A : : : : : : > > > > > >+  (           > > >*
o 
o 
o	M 	M 	M 4  4  4FS S S<> > > 	g 	g 	g( ( (	g 	g 	g] ] ](] ] ]   j j j j jr   