
    j                       d dl mZ d dlZ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 d
 Zd ZdddddddZddZej2                  j5                  dg d      dd       ZddZddZddZy)    )annotationsN)HTTPException)confirm_create_budget_account)confirm_create_category)import_budget_csv_text)batch_mark_candidatesconfirm_duplicate_overrideconfirm_transaction_candidatelist_transaction_candidates preview_batch_confirm_candidates)connect_memory)apply_migrationsc                 0    t               } t        |        | S )N)r   r   )conns    3tests/unit/test_budget_duplicate_handling_hotfix.pydbr      s    DTK    c                T    t        | dddd      d   }t        | ddd      d   }||fS )	NzBudget KontocashCHF)nameaccount_typecurrency	entity_idzEssen & Haushaltexpense)r   category_type)r   r   )r   accountfoods      r   
setup_baser      sG    +D>[aot2uv  xC  DG"42DW`)abcnoDD=r   pendingz
M Windischmigros_receiptsstatuscategory_iddescriptionsource_typer#   c               X    | j                  d||||||||f       | j                          y )Nu  
        INSERT INTO budget_transaction_candidates(
            transaction_candidate_id, source_file_label, source_row_or_range, source_type,
            transaction_date, description, merchant, amount_original, currency_original,
            proposed_category_id, proposed_category_name, confidence, requires_review, status,
            classification, review_reason, raw_fingerprint, created_at, updated_at
        ) VALUES (?, '2026 Migros Einkäufe.csv', ?, ?, '2026-03-20', ?, 'M Windisch', '0.40', 'CHF', ?,
            CASE WHEN ? IS NULL THEN NULL ELSE 'Essen & Haushalt' END, '0.80', 0, ?, 'migros_receipt_food_household',
            'duplicate_detection_v1', ?, '2026-01-01T00:00:00', '2026-01-01T00:00:00')
        )executecommit)r   cidr#   r$   r%   r&   s         r   	candidater+       s4    LL		 
c;[+vsS 	KKMr   c                    t               } t        |       \  }}t        | dd|       t        | dd|       t        | dd|       t        | dd	|       t        | d
      D ch c]  }|d   	 }}t        | dd
      D ch c]  }|d   	 }}t        | dd
      D ch c]  }|d   	 }}|dhk(  sJ |dhk(  sJ |h dk(  sJ y c c}w c c}w c c}w )Nopen1r    r#   r$   dup1duplicate_candidateblocked1duplicate_blocked	possible1possible_duplicate2026)budget_yeartransaction_candidate_idmigros)tabr6   
duplicates>   r/   r1   r3   )r   r   r+   r   )r   _accountr   r
normal_ids
migros_idsduplicate_idss          r   Rtest_normal_review_and_migros_tab_exclude_duplicates_but_duplicates_tab_shows_themr@   1   s   4D*T"24dGI4@dF#8dKdJ':MdK(<$O9TUYgm9noA!./oJo9TUY_gu{9|}A!./}J}<WX\bn  }C  =D  EqQ12  EM  E'"""'"""==== p} Es   $CC C)r0   r2   r4   
supersededcovered_by_migrosignoredc           	        t               }t        |      \  }}t        |d|  | |       t        j                  t
              5 }t        |d|  ||dd       d d d        j                  j                  dk(  sJ dt        |j                  j                        v sJ |j                  d      j                         d   dk(  sJ y # 1 sw Y   oxY w)	Ncand_r.   r5   
account_idr$   r6   i  z2Kandidat ist als Duplikat/covered/ignored markiert(SELECT COUNT(*) FROM budget_transactionsr   )r   r   r+   pytestraisesr   r
   valuestatus_codestrdetailr(   fetchone)r#   r   r   r   excs        r   ?test_normal_confirm_guard_blocks_duplicate_and_covered_statusesrQ   A   s    4DD!1$deF8$VF	}	% C%deF8,<Wei  {A  ?B  	CC 99  C'''?3syyGWGWCXXXX<<BCLLNqQUVVVVC Cs   CCc            	         t               } t        |       \  }}t        | dd|       t        j                  t
              5 }t        | d||dd       d d d        j                  j                  dk(  sJ t        | d||ddd      }|d	   d
k(  sJ | j                  d      j                         d   dk(  sJ | j                  d      j                         D ch c]  }|d   	 }}d|v sJ y # 1 sw Y   xY wc c}w )Nr/   r0   r.   r5   rF   i  z#Bewusst separater Bon trotz Treffer)rG   r$   r6   reasonr#   	confirmedrH   r      zSELECT action FROM audit_log&candidate_duplicate_override_confirmed)r   r   r+   rI   rJ   r   r	   rK   rL   r(   rO   fetchall)r   r   r   rP   resultr<   audit_actionss          r   Ctest_duplicate_override_requires_reason_and_audits_explicit_bookingrZ   N   s   4DD!1$dF#8dK	}	% v"4X\ms1tuv99  C''''fW]arx  Ej  7k  lF({***<<BCLLNqQUVVVV#'<<0N#O#X#X#Z[aQqT[M[3}DDDv v \s   C/C;/C8c                    t               } t        |       \  }}t        | dd|dd       t        | dd|       t        | ddg|d	
      }|d   dk(  sJ |d   du sJ |d   dddgk(  sJ t	        | ddgd||d   d	      }|d   dk(  sJ |d   dk(  sJ |d   dddgk(  sJ | j                  d      j                         d   dk(  sJ y )Nok1r    zCoop Einkaufvisa_credit_cardr"   r/   r2   r.   r5   )candidate_idsrG   r6   countrU   can_confirmF	conflictsduplicate_candidate_blocked)candidate_idrS   confirm
preview_id)r^   actionrG   re   r6   confirmed_countskipped_counterrors)rc   errorzVSELECT status FROM budget_transaction_candidates WHERE transaction_candidate_id='dup1'r   )r   r   r+   r   r   r(   rO   )r   r   r   previewrX   s        r   Ctest_batch_confirm_skips_duplicates_and_reports_per_candidate_errorrl   ^   s<   4DD!1$dE)>gyzdF#6DI.tE6?_ftz{G7q   =!U***;VGd$e#ffff"4vyel  zA  BN  zO  ]c  dF#$)))/"a'''(B_ `aaaa<<pqzz|}~  DW  W  W  Wr   c                 @   t               } t        |       \  }}d}t        | d|dd|      }t        | d|dd|      }|d   dk(  sJ |d   d	k(  sJ | j                  d
      j	                         d	   dk(  sJ | j                  d      j	                         d	   dk(  sJ y )NzDatum;Zeit;Filiale;Kassennummer;Transaktionsnummer;Artikel;Menge;Aktion;Umsatz
02.01.2026;10:00;Migros Test;1;99;Artikel A;1;;1.10
02.01.2026;10:00;Migros Test;1;99;Artikel B;1;;2.20
r!   u   2026 Migros Einkäufe.csvF)source_file_labeldry_rundefault_category_idzsame receipt exported again.csvcandidate_countrU   r   zlSELECT COUNT(*) FROM budget_transaction_candidates WHERE source_type IN ('migros_receipts','migros_receipt')z-SELECT COUNT(*) FROM budget_import_line_items   )r   r   r   r(   rO   )r   r;   r   csv_textfirstseconds         r   ^test_migros_receipt_key_import_is_idempotent_across_reimports_and_article_rows_are_detail_onlyrv   o   s    4D*T"24 LH"4):HXs  ~C  Y]  ^E#D*;XYz  EJ  `d  eF"#q(((#$)))<<  G  H  Q  Q  S  TU  V  Z[  [  [  [<<GHQQSTUVZ[[[[r   )r*   rM   r#   rM   r$   z
str | Noner%   rM   r&   rM   returnNone)rw   rx   )r#   rM   rw   rx   )
__future__r   rI   fastapir   'jarvis_finance.services.budget_accountsr   )jarvis_finance.services.budget_categoriesr   *jarvis_finance.services.budget_csv_importsr   &jarvis_finance.services.budget_importsr   r	   r
   r   r   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r   r+   r@   markparametrizerQ   rZ   rl   rv    r   r   <module>r      s    "  ! Q M M  ; > 09TXmy  O` ">    $T  U	W U	WE W"
\r   