
    bj6d                        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 d7dZd8dZd8dZd8dZd9dZd:dZd;dZd<d=dZd<d>dZd?d"Zd@d'ZdAd+ZdBd/Zd0d1dCd2ZdDd3Zd0d1dEd4Zd0d1dEd5Zd<d=d6ZdS )F    )annotations)dateDecimal)
Connectionrow_to_dict)list_budget_transactionsconnr   returnstrc                @   |                      d                                          }|r|d         r|d         S |                      d                                          }|r|d         r|d         S |                      d                                          d         S )NzJSELECT substr(MAX(transaction_date),1,7) AS month FROM budget_transactionsmonthzHSELECT MIN(plan_month) AS month FROM budget_plan_items WHERE is_active=1zSELECT substr(date('now'),1,7)r   )executefetchone)r   txplans      /home/agent/.hermes/worktrees/FinanceManager-sprint3-reconciliation-snapshot-foundation/src/jarvis_finance/services/budget_overview.py_current_monthr      s    	b	c	c	l	l	n	nB	 bk '{<<bccllnnD W G}<<899BBDDQGG    r   c                Z    t          t          | d         p	| d         pd                    S )N
amount_chfamount_original0r   r   )rows    r   _amountr      s-    3s<(IC0A,BIcJJKKKr   c                    | d         r"t          t          | d                             S | d         r2t          t          | d                             t          d          z  S t          d          S )Nmonthly_amount_chfannual_amount_chf12r   r   r   s    r   _monthly_plan_amountr#      sn     ! 8s4 4566777  Gs4 345566FF3<<r   c                    | d         r"t          t          | d                             S | d         r2t          t          | d                             t          d          z  S t          d          S )Nr    r   r!   r   r   r"   s    r   _annual_plan_amountr%   !   sn      7s4 3455666 ! Hs4 456677'$--GG3<<r   valuec                b    t          |                     t          d                    d          S )Nz0.01f)formatquantizer   )r&   s    r   _fmtr+   )   s$    %..113777r   dict[str, dict]c                h    |                      d                                          }d |D             S )NzpSELECT category_id, parent_category_id, name, category_type, sort_order FROM budget_categories WHERE is_active=1c                T    i | ]%}t          |d                    t          |          &S category_id)r   r	   .0rs     r   
<dictcomp>z"_category_meta.<locals>.<dictcomp>/   s-    @@@aC- !!;q>>@@@r   )r   fetchall)r   rowss     r   _category_metar7   -   sI    <<  K  L  L  U  U  W  WD@@4@@@@r   r0   
str | Nonemeta	list[str]c                l   | r| |vrg S g }||                               d          }t                      }|r~||v rz||vrv|                    t          |                     |                    t          |                     |t          |                                        d          }|r||v r||vv|S )Nparent_category_id)getsetappendr   add)r0   r9   outparentseens        r   _ancestor_idsrD   2   s     +T11	C+""#788FUUD
 =Vt^^d(:(:

3v;;Vc&kk"&&';<<  =Vt^^d(:(: Jr   Nr   dictc                   |pt          |           }|                     d|f                                          }t          d          }t          d          }|D ]0}t	          |          }|d         dv r||z  }!|d         dv r||z  }1|t          |          t          |          t          ||z
            t          |          dS )N]SELECT * FROM budget_transactions WHERE status='confirmed' AND substr(transaction_date,1,7)=?r   transaction_type>   incomerefund>   feeexpense)r   
income_chfexpense_chfnet_cashflow_chftransaction_count)r   r   r5   r   r   r+   len)r   r   selected_monthr6   rI   rL   r   amounts           r   get_monthly_summaryrT   ?   s$   2nT22N<<w  {I  zK  L  L  U  U  W  WDS\\FcllG  !"&:::fFF#$(:::vG#4<<PTU\P]P]swx~  BI  yI  tJ  tJ  ad  ei  aj  aj  k  k  kr   
list[dict]c           
     <   |pt          |           }|                     d|f                                          }i }|D ]}|                    |d         |d         |d         t	          d          dd          }|dxx         t	          t          |d         p	|d         pd                    z  cc<   |d	xx         t          |d
                   z  cc<   t          |                                          }|	                    d d           d |D             S )Na  
        SELECT COALESCE(c.category_id, 'uncategorized') AS summary_category_id,
               COALESCE(c.name, 'Unkategorisiert') AS summary_category_name,
               t.transaction_type,
               t.amount_chf,
               t.amount_original,
               COUNT(*) AS count
        FROM budget_transactions t
        LEFT JOIN budget_categories c ON c.category_id=t.category_id
        WHERE t.status='confirmed' AND substr(t.transaction_date,1,7)=?
          AND t.transaction_type IN ('income','expense','refund','fee')
        GROUP BY COALESCE(c.category_id, 'uncategorized'), COALESCE(c.name, 'Unkategorisiert'), t.transaction_type, t.amount_chf, t.amount_original
        summary_category_idsummary_category_namer   r   )r0   category_namer   rP   r   r   rP   countc                    | d         S )Nr    )xs    r   <lambda>z&get_category_summary.<locals>.<lambda>e   s
    ao r   Tkeyreversec                D    g | ]}i |d t          |d                    iS )r   )r+   r1   s     r   
<listcomp>z(get_category_summary.<locals>.<listcomp>f   s4    GGG16q6,Q|_ 5 566GGGr   )
r   r   r5   
setdefaultr   r   intlistvaluessort)r   r   rR   r6   totalsr   itemresults           r   get_category_summaryrl   M   sp   2nT22N<<	 
  hjj 	  !F 7 7  %:!;SQfMgz}  V  {W  gn  or  gs  gs  JK  >L  >L  M  M\gc#l*;*\sCT?U*\Y\&]&]^^^ !!!SW%6%66!!!!&--//""F
KK--tK<<<GGGGGGr   yearmonths_with_bookingsre   c           
         t          j                    }t          |j                  | k    r|j        }nd}t          dt          dt          ||                              S )N      )r   todayr   rm   r   maxmin)rm   rn   rr   elapseds       r   _months_denominatorrv   i   sS    JLLE
5:$+q#b#2G<<==>>>r   category_typebudget_yearforecast_yearactual_yearc                6   |dk    r|dk    rdS |dk    s|dk    s|dk    rdS ||z  }| dk    r,|t          d          k    rdS |t          d          k    rdS d	S |t          d
          k    rdS |t          d          k    rd	S |t          d          k    rdS dS )Nr   ohne BudgetNoch keine DatenrI   1   Grün0.90GelbRotz1.15Kritischr   )rw   rx   ry   rz   rn   ratios         r   _statusr   r   s    aK!OO}a/144q8H8H!!K'E  GCLL  7GFOO##6uwvzws||uv7r   actualbudgettuple[str, str]c                    |dk    r|dk    rdS |dk    s|dk    rdS ||z  }| dk    r,|t          d          k    rdS |t          d          k    rdS d	S |t          d          k    rd	S |t          d          k    rdS dS )
Nr   )r|   slate)r}   r   rI   r~   )r   greenr   )r   yellow)r   redr   )rw   r   r   r   s       r   _month_statusr      s    {{vzz%%{{fkk**VOE  GCLL  ##GFOO####|ws|||r   budget_monthmonthlydict[str, Decimal]c                N   g d}g }t          |d          D ]\  }}|d}|                    |t          d                    }	t          | |	|          \  }
}|                    | d| |t          |	          t          |          t          |	|z
            |
|d           |S )N)JanFebMrzAprMaiJunJulAugSepOktNovDezrq   )start02dr   -)r   month_label
actual_chf
budget_chfdifference_chfstatus	bar_color)	enumerater=   r   r   r?   r+   )rw   rm   r   r   labelsrA   idxlabelr`   r   r   colors               r   _monthly_analysisr      s    aaaF
Ca000  
UllS'#,,//%mV\JJ

__s__ v,,|,,"6L#899
 
 	 	 	 	 Jr   2026rm   c               $   !"# t          |           !|                     d|f                                          }|                     d|f                                          }i i "i #dTdU"#fd}i }|D ][}t          |d         pd          }|r|!vr!t	          t          |d         pd                    }t          |d         pd          dd         }	 ||||	           !|         }
|                    |||
d         |
d         |
                    d          pdt	          d          t	          d          g ddd	           t          |!          D ]v}!|         } ||||	|           d|                    |||d         |d         |                    d          pdt	          d          t	          d          g ddd	          d<   w]|D ]}t          |d                   }|                    |||d         |d         |d         pdt	          d          t	          d          g dt          #                    |                    d	          }t          |          }t          |          }|dxx         |z  cc<   |dxx         |z  cc<   |d                             |d                    d|d<   g }|                                D ]6\  }}                    |t	          d          t                      f          \  }}t          |          }|dk    r	|d         sXt          ||          }|t	          |          z  }|r|t	          d           z  nt	          d          }|r|t	          d           z  nt	          d          }||d         z
  }t!          |d         |d         |||          }"                    |i            t          t#          j                    j                  |k    rt#          j                    j        d!nd }|                    i d|d"|d"         d|d         d|d         rt+          |d                   nd d|d         rt+          |d                   nd d#t          |d                   d$d%d&t+                               |t	          d                              d't+          |          d( fd)t-          d*d+          D             d,t/          |d         ||d         r|d         nt	          d                     d-t+          |          d.t+          |          d/t+          |          d0t+          |          d1t+          |t	          d           z            d2||d3k    r|d         d4k    rd5n	|d3k    rd6nd||d         t          |                    d                    t          #                    |t                                          d7           8|                    !fd89           	 dd:lm} d;  || |<                              d=g           D             }|D ]}|                    |d                   }|r|                    d          d>k    r:|                    i d|                    d?          d|                    d@          d.|                    dA          dB|                    dC          dD|                    dE          dF|                    dE          dG|                    dG          dH|                    dI          d0|                    dJ          d2|                    d2          dKk    r|                    d2          n)|                    d2          p|                    d2          dL|                    dL          dM|                    dM          dN|                    dN          dO|                    dO          dP|                    dP          dQ|                    dQ          dR|                    dR          dS|                    dS          i           !n# t8          $ r Y nw xY w|S )VNa0  
        SELECT p.*, c.name AS category_name, c.category_type, c.sort_order
        FROM budget_plan_items p
        JOIN budget_categories c ON c.category_id=p.category_id
        WHERE p.is_active=1 AND c.is_active=1 AND substr(p.plan_month,1,4)=?
        ORDER BY c.sort_order, c.name, p.name
        a  
        SELECT category_id, transaction_date, COALESCE(amount_chf, amount_original, '0') AS amount
        FROM budget_transactions
        WHERE status='confirmed' AND substr(transaction_date,1,4)=?
          AND transaction_type IN ('income','refund','expense','fee')
        r0   r   rS   r   month_nosource_childr8   r   Nonec                                        | t          d          t                      f          \  }}|                    |           ||z   |f| <                       | i                                |t          d                    |z                       | i           |<   |r7                    | t                                                    |           d S d S )Nr   )r=   r   r>   r@   rd   )	r0   rS   r   r   totalmonthsr   monthly_actualsrollup_child_idss	         r   
add_actualz1get_budget_status_by_category.<locals>.add_actual   s    

;suu0EFFv

8$v~v6{@O@Z@Z[fhj@k@k@o@opx  {B  CF  {G  {G  AH  AH  KQ  AQ"";33H= 	N''SUU;;??MMMMM	N 	Nr    r   transaction_date      namerw   
sort_order  F)	r0   categoryrw   r   r   rx   planshas_plan	is_rollupTr   rY   r   rx   r   r   r   r!   r   r   
has_budgetpurposecategory_controlactual_current_monthactual_year_to_dater   c                z    i | ]7}|d t                              |d t          d                              8S )r   r   )r+   r=   r   )r2   mcategory_monthlys     r   r4   z1get_budget_status_by_category.<locals>.<dictcomp>  sG    wwwef1

D1A1E1EjjRYZ]R^R^1_1_,`,`wwwr   rq      monthly_analysisactual_avg_monthry   forecast_avg_monthdeviation_yeardeviation_monthr   r|   rI   z(Ausgaben vorhanden, aber kein Budgetplanz)Einnahmen vorhanden, aber kein Budgetplan)status_hintrn   
plan_namesr   rollup_child_countc                    | d         dk    rdnd                     | d         i                                d          pd| d         fS )	Nrw   rI   r   rq   r0   r   r   r   )r=   )r3   r9   s    r   r^   z/get_budget_status_by_category.<locals>.<lambda>  sj    Q%78%C%CDHHUVWdUegiLjLjLnLno{L|L|  MD  AD  FG  HR  FS   T r   )r`   )get_budget_planning_matrixc                     i | ]}|d          |S r/   r\   )r2   r   s     r   r4   z1get_budget_status_by_category.<locals>.<dictcomp>  s    yyyc#m,cyyyr   r   r6   rL   budget_month_chfbudget_year_chfbudget_adjusted_forecast_chflinear_forecastlinear_forecast_chfactual_2025_yearprevious_year_total_chfprevious_year_totalprevious_year_monthsdeviation_previous_yearforecast_vs_previous_year_chfforecast_vs_budget_chfzBudget fehltdata_explorer_urleffective_expenses_urlmonthly_charthas_previous_yearknown_recurring_month_chfknown_recurring_year_chffixed_cost_quote_percent variable_actual_year_to_date_chfN)
r0   r   rS   r   r   r   r   r8   r   r   )r7   r   r5   r   r   rd   r=   rD   boolr#   r%   r?   itemsr>   rQ   rv   r   r   rr   rm   r   r+   ranger   rh   'jarvis_finance.services.budget_planningr   update	Exception)$r   rm   	plan_rowstx_rowsr   groupedr   r0   rS   r   catancestor_idancestorr   rj   bmbyresultsrz   	month_setr   denom
actual_avgry   forecast_month	deviationr   current_month_nor   planning_by_idplanningr   r   r9   r   r   s$                                  @@@@@r   get_budget_status_by_categoryr     s   $D	 
	 	 hjj  ll	 
  hjj  35F57O,.N N N N N N N N N  "G G G#m,233 	k55S]1c2233s-.4"55ac:
;111;;QTU[Q\or  tC  pD  TW  T[  T[  \h  Ti  Ti  Tp  mp  BI  JM  BN  BN  _f  gj  _k  _k  vx  FK  Z_  )`  )`  	a  	a  	a(d;; 	G 	GKK(HJ{FHkBBB CGG{KU]^dUe  yA  BQ  yR  bj  bn  bn  o{  b|  b|  bC  @C  U\  ]`  Ua  Ua  ry  z}  r~  r~  IK  Y^  mq  -r  -r  s  s  t  @  @	G
     $}-..!!+&_-!/2|,3#CLL"3<<.22;??@@
0
 
0
 
 
 "$'' &&^"]r!WT&\***ZG$]]__ $ $T!'K'#,,9N!O!OYY!D$4#D&11 75>>1
6AS
WT]]22ws||:GY66WUX\\!D$77	o.]0C]T_aghh*..{B??:=djll>O:P:PTX:X:Xdjll0666^b 
;
Z(
 T/2
 $z:JTDn!5666PT	

 Z8HR4] 3444d
 $tJ/00
 )
 #D)9)=)=>NPWX[P\P\)])]$^$^
 "4#4#4
 wwwwjopqsujvjvwww
  1$2Ggklvgw  PJtTbOcOc  ~E  FI  ~J  ~J  L\  !]  !]
 Z 0 0
 T-00
 !$~"6"6
 d9oo
  tI$=>>!
" f#
$ JPS`I`I`eijyez  G  fG  fGEE  }C  GT  }T  }T  Ny  Ny  Z\$*w-dhh{3344"%&6&:&:;&N&N"O"O-
 
 
 	 	 	 	0 LL  T  T  T  TL  U  U  UVVVVVVyy=W=WX\cg=h=h=h=l=lmsuw=x=xyyy 	 	C%))#m*<==H sww779DDJJ -? @ @x||,=>>  .L!M!M "8<<0E#F#F	
 #HLL1J$K$K &x||4M'N'N '5K(L(L *8<<8W+X+X !(,,/G"H"H x||H/E/E/W/W#''(+++^f^j^jks^t^t  _Jx{xx  AI  yJ  yJ $X\\2E%F%F )(,,7O*P*P  o!>!> $X\\2E%F%F ,X\\:U-V-V  +HLL9S,T,T!" +HLL9S,T,T#$ 3HLLAc4d4d%     		0    Ns   +Ib   
bbc                  |r|rt          |          dk     rt          d          |                     d|f                                          }|st          d          |d d         }|                     d||f                                          }t          d |D             t          d                    }|                     d	||f                                          }t          d
 |D             t          d                    }||z
  }	|dk    rt          d          n|	|z  t          d          z  }
t          t          |d                   ||          \  }}i }|D ]|}t          |d         p|d         p	|d         pd          }|	                    |t          d                    t          t          |d         p	|d         pd                    z   ||<   }g }t          |                                d d          D ]b\  }}|dk    rt          d          n||z  t          d          z  }|                    |t          |          t          |          d           cg }|D ]X}t          |          }t          |d         pd          |d<   t!          |d                   |d<   |                    |           Y|t          |d                   t          |d                   |t          |          t          |          t          |	          t          |
          ||t#          d |D                       rdnd||d| d| d | d!S )"Nr   z*category_id and month YYYY-MM are requiredzRSELECT category_id, name, category_type FROM budget_categories WHERE category_id=?zcategory not found   zz
        SELECT * FROM budget_plan_items
        WHERE is_active=1 AND category_id=? AND substr(plan_month,1,4)=?
        c              3  4   K   | ]}t          |          V  d S r   )r#   )r2   ps     r   	<genexpr>z,get_category_month_detail.<locals>.<genexpr>E  s+      CCA,Q//CCCCCCr   r   a  
        SELECT t.*, a.name AS account_name, c.name AS category_name,
               COALESCE(li.line_item_count, 0) AS line_item_count
        FROM budget_transactions t
        JOIN budget_accounts a ON a.budget_account_id=t.account_id
        LEFT JOIN budget_categories c ON c.category_id=t.category_id
        LEFT JOIN (
            SELECT transaction_candidate_id, COUNT(*) AS line_item_count
            FROM budget_import_line_items
            GROUP BY transaction_candidate_id
        ) li ON li.transaction_candidate_id=t.source_candidate_id
        WHERE t.status='confirmed' AND t.category_id=? AND substr(t.transaction_date,1,7)=?
          AND t.transaction_type IN ('expense','fee','income','refund')
        ORDER BY t.transaction_date, t.created_at
        c              3  n   K   | ]0}t          t          |d          p	|d         pd                    V  1dS )r   r   r   Nr   r1   s     r   r
  z,get_category_month_detail.<locals>.<genexpr>X  sG      ``ST'#aoL3D1ELMMNN``````r   r   100rw   payeeaccount_namesource_typeQueller   r   c                    | d         S )Nrq   r\   )kvs    r   r^   z+get_category_month_detail.<locals>.<lambda>a  s
    r!u r   Tr_   )r   r   share_percentline_item_countarticle_rows_detail_onlyr   c              3  &   K   | ]}|d          V  dS )r  Nr\   r1   s     r   r
  z,get_category_month_detail.<locals>.<genexpr>u  s&      +H+H1AgJ+H+H+H+H+H+Hr   merchantsourcez&/planning/budget/expenses/actual?year=z&month=z&category_id=)r0   r   rw   r   r   r   r   difference_percentr   r   breakdown_mode	breakdowntransactionsexpense_filter_url)rQ   
ValueErrorr   r   r5   sumr   r   r   r=   sortedr   r?   r+   r	   re   r   any)r   r0   r   r   rm   r   r   r   r   
differencediff_pctr   r   r   r   r   r  r&   sharer  rj   s                        r   get_category_month_detailr%  7  s    Ge Gs5zzA~~EFFF
,,knym{
|
|  F  F  H  HC /-...!9D	 
d  hjj  CCCCCWS\\RRLll	 
e! " hjj# $ ``X_```bijmbnbnooF,&J+q00ws|||zL7PSZ[`SaSa7aH!#c/&:";";V\RRMFE"$G } }CLYC$7Y3};MYQYZZ UGCLL99GCLHYHz]`ar]sHzwzD{D{<|<||Iw}}4D4DdSSS d du &!%&.75>>2Q5UVZ[`VaVabbccccL " "3"%c*;&<&A"B"B+/5F0G+H+H'(D!!!!"F$$S122\**6llz**"8nn(++H+H+H+H+H(H(HV**h$utuuTYuuhsuu  r   c                  |                      df                                          }g }|D ]}t          t          |d         pd                    }t          t          |d         pd                    }|                    |d         t          |          t          |          t          ||z
            d           t          |           }fd|D             }d	 |D             }	| |||	d
S )Na  
        SELECT substr(transaction_date,1,7) AS month,
               SUM(CASE WHEN transaction_type IN ('income','refund') THEN CAST(COALESCE(amount_chf, amount_original, '0') AS REAL) ELSE 0 END) AS income,
               SUM(CASE WHEN transaction_type IN ('expense','fee') THEN CAST(COALESCE(amount_chf, amount_original, '0') AS REAL) ELSE 0 END) AS expense
        FROM budget_transactions
        WHERE status='confirmed' AND substr(transaction_date,1,4)=?
        GROUP BY substr(transaction_date,1,7)
        ORDER BY month
        rI   r   rL   r   )rm   r   rM   rN   rO   r   c                z    g | ]7}|d          |d         |d         |d         |d         |d         |d         d8S )r0   r   rw   rx   r   ry   r   )rm   r0   r   rw   rx   r   ry   r   r\   )r2   r3   rm   s     r   rc   z*get_budget_charts_2026.<locals>.<listcomp>  s        a&6AjMdefudv  HI  JW  HX  qr  sH  qI  \]  ^m  \n  z{  |D  zE  	F  	F  r   c                &    g | ]}|d          dv |S )r   >   r   r   r\   r1   s     r   rc   z*get_budget_charts_2026.<locals>.<listcomp>  s'    RRRaq{>Q/Q/Q/Q/Q/Qr   )rm   empty_statecashflow_by_monthbudget_vs_actual_by_categoryforecast_overruns)r   r5   r   r   r?   r+   r  )
r   rm   	cash_rowscashflowr3   rI   rL   status_rowsbudget_vs_actualoverrunss
    `        r   get_budget_charts_2026r2  |  sg   	 
  hjj  H c cQx[-A..//73q|GXWXCYCY;Z;Z'
$v,,gklsgtgt  KO  PV  Y`  P`  Ka  Ka  b  b  	c  	c  	c  	c/4@@@K      SR+RRRH#|%(8%  r   c               T   d t          | |          D             dfd} |d          } |d	          } |d
          } |d          }t          t          j                    j                  |k    rt          j                    j        dndt          fdD             t          d                    }||z
  }|r|t          d          z  nt          d          }	||z
  }
t          d|||t          d D             d                    }|dk    rd}n|
dk    r|
dk    rdnd}nd}|t          |          t          |          t          |	          t          |          t          |          t          |          t          |          t          |
          ||dS )Nc                *    g | ]}|d          dk    |S )rw   rI   r\   r1   s     r   rc   z%get_income_status.<locals>.<listcomp>  s(    hhh!?I[_gIgIgAIgIgIgr   r   r`   r   r   r   c                X     t           fdD             t          d                    S )Nc              3  `   K   | ](}t          t          |         pd                     V  )dS )r   Nr   )r2   r3   r`   s     r   r
  z/get_income_status.<locals>.s.<locals>.<genexpr>  s;      >>AGC##..//>>>>>>r   r   )r  r   )r`   r6   s   `r   szget_income_status.<locals>.s  s/    >>>>>>>MMMr   r   rx   ry   r   r   r!   c           	   3     K   | ]I}t          t          |                    d           pi                     d                              V  JdS )r   r   N)r   r   r=   )r2   r3   r  s     r   r
  z$get_income_status.<locals>.<genexpr>  sX      xxnoQUU3D-E-E-K,P,PQacf,g,g(h(h i ixxxxxxr   r   rI   c              3  @   K   | ]}t          |d                    V  dS )rn   N)re   r1   s     r   r
  z$get_income_status.<locals>.<genexpr>  s2      LzLzpqSQRSiQjMkMkLzLzLzLzLzLzr   r   )defaultzNoch keine Ist-DatenzIm Planu
   Über Planz
Unter Plan)rm   planned_income_monthplanned_income_yearplanned_income_monthly_averageactual_income_current_monthactual_income_year_to_dateforecast_income_yeardeviation_current_monthr   r   status_label
categories)r`   r   r   r   )r  r   r   rr   rm   r   r  r   r   rs   r+   )r   rm   r7  r   rx   ry   rz   r   rA  planned_monthly_averager   r   rB  r  r6   s                @@r   get_income_statusrE    s0   hh4TEEEhhhDN N N N N N1^$$L!M""KAo&&M!)**K69$*,,:K6L6LPT6T6T$*,,,222Z^xxxxswxxx  {B  CF  {G  {G  H  H2\A=HZkGDMM99gVYll ;.NX{M;LzLzuyLzLzLz  EF  IG  IG  IG  H  HFa-	1		$2a$7$7yy\# $\ 2 2#K00*./F*G*G'+,@'A'A&*;&7&7 $] 3 3#'(?#@#@~..$  r   c           	        |pt          |           }|d d         }t          | |          }|                     d|f                                          }|                     d|f                                          d         }|                     d                                          d         }|                     d|f                                          d         }t          d |D                       }t          | |          }	t          d	 |	D             t          d
                    }
t          d |	D             t          d
                    }t          t          |d                             }t          t          |d                             }|
|z
  }||z
  }||z
  }t          d |	D                       }d |D             }ddl	m
}  || | d          }|                    di           }d|i|i dt          |          d|dt          |          dt          |          dt          |
          dt          |          dt          |          dt          |          dt          |          dt          |          d|d |                    d!d"          d#|                    d#d"          d$|                    d%d          d&|                    d'd          d(t          |          d)t          |          |	sd*n|sd+n	|dk     rd,nd-|sd.nd/|	|t          | |          d d0         t          |           d d1         d2S )3Nr  rG   ai  
        SELECT COUNT(*) FROM budget_transactions t
        LEFT JOIN budget_transaction_tags tt ON tt.budget_transaction_id=t.budget_transaction_id
        LEFT JOIN budget_tags tag ON tag.tag_id=tt.tag_id
        WHERE t.status='confirmed' AND substr(t.transaction_date,1,7)=? AND (t.category_id IS NULL OR tag.name='Review' OR t.fx_status='missing')
        r   zjSELECT COUNT(*) FROM budget_seed_candidates WHERE status IN ('pending','needs_review','edited','accepted')zSELECT COUNT(*) FROM budget_transaction_candidates WHERE substr(transaction_date,1,4)=? AND status IN ('pending','needs_review')c              3  >   K   | ]}|d          
|d         dv dV  dS )r0   NrH   >   rK   rI   rJ   rL   rq   r\   r1   s     r   r
  z&get_budget_overview.<locals>.<genexpr>  se        I  Ia1]+;+CJ\H]  bH  IH  IH  IH  IH  IH  IH  I  Ir   r   c              3  v   K   | ]4}|d          dk    t          t          |d         pd                    V  5dS )rw   rI   r   r   Nr   r1   s     r   r
  z&get_budget_overview.<locals>.<genexpr>  sN      xxQYZ[jYkowYwYw'#a&7&>3"?"?@@YwYwYwYwxxr   r   c              3  v   K   | ]4}|d          dk    t          t          |d         pd                    V  5dS )rw   rL   r   r   Nr   r1   s     r   r
  z&get_budget_overview.<locals>.<genexpr>  sN      zzaZ[\kZlpyZyZy73q'8'?C#@#@AAZyZyZyZyzzr   rM   rN   c              3  2   K   | ]}|d          dk    dV  dS )r   r}   rq   Nr\   )r2   rj   s     r   r
  z&get_budget_overview.<locals>.<genexpr>  s1      aaTDNN`<`<`q<`<`<`<`aar   c                P    g | ]#}|d          
|d         dv t          |          $S )r0   NrH   >   rK   rI   rJ   rL   r   r1   s     r   rc   z'get_budget_overview.<locals>.<listcomp>  s[      X  X  XQ!M:J:RWXYkWl  qW  XW  XW+a..  XW  XW  XWr   )get_recurring_dashboardz-28)rr   kpiscurrent_monthreview_countuncategorized_countpending_seed_candidate_count#pending_transaction_candidate_countplanned_income_chfplanned_expense_chfplanned_net_chfactual_income_chfactual_expense_chfactual_net_chfopen_categories_without_actualsfixed_costs_month_chfmonthly_fixed_costs_chfz0.00r   open_fixed_cost_candidate_countopen_candidate_count missing_fixed_cost_payment_countmissing_payment_countplanned_budget_chfremaining_budget_chfno_plans
no_actualsover_budgetokznoch keine BuchungenzBuchungen vorhandenr      )budget_statusactuals_labelbudget_categoriesuncategorized_transactionstop_categoriesrecent_transactions)r   rT   r   r5   r   r  r  r   r   (jarvis_finance.services.budget_recurringrL  r=   re   r+   rl   r
   )r   r   rm   r   r6   rO  pending_seed_countpending_tx_candidatesuncategorizedr/  planned_incomeplanned_expenseactual_incomeactual_expenseplanned_net
actual_netremaining_totalopen_without_actualsuncategorized_rowsrL  	recurringrecurring_kpiss                         r   get_budget_overviewr|    s   )^D))E!9D!$..G<<wz  zB  C  C  L  L  N  ND<<	 
  hjjL   'S  T  T  ]  ]  _  _  `a  b LL  *l  os  nu  v  v      A  A  BC  D  I  I4  I  I  I  I  IM/4@@@Kxx+xxx  {B  CF  {G  {G  H  HNzz;zzz  }D  EH  }I  }I  J  JOC 56677MS!78899N ?2K/J%6Oaa[aaaaa X  X$  X  X  XPPPPPP''uMMMBBBI]]62..N
  	L)) 	}	
 	',>(?(? 	.s3H/I/I 	d>22 	tO44 	4,, 	T-00 	d>22 	$z** 	*+? 	 !3!34Mv!V!V 	#N$6$67QSY$Z$Z  	*>+=+=>TVW+X+X!" 	+N,>,>?VXY,Z,Z#$ 	d?33%& 	_ 5 5' ( ,7  MQU  >L\\m|  @A  nA  nA\i\i  GK7;V//AV(&8.tU;;BQB?7==bqbA3   r   )r   r   r   r   )r   r   )r&   r   r   r   )r   r   r   r,   )r0   r8   r9   r,   r   r:   r   )r   r   r   r8   r   rE   )r   r   r   r8   r   rU   )rm   r   rn   re   r   re   )rw   r   rx   r   ry   r   rz   r   rn   re   r   r   )rw   r   r   r   r   r   r   r   )
rw   r   rm   r   r   r   r   r   r   rU   )r   r   rm   r   r   rU   )r   r   r0   r   r   r   r   rE   )r   r   rm   r   r   rE   )
__future__r   datetimer   decimalr   sqlite3r   %jarvis_finance.services.budget_commonr	   +jarvis_finance.services.budget_transactionsr
   r   r   r#   r%   r+   r7   rD   rT   rl   rv   r   r   r   r  r%  r2  rE  r|  r\   r   r   <module>r     sF   " " " " " "                   = = = = = = P P P P P PH H H HL L L L      8 8 8 8A A A A

 
 
 
k k k k kH H H H H8? ? ? ?   *   &   & DJ G G G G G GTB B B BJ =C      @ 8> ! ! ! ! ! !H8 8 8 8 8 8 8r   