
    2njJ                        d dl mZ d dlZd dlmc m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 d dlmZmZ d d	lmZ d d
lmZ d Zd Zd ZddZddZddZddZdS )    )annotationsN)Path)confirm_create_budget_account)confirm_create_category)preview_drive_monthly_import) confirm_manual_recurring_payment)build_finance_command_centergenerate_monthly_report)connect_memory)apply_migrationsc                 @    t                      } t          |            | S )N)r   r   )conns    _/home/agent/.hermes/repos/FinanceManager/tests/unit/test_finance_command_center_household_v1.pydbr      s     DTK    c                    t          | dddd          d         }t          | ddd          d         }t          | d	d
d          d         }t          | ddd          d         }||||fS )NHaushaltcashCHF)nameaccount_typecurrency	entity_idzEssen & Haushaltexpense)r   category_typezLohn MarcelincomezElektronische Medien)r   r   )r   accountfoodr   medias        r   setup_budgetr       s    +D:W]kp2q2qrrs~G"42DW`)a)abbcnoD$TMT\+]+]^^_jkF#D3I\e*f*fgghstED&%''r   c                j    |                      d||||||||f           |                                  d S )Na  INSERT INTO budget_transactions (
            budget_transaction_id, account_id, category_id, transaction_date, transaction_type,
            description, amount_original, currency_original, amount_chf, fx_status, status, source_type, created_at, updated_at
        ) VALUES
        ('tx_income', ?, ?, '2026-05-25', 'income', 'Lohn', '100.00', 'CHF', '100.00', 'not_needed', 'confirmed', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
        ('tx_expense', ?, ?, '2026-05-10', 'expense', 'Haushalt', '-30.00', 'CHF', '-30.00', 'not_needed', 'confirmed', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
        ('tx_candidate_should_not_count', ?, ?, '2026-05-11', 'expense', 'Candidate-like pending', '-999.00', 'CHF', '-999.00', 'not_needed', 'draft', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
        ('tx_transfer_should_not_count', ?, ?, '2026-05-12', 'transfer', 'Interner Transfer', '-500.00', 'CHF', '-500.00', 'not_needed', 'confirmed', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
        )executecommit)r   r   r   r   s       r   seed_confirmed_transactionsr$      sF    LL	 
&'4$F   	KKMMMMMr   returnNonec            
        t                      } t          |           \  }}}}t          | |||           t          | ddddgd||           t	          | d|dd	d
dd           t          | 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         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         }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         }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         }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         }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"         }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#}||v}|st          j        d$|fd%||f          t          j        |          d&t          j                    v st          j        |          rt          j        |          nd&d'z  }d(d)|iz  }t          t          j
        |                    d x}}d* |d+         D             }t          |          }|sd,d-t          j                    v st          j        t                    rt          j        t                    nd-t          j        |          t          j        |          d.z  }	t          t          j
        |	                    d x}}d/}|d0         }||v }|slt          j        d1|fd2||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j
        |
                    d x}x}}|d3         d4         }d}||k    }|slt          j        d |fd!||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j
        |
                    d x}x}}d5}|d6         }||v }|slt          j        d1|fd2||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j
        |
                    d x}x}}d7 |d8         D             }t          |          }|sd,d-t          j                    v st          j        t                    rt          j        t                    nd-t          j        |          t          j        |          d.z  }	t          t          j
        |	                    d x}}d S )9NvisazVISA_Mai.csvzgTransactionId,CardId,Date,Amount,Currency,MerchantName,Details
T1,C1,2026-05-01,-10.00,CHF,Netflix,Abo
)idr   textF)dry_rundefault_category_idincome_category_idNetflixz10.00r   monthlysubscription)r   category_idexpected_amount_textr   	frequencyrecurring_type2026-05monthpurposefinance_command_center_v1==z%(py1)s == %(py4)spy1py4assert %(py6)spy6kpisincome_month_chf100.00expense_month_chf30.00net_cashflow_month_chf70.00savings_rate_percentopen_review_candidates   )>=)z%(py1)s >= %(py4)sopen_review_amount_chfmonthly_closenot in)z%(py1)s not in %(py3)scenterr>   py3assert %(py5)spy5c              3  .   K   | ]}|d          dk    V  dS )sourceVISAN ).0items     r   	<genexpr>z]test_command_center_kpis_grouped_review_imports_todos_and_compact_sections.<locals>.<genexpr>=   s+      LLDtH~'LLLLLLr   import_statusz,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anypy0py2r?   top_overrunsbudget_status_compactin)z%(py1)s in %(py4)sfixed_costs_compactactive_subscriptionsasset_allocationportfolio_crypto_compactc              3  :   K   | ]}|d          dv o|d         V  dS )priority>   lowhighmediumlinkNrY   )rZ   todos     r   r\   z]test_command_center_kpis_grouped_review_imports_todos_and_compact_sections.<locals>.<genexpr>A   s7      jjRVtJ#<<Mfjjjjjjr   todos)r   r    r$   r   r   r	   
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanation@py_builtinslocals_should_repr_global_namer^   )r   r   r   r   r   rQ   @py_assert0@py_assert3@py_assert2@py_format5@py_format7@py_format4@py_format6@py_assert1s                 r   Jtest_command_center_kpis_grouped_review_imports_todos_and_compact_sectionsr   ,   s	   44D#/#5#5 GT65gtV<<< v~  XC  )D  )D  (E  OT  jo  DJ  K  K  K  K$TIemt  CH  W`  tB  ,C  ,C  D  D  D)$i@@@F); ;; ;;;;;;;;;;; ;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;&>,-99-9999999999-99999-9999999999999999999999999999999&>-.9'9.'9999999999.'99999.9999'999999999999999999999999999&>23>w>3w>>>>>>>>>>3w>>>>>3>>>>w>>>>>>>>>>>>>>>>>>>>>>>>>>>&>01<W<1W<<<<<<<<<<1W<<<<<1<<<<W<<<<<<<<<<<<<<<<<<<<<<<<<<<&>238q83q88888888883q8888838888q888888888888888888888888888&>23>w>3w>>>>>>>>>>3w>>>>>3>>>>w>>>>>>>>>>>>>>>>>>>>>>>>>>>(?&((((((((((?&(((((?(((((((((((&(((((&(((((((((((((((((((((((((((LLF?4KLLLL3LLLLLLLLLLLLLLLL3LLLLL3LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL<V$;<<><<<<<<<<<<<><<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'()?@EAE@AEEEEEEEEEE@AEEEEE@EEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEC(B!CC!CCCCCCCCCCC!CCCCCCCCCC!CCCCCCCCCCCCCCCCCCCCCCCCCCCCjjZ`ahZijjjj3jjjjjjjjjjjjjjjj3jjjjj3jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjr   c                    t                      } t          |           \  }}}}t          | |||           t          | d          }|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         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         }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 )Nr5   r6   rB   rC   rD   r:   r<   r=   r@   rA   rE   rF   rG   rH   )	r   r    r$   r	   rr   rs   rt   ru   rv   )r   r   r   r   _mediarQ   rz   r{   r|   r}   r~   s              r   Stest_command_center_counts_only_confirmed_actuals_and_excludes_transfers_candidatesr   D   sW   44D$0$6$6!GT66gtV<<<)$i@@@F&>,-99-9999999999-99999-9999999999999999999999999999999&>-.9'9.'9999999999.'99999.9999'999999999999999999999999999&>23>w>3w>>>>>>>>>>3w>>>>>3>>>>w>>>>>>>>>>>>>>>>>>>>>>>>>>>>>r   tmp_pathr   c                
   t                      }t          |          \  }}}}t          ||||           t          j                    }| dz  }t          |d||          }t          |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}}|	j        } |            }|sddt          j                    v st          j        |	          rt          j        |	          ndt          j        |          t          j        |          dz  }t          t          j
        |                    d x}}|	j        }||v }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          nd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}}|	j        }||v}|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          nd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}
|
|v }|st          j        d|fd|
|f          t          j        |
          dt          j                    v st          j        |          rt          j        |          nddz  }dd|iz  }t          t          j
        |                    d x}
}d}
|
|v }|st          j        d|fd|
|f          t          j        |
          dt          j                    v st          j        |          rt          j        |          nddz  }dd|iz  }t          t          j
        |                    d x}
}d}
|
|v }|st          j        d|fd|
|f          t          j        |
          dt          j                    v st          j        |          rt          j        |          nddz  }dd|iz  }t          t          j
        |                    d x}
}d S )Nruntime_reportsr5   r7   reports_dir	repo_rootpathformatmarkdownr:   r<   r=   r@   rA   zAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}report_pathr_   rd   )z/%(py0)s in %(py4)s
{%(py4)s = %(py2)s.parents
}runtime_reports_dirrO   )z3%(py0)s not in %(py4)s
{%(py4)s = %(py2)s.parents
}r   z# Monatsreport 2026-05)z%(py1)s in %(py3)sr*   rR   rT   rU   
Disclaimeru   Preview → Confirm → Audit)r   r    r$   r   cwdr
   rr   rs   rt   ru   rv   existsrw   rx   ry   parents	read_text)r   r   r   r   r   r   r   r   reportr   rz   r{   r|   r}   r~   r   r*   r   r   s                      r   <test_monthly_report_is_runtime_only_markdown_and_not_in_repor   P   s5   44D$0$6$6!GT66gtV<<<

I"%66$TH[gpqqqFvf~&&K()z)z))))))))))z)))))))))z)))))))))))))))))))))))))));;"-"55"55555555555"5555555555555555555555555555555+55555+555555"55555555555555555555555555'//9///////////9/////////////9/////9/////////////K/////K////////////////////////////////  ""D#+#t++++++++++#t+++++#+++++++++++t+++++t+++++++++++++++++++++++++++<4<4<44*2*d2222222222*d22222*22222222222d22222d22222222222222222222222222222r   c                   t                      }t          |          \  }}}}t          ||||           |                    d||f           |                                 t          |d          }|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}	}	 t          |d| dz  t          j                               t          d          # t          $ r}d}t          |          }||v }	|	st          j        d|	fd||f          t          j        |          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        |          dz  }dd|iz  }t          t          j
        |                    d x}x}	}Y d }~d S d }~ww xY w)Na  INSERT INTO budget_transactions (budget_transaction_id, account_id, category_id, transaction_date, transaction_type, description, amount_original, currency_original, amount_chf, fx_status, status, source_type, created_at, updated_at)
        VALUES ('tx_june_must_not_count', ?, ?, '2026-06-01', 'expense', 'June', '-70.00', 'CHF', '-70.00', 'not_needed', 'confirmed', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)r5   r6   rB   rE   rF   r:   r<   r=   r@   rA   z2026-05/../../evilr   r   zinvalid month acceptedmonth_must_be_yyyy_mmrd   )z0%(py1)s in %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}strexc)r>   rS   r?   rA   zassert %(py8)spy8)r   r    r$   r"   r#   r	   rr   rs   rt   ru   rv   r
   r   r   
ValueErrorr   rw   rx   ry   )r   r   r   r   r   r   rQ   rz   r{   r|   r}   r~   r   @py_assert5@py_format9s                  r   Ltest_month_boundaries_use_exclusive_next_month_and_invalid_month_is_rejectedr   d   s   44D$0$6$6!GT66gtV<<<LL	z	$  
 	KKMMM)$i@@@F&>-.9'9.'9999999999.'99999.9999'9999999999999999999999999997,@hYjNjvzv~  wA  wA  	B  	B  	B  	B 5666  3 3 3&2#c((2&(2222222222&(22222&22222222222#22222#2222222222222c22222c222222(2222222222222222222222222222222223s   ='D3 3I>DII)r%   r&   )r   r   r%   r&   ) 
__future__r   builtinsrw   _pytest.assertion.rewrite	assertionrewriterr   pathlibr   'jarvis_finance.services.budget_accountsr   )jarvis_finance.services.budget_categoriesr   -jarvis_finance.services.budget_monthly_importr   (jarvis_finance.services.budget_recurringr   .jarvis_finance.services.finance_command_centerr	   r
   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r    r$   r   r   r   r   rY   r   r   <module>r      sS   " " " " " "                     Q Q Q Q Q Q M M M M M M V V V V V V U U U U U U p p p p p p p p : : : : : : > > > > > >  ( ( (   k k k k0	? 	? 	? 	?3 3 3 3(7 7 7 7 7 7r   