
    aj;$                        d dl mZ d dlZd dlmc mZ d dlm	Z	 d dl
Z
d dlmZmZ d dlmZmZ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dZddZddZddZddZ ddZ!ddZ"ddZ#ddZ$ddZ%ddZ&dS )    )annotationsN)Decimal)calculate_crypto_holdingscreate_initial_holding_snapshot) CRYPTO_MANUAL_REVIEW_COIN_LABELSadd_crypto_positionadjust_crypto_positionget_crypto_management_optionsreduce_crypto_positiontransfer_crypto_positioncreate_wallet)connect_memory)apply_migrationsc                 @    t                      } t          |            | S )N)r   r   conns    X/home/agent/.hermes/worktrees/FinanceManager-sprint0-v2/tests/unit/test_crypto_manage.py
setup_connr      s     DTK    returnstrc                &    t          | dd          S )NzSynthetic Review WalletzSoftware Walletwallet_namewallet_typer   r   s    r   seed_walletr      s    +DRcddddr   c                &    t          | dd          S )NzSynthetic Target WalletExchanger   r   r   s    r   seed_second_walletr       s    +DR\]]]]r   actionintc                `    |                      d|f                                          d         S )Nz2SELECT COUNT(*) AS c FROM audit_log WHERE action=?c)executefetchone)r   r!   s     r   audit_countr'   #   s+    <<LviXXaaccdghhr   Nonec                    t                      } t          |           }t          | ddd|ddddd	
  
        }|                     d
|j        f                                          }|                     d|j        f                                          }|d         }d}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}|d         }d}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}|d         }d}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}d}t          | |          }
d}|
|k    }|st          j        d|fd|
|f          dt          j                    v st          j        t                    rt          j	        t                    nddt          j                    v st          j        |           rt          j	        |           ndt          j	        |          t          j	        |
          t          j	        |          dz  }dd|iz  }t          t          j        |                    d x}x}
x}}|j        }g }
||
k    }|st          j        d|fd||
f          dt          j                    v st          j        |          rt          j	        |          ndt          j	        |          t          j	        |
          dz  }dd |iz  }t          t          j        |                    d x}x}}
d S )!NzSynthetic CardanoADAcardano
0.00000001
2025-12-31initial_snapshot_additionzsynthetic confirmed additionT		coin_namesymbolcoingecko_id	wallet_idquantity_texteffective_dateoperation_typenoteconfirmz7SELECT * FROM crypto_holdings WHERE crypto_holding_id=?z,SELECT * FROM crypto_assets WHERE asset_id=?quantity==z%(py1)s == %(py4)spy1py4assert %(py6)spy6legacy_snapshot_dater2   initial_crypto_holding_snapshot   z9%(py5)s
{%(py5)s = %(py0)s(%(py1)s, %(py3)s)
} == %(py8)sr'   r   py0r>   py3py5py8assert %(py10)spy10)z0%(py2)s
{%(py2)s = %(py0)s.warnings
} == %(py5)sresult)rG   py2rI   assert %(py7)spy7)r   r   r   r%   
holding_idr&   asset_id
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanationr'   @py_builtinslocals_should_repr_global_namewarnings)r   r3   rM   holdingasset@py_assert0@py_assert3@py_assert2@py_format5@py_format7@py_assert4@py_assert7@py_assert6@py_format9@py_format11@py_assert1@py_format6@py_format8s                     r   Btest_add_initial_snapshot_addition_creates_asset_holding_and_auditrk   '   s   <<DD!!I %"#2+  F llTW]WhVjkkttvvGLLG&/I[\\eeggE:.,.,..........,.........,...........................)*:l:*l::::::::::*l:::::*::::l::::::::::::::::::::::::::: -I- I---------- I----- ----I--------------------------->D;t>??D1D?1DDDDDDDDDD?1DDDDDDDDDDDD;DDDDD;DDDDDDDDDDDDDtDDDDDtDDDDDD>DDDD?DDDD1DDDDDDDDDDDDDDDDDDDDDDDDDDDDD? b ?b          ?b            6     6      ?    b                             r   c                    t                      } t          |           }t          | ddd |dddddd	          }|                     d
|j        f                                          d         }d}||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j        |                    d x}}|                     d                                          d         }d}	||	k    }|slt          j        d|fd||	f          t          j        |          t          j        |	          dz  }
dd|
iz  }t          t          j        |                    d x}x}}	d}|j        }||v }|st          j        d|fd||f          t          j        |          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dz  }dd |iz  }t          t          j        |                    d x}x}}d S )!NzSynthetic MysteryMYSTr,   r-   r.   z$synthetic uncertain mapping acceptedmissing_confirmedT)
r0   r1   r2   r3   r4   r5   r6   r7   coingecko_statusr8   z>SELECT quantity FROM crypto_holdings WHERE crypto_holding_id=?r9   r:   )z%(py0)s == %(py3)sstored)rG   rH   assert %(py5)srI   zESELECT COUNT(*) AS c FROM alerts WHERE rule_id='missing_coingecko_id'r$   rD   )>=)z%(py1)s >= %(py4)sr=   r@   rA   missing_coingecko_idin)z0%(py1)s in %(py5)s
{%(py5)s = %(py3)s.warnings
}rM   )r>   rH   rI   rO   rP   )r   r   r   r%   rQ   r&   rS   rT   rX   rY   rZ   rU   rV   rW   r[   )r   r3   rM   rp   r`   rh   @py_format4ri   r^   r_   ra   rb   rc   rj   s                 r   Mtest_add_coin_without_coingecko_id_creates_warning_and_preserves_decimal_textrw   A   s   <<DD!!I %"#23,  F \\Z]c]n\pqqzz||  ~H  IF!!6\!!!!!!!!!!6\!!!!!!!!!!!!6!!!!!6!!!!!!\!!!!!!!!!!!!!!!!!!!!!!!!!<<_``iikkloputuuptuuuuuuuuuuuptuuuuuupuuuutuuuuuuuuuuuuuuuuuuuuuuuuuuuu!4V_4!_4444444444!_44444!44444444444V44444V444444_44444444444444444444444444444r   c                    t                      } t          |           }t          | ddd|ddddd	
  
        }t          j        t
          d
          5  t          | |j        |dddd           d d d            n# 1 swxY w Y   t          | |j        |dddd          j        }t          |           }|j
        ||j        f         }|j        }d}t          |          }||k    }	|	st          j        d|	fd||f          t          j        |          t          j        |          dt!          j                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |          dz  }
dd|
iz  }t'          t          j        |                    d x}x}x}	x}}|                     d|f                                          }d}|d         }||v }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t'          t          j        |                    d x}x}}d}|d          }||v }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t'          t          j        |                    d x}x}}d S )!NzSynthetic BitcoinBTCbitcoinz1.25r-   r.   synthetic initialTr/   r7   matchz1.30z
2026-01-15 rR   r3   new_quantity_textr5   r7   r8   zsynthetic correction noter:   zN%(py3)s
{%(py3)s = %(py1)s.quantity
} == %(py9)s
{%(py9)s = %(py5)s(%(py7)s)
}r   r>   rH   rI   rP   py9assert %(py11)spy11znSELECT old_values_json, new_values_json FROM audit_log WHERE entity_id=? AND action='crypto_manual_adjustment'z"quantity": "1.25"old_values_jsonrt   z%(py1)s in %(py4)sr=   r@   rA   z"quantity": "1.30"new_values_json)r   r   r   pytestraises
ValueErrorr	   rR   transaction_idr   wallet_holdingsr9   r   rS   rT   rU   rX   rY   rZ   rV   rW   r%   r&   )r   r3   addedtxidholdingsr^   r`   re   @py_assert8rc   @py_format10@py_format12auditr_   ra   rb   s                   r   ?test_manual_adjustment_requires_note_and_records_old_new_valuesr   Y   s   <<DD!!I%#2   E 
z	0	0	0 	
 	
^$'	
 	
 	
 	
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 " #(    	 )..H#Y$?@\@I\U[\WU[__\I_\\\\\\\\\\I_\\\\\@\\\\I\\\\\\\\\\\W\\\\\W\\\\\\U[\\\\_\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\LL  J  MQ  LS  T  T  ]  ]  _  _E;5):#;;#;;;;;;;;;;;#;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5):#;;#;;;;;;;;;;;#;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;s   A::A>A>c                    t                      } t          |           }t          | ddd|ddddd	
  
        }t          | |j        |dd
dd           |                     d|j        |f                                          d         }d}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd|iz  }t          t          j        |                    d x}x}}t          |           j        ||j        f         }|j        }d}t          |          }	||	k    }
|
st          j        d|
fd||	f          t          j	        |          t          j	        |          dt!          j                    v st          j        t                    rt          j	        t                    ndt          j	        |          t          j	        |	          dz  }dd|iz  }t          t          j        |                    d x}x}x}
x}}	t'          j        t*          d          5  t          | |j        |dd
dd           d d d            d S # 1 swxY w Y   d S )NSynthetic EtherETHethereum2r-   r.   r{   Tr/   z
2026-02-01zsynthetic remove via adjustment)rR   r3   reduction_quantity_textr5   r7   r8   zJSELECT COUNT(*) AS c FROM crypto_holdings WHERE asset_id=? AND wallet_id=?r$   rD   r:   r<   r=   r@   rA   0r   r   r   r   r   negativer|   r,   zsynthetic over reduce)r   r   r   r   rR   r%   r&   rS   rT   rU   rV   rW   r   r   r9   r   rX   rY   rZ   r   r   r   )r   r3   r   r^   r_   r`   ra   rb   re   r   rc   r   r   s                r   Ltest_reduce_to_zero_preserves_holding_row_without_delete_and_blocks_negativer      s   <<DD!!I##2   E  ##.    <<dglgu  xA  gB  C  C  L  L  N  N  OR  S  X  WX  X  S  WX  X  X  X  X  X  X  X  X  X  X  S  WX  X  X  X  X  X  S  X  X  X  X  WX  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X$T**:Iu~;VWpW`plopdklodpdpp`dppppppppppp`dppppppWpppp`pppppppppppdkpppppdkpppppploppppdpppppppppppppppppppppppppppppppp	z	4	4	4 	
 	
^$0'(	
 	
 	
 	
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
s   I,,I03I0c                    t                      } t          |           }t          |           }t          | ddd|ddddd	
  
        }t	          | |j        ||d
dddd	  	        }t          |           }|j        ||j        f         }|j        }d}t          |          }	||	k    }
|
st          j        d|
fd||	f          t          j        |          t          j        |          dt          j                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |	          dz  }dd|iz  }t!          t          j        |                    d x}x}x}
x}}	|j        ||j        f         }|j        }d
}t          |          }	||	k    }
|
st          j        d|
fd||	f          t          j        |          t          j        |          dt          j                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |	          dz  }dd|iz  }t!          t          j        |                    d x}x}x}
x}}	|j        }|sxddt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }t!          t          j        |                    d }d}t'          | |          }
d}|
|k    }|st          j        d|fd|
|f          dt          j                    v st          j        t&                    rt          j        t&                    nddt          j                    v st          j        |           rt          j        |           ndt          j        |          t          j        |
          t          j        |          dz  }dd |iz  }t!          t          j        |                    d x}x}
x}}d S )!Nr   r   r   4r-   r.   r{   Tr/   z1.5z0.1z
2026-03-01zsynthetic transfer)rR   from_wallet_idto_wallet_idr4   fee_quantity_textr5   r7   r8   z2.4r:   r   r   r   r   r   z2assert %(py2)s
{%(py2)s = %(py0)s.transaction_id
}rM   )rG   rN   crypto_transferrD   rE   r'   r   rF   rK   rL   )r   r   r    r   r   rR   r   r   r9   r   rS   rT   rU   rX   rY   rZ   rV   rW   r   r'   )r   sourcetargetr   rM   r   r^   r`   re   r   rc   r   r   rh   @py_format3rd   rf   rg   s                     r   :test_transfer_between_wallets_via_manage_helper_is_auditedr      s   <<DF%%F0A%^htz  KN  _k  |W  ^q  {  @  @  @E%dU^TZio  @E  Y^  o{  BV  `d  e  e  eF(..H#VU^$<=X=FXRWX'RW..XF.XXXXXXXXXXF.XXXXX=XXXXFXXXXXXXXXXX'XXXXX'XXXXXXRWXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#VU^$<=X=FXRWX'RW..XF.XXXXXXXXXXF.XXXXX=XXXXFXXXXXXXXXXX'XXXXX'XXXXXXRWXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX              6     6                        .4;t.//414/14444444444/1444444444444;44444;4444444444444t44444t444444.4444/444414444444444444444444444444444444r   c                    t                      } t          |           }t          j        t          d          5  t          | dd|ddddd	
	  	         d d d            n# 1 swxY w Y   t          j        t          d          5  t          | dddddddd	
	  	         d d d            n# 1 swxY w Y   t          j        t          d          5  t          | dd|ddddd	
	  	         d d d            n# 1 swxY w Y   t          j        t          d          5  t          | dd|ddddd
	  	         d d d            d S # 1 swxY w Y   d S )Nr9   r|   zSynthetic BadBADr   r-   r.   	syntheticT)r0   r1   r3   r4   r5   r6   r7   r8   walletr~   1r1   r8   F)r   r   r   r   r   r   )r   r3   s     r   Btest_validations_reject_bad_amounts_wallets_and_unconfirmed_writesr      s"   <<DD!!I	z	4	4	4 \ \DOEU^nq  CO  `{  BM  W[  	\  	\  	\  	\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \	z	2	2	2 U UDOEUWgj  |H  Yt  {F  PT  	U  	U  	U  	UU U U U U U U U U U U U U U U	z	2	2	2 Y YDOBR[kn  @L  ]x  J  TX  	Y  	Y  	Y  	YY Y Y Y Y Y Y Y Y Y Y Y Y Y Y	z	3	3	3 ] ]DOEU^nq  CO  `{  BM  W\  	]  	]  	]  	]] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]sG   AA"%A"B))B-0B-C44C8;C8E  EEc                    t                      } t          |           }d}|t          v }|st          j        d|fd|t          f          t          j        |          dt          j                    v st          j        t                    rt          j        t                    nddz  }dd|iz  }t          t          j
        |                    d x}}d}|d	         }||v }|slt          j        d|fd
||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|d         }g }||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}d S )NzADA Cardanort   )z%(py1)s in %(py3)sr   )r>   rH   rq   rI   zUSTC Terra Classicmanual_review_coin_labelsr   r=   r@   rA   walletsr:   r<   )r   r
   r   rS   rT   rU   rX   rY   rZ   rV   rW   )	r   optionsr^   r`   rv   ri   r_   ra   rb   s	            r   9test_crypto_management_options_include_manual_review_listr      s:   <<D+D11G<=<<<<<<<<<<<=<<<<<<=<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<G7+F#GG#GGGGGGGGGGG#GGGGGGGGGG#GGGGGGGGGGGGGGGGGGGGGGGGGGGG9##################################################r   c                 :   t                      } t          |           }t          | ddd|ddddd	
  
        j        }t	          | ||d
ddd           t          |           j        ||f         }|j        }d
}t          |          }||k    }|st          j
        d|fd||f          t          j        |          t          j        |          dt          j                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}x}x}}|                     d                                          d         }d}
||
k    }|slt          j
        d|fd||
f          t          j        |          t          j        |
          dz  }dd|iz  }t          t          j        |                    d x}x}}
d S )NzSynthetic SolanaSOLsolanar   r-   r.   r{   Tr/   z
1.00000001z
2026-01-01zsynthetic tiny correctionr   r:   r   r   r   r   r   zKSELECT COUNT(*) AS c FROM audit_log WHERE action='crypto_manual_adjustment'r$   rD   r<   r=   r@   rA   )r   r   r   rR   r	   r   r   r9   r   rS   rT   rU   rX   rY   rZ   rV   rW   r%   r&   )r   r3   r]   r^   r`   re   r   rc   r   r   r_   ra   rb   s                r   Ftest_manual_adjustment_transaction_type_is_used_by_holding_calculationr      s   <<DD!!I$#2     
 4%9Xd  vB  Id  nr  s  s  s  s$T**:Iu;MNpNWpcop[bco[p[ppW[pppppppppppW[ppppppNppppWppppppppppp[bppppp[bppppppcopppp[pppppppppppppppppppppppppppppppp<<effooqqruv{z{{vz{{{{{{{{{{{vz{{{{{{v{{{{z{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{r   )r   r   )r!   r   r   r"   )r   r(   )'
__future__r   builtinsrX   _pytest.assertion.rewrite	assertionrewriterS   decimalr   r   jarvis_finance.crypto.holdingsr   r   jarvis_finance.crypto.manager   r   r	   r
   r   r   jarvis_finance.crypto.walletsr   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r   r    r'   rk   rw   r   r   r   r   r   r    r   r   <module>r      s   " " " " " "                      e e e e e e e e                8 7 7 7 7 7 : : : : : : > > > > > >  e e e e^ ^ ^ ^i i i i! ! ! !45 5 5 50)< )< )< )<X&
 &
 &
 &
R5 5 5 5] ] ] ]$ $ $ $| | | | | |r   