
    jd                        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mZmZ d dlmZ d dlmZ d	 Zd
 ZddZddZddZdS )    )annotationsN)Path)confirm_create_budget_account)confirm_create_category)generate_report_v1list_reports_v1preview_report_v1)connect_memory)apply_migrationsc                 @    t                      } t          |            | S )N)r
   r   )conns    F/home/agent/.hermes/repos/FinanceManager/tests/unit/test_reports_v1.pydbr      s    D-d333D[    c                .   t          | dddd          d         }t          | dddd          d         }t          | d	d
d          d         }|                     d||||||||f           |                     d           |                                  d S )NHaushaltcashCHF)nameaccount_typecurrency	entity_idexpense100.00)r   category_typemonthly_budgetLohnincome)r   r   a  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
    ('income_ok', ?, ?, '2026-05-01', 'income', 'Lohn', '100.00', 'CHF', '100.00', 'not_needed', 'confirmed', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
    ('expense_ok', ?, ?, '2026-05-02', 'expense', 'Haushalt Laden', '-30.00', 'CHF', '-30.00', 'not_needed', 'confirmed', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
    ('candidate_no_count', ?, ?, '2026-05-03', 'expense', 'Pending', '-999.00', 'CHF', '-999.00', 'not_needed', 'draft', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
    ('transfer_no_count', ?, ?, '2026-05-04', 'transfer', 'Transfer', '-500.00', 'CHF', '-500.00', 'not_needed', 'confirmed', 'manual', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
    a  INSERT INTO budget_transaction_candidates (transaction_candidate_id, source_type, source_file_label, transaction_date, description, amount_original, currency_original, status, classification, requires_review, created_at, updated_at)
    VALUES
    ('cand_review', 'visa_credit_card', 'visa.csv', '2026-05-05', 'Review', '-10.00', 'CHF', 'needs_review', 'expense_candidate', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
    ('cand_dup', 'migros_purchase', 'migros.csv', '2026-05-06', 'Dup', '-11.00', 'CHF', 'duplicate_candidate', 'expense_candidate', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
    ('cand_covered', 'migros_purchase', 'migros.csv', '2026-05-07', 'Covered', '-12.00', 'CHF', 'covered_by_source', 'expense_candidate', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
    )r   r   executecommit)r   accountexpense_cat
income_cats       r   seedr$      s    +D:W]kp2q2qrrs~G)$V_s{0|0|}}  J  KK(QY/Z/Z[[\ghJLL  :wWk7T_	`b b b 	LL  	 	 	 	KKMMMMMr   tmp_pathr   returnNonec                   t                      }t          |           t          j                    }| dz  }g d}|D ]}t	          ||dd||          }t          |d                   }|d         }d}	||	u }
|
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    }
|
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}}
|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}}	|j        }d}||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#}|j        }d$} ||%          }||v }
|
st          j        d|
fd&||f          t          j        |          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}x}}t#          |*          }t%          |          }
t%          |          }|
|k    }|sxt          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        |
          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        |          d0z  }d1d2|iz  }t          t          j	        |                    d x}
x}}|d3z  }|j        } |            }	|	sdd4t          j                    v st          j        |          rt          j        |          nd4t          j        |          t          j        |	          dz  }t          t          j	        |                    d x}}	|j        }d$}	 ||	%          }|j        }d5} ||          }t%          |          }||k    }|st          j        d+|fd6||f          d4t          j                    v st          j        |          rt          j        |          nd4t          j        |          t          j        |	          t          j        |          t          j        |          t          j        |          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        |          d7
z  } d8d9| iz  }!t          t          j	        |!                    d x}x}	x}x}x}x}x}}d S ):Nruntime_reports)budget_monthlycashflow_householdbudget_review_statuscrypto_statusportfolio_status2026-05html)report_typeperiodformatreports_dir	repo_rootpathruntime_onlyT)is)z%(py1)s is %(py4)spy1py4assert %(py6)spy6metadatar1   ==)z%(py1)s == %(py3)skind)r:   py3zassert %(py5)spy5zAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
})py0py2r;   in)z/%(py0)s in %(py4)s
{%(py4)s = %(py2)s.parents
}r4   not in)z3%(py0)s not in %(py4)s
{%(py4)s = %(py2)s.parents
}repoz.html)z.%(py2)s
{%(py2)s = %(py0)s.suffix
} == %(py5)s)rD   rE   rC   zassert %(py7)spy7u   Datenqualitätzutf-8)encoding)zX%(py1)s in %(py9)s
{%(py9)s = %(py5)s
{%(py5)s = %(py3)s.read_text
}(encoding=%(py7)s)
})r:   rB   rC   rK   py9zassert %(py11)spy11)r4   >=)zN%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py8)s
{%(py8)s = %(py5)s(%(py6)s)
}lenlistedreport_types)rD   r:   rB   rC   r=   py8zassert %(py10)spy10zreport_events.jsonlauditreport_generated)z%(py12)s
{%(py12)s = %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.read_text
}(encoding=%(py4)s)
}.count
}(%(py10)s)
} >= %(py17)s
{%(py17)s = %(py14)s(%(py15)s)
})
rD   rE   r;   r=   rT   rU   py12py14py15py17zassert %(py19)spy19)r   r$   r   cwdr   
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanation@py_builtinslocals_should_repr_global_nameexistsparentssuffix	read_textr   rQ   count)"r%   r   rJ   r4   rS   rA   resultr6   @py_assert0@py_assert3@py_assert2@py_format5@py_format7@py_format4@py_format6@py_assert1@py_assert4@py_format8@py_assert6@py_assert8@py_format10@py_format12rR   @py_assert7@py_format9@py_format11rV   @py_assert5@py_assert9@py_assert11@py_assert16@py_assert13@py_format18@py_format20s"                                     r   Btest_reports_v1_generate_all_types_runtime_only_metadata_and_auditr   $   s
   44Dd8::D..KxxxL 	D 	D#Dd9U[it  AE  F  F  FF6N##n%--%----------%-----%-------------------------------j!-080D88888888880D88888088888888888D88888D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{{{}}}tt{}"l*{l**********{l************{*****{*************d*****d******l*************************<'t<''''''''''t<''''''''''''t'''''t'''''''''''''4'''''4''''''<'''''''''''''''''''''''''{%g%{g%%%%%%%%%%{g%%%%%%%%%%%%t%%%%%t%%%%%%{%%%%g%%%%%%%%%%%%%%%%%%%%%%%%%%%C4>C7C>>7#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C4CCCCC4CCCCCC>CCCC7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555Fv;;+#l+++;+++++++++++;+++++++++++++3+++++3+++++++++++++v+++++v++++++;+++++++++++#+++++#+++++++++++++l+++++l++++++++++++++++++++++++++++++++++//E<<<>>>55<>?[G[??G,,,[,2[3E[223EFF[#lJ[J[[FJ[[[[[[[[[[[FJ[[[[[[[[[[[[[5[[[[[5[[[[[[?[[[[G[[[[,[[[[2[[[[3E[[[[F[[[[[[[[[[[#[[[[[#[[[[[[[[[[[[[l[[[[[l[[[[[[J[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[r   c                   t                      }t          |           t          |d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         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         }|s:ddt          j        |          iz  }t          t          j        |                    d }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}}	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}}	d S )$Nr*   r/   r1   r2   totals
income_chfr   r?   )z%(py1)s == %(py4)sr9   r<   r=   expense_chfz30.00net_cashflow_chfz70.00review
open_total   rO   z%(py1)s >= %(py4)spossible_duplicatescovered_by_sourcesectionstop_categoriesassert %(py1)sr:   z999.00rH   )z4%(py1)s not in %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}strpreview)r:   rB   r;   r=   zassert %(py8)srT   z500.00)r   r$   r	   r^   r_   r`   ra   rb   r   rc   rd   re   )r%   r   r   rl   rm   rn   ro   rp   @py_format2r}   r{   s              r   Jtest_budget_monthly_report_counts_confirmed_only_and_candidates_separatelyr   <   s   44Dd2B9UUUG8\*6h6*h6666666666*h66666*6666h6666666666666666666666666668]+6w6+w6666666666+w66666+6666w6666666666666666666666666668/0;G;0G;;;;;;;;;;0G;;;;;0;;;;G;;;;;;;;;;;;;;;;;;;;;;;;;;;8\*/a/*a//////////*a/////*////a///////////////////////////8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8016Q61Q66666666661Q6666616666Q666666666666666666666666666:/0000000000000000000000000'3w<<'8<''''''''''8<'''''8'''''''''''3'''''3'''''''''''''w'''''w''''''<''''''''''''''''''''''''''''3w<<'8<''''''''''8<'''''8'''''''''''3'''''3'''''''''''''w'''''w''''''<'''''''''''''''''''''''''''''r   c                    t                      } t          |            t          | dd          }t          | dd          }|d         d         }|s:dd	t          j        |          iz  }t          t          j        |                    d }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}|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         }|s:dd	t          j        |          iz  }t          t          j        |                    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 S )Nr+   2026r   r,   r/   r   monthly_cashflowr   r:   transfers_separaterF   )z%(py1)s in %(py4)sr9   r<   r=   savings_rate_percentr   fixed_cost_ratio_percentcandidates_by_sourcer   r   r   rO   r   r   )r   r$   r	   r^   r`   ra   rb   r_   )	r   cashflowr   rl   r   rm   rn   ro   rp   s	            r   9test_cashflow_and_review_reports_expose_required_sectionsr   K   sU   44Dd 3GPVWWWHt1GPYZZZFJ 2333333333333333333333333378J#77#77777777777#7777777777#7777777777777777777777777777!7Xh%77!%77777777777!%777777!7777%7777777777777777777777777777%;();;%);;;;;;;;;;;%);;;;;;%;;;;);;;;;;;;;;;;;;;;;;;;;;;;;;;;*4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(127a72a77777777772a7777727777a777777777777777777777777777(/05A50A55555555550A5555505555A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5r   )r%   r   r&   r'   )r&   r'   )
__future__r   builtinsrc   _pytest.assertion.rewrite	assertionrewriter^   pathlibr   'jarvis_finance.services.budget_accountsr   )jarvis_finance.services.budget_categoriesr   "jarvis_finance.services.reports_v1r   r   r	   jarvis_finance.storage.databaser
   !jarvis_finance.storage.migrationsr   r   r$   r   r   r    r   r   <module>r      s   " " " " " "                     Q Q Q Q Q Q M M M M M M e e e e e e e e e e : : : : : : > > > > > >A A A  (\ \ \ \0( ( ( (6 6 6 6 6 6r   