
    j0                        d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZ d dlmZ d dlmZ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dZy)    )annotations)
TestClient)get_db)
create_app)confirm_seed_candidateignore_seed_candidatelist_seed_candidatespreview_seed_candidate seed_budget_candidates_from_rows)connect_memory)apply_migrationsget_schema_versionc                 0    t               } t        |        | S N)r   r   conns    -tests/unit/test_budget_phase12_seed_review.pydbr      s    DTK    c                 *    ddggg dg dg dg dgdS )NAltWert	KategoriePositionJanFebJahrTyp)WohnenMiete100.00r"   1200.00	Fixkosten)EssenHaushaltz50.00z60.00z660.00variabel) zUnklar ohne Betragr(   r(   r(   r(   )Archiv2026 r+   r   r   synthetic_workbookr,      s'    6?#BKI6	
 r   c                     t               } t        |       dk(  sJ | j                  d      D ci c]  }|d   |d    }}h dj                  |      sJ |d   j	                         dk(  sJ y c c}w )N&   z)PRAGMA table_info(budget_seed_candidates)nametype>   notesstatuscurrency
confidence
created_at
updated_atsource_labelsource_sheetproposed_namecandidate_typerequires_reviewseed_candidate_idsource_file_labelsource_row_or_rangeproposed_amount_textproposed_category_idproposed_period_typeproposed_parent_labelr?   TEXT)r   r   executeissubsetupper)r   rowcolss      r   >test_phase12_schema_has_requested_budget_seed_candidates_tablerI   $   s    4Dd#r)))04=h0ijCKV$jDj& htn'  ( &'--/6999+ ks   A.c                 0   t               } | j                  d      j                         d   }t        | t	               d      }| j                  d      j                         d   }||k(  sJ |d   dk(  sJ |d   dk(  sJ |d	   dk(  sJ |d
   dk(  sJ |d   dk(  sJ t        |       }|D ch c]  }|d   	 c}h dk\  sJ t        d |D              sJ t        d |D              sJ | j                  d      j                         d   dk(  sJ y c c}w )N&SELECT COUNT(*) FROM budget_plan_itemsr   synthetic budget workbookr=   current_budget_sheetr*   category_candidate_count   budget_plan_candidate_countrecurring_candidate_count   unclean_range_countr:   >   categorybudget_planunclean_rangerecurring_candidatec              3  *   K   | ]  }|d    dv   yw)r2   >   pendingneeds_reviewNr+   .0cs     r   	<genexpr>z^test_excel_dry_run_persists_seed_candidates_without_productive_budget_plans.<locals>.<genexpr>L   s     Naq{99Ns   c              3  @   K   | ]  }|d    dk(  xr |d   dk(    yw)r?   r"   r:   rV   Nr+   r\   s     r   r_   z^test_excel_dry_run_persists_seed_candidates_without_productive_budget_plans.<locals>.<genexpr>M   s0     rbcq'(H4];K9LP]9]]rs   znSELECT typeof(proposed_amount_text) FROM budget_seed_candidates WHERE proposed_amount_text IS NOT NULL LIMIT 1text)r   rD   fetchoner   r,   r	   allany)r   before_planssummaryafter_plans
candidatesr^   s         r   Ktest_excel_dry_run_persists_seed_candidates_without_productive_budget_plansri   ?   sm   4D<< HIRRTUVWL.t5G5I]xyG,,GHQQSTUVK,&&&)*f444-.!33301Q666./1444()Q...%d+J)34AA48{{{{N:NNNNrgqrrrr<<  I  J  S  S  U  VW  X  \b  b  b  b 5s   -Dc                    t               } t        | t               d       t        |       }t	        d |D              }t	        d |D              }t	        d |D              }t        | |d   i       }|d   dk(  sJ t        | |d   |d	         }|d
   dk(  sJ t        | |d   ddi      }|d   dk(  sJ t        | |d   |d	         }|d
   dk(  sJ | j                  d|d   f      j                         }	t        |	      dk(  sJ t        | |d   d      }
|
d
   dk(  sJ | j                  d      j                         d   dk\  sJ y )NrL   rM   c              3  D   K   | ]  }|d    dk(  s|d   dk(  s|  yw)r:   rU   r9   r    Nr+   r\   s     r   r_   zTtest_seed_candidate_category_budget_plan_ignore_confirm_and_audit.<locals>.<genexpr>U   s,     |Aq9I7Jj7X]^_n]os{]{a|      c              3  D   K   | ]  }|d    dk(  s|d   dk(  s|  yw)r:   rV   r9   r!   Nr+   r\   s     r   r_   zTtest_seed_candidate_category_budget_plan_ignore_confirm_and_audit.<locals>.<genexpr>V   s,     z15E3F-3W\]^m\nry\y!zrl   c              3  2   K   | ]  }|d    dk(  s|  ywr:   rW   Nr+   r\   s     r   r_   zTtest_seed_candidate_category_budget_plan_ignore_confirm_and_audit.<locals>.<genexpr>W   s     ]1a8H6I_6\Q]   r<   actionaccept_categorypayloadr2   	confirmedrA   monthlyaccept_budget_planzZSELECT source_type, typeof(monthly_amount_chf) FROM budget_plan_items WHERE plan_item_id=?	entity_id)excel_seed_dry_runra   zsynthetic ignorenoteignoredzrSELECT COUNT(*) FROM audit_log WHERE entity_type IN ('budget_seed_candidate','budget_category','budget_plan_item')r      )r   r   r,   r	   nextr
   r   rD   rb   tupler   )r   rh   category_candidateplan_candidateunclean_candidatecategory_previewcategory_resultplan_previewplan_resultrG   r{   s              r   Atest_seed_candidate_category_budget_plan_ignore_confirm_and_auditr   Q   s   4D$T+=+?Sno%d+J|||zZzzN]
]]-d4FGZ4[]_`H%)::::,T3EFY3Z\lmv\wxO8$333)$?R0SVlnwUxyL!%9999(~>Q/RT`ajTklKx K///
,,s  wB  CN  wO  vQ  R  [  [  ]C:7777#D*;<O*PWijG8	)))<<  M  N  W  W  Y  Z[  \  `a  a  a  ar   c                   
 t               
t               } 
fd}|| j                  t        <   t	        |       }|j                  ddt               d      }|j                  dk(  sJ |j                         d   dk(  sJ |j                  d	      j                         }t        |      d
k\  sJ t        d |D              }|j                  d| dddi      }|j                  dk(  sJ |j                  d| d|j                         d         }|j                  dk(  sJ t        d |D              }|j                  d| dddi      }	|	j                  dk(  sJ y )Nc               3     K     y wr   r+   r   s   r   override_dbzTtest_budget_seed_review_api_lists_previews_confirms_and_ignores.<locals>.override_dbn   s     
s   	z$/api/budget/seed-candidates/generate	synthetic)r=   workbook_rows)json   rQ   rP   z/api/budget/seed-candidatesrS   c              3  8   K   | ]  }|d    dk(  s|d     yw)r:   rV   r<   Nr+   r\   s     r   r_   zRtest_budget_seed_review_api_lists_previews_confirms_and_ignores.<locals>.<genexpr>x   s$     baQ?O=PTa=a1()b   
z/api/budget/seed-candidates/z/previewrA   ru   z/confirmrs   c              3  8   K   | ]  }|d    dk(  s|d     yw)r:   rW   r<   Nr+   r\   s     r   r_   zRtest_budget_seed_review_api_lists_previews_confirms_and_ignores.<locals>.<genexpr>}   s$     gBR@SWf@fa+,gr   z/ignorerz   znot suitable)r   r   dependency_overridesr   r   postr,   status_coder   getlenr}   )appr   clientgeneratelistedplan_idpreviewconfirm
unclean_idr{   r   s             @r   ?test_budget_seed_review_api_lists_previews_confirms_and_ignoresr   j   s   4D
,C (3CV$_F{{A^i  }O  }Q  IR{  SH3&&&==?89Q>>>ZZ56;;=Fv;!b6bbGkk8	JRhjsQtkuG#%%%kk8	JQXQ]Q]Q_`iQjkkG#%%%gfggJkk8GLTZ\jSkklG#%%%r   c                 |    g dg} | t        d      D cg c]  }g d c}z  } | g dg dg dg dgz  } d| iS c c}w )	Nr   #   )r(   r(   r(   r(   r(   r(   )r(   Lohn Marcelr"   r(   r(   r(   )r(   Lohn Melaniez110.00r(   r(   r(   )r(   Gratifikationr(   r(   r#   r(   )r(   Sonstige Einnahmenz25.00r(   r(   r(   r*   )range)rows_s     r   income_workbookr      sP    BCDuRy9!%99D1247	 D D> :s   9c                    ddl m}  t               }t        |t	               d       t        d t        |      D              }t        ||d   d        | ||d         }|d	   d
k(  sJ |j                  d|d   f      j                         d   d
k(  sJ |j                  d|d   f      j                         d   dk(  sJ y )Nr   )reopen_seed_candidaterL   rM   c              3  2   K   | ]  }|d    dk(  s|  ywro   r+   r\   s     r   r_   zEtest_ignored_candidate_can_be_reopened_and_audited.<locals>.<genexpr>   s     e1a@P>QUd>dQerp   r<   mistakery   r2   rZ   zCSELECT status FROM budget_seed_candidates WHERE seed_candidate_id=?zKSELECT COUNT(*) FROM audit_log WHERE action='status_change' AND entity_id=?rS   )
*jarvis_finance.services.budget_seed_reviewr   r   r   r,   r}   r	   r   rD   rb   )r   r   	candidateresults       r   2test_ignored_candidate_can_be_reopened_and_auditedr      s"   P4D$T+=+?Snoe 4T :eeI$	*= >YO"43F)GHF(y(((<<]`ij}`~  `A  B  K  K  M  NO  P  T]  ]  ]  ]<<ehq  sF  iG  hI  J  S  S  U  VW  X  \]  ]  ]  ]r   c                 b   ddl m}  t               }t        |t	               d       t        d t        |      D              } | ||d   ddd	i       | ||d   d
ddd      d   dk(  sJ d   dk(  sJ t        |      }t        fd|D              sJ t        fd|D              sJ y )Nr   )convert_unclean_rangerL   rM   c              3  2   K   | ]  }|d    dk(  s|  ywro   r+   r\   s     r   r_   z]test_unclean_range_can_be_converted_to_category_and_budget_plan_candidates.<locals>.<genexpr>   s     cA>N<OSb<b1crp   r<   rU   r9   
SonderfallrV   Sonderbudgetz42.00)r9   r?   r2   createdc              3  H   K   | ]  }|d    d   k(  xr |d   dk(    yw)r<   rw   r:   rU   Nr+   )r]   r^   cats     r   r_   z]test_unclean_range_can_be_converted_to_category_and_budget_plan_candidates.<locals>.<genexpr>   s6     qdeq$%[)99_a@P>QU_>__q   "c              3  H   K   | ]  }|d    d   k(  xr |d   dk(    yw)r<   rw   r:   rV   Nr+   )r]   r^   plans     r   r_   z]test_unclean_range_can_be_converted_to_category_and_budget_plan_candidates.<locals>.<genexpr>   s6     uhiq$%k)::cqAQ?RVc?ccur   )r   r   r   r   r,   r}   r	   rd   )r   r   uncleanr   r   r   s       @@r   Jtest_unclean_range_can_be_converted_to_category_and_budget_plan_candidatesr      s    P4D$T+=+?Snoc248ccG
g.A&BJQ`bnPo
pC w/B'C]ft  OV  UW  XDx=I%%%>Y&&&"4(Gqipqqqqumtuuuur   c                 ^   t               } t        | t               d      }t        |       }|D cg c]%  }|d   dk(  sd|j	                  d      xs dv s$|' }}|d   d	k(  sJ t        |      d	k(  sJ |D ch c]  }|d
   	 c}h dk\  sJ t        d |D              sJ y c c}w c c}w )Nzincome synthetic workbookrM   r:   rV   ztype:incomer1   r(   income_candidate_count   r9   >   r   r   r   r   c              3  8   K   | ]  }|d    dk(  s|d     yw)r9   r   r;   Nr+   r\   s     r   r_   zFtest_income_candidates_from_2026_sheet_are_detected.<locals>.<genexpr>   s#     bq7IMa7aq"#br   )r   r   r   r	   r   r   rd   )r   rf   rh   r^   incomes        r   3test_income_candidates_from_2026_sheet_are_detectedr      s    4D.t_5FZuvG%d+J#xAq)9':m'KP]bcbgbghobpbvtvPwaxFx+,111v;!(./1Ao/3yyyybVbbbb	 y 0s   B%B%B%:B*c                    ddl m} m}m}m} t               }t        |t               d        ||      }|d   dk(  sJ  ||      }|d   dk(  sJ  ||      }|d   dk\  sJ  | |      }|j                  d      j                         d   }	 | |      }
|j                  d      j                         d   }|d   dk\  sJ |
d	   dk\  sJ ||	k(  sJ y )
Nr   )confirm_budget_plan_takeoverconfirm_clear_category_takeoverpreview_budget_plan_takeoverpreview_clear_category_takeoverrL   rM   countrP   confirmed_countrK   skipped_count)
r   r   r   r   r   r   r   r,   rD   rb   )r   r   r   r   r   cat_preview
cat_resultr   result1beforeresult2afters               r   Etest_clear_categories_and_budget_plans_can_be_taken_over_idempotentlyr      s     x  x4D$T+=+?Sno1$7Kw1$$$06J'(A---/5L A%%%*40G\\BCLLNqQF*40GLLABKKMaPE$%***?#q(((F??r   c                     ddl m}  ddlm} t	               }t        |t               d        ||        | |d      }|d   dk7  sJ |d	   d
k(  sJ |d   dk(  sJ |d   dk(  sJ y )Nr   get_budget_overview)r   rL   rM   2026-01planned_budget_chf0actual_expense_chfz0.00actuals_labelznoch keine Buchungenbudget_status
no_actuals)'jarvis_finance.services.budget_overviewr   r   r   r   r   r,   )r   r   r   overviews       r   Btest_budget_overview_shows_plan_values_without_actual_transactionsr      s    KW4D$T+=+?Sno &"43H()S000()V333O$(>>>>O$444r   c                    ddl m}  ddlm} ddlm} t               } | |dddd      d	   }|j                  d
      j                         d   }|j                  d      j                         d   } |||ddddd|d        |||ddddd|d        ||d      }|d   dk(  sJ |d   dk(  sJ |j                  d      j                         d   dk(  sJ y )Nr   )confirm_create_budget_accountr   )confirm_budget_transactionz	UAT KontocashCHF)r/   account_typer3   rw   z@SELECT category_id FROM budget_categories WHERE name='Einnahmen'z=SELECT category_id FROM budget_categories WHERE name='Wohnen'r   z
2026-01-10z
UAT incomer"   )
account_idtransaction_typetransaction_datedescriptionamount_originalcurrency_originalcategory_idexpensez
2026-01-11zUAT expensez20.00r   actual_income_chfr   zESELECT COUNT(*) FROM audit_log WHERE entity_type='budget_transaction'rP   )	'jarvis_finance.services.budget_accountsr   r   r   +jarvis_finance.services.budget_transactionsr   r   rD   rb   )r   r   r   r   account
income_catexpense_catr   s           r   =test_manual_income_and_expense_update_actual_values_and_auditr      s2   UKV4D+D;X^lq2rst  AG`ajjlmnoJ,,^_hhjklmKtGQYo{  MY  nv  MR  cm  &n  otGQZp|  N[  pw  NS  do  &p  q"43H'(H444()W444<<_`iiklmnrssssr   N)returnzdict[str, list[list[str]]])r   None) 
__future__r   fastapi.testclientr   jarvis_finance.api.dependenciesr   jarvis_finance.api.mainr   r   r   r   r	   r
   r   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r   r,   rI   ri   r   r   r   r   r   r   r   r   r   r+   r   r   <module>r      sj    " ) 2 .  ; R	:6b$a2&0	
]vc(5tr   