
    bj|`                       d dl mZ d dlmZ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 djdZdkdZdldZdmdZdndodZdpd Zdqd"Zd#d$drd'Zh d(Zd)d*gd+d,d-d.d/d*d0d1d+d2d3d4d*d5d6d+d7d3d8d9d5d:d;d-d.d/d<d5d=d;d2d3d4d<d5d>d;d-d.d/d<d5d?d;d2d3d4d<d5d@d;d7d3d8d9d5dAdBdCdDd3dEdFdGdHdBdIdJdKdLd5g
ZdMdNdsdRZdtdTZdtdUZdtdVZddWdXdud\Zd]dMd^dvd_Zd]d`dwdaZd]d`dxdbZ d]d`dxdcZ!dydeZ"dydfZ#dzdgZ$d]d`d{diZ%dS )|    )annotations)DecimalInvalidOperation)
Connection)HTTPException)record_audit_event)new_idnowrow_to_dictvaluer   returnstrc                b    t          |                     t          d                    d          S )Nz0.01f)formatquantizer   )r   s    /home/agent/.hermes/worktrees/FinanceManager-sprint3-reconciliation-snapshot-foundation/src/jarvis_finance/services/budget_plans.py_fmtr      s$    %..113777    rowdicttuple[str, str]c                   t          t          |                     d          pd                    }t          t          |                     d          pd                    }t          |                     d          pd          }|r|s|t          d          z  }n|r|s|dk    r|n|t          d          z  }t          |          t          |          fS )Nmonthly_amount_chf0annual_amount_chfcadencemonthly12one_time)r   r   getr   )r   r   annualr   s       r   _derived_amountsr#      s    c#''"677>3??@@GS!455<==>>F#'')$$1	22G Og O74==(	 O O#z11w7N==$v,,&&r   tuple[str, str, str]c                    t          |           \  }}t          |          rt          |          t          d          z  nt          d          }||t          |          fS )Nr   r   )r#   r   r   )r   r   r"   monthly_averages       r   _income_projectionr'      sU    &s++OGV9@Zgfoo55gVYllOFD1111r   notes
str | Nonedict[str, str]c                   i }t          | pd                              dd                              d          D ]H}d|v rB|                    dd          \  }}|                                ||                                <   I|S )N |;=   )r   replacesplitstrip)r(   resultpartkvs        r   _parse_notesr8   !   s    FEKR  ((c2288== * *$;;::c1%%DAq !		F17799Mr   Nmetaextrac                    d |                                  D             }|r"|                    t          |                     d                    |          S )Nc                &    g | ]\  }}|| d | S )r/    ).0keyr   s      r   
<listcomp>z$_notes_from_meta.<locals>.<listcomp>+   s/    FFF*#uFeFFFr   r.   )itemsappendr   join)r9   r:   partss      r   _notes_from_metarE   *   sM    FF

FFFE !SZZ   88E??r   connr   yearnames	list[str]dict | Nonec                    d |D             }d                     d |D                       }|                     d| d|g|                                          }|rt          |          nd S )Nc                6    g | ]}|                                 S r=   )lowerr>   ns     r   r@   z5_find_active_income_plan_by_names.<locals>.<listcomp>2   s     (((Qqwwyy(((r   ,c              3     K   | ]}d V  dS )?Nr=   )r>   _s     r   	<genexpr>z4_find_active_income_plan_by_names.<locals>.<genexpr>3   s"      11AC111111r   z
        SELECT p.*, c.category_type
        FROM budget_plan_items p
        JOIN budget_categories c ON c.category_id=p.category_id
        WHERE substr(p.plan_month,1,4)=? AND p.is_active=1 AND c.category_type='income'
          AND lower(p.name) IN (z0)
        ORDER BY p.created_at LIMIT 1
        )rC   executefetchoner   )rF   rG   rH   loweredplaceholdersr   s         r   !_find_active_income_plan_by_namesrY   1   s    ((%(((G881111111L
,,	
 ".	 	 	 

 
 hjj   #,;s,r   namec                    |                      d|f                                          }|rt          |d                   nd S )NzSELECT category_id FROM budget_categories WHERE is_active=1 AND category_type='income' AND lower(name)=lower(?) ORDER BY sort_order LIMIT 1category_id)rU   rV   r   )rF   rZ   r   s      r   _category_id_by_namer]   B   s`    
,,  e  hl  gn  o  o  x  x  z  zC&)33s=!"""t3r   i  
sort_orderr_   intc          
         t          | |          }|r|S t          d          }t                      }|                     d|||||f           t	          | ddd||ddd	           |S )
Nbcatz
        INSERT INTO budget_categories(category_id, parent_category_id, name, category_type, color, icon, is_active, sort_order, created_at, updated_at)
        VALUES (?, NULL, ?, 'income', NULL, NULL, 1, ?, ?, ?)
        vue_dashboard income_template_category_createdbudget_categoryincome)rZ   category_typeusersourceactionentity_type	entity_id
new_values
created_by)r]   r	   r
   rU   r   )rF   rZ   r_   existingr\   tss         r   _ensure_income_categoryrr   G   s    #D$//H ..K	BLL	 
dJB/   tO<^l}  JU  ko  BJ  bK  bK  X^  _  _  _  _r   >   r"   r   r    	irregular	quarterlyzLohn Marcel (ERNE)zLohn MarcelMarcelERNELohnr   	monatlich)rZ   legacy_namespersonemployerincome_typer   target_monthcategoryz13. Monatslohn Marcelz13. Monatslohnr"   Dezember)rZ   rz   r|   r   r}   r~   zBonus MarcelBonusAprilGratifikationzLohn Melanie MusikschuleMelaniezLohn Melaniez"13. Monatslohn Melanie Musikschuleu&   Lohn Melanie – Gasser Bauunternehmenu0   13. Monatslohn Melanie – Gasser BauunternehmenzBonus Melanieu   Rückvergütung SolarstromHaushalt
Solarstromu   Rückvergütungznoch festzulegenzSonstige Einnahmen)rZ   rz   r{   r|   r   r}   r~   u&   Rückerstattungen / Sonstige Einnahmenu   Rückerstattungrs   z
bei Bedarfu   RückerstattungenF)requiredobjectr   boolc               0   | dv r|rt          dd          d S 	 t          t          |                                                     }n'# t          t
          f$ r t          dd          d w xY w|dk     rt          dd          t          |d          S )	N)Nr,     zamount is requiredstatus_codedetailzinvalid decimal amountr   zamount must be positiver   )r   r   r   r3   r   
ValueErrorr   )r   r   amounts      r   _decimal_textr   h   s    
 	NC8LMMMMtXU))++,,j) X X X4LMMMSWWXzz4MNNNN&#s   .A
 
$A.payloadc                l   t          |                    d          pd                                          }t          |          dk    s|d         dk    rt	          dd          t          |                    d	          pd                                          }|st	          dd
          |                     d|f                                          }|st	          dd          t          |                    d          pd                                          }|st	          dd          t          |                    d          pd                                          }|t          vrt	          dd          t          |                    d                    }t          |                    d                    }t          |                    d                    }	|,|*|	                    d          dk    rt	          dd          |                    d          pt          d          ||||||t          |                    dd                    |                    d          pd|                    d          pd t          |                    d          pd          d S )!N
plan_monthr,         -r   zplan_month must be YYYY-MMr   r\   zcategory_id is requiredz3SELECT 1 FROM budget_categories WHERE category_id=?zcategory not foundrZ   zname is requiredr   r   zinvalid cadencer   r   r(   templatetruez$monthly or annual amount is requiredplan_item_idbplanis_fixed_costFsource_typemanualr_     )r   r   r\   rZ   r   r   r   r   r   r(   r_   )r   r!   r3   lenr   rU   rV   CADENCESr   r8   r	   r   r`   )
rF   r   r   r\   r~   rZ   r   r   r"   r9   s
             r   _normalise_plan_payloadr   v   s   W[[..4"55;;==J
:!z!}334PQQQQgkk-006B77==??K O4MNNNN||QT_SabbkkmmH J4HIIIIw{{6""(b))//11D H4FGGGG'++i((5I66<<>>Gh4EFFFFGKK(<==>>G7;;':;;<<FG,,--D6>dhhz.B.Bf.L.L4Z[[[[N33Fvg "%#gkk/5AABB{{=11=XW%%-'++l33:s;;  r   c                ~    t          | |          }t          d          |d          d|d          d|d          g |dS )NpreviewrZ   u    · r   r   )
preview_idsummarywarningsr   )r   r	   )rF   r   
normaliseds      r   create_budget_plan_item_previewr      sZ    (w77JY'' (ccj.FccJW`Lacc	  r   c                F   t          | |          }|                     d|d         |d         |d         |d         |d         |d         |d         f                                          }|rgt          | d	d
dt	          |d                   d|d         |d         dd          }|                                  dt	          |d                   |ddS t                      }|                     d|d         |d         |d         |d         |d         |d         |d         |d         rdnd|d         |d         |d         ||f           t          | d	dd|d         d |                                D             d          }|                                  d|d         |ddS )Na]  
        SELECT plan_item_id FROM budget_plan_items
        WHERE plan_month=? AND category_id=? AND lower(name)=lower(?)
          AND COALESCE(monthly_amount_chf, '')=COALESCE(?, '')
          AND COALESCE(annual_amount_chf, '')=COALESCE(?, '')
          AND cadence=? AND source_type=? AND is_active=1
        ORDER BY created_at LIMIT 1
        r   r\   rZ   r   r   r   r   rc   idempotent_confirmbudget_plan_itemr   T)deduplicatedrZ   r   rh   ri   	confirmedzBudgetplan bereits vorhandenstatusrm   audit_idmessagea  
        INSERT INTO budget_plan_items(plan_item_id, plan_month, category_id, name, monthly_amount_chf, annual_amount_chf, cadence, is_fixed_cost, source_type, notes, sort_order, is_active, created_at, updated_at)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?)
        r   r0   r   r(   r_   createc                &    i | ]\  }}|d k    ||S )r   r=   r>   r6   r7   s      r   
<dictcomp>z,confirm_budget_plan_item.<locals>.<dictcomp>   sk      c_  c_  c_  mq  mn  pq  KL  P^  K^  K^  de  gh  K^  K^  K^r   zBudgetplan gespeichert)r   rU   rV   r   r   commitr
   rA   )rF   r   r   rp   r   rq   s         r   confirm_budget_plan_itemr      sW   (w77J||	 |$}%v+,*+y!}%	
 $ hjj% &  T%"'*(>233(,j6HXbcoXpqq
 
 
 	%C8P4Q4Q_g  uS  T  T  	T	BLL	
 ~&|$}%v+,*+y!O,3AA!}%w|$	
  * "$x]o  |F  GU  |V  c_  c_  u  uE  uE  uG  uG  c_  c_  c_  lr  s  s  sHKKMMM!
>0JX`  nF  G  G  Gr   T)monthinclude_archivedr   r   
list[dict]c               8   g }g }|r*|                     d           |                     |           |s|                     d           |rdd                    |          z   nd}|                     d| d|                                          }d |D             S )	Nzp.plan_month=?zp.is_active=1zWHERE z AND r,   z
        SELECT p.*, c.name AS category_name, c.category_type
        FROM budget_plan_items p
        JOIN budget_categories c ON c.category_id=p.category_id
        zB
        ORDER BY p.plan_month DESC, c.sort_order, p.name
        c                    g | ]=}t          |          t          |d                    t          |d                   dz  >S )	is_activer   r   r   r   r   )r>   r   s     r   r@   z*list_budget_plan_items.<locals>.<listcomp>   s]      C  C  CvyKT#k2B-C-CVZ[^_n[oVpVpqqq  C  C  Cr   )rB   rC   rU   fetchall)rF   r   r   clausesparamswhererowss          r   list_budget_plan_itemsr      s    GF '(((e ('''07?Hw||G,,,,RE<<	 
		 	 	 		 	 hjj 	 C  C  ~B  C  C  C  Cr   2026)rG   r   c                  |                      d||rdndf                                          }g }|D ]=}t          |          t          |d                   t          |d                   dz  }t	          |          \  }}}	t          |                    d                    }
|                      d|d	         |f                                          }|r$t          t          |d
         pd                    nt          d          }t          |          }||z
  }|
                    |||	t          |          t          |          t          |          |sdn|t          d          k    rdnd|
                    d          p|
                    d          pd|
                    d          p|
                    d          pd|
                    d          p|
                    d          pd|
                    d          p1|
                    d          p|                    d          dk    rdnd|
                    d          dk    d           |                    |           ?|S )NaV  
        SELECT p.*, c.name AS category_name, c.category_type
        FROM budget_plan_items p
        JOIN budget_categories c ON c.category_id=p.category_id
        WHERE c.category_type='income' AND substr(p.plan_month,1,4)=?
          AND (? OR p.is_active=1)
        ORDER BY p.is_active DESC, p.sort_order, c.sort_order, p.name
        r0   r   r   r   r   r(   z
            SELECT COALESCE(SUM(amount_chf),0) AS actual_ytd
            FROM budget_transactions
            WHERE status='confirmed' AND transaction_type='income'
              AND category_id=? AND substr(transaction_date,1,4)=?
            r\   
actual_ytdr   zNoch keine PlanwertezIm Planu   Prüfenrz   rj   r   r{   r,   r|   typezSonstige Einnahmer}   r   r   r   rx   r   r   )monthly_value_chfannual_value_chfmonthly_average_chfactual_income_year_to_date_chfforecast_income_year_chfdeviation_year_chfstatus_labelperson_sourceemployer_sourcer|   r}   is_template)rU   r   r   r   r'   r8   r!   rV   r   r   updater   rB   )rF   rG   r   r   r4   r   itemr   r"   r&   r9   
actual_rowr   forecast_yeardeviation_years                  r   list_income_plan_itemsr      s   <<	 
$+qq!,
 
 hjj 	 F  3S5E0F0FY]^abq^rYsYs"t"tt+=d+C+C(DHHW--..\\ - $'
 
 (** 	 GQbWSL!9!@SAABBBV]^aVbVb
#m3!( &#2.2:.>.>(,](;(;"&~"6"6:G  F22[eipqtiuiu[u[uii  |E!XXh//S488H3E3ES#xx
33Otxx7I7IOR88M22]dhhv6F6F]J] HH^44  G8I8I  G]a]e]efo]p]pt}]}]}kk  DF88J//69
 
 	 	 	 	dMr   rG   c               ~    |                      dd| dd| df                                          }d |D             S )Na  
        SELECT * FROM budget_seed_candidates
        WHERE status IN ('pending','needs_review','edited','accepted')
          AND (candidate_type IN ('income_plan','budget_plan') OR lower(COALESCE(proposed_name,'') || ' ' || COALESCE(proposed_parent_label,'') || ' ' || COALESCE(notes,'')) LIKE '%lohn%' OR lower(COALESCE(proposed_name,'') || ' ' || COALESCE(proposed_parent_label,'') || ' ' || COALESCE(notes,'')) LIKE '%gratifikation%' OR lower(COALESCE(proposed_name,'') || ' ' || COALESCE(proposed_parent_label,'') || ' ' || COALESCE(notes,'')) LIKE '%einnah%')
          AND (COALESCE(proposed_period_type,'')='' OR COALESCE(proposed_period_type,'') LIKE ? OR COALESCE(source_sheet,'') LIKE ?)
        ORDER BY requires_review DESC, source_sheet, source_row_or_range
        %c                \    g | ])}t          |          d t          |d                    iz  *S )requires_reviewr   r>   rs     r   r@   z/list_income_seed_candidates.<locals>.<listcomp>0  s8    [[[QRKNN/a8I6J1K1KLL[[[r   )rU   r   )rF   rG   r   s      r   list_income_seed_candidatesr   %  sZ    <<	 
Tk$kkk"	 	 hjj 	 \[VZ[[[[r   c                  d |                      d|f                                          D             fdt          D             }t          d          |t	          |          t          d |D                       |ddgdS )	Nc                \    h | ])}t          |d                                                    *S )rZ   r   rM   r   s     r   	<setcomp>z0preview_income_plan_templates.<locals>.<setcomp>4  s:     " " "1AfI$$&& " " "r   z
        SELECT p.name
        FROM budget_plan_items p
        JOIN budget_categories c ON c.category_id=p.category_id
        WHERE substr(p.plan_month,1,4)=? AND p.is_active=1 AND c.category_type='income'
        c                   g | ]}|d          |d         |                     d          pd|d         |d         |d         |d                                          v p.t          fd|                     dg           D                       d	S )
rZ   rz   r{   r,   r|   r   r}   c              3  ^   K   | ]'}t          |                                          v V  (d S Nr   )r>   legacyrp   s     r   rT   z;preview_income_plan_templates.<locals>.<listcomp>.<genexpr>B  s\        FR  FRjpc&kkFWFWFYFY]eFe  FR  FR  FR  FR  FR  FRr   ry   )rZ   rz   r{   r|   r   r}   already_exists)r!   rM   any)r>   specrp   s     r   r@   z1preview_income_plan_templates.<locals>.<listcomp>:  s         L8n,,2.I 0"6l0022h>  R#  FR  FR  FR  FRtxt|t|  ~L  NP  uQ  uQ  FR  FR  FR  CR  CR	
 	
  r   r   c              3  *   K   | ]}|d          
dV  dS )r   r0   Nr=   )r>   ts     r   rT   z0preview_income_plan_templates.<locals>.<genexpr>F  s`        qb  qbwx  NO  P`  Na  qbqr  qb  qb  qb  qb  qb  qbr   Tu/   Templates enthalten bewusst keine Planbeträge.)r   rG   template_countcreate_count	templatesrequires_explicit_confirmr   )rU   r   INCOME_TEMPLATE_SPECSr	   r   sum)rF   rG   r   rp   s      @r   preview_income_plan_templatesr   3  s    " " >
 W1 1
 hjj" " "H    *  I !++TSQZ^^mp  qb  qb  }F  qb  qb  qb  nb  nb  qz  Y]  l]  k^  _  _  _r   c                  t          | |          }t                      }dx}}d}g }t          t          d          D ]\  }}	|                     d||	d         f                                          r|dz  }<|	                    d          r/t          | |d |	                    dg           D                       nd }
|
rt          |
                    d	                    t          |	d
                   t          |	d                   t          |	d                   ddz  }|	                    d          rt          |	d                   |d<   |                     d|	d         t          |          ||
d         f           t          | dddt          |
d                   d|
d         i|	d         |	                    d          dd           |dz  }|dz  }t          | t          |	d                   d|z             }t          d          }t          |	d
                   t          |	d                   t          |	d                   dd}|	                    d          rt          |	d                   |d<   t          |          }|                     d|| d||	d         |	d         ||dz  ||f	           t          | dd d||	d         |d!d"d#           |                    |           |dz  }t          | dd$dd%| ||||d&         d'd#          }|                                  d(|||||d)d*S )+Nr   r   r0   starta  
            SELECT 1
            FROM budget_plan_items p
            JOIN budget_categories c ON c.category_id=p.category_id
            WHERE substr(p.plan_month,1,4)=? AND lower(p.name)=lower(?) AND p.is_active=1 AND c.category_type='income'
            rZ   ry   c                ,    g | ]}t          |          S r=   )r   rN   s     r   r@   z1confirm_income_plan_templates.<locals>.<listcomp>X  s    ?m?m?m1A?m?m?mr   r(   rz   r|   r}   r   )rz   r|   r}   r   r{   zOUPDATE budget_plan_items SET name=?, notes=?, updated_at=? WHERE plan_item_id=?r   rc   income_template_renamedr   )rZ   r{   rh   rj   rk   rl   rm   
old_valuesrn   ro   r~   d   r^   r   a1  
            INSERT INTO budget_plan_items(plan_item_id, plan_month, category_id, name, monthly_amount_chf, annual_amount_chf, cadence, is_fixed_cost, source_type, notes, sort_order, is_active, created_at, updated_at)
            VALUES (?, ?, ?, ?, NULL, NULL, ?, 0, 'system', ?, ?, 1, ?, ?)
            z-01r   
   income_template_createdF)rZ   rG   
has_amountri   income_templates_seededzincome-templates:r   )created_countrenamed_countskipped_countr   r   z'Income templates seeded without amounts)r   r  r  r  
entity_idsr   r   )r   r
   	enumerater   rU   rV   r!   rY   r8   r   rE   r   rr   r	   rB   r   )rF   rG   r   rq   createdskippedrenamedcreated_idsidxr   r   r9   r\   plan_idr(   r   s                   r   confirm_income_plan_templatesr  I  s-   +Dt<<<G	BGgGK4A>>> " "	T<< 
 V%' '
 (0xzz	 qLGrvrzrz  |J  sK  sK  U24?m?mPTPXPXYgikPlPl?m?m?mnnn  QU 	

7 3 344#d8nBUBUfijno|j}f~f~  QT  UY  Zh  Ui  Qj  Qj  x~  8  8  Dxx
## 9#&tJ'7#8#8Z LLjmqrxmy  |L  MQ  |R  |R  TV  X^  _m  Xn  mo  p  p  ptOD]k}  JM  NT  Uc  Nd  Je  Je  sy  {A  BH  {I  rJ  `d  ek  `l  z~  zB  zB  CM  zN  zN  WO  WO  \b  c  c  c  cqLGqLG-dCZ8H4I4IVY\_V_```//d8n--c$}BU>V>Vhklpq  mA  iB  iB  PV  W  W88J 	5"4
#344D && lllKftIPUWZ]_W_acegh	
 	
 	
 	4@Ygy  FM  cg  hn  co  y}  MR  ZS  ZS  `f  	g  	g  	g  	g7###1!$G`  oA  Mg  ae  Mg  Mg  FM  `g  zA  U\  ]m  Un  to  to  |B  C  C  CHKKMMM!Ggho  @K  Ya  nW  X  X  Xr   r   c                   |                      d|f                                          }|st          dd          t          |          d |                                D             z  }|                    d          s*|                    d          s|                    d          rmt          |d	                   }d
D ]/}|                    |          rt          ||                   ||<   0t          ||                    d                    |d	<   t          | |          }t          |          \  }}	}
t          |                    d	                    }t          d          d|d          g |d|iz  d|d         |                    d          pd||	|
|                    d          p|d         dk    rdnd|d         ddS )N4SELECT * FROM budget_plan_items WHERE plan_item_id=?  budget plan item not foundr   c                "    i | ]\  }}|d v 	||S )>	   rZ   r(   r   r   r_   r\   r   r   r   r=   r   s      r   r   z3preview_update_income_plan_item.<locals>.<dictcomp>{  sJ      !M  !M  !M$!QQ  KL  FL  FLA  FL  FL  FLr   rz   r|   r}   r(   )rz   r|   r}   
extra_noter   zEinkunft aktualisieren: rZ   r   TEinkunftr   r   rx   r,   )rZ   r|   r   r   r   r}   r   )r   r   r   r   r   review)rU   rV   r   r   rA   r!   r8   r   rE   r   r'   r	   )rF   r   r   r   mergedr9   r?   r   r   r"   r&   s              r   preview_update_income_plan_itemr  w  s   
,,MP\
_
_
h
h
j
jC R4PQQQQ  !M  !M'--//  !M  !M  !M  MF{{8 LM : : Lgkk.>Y>Y LCL))< 	. 	.C{{3 .--S	*4\1J1JKKw(v66J'9*'E'E$GV_
w//00DY''Bj.@BB >>%)v&88M22@j!( &#2 HH^44s
S\H]ajHjHjpr!),
 
  r   c                ~   |                      d|f                                          }|st          dd          t          | ||          }|d         }t	                      }|                      d|d         |d         |d	         |                    d
          |                    d          |d         |                    d          pd|                    d          |                    d          pd||f           t          | ddd|t          |          |d          }|                                  d||ddS )Nr  r  r  r   r   z
        UPDATE budget_plan_items
        SET plan_month=?, category_id=?, name=?, monthly_amount_chf=?, annual_amount_chf=?, cadence=?, source_type=?, notes=?, sort_order=?, updated_at=?
        WHERE plan_item_id=?
        r   r\   rZ   r   r   r   r   r   r(   r_   r   rc   income_plan_updatedr   rh   r   updatedzEinkunft aktualisiertr   )	rU   rV   r   r  r
   r!   r   r   r   )rF   r   r   r   r   r   rq   r   s           r   confirm_update_income_plan_itemr    s   
,,MP\
_
_
h
h
j
jC R4PQQQQ-dL'JJG#J	BLL	
 
L	!:m#<j>PR\R`R`auRvRv  yC  yG  yG  H[  y\  y\  ^h  ir  ^s  u  uC  uC  DQ  uR  uR  u^  V^  `j  `n  `n  ov  `w  `w  yC  yG  yG  HT  yU  yU  y\  Y\  ^`  bn  	o   "$G\j|  IU  bm  nq  br  br  I  V\  ]  ]  ]HKKMMMl]tuuur   c           
     H   |                      d|f                                          }|st          dd          t                      }|                      d||f           t	          | ddd|t          |          d	d
id          }|                                  d||ddS )Nr  r  r  r   zKUPDATE budget_plan_items SET is_active=0, updated_at=? WHERE plan_item_id=?rc   archiver   r   r   rh   r   archivedzBudgetplan archiviertr   )rU   rV   r   r
   r   r   r   )rF   r   r   rq   r   s        r   archive_budget_plan_itemr    s    
,,MP\
_
_
h
h
j
jC R4PQQQQ	BLL^aceq`rsss!$y^p  }I  Va  be  Vf  Vf  t  AB  sC  PV  W  W  WHKKMMM |^uvvvr   plan_item_idsc                  t                      }d}g }g }t          |d          D ]\  }}|                     d||f                                          }	|	s2|                    ||	d         d           |dz  }
|                    ||
d           t          |	d         pd          |
k    r|                     d|
||f           |dz  }t          | d	d
dd| d|i|||dd          }|                                  d||dS )Nr   r0   r   a  
            SELECT p.plan_item_id, p.sort_order
            FROM budget_plan_items p
            JOIN budget_categories c ON c.category_id=p.category_id
            WHERE p.plan_item_id=? AND p.is_active=1 AND c.category_type='income' AND substr(p.plan_month,1,4)=?
            r_   )r   r_   r   zLUPDATE budget_plan_items SET sort_order=?, updated_at=? WHERE plan_item_id=?rc   reorder_income_plansr   zincome-plans:order)r#  updated_countrG   rh   r   	reordered)r   r$  r   )r
   r  rU   rV   rB   r`   r   r   )rF   r   rG   rq   r  	old_order	new_orderr  r  r   new_sortr   s               r   reorder_income_plan_itemsr)    s   	BGII!-q999  Wll dO
 
 (** 	  	'\ARSSTTT8'JJKKKs< %A&&(22LLgjrtvx  jA  B  B  BqLG!$G]k}  J`  Z^  J`  J`  nu  w@  mA  Xa  t{  EI  NJ  NJ  W]  ^  ^  ^HKKMMM!GRRRr   )r   r   r   r   )r   r   r   r   )r   r   r   r$   )r(   r)   r   r*   r   )r9   r*   r:   r)   r   r   )rF   r   rG   r   rH   rI   r   rJ   )rF   r   rZ   r   r   r)   )rF   r   rZ   r   r_   r`   r   r   )r   r   r   r   r   r)   )rF   r   r   r   r   r   )rF   r   r   r)   r   r   r   r   )rF   r   rG   r   r   r   r   r   )rF   r   rG   r   r   r   )rF   r   rG   r   r   r   )rF   r   r   r   r   r   r   r   )rF   r   r   r   r   r   )rF   r   r   rI   rG   r   r   r   )&
__future__r   decimalr   r   sqlite3r   fastapir   jarvis_finance.audit.logr   %jarvis_finance.services.budget_commonr	   r
   r   r   r#   r'   r8   rE   rY   r]   rr   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r)  r=   r   r   <module>r0     s   " " " " " " - - - - - - - -       ! ! ! ! ! ! 7 7 7 7 7 7 J J J J J J J J J J8 8 8 8' ' ' '2 2 2 2       - - - -"4 4 4 4
 OR      " GFF "M?hdj  |B  OX  ju  CP  Q  Q$IYfn  AK  Yf  g  gxT\nu  DS  T  T'9V`i  |G  Uc  d  d1YWgt|  OY  gu  v  v5[anw  JU  cq  r  r?9eu  CK  ]g  uC  D  D	'V^pw  FU  V  V)Z\j{  IQ  cu  CW  X  X5\m  {F  Xd  rE  F  F  6;      ! ! ! !H   9G 9G 9G 9Gx EIcg C C C C C C, =C]b , , , , , ,^ BH \ \ \ \ \ \ DJ _ _ _ _ _ _, DJ +X +X +X +X +X +X\   @v v v v(w w w w Z` S S S S S S S Sr   