
    {mj                     4   S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
rSSKrSSKr\	R                  r\	R                   r\R$                  R'                  \S5      rSrSrSrSrSS	S
S.r0 r0 rSrSrS1rSrSr Sr!SSK"J#r$J%r&J'r'J(r(  / SQr)SSSSS.r*Sr+S r,S r-S r.SS jr/SS jr0S r1S r2S  r3\\4S! jr4\\ \!4S" jr5S#S$S%S&S'S(S)S*S+S,S-S.S/.r6S0 r7S1 r8\S24S3 jr9S4 r:S5 r;SS6 jr<S7 r=S8 r>S9 r?S: r@S; rAS< rBS= rCS> rDS? rES@ rFSArGSBrH\	R                  rJSC rKSD\R                   V s/ s H   o R                  \R                  :w  d  M  U PM"     sn 4SE\R                   V s/ s H   o R                  \R                  :X  d  M  U PM"     sn 4/rO\R                   V s/ s H  o R                  U R                  4PM     sn rRSFrSSG\SSH/SI4SJSK/SL4SMSN/SL4SOSP/SL4SQSR/SL4/4SSSTSU/SV4SWSX/SV4SYSZ/SV4/4S[S\S]/S^4S_S`/S^4SaSb/S^4/4ScSdSe/SL4SfSg/SL4ShSi/SL4SjSk/SL4/4SlSmSn/SL4SoSp/SL4SqSr/SL4SsSt/SL4SuS/SL4/4Sv/ 4/rT\T VVVs/ s H  u  pU  H  o3PM     M     snnnrUSwrVSxrWSyrXSzrYS{rZ0 \VS|_\YS}_\XS~_\WS_S%S_S&S_S'S_S(S_S)S_S*S_S+S_S,S_S-S_SS_SS_SS_SHS_0 SKS_SUS_SNS_SPS_SRS_SiS_SkS_SgS_SXS_S]S_S`S_SeS_SnS_SbS_StS_SrS_SpS_ESSSS.Er[S r\S r]SS jr^\_S:X  a  SSK`r`\^" S\`R                  ;   S9  ggs  sn f s  sn f s  sn f s  snnnf )u  Лист «Касса» — кассовый прогноз (v3).

От сегодняшнего остатка проецируем вперёд по месяцам (без новых кредитов),
чтобы видеть, когда касса уходит в минус (кассовый разрыв).

Базы прогноза:
  - строки расходов — из финмодели (Google Sheet), колонка ищется ПО ШАПКЕ
    (год в строке 0, месяц в строке 1), поэтому горизонт спокойно уходит в 2027-й;
  - ЗП педагогов — МАКСИМУМ из строки финмодели и проекции по расписанию CRM
    (regular-lesson: слот × вхождения дня недели в месяце × ставка × сезон).
    Решение Наташи 29.07.2026: модель занижала (сен: 919к против 1.79М по живому
    расписанию), а расписание занижает месяцы, которые ещё не продлили;
  - кредиты — явный график plan_sync.CREDITS (суммы, since/until), НЕ строка модели;
  - НДС — отдельной строкой из plan_sync.MONTHLY_SINCE: в строке 40 финмодели его нет,
    там только УСН 5% + 1% с дохода;
  - остаток текущего месяца = «сколько обычно за месяц минус сколько уже заплачено».

Крутилки (KNOBS ниже): горизонт, сезонный коэффициент, коэф.доборов, выручка, разовые.
Запуск: python3 cashflow.py            # посчитать и записать лист «Касса»
        python3 cashflow.py --dry      # только посчитать и напечатать (лист не трогаем)
    Nzgsheets_sa.jsonz,1C0z2ONr-QrLozztfTCjkFqBteKLZyxFW5yg9RIhbLvAz,1MaEMGjyFfMeHw-xhaW38MjT954Bg9a3rFEZSAjLe1t0)i           ?g(\?
ףp=
?g?)         g333333?g{Gz?+   g?)i  r   )CREDITSMONTHLY_SINCEcredit_activecredits_without_end)"   Аренда и помещение   ЗП педагогов   ЗП бэк-офиса3   Проценты по кредитам/займам   Налоги   Прочие расходы   Индивидуальный   Пробный   Вписанный   ФИТМОСТ)      r      )r   r   r   r   c                 .    [         R                  U S5      $ Nr   )SEASONget)mos    /home/rasp/finsync/cashflow.pyseasonr!   V   s    ::b#    c                     U u  p[          VVVVVVV	s/ s H  u  p4pVpxn	[        XX5      (       d  M  XF4PM      sn	nnnnnn$ s  sn	nnnnnnf )u   [(описание, сумма)] кредитных платежей, действующих в месяце (год, месяц). Чистая функция.)_PS_CREDITSr   )
ymyr   _sdesc_camt_daysinceuntils
             r    credit_rowsr.   Z   sM    EAEP 3 3[ABbtEQE1 TK[ 3 3 3 3s
   AAc                 8    [        S [        U 5       5       5      $ )uZ   Сумма всех кредитных платежей месяца (год, месяц).c              3   *   #    U  H	  u  pUv   M     g 7fN .0_das      r    	<genexpr>credit_sched.<locals>.<genexpr>c   s     .oURqo   )sumr.   )r%   s    r    credit_schedr;   a   s    .k"o...r"   c                 ~    [          VVVVVVs/ s H  u  p#pEpgX:  d  M  X!;  d  M  X54PM     snnnnnn$ s  snnnnnnf )u  [(описание, сумма)] ежемесячных платежей «с даты» из plan_sync.MONTHLY_SINCE.

НДС по умолчанию пропускаем: в plan_sync он лежит плоской оценкой 215к (нужен, чтобы
создать плановую операцию в Финтабло), а касса считает его от выручки — см. nds_for_month.
Складывать оба — двойной счёт.
)_PS_MONTHLY)r%   skipslugr(   r)   r*   r+   r,   s           r    monthly_since_rowsr@   f   sI     AL 1 1<D{ #/ TK 1 1 1s   555c                 8    [        S [        X5       5       5      $ )Nc              3   *   #    U  H	  u  pUv   M     g 7fr1   r2   r3   s      r    r7   &monthly_since_total.<locals>.<genexpr>r   s     ;:URq:r9   )r:   r@   )r%   r>   s     r    monthly_since_totalrD   q   s    ;0:;;;r"   c                 "    U u  pXS-
  S-  S-   4$ )Nr   r   r2   r%   r&   r   s      r    
quarter_ofrG   v   s    EAQ1}q !!r"   c                 N    U u  pS Vs/ s H  o1US-
  S-  U-   4PM     sn$ s  snf )N)r      r   r   r   r2   )qr&   nis       r    quarter_monthsrM   {   s0    DA*34)QQ!a )444s   "c                 0    U u  pUS:X  a  US-
  S4$ XS-
  4$ )Nr   r   r2   )rJ   r&   rK   s      r    prev_quarterrO      s(    DAaAE1:/aQZ/r"   c                 T  ^^^^ U u  pVUU4S jmUU4S jnUS:X  a	  U" US5      $ US:X  a  [        SU" US5      U" US5      -
  5      $ US:X  a  [        SU" US	5      U" US5      -
  5      $ US:X  a7  US
-
  nT" US5      u  p[        S[        TX-
  -  XI-  5      U" US	5      -
  5      $ g)u  Платёж по УСН Д−Р в месяце (год, месяц). Чистая функция.

Механика: авансы считаются от базы НАРАСТАЮЩИМ ИТОГОМ и платятся до 28-го числа
месяца, следующего за кварталом (апрель / июль / октябрь), каждый за вычетом ранее
исчисленных. Годовой платёж — до 28 марта следующего года, и вот в нём уже работает
минимальный налог: если 15% с прибыли меньше 1% с доходов, платим 1% с доходов.

Отсюда важное для кассы: пока прибыль нарастающим итогом в минусе, авансов НЕТ вообще,
а весь налог падает одним платежом в марте. Строка 40 модели вместо этого размазывала
6% с оборота по осенним месяцам.
c                    > [        SUS-   5       Vs/ s H  o U4PM     nn[        U4S jU 5       5      [        U4S jU 5       5      4$ s  snf )Nr   c              3   4   >#    U  H  nT" U5      v   M     g 7fr1   r2   )r4   m	income_ofs     r    r7   +usn_payment.<locals>.cum.<locals>.<genexpr>   s     0A9Q<<   c              3   4   >#    U  H  nT" U5      v   M     g 7fr1   r2   )r4   rS   
expense_ofs     r    r7   rU      s     5TVjmmVrV   )ranger:   )yyuptorS   monthsrX   rT   s       r    cumusn_payment.<locals>.cum   sL    #(D1H#56#5aq'#56000#5TV5T2TTT 7s   Ac                 :   > T" X5      u  p#[        STX#-
  -  5      $ )N        max)rZ   r[   incexpr]   rates       r    advusn_payment.<locals>.adv   s"    r=3	*++r"   r   r   r   r`      
   	   r   r   ra   )r%   rT   rX   re   min_rater&   r   rf   pyrc   rd   r]   s    ```       @r    usn_paymentrm      s     EAU, 
Qw1ay	Qw3Aq	C1I-..	Rx3Aq	C1I-..	QwUr2;3DCI.?#b!*LMMr"   c                    ^ [        [        [        U 5      5      5       Vs/ s H  oUU:  d  M
  UPM     nnU(       d  gX$-  [        U4S jU 5       5      -  S-  $ s  snf )u  Платёж по НДС в месяце (год, месяц). Чистая функция (выручку отдаёт rev_of_month).

НДС за квартал платится ТРЕМЯ равными долями до 28-го числа каждого месяца следующего
квартала. Начисление — с accrue_from (июль 2026, Q3) → первые платежи в октябре.
Раньше в кассе стояла плоская константа 215к/мес: она была посчитана от 13М выручки
квартала, а по прогнозу квартал уже 15,8–17М — недобор ~50–70к в месяц.
r`   c              3   4   >#    U  H  nT" U5      v   M     g 7fr1   r2   )r4   rS   rev_of_months     r    r7    nds_for_month.<locals>.<genexpr>   s     "?Bq<??BrV   r   )rM   rO   rG   r:   )r%   rp   re   accrue_from
base_sharerS   mss    `     r    nds_for_monthru      sX     $LB$@A	VA+EU!AB	Vs"?B"???!CC 
Ws
   	AAr   rI   r   r   r   rh   r   r   rj   ri      r   )u   янвu   февu   марu   апрu   майu   июнu   июлu   авгu   сенu   октu   нояu   декc           	         U (       a  U S   O/ n[        U 5      S:  a  U S   O/ n0 n[        S[        [        U5      [        U5      5      5       H  nU[        U5      :  a  [        R                  " X   5      OSnU[        U5      :  a  [        R                  " X$   5      SS OSnUR                  5       (       d  Mo  U[        ;   d  M{  XCS[        U5      -   [        U   4'   M     U$ )u~  {(год, месяц): индекс колонки} из шапки финмодели. Чистая функция.

Строка 0 — год («26»/«27»), строка 1 — месяц («янв»). Раньше колонка считалась как
mm+1: для 2026-го совпадало, а для 2027-го молча бралcя чужой месяц 2026 года.
r   r   rI    Nr   i  )lenrY   rb   corenormisdigit	MONTHS_RUint)planyearsnamesidxcr&   nms          r    month_columnsr      s     DGE4y1}DG"E
C1c#e*c%j12#$s5z>DIIehr()CJTYYux !$B99;;2?23A	"./	 3
 Jr"   c                 0    U u  pUS:X  a  US-   S4$ XS-   4$ )Nr   r   r2   rF   s      r    
next_monthr      s(    EArAE1:26{2r"   Fc                     / / U penXb::  a*  Xa;   a  UOUR                  U5        [        U5      nXb::  a  M*  U(       a  XE4$ U$ )u  [(год, месяц)] от start до horizon включительно — сквозь границу года.

Месяцы, которых нет в финмодели, считать не из чего: их выкидываем (и, если попросили,
возвращаем списком, чтобы предупредить — иначе расходы молча стали бы нулём).
)appendr   )startcolidxhorizonreport_missinggotmissingr%   s          r    forecast_monthsr      sI     2u"C
-'11"5^ - ,C>44r"   c                     U (       a  U $ U$ )uR  Прогноз месяца: планки Финтабло, если они есть, иначе финмодель.

Чистая функция — оба аргумента {slug: сумма}. Пустые планки (дальние месяцы)
это норма, а не сбой: до них Наташа ещё не дошла.
r2   )plan_ftmodels     r    pick_revenuer      s     7(5(r"   c                 P    [        SX-
  5      nU S:  a  [        SX -  5      OSnX#4$ )u  (остаток к сбору, коэффициент гашения строк) для текущего (незакрытого) месяца.

Остаток = план минус уже собранное — но НЕ МЕНЬШЕ НУЛЯ: если план на месяц занесён
частично (одна-две строки канона), а факт уже перекрыл эту урезанную сумму, «плана
собрать ещё» не бывает отрицательным — это не кассовый разрыв, а неполная планка
(см. partial_plan_months). Без этого зажима «ВЫРУЧКА» текущего месяца рисовала
многомиллионный провал, хотя строки разбивки под ней (гашённые тем же коэффициентом)
показывали ноль — сумма строк расходилась с шапкой (ревью Task 4, Critical).

Тот же паттерн уже используется в rev_full: max(planned, fact) для полной выручки
месяца; здесь — эквивалент для ОСТАТКА: max(planned - fact, 0) = max(planned, fact) - fact.
r`   r   r   ra   )
plan_total	collectedrem_rev	rem_ratios       r    current_month_revenuer      s3     #z-.G2<q.C-.cIr"   c                     [         R                   Vs/ s H-  o"R                  U R                  UR                  S5      U-  4PM/     sn$ s  snf )uc  [(имя строки канона, сумма)] из {slug: сумма} (результат pick_revenue).

Чистая функция — не знает про push()/сеть/финмодель, поэтому тестируется без
моков. rem_ratio=1.0 (дефолт) ничего не гасит — так считаются месяцы прогноза.
Для текущего (незакрытого) месяца push() передаёт REM_REV, чтобы сумма строк
совпала с уже показанным остатком «ВЫРУЧКА» (см. rev_val/REM_REV).
r`   )ilLINESnamer   r?   )srcr   ls      r    revenue_breakdownr      s=     ACI1VVSWWQVVS)I56IIIs   4A
c                 \   ^ ^ UR                  U5      mTc  g[        UU 4S jU 5       5      $ )uq   Сумма строк rlist финмодели за месяц (год, месяц). Чистая функция.r`   c              3      >#    U  H:  o[        T5      :  d  M  T[        TU   5      :  d  M'  [        TU   T   5      v   M<     g 7fr1   )ry   _num)r4   rr   r   s     r    r7   pv.<locals>.<genexpr>
  s?     UAc$i-ADQRGDTtDGAJs   AAA)r   r:   )r   r   rlistr%   r   s   `   @r    pvr     s)    

2AyUUUUr"   c                     [        X5      $ )u-  ЗП педагогов: максимум из строки финмодели и проекции по расписанию CRM.

Решение Наташи 29.07.2026. Модель систематически занижала (сен: 919к против 1.79М по
живому расписанию, доля от выручки 17% против фактических 32%), а расписание занижает
месяцы, которые ещё не продлили. CRM недоступна → crm_val = 0 → падаем на модель.
ra   )	model_valcrm_vals     r    teachers_valr     s     y""r"   c                 l  ^ [         R                  " U 5      mUS:X  a  [        U4S jS 5       5      (       a  ggST;   d  ST;   d  TS:X  d  S	T;   a  g
ST;   a  gST;   d  ST;   d  ST;   a  gTR                  S5      (       d  ST;   d  ST;   d  ST;   d  ST;   a  ST;  a  gST;   d  ST;   d  ST;   a  gg)Nincomec              3   ,   >#    U  H	  oT;   v   M     g 7fr1   r2   )r4   krK   s     r    r7   cash_line.<locals>.<genexpr>  s      _  ^!Av  ^   )   кредит   займu   ввод средствu   получениеu   депозитu(   перевод между счетами
__fin_in__   Притокu$   аренда и содержание   хозяйствен   ремонтu   мебельr   u   зарплаты педагогr   u   зарплаты бэкu   зарплаты админ   аутсорсr   %u   тело кредитаr   r   u   овердрафтu   комиссr   
   налогu   ндфлu   взносы в фондыr   r   )rS   _normany
startswith)cat_namegrouprK   s     @r    	cash_liner     s    	A
  _  ^ _ _ _-26LPQ6QUVZhUhlz~l3(A-( A%)F!)KO_cdOd'||C5:RS@SWaefWfj~  CD  kD  JX  `a  JaDqJ!O/Kq/P(r"   c                     [         R                  " U S9 Vs/ s H  oR                  S5      (       a  M  UPM     sn$ s  snf )Nr   isPlan)rz   ft_transactionsr   )r   ts     r    _scanr   0  s/    ++%8P8!hA8PPPs   ==c            	         [         R                  " 5       n [         R                  " 5       nU Vs0 s H  o"0 _M     nnS H  n[        U5       H  nUR	                  S5      nX#;  a  M  [        U R	                  UR	                  S5      S5      U5      nX2   R	                  US5      [        UR	                  S5      =(       d    S5      -   X2   U'   M     M     X4$ s  snf )N)r   outcome	factMonth
categoryIdrx   r`   valuer   )rz   ft_categoriesmonths_to_nowr   r   r   float)catsr\   r   factgrpr   lines          r    fact_by_monthr   4  s    D!F#$VrFVD$$sA{#B~TXXaeeL&92>DD!X\\$4uQUU7^=Pq7QQDHTN  % < %s   Cc                     [         R                  " S5      R                  S/ 5      n / Sp!U  H  nUR                  S5      (       d  UR                  S5      (       a  M1  SUR                  S5      =(       d    SR                  5       ;   a  M_  [	        UR                  S	5      =(       d    S
5      nX$-  nUR                  UR                  S5      U45        M     X!4$ )N/v1/moneybagitemsr`   archivedhideInTotal
   рабочr   rx   balancer   )rz   ftgetr   lowerr   r   )r   detailtotalxbs        r    balancesr   B  s    JJ~&**7B7EE55m 4 4AEE&M/R6688!%%	"'a(
quuV}a()  =r"   c                  ,   [         R                  " S5      R                  S/ 5       Hj  n U R                  S5      (       d,  SU R                  S5      =(       d    SR                  5       ;  a  MG  [	        U R                  S5      =(       d    S5      s  $    g	)
u1  Остаток транзитного счёта «Рабочие руки» — деньги, уже переведённые площадке
под выплаты самозанятым.

В «Свободно» они не входят (см. balances), но и требовать их повторно из свободного
остатка нельзя: планка ЗП педагогов висит непогашенной, пока Оля не разнесла выплату,
и отчёт просил те же деньги второй раз.
r   r   r   r   r   rx   r   r   r`   )rz   r   r   r   r   )r   s    r    platform_balancer   Q  sq     ZZ'++GR855QUU6]5Hb4O4O4Q QQUU9%*++ 9 r"   c                 v    / n[         R                   H"  nU[         R                  " SU S30 U 5      -  nM$     U$ )Nz/v2api/z/regular-lesson/index)rz   BRANCHESalfa_all)tokenregbrs      r    fetch_scheduler   a  s;    
Cmmt}}wrd*?@"eLL Jr"   c                    [         R                  " X5      S   n[        SS5       Vs0 s H  oDS_M     nn[        SUS-   5       H3  nU[        R                  " XU5      R                  5       ==   S-  ss'   M5     U SUS S3U SUS SUS 3pSn	U  H  n
[        R                  U
R                  S5      5      nU[        ;  a  M3  U
R                  S	5      =(       d    S
U:  d  U
R                  S5      =(       d    SU:  a  Mq  XR                  U
R                  S5      S5      [        R                  R                  US5      -  -  n	M     U	[        -  [        U5      -  $ s  snf )ub   Проекция ЗП 1-1 за месяц из расписания × доборы × сезон.r   r   r   -02dz-01r`   lesson_type_idb_daterx   e_date9999day)calendar
monthrangerY   datetimedate
isoweekdayLTr   
ONE_BUCKETrS   LESSON_TYPE_RATEDOBORr!   )r   r&   r   ndayswdoccdfirstlastbaseer   s               r    salary_1_1_projectionr  h  sB   &q)E A;
';Rq5;C
'1eai HMM!#..01Q61 !CqC$1RHAeC[&A4DVVAEE*+,ZEE(O!rT)aeeHo.G5-Pea(1+=+=+A+A"a+HHH  %<&*$$ (s   E"c                  `   S[          S3n [        R                  R                  U SS9R	                  5       R                  S5      n0 n[        R                  " [        R                  " U5      5       GH7  nUR                  S5      =(       d    SR                  5       R                  5       R                  S5      (       d  MP  UR                  S	5      =(       d    SR                  S
S5      R                  SS5      R                  SS5      R                  SS5      n[        R                   " SU5      nU(       a  [#        US   5      OSnUR                  S5      =(       d    SR                  5       n[%        U5      S:  a  USS  OS nU(       d  GM   UR                  US5      U-   X('   GM:     U$ )N'https://docs.google.com/spreadsheets/d/z/export?format=csv&gid=0   timeoututf-8u   Статусrx   u   не оплачu
   Суммаu   р.     ,.z-?\d+\.?\d*r   r`   u   Дата платежаri   r   )OLYA_IDurllibrequesturlopenreaddecodecsv
DictReaderioStringIOr   stripr   r   replacerefindallr   ry   )	urlrawby_monthr   smmvalr   keys	            r    	olya_planr%  {  sW   3G9<T
UC
..
 
 b
 
1
6
6
8
?
?
HCH^^BKK,-n%+224::<GGHYZZUU< &B//r:BB62NVVWZ\^_gghkmpqZZ* eBqElcUU,-3::<1v|ae3$LLc2S8HM . Or"   ,1orFwTHu_qKAagxd3eMU7LyaFsVNkt94gf03QFIZwO4A
2015808034c                      S[          S[         3n [        [        R                  " [
        R                  " [        R                  R                  U SS9R                  5       R                  S5      5      5      5      $ )Nr  z/export?format=csv&gid=r  r	  r  )FM_IDFM_GIDlistr  readerr  r  r  r  r  r  r  )r  s    r    	read_planr-    si    3E7:QRXQY
ZC

2;;sB/446==gFH I J Jr"   B2CB2Bu   Занятия 1-1u   ФОТ педагогов   r   u   B2B занятия   r   u   Хоровые курсы   u0   Групповые занятия вокалом   u   Онлайн-подписка   u   Помещениеu   Аренда здания   r   u   Хозяйственныеr  u   Ремонт)   u   ФОТ бэк-офисаu)   Бэк-офис (с фаундерами)   r   u   Администраторы    u   Аутсорс#   u.   Маркетинг и производствоu   Маркетинг!   u   Съёмки   u   B2B ивенты   u!   Внутренние ивенты   u   Операционкаu   Сервисы"   u5   Комиссии (эквайринг, банк, РР)'   u!   Возвраты клиентам%   u)   Прочее / неразнесённое$   u   Возврат займаr      2   -   &   (   )u
   выруч)r   )u   расход)u   прибыл)u   аренда)u   абонемент)u
   хоров)u   группов)u   онлайн)u   мероприят)u
   ивент)session)u   мерч         )u
   аренд)u
   занятu   педагог)b2b)u   съем)r   )u   бэк)u   администратор)u   маркетинг)u   сервис)r   )u   прочее)   возврат)u   комисси)r   )r   )rL  r   )rF  r6  r	   c                     U[        U 5      :  a  X   O/ n[        R                  " SR                  S USS  5       5      5      $ )ug   Подпись строки финмодели (лежит в A или B). Чистая функция.r  c              3   6   #    U  H  o(       d  M  Uv   M     g 7fr1   r2   r4   r   s     r    r7   row_label.<locals>.<genexpr>  s     6AAaas   
	NrI   )ry   rz   r{   join)r   r   rows      r    	row_labelrS    s9    T]$'C99SXX6Ra6677r"   c                    ^ / n[         R                  5        H\  u  p#[        X5      m[        U4S jU 5       5      (       a  M,  UR	                  SUS-    SSR                  U5       STSS  S	35        M^     U$ )
u   Подписи ключевых строк финмодели на месте? → [] или список расхождений. Чистая функция.c              3   ,   >#    U  H	  oT;   v   M     g 7fr1   r2   )r4   r   labels     r    r7   $check_plan_layout.<locals>.<genexpr>  s     ,t!:tr   u   строка r   u   : ожидали /u   , а там «NrF     »)	FM_EXPECTr   rS  r   r   rQ  )r   badr   keysrV  s       @r    check_plan_layoutr]    sx    
C??$$",t,,,JJq1ug->sxx~>Nn]bcfdf]g\hhjkl % Jr"   c                 !  ^
^^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_^`^a^b^c^d^e^f^g^h^i^j^k^l^m^n^o^p^q^r^s^t^u [        5       mh[        Th5      nU(       a  [        SSR                  U5      -   5      e[	        5       u  nmaU(       d  [        S[
         S35      e[        5       u  p4[        5       n[        Th5      m\U\Uh4S jme[        R                  " SS9mY0 0 smQmRUQUY4S jmTURU\Uh4S	 jmSUSUT4S
 jmXUX4S jmmUm4S jmnUS   mb[
        [        TbS S 5      4m`Tn" T`5      n[        UTaTb   R                  SS5      5      u  mimP[        T`T\SS9u  m]nT](       d  [        ST`S   S ST`S    S35      eT]nT] V	V
s/ s H%  u  pU
S S[        U	5      SS   3X4T`:X  a  SOS-   PM'     sn
n	mdUSUTU]4S jnSn [!        [        R"                  " 5       5      nT] Vs0 s H  o[%        XS   US   5      _M     snm_U`UiUn4S jmlUPU`4S jmVUVUX4S  jmWUW4S! jmkUk4S" jnUTUVUeUn4S# jnU`UaUbUn4S$ jmjU_Ue4S% jm[Ue4S& jmrU[U`UaUr4S' jmqUjUq4S( jmtUj4S) jmf0 n[,         H'  u  nnnUR                  US5      T[" UUT`5      -   UU'   M)     UR                  S*S5      Tr" T`5      -   US*'   UR                  S+S5      Tf" T`5      -   Tt" T`5      -   US+'   [/        T`5      US,'   UR1                  5        VVs0 s H4  u  nnUUS:  a%  [3        SSTaTb   R                  US5      U-  -
  5      OS-_M6     snnmOUOU`4S. jmUUUU[4S/ jmcUUUr4S0 jmsUU4S1 jm^UUUf4S2 jmgUUUt4S3 jmuUc4S4 jmoU^UgUoUsUu4S5 jnUS S n[5        Ue4S6 jU 5       5      nU(       a  U(       a  [5        Ua4S7 jU 5       5      U-  OS-mZUTUZUl4S8 jnS9TdS    S:3/S/[7        T]5      -  -   /nS;R                  S< U 5       5      nUR9                  S=[;        U5      S> 3R=                  S>S?5      /S/[7        T]5      -  -   5        UR9                  S@U-   SA-   /S/[7        T]5      -  -   5        U V
^
s/ s H<  m
[;        TaT
   R                  SS5      [5        UaU
4SB j[>         5       5      -
  5      PM>     nn
UR9                  SCS;R                  SD [A        UU5       5       5      -   /S/[7        T]5      -  -   5        UR9                  TdS    SE3/S/[7        T]5      -  -   5        UR9                  SFU(       a  SGU 3OS-   /S/[7        T]5      -  -   5        U(       a;  UR9                  SHSIR                  SJ U 5       5      -   /S/[7        T]5      -  -   5        U" 5       nU(       a;  UR9                  SKSLR                  SM U 5       5      -   /S/[7        T]5      -  -   5        UR9                  S/[7        T]5      S-   -  5        UR9                  SN/Td-   5        [7        U5      nUR9                  SO/T] Vs/ s H  n[;        Tl" U5      5      PM     sn-   5        [7        U5      n / n![B         H  u  n"n#UR9                  U"/T] Vs/ s H  n[;        U" U#U5      5      PM     sn-   5        U!R9                  [7        U5      5        U# HY  n$T] Vs/ s H  n[;        Tk" U$U5      5      PM     n%n[E        U%5      (       d  M7  UR9                  SPU$RF                   3/U%-   5        M[     M     T] Vs/ s H  n[;        U" U5      5      PM     n&n[E        U&5      (       a/  UR9                  SQ/U&-   5        U!R9                  [7        U5      5        UR9                  S/[7        T]5      S-   -  5        S+SRTu4SSTg4/0n'[H         GH6  u  n"n#U'R                  U"/ 5      n(T] V^s/ s H,  m[;        To" U#T5      [5        U4ST jU( 5       5      -   5      * PM.     n)nUR9                  U"/U)-   5        U!R9                  [7        U5      5        U# HV  u  nnnT] Vs/ s H  n[;        Tc" UUUU5      5      * PM     n%n[E        U%5      (       d  M>  UR9                  SPU 3/U%-   5        MX     U( HR  u  nn*T] Vs/ s H  n[;        U*" U5      5      * PM     n%n[E        U%5      (       d  M:  UR9                  SPU 3/U%-   5        MT     GM9     UU4SU jn+UR9                  SV/T] Vs/ s H  n[;        T^" U[.        5      5      * PM     sn-   5        U!R9                  [7        U5      5        [J         V,V-V.V/V0V1V2s/ s H  u  n,n-n.n/n0n1n2U-PM     sn2n1n0n/n.n-n, HP  n3T] Vs/ s H  n[;        U+" U3U5      5      * PM     n%n[E        U%5      (       d  M8  UR9                  SPU3 3/U%-   5        MR     [L        (       a]  UR9                  SW/T] Vs/ s H"  n[;        [L        R                  US5      5      PM$     sn-   5        U!R9                  [7        U5      5        T] Vs/ s H  n[;        Ts" U5      5      * PM     n4n[E        U45      (       a/  UR9                  SX/U4-   5        U!R9                  [7        U5      5        UR9                  SY/T] Vs/ s H  n[;        U" U[.        5      5      * PM     sn-   5        [7        U5      n5T] Vs/ s H"  n[;        Tl" U5      U" U[.        5      -
  5      PM$     n6nUR9                  SZ/U6-   5        [7        U5      n7/ Un9n8U6 H"  n:U9U:-  n9U8R9                  [;        U95      5        M$     UR9                  S[/U8-   5        [7        U5      n;T] Vs/ s H"  n[;        U" U5      U" U[.        5      -
  5      PM$     n<nUR9                  S\[;        TZS]-  5       S^3/U<-   5        [7        U5      n=/ Un9n>U< H"  n:U9U:-  n9U>R9                  [;        U95      5        M$     UR9                  S_/U>-   5        [7        U5      n?[O        Ud4S` j[Q        U85       5       S 5      n@U (       a  [S        Sa5        U H$  nA[S        SbR                  Sc UA 5       5      5        M&     [S        Sd[;        U5       Se[;        TZS]-  5       SfW@=(       d    Sg 35        U(       a  [S        ShSLR                  U5      -   5        g [T        RV                  " [X        Si9nBUBR[                  [\        5      nC UCR_                  Sj5      nDWDRd                  mpWCRg                  5       nE[O        Up4Sm jUESn    5       S5      nFSoSpTp0Sq0 0SqSr.0/nGUG[i        UF5       VHs/ s H
  nHSsTpSSt.0PM     snH-  nGWCRk                  SuUG05        WDRm                  5         UDRo                  USv5        [7        U5      nI[q        [s        Sw5      [7        U5      -   S-   5      nJSSSSx.nKUDRu                  SyUJ UI 3SzS{S|00S}.S~U SUJ UI 3SSSS.0S}.SvSzSSS.0S}.SSzSS00S}.SwU SUJ U 3SSSSx.SUKS.SS.S}.SwU 3SS0S}.SwU  SUJ U  3SzSS00S}./U! VAs/ s H  nASwUA SWJ UA 3SS0SSSSx.S.S}.PM     snAQSwU5 SWJ U5 3SzSS00S}.PSwU7 SUJ U7 3SzSS00S}.PSwU; SUJ U; 3SSSSx.SS0S.S}.PSwU= SUJ U= 3SzSSS.0S}.PSwU? SUJ U? 3SSSSx.SS0S.S}.P5        WDRw                  USSl9  SzSSSSSx.00nLWCRk                  SuSTpSSSS.SS0SS.0SU;U?4 VAs/ s H  nATpUAS-
  UAS[7        U5      S-   S.PM     snASSS0/S.WLS.S.SS.0/05        [O        Ud4S j[Q        U85       5       S 5      nM[O        Ud4S j[Q        U>5       5       S 5      nN[S        SWCRx                  S5        U(       a  [S        SSLR                  U5      -   5        [S        Sd[;        U5       S[;        TZS]-  5       S35        [S        S[{        [A        TdU85      5      SWM=(       d    Sg5        [S        S[{        [A        TdU>5      5      SWN=(       d    Sg5        g s  sn
n	f s  snf ! [&         a=  nT] Vs0 s H  oS_M     Os  snf snm_S[)        U5      R*                   S3n S nAGNjS nAff = fs  snnf s  sn
f s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  sn2n1n0n/n.n-n,f s  snf s  snf s  snf s  snf s  snf s  snf ! [T        R`                   a!    WCRc                  SjSk[7        U5      S-   Sl9nD GNf = fs  snHf s  snAf s  snAf )Nut   разметка финмодели поехала — план считался бы из чужих строк:
  z
  uC   нет месяцев для расчёта: сегодня вне u    года (см. FINSYNC_YEAR)c                    > [        TTX5      $ r1   )r   )r   r%   r   r   s     r    mvpush.<locals>.mv  s    $**r"   r   r   c                 h   > SU S   U S   4-  nUT;  a  [         R                  " UT5      TU'   TU   $ )u   {slug: сумма} планок Финтабло на месяц (как есть, включая slug вне канона —
нужно для rev_unassigned, чтобы ловить «осиротевшие» планки).z%02d.%dr   r   )r   plan_from_fintablo)r%   r"  	_ft_cache
all_incomes     r    _plan_ftpush.<locals>._plan_ft  sC     "Q%A'Y11"jAIbM}r"   c                 P   > U T;  a  [         R                  " TTU 5      TU '   TU    $ r1   )r   plan_from_model)r%   _model_cacher   r   s    r    
_model_revpush.<locals>._model_rev  s/    \!!11$CLBr"   c                 4   > [        T" U 5      T" U 5      5      $ )u  {slug: сумма} канона за месяц — как есть, без сглаживания текущего месяца
(см. REM_REV ниже — гашение уже собранного делает вызывающий код при печати).)r   )r%   rk  rf  s    r    _revenue_srcpush.<locals>._revenue_src  s     HRL*R.99r"   c                 &   > [        T" U 5      5      $ )u|   [(имя строки канона, сумма)] за месяц — из прогноза либо из финмодели.)r   )r%   rn  s    r    revenue_linespush.<locals>.revenue_lines$  s     b!122r"   c                 4   > [        S T" U 5       5       5      $ )Nc              3   *   #    U  H	  u  pUv   M     g 7fr1   r2   )r4   _nvs      r    r7   +push.<locals>.revenue_of.<locals>.<genexpr>)  s     4"31"3r9   r:   )r%   rq  s    r    
revenue_ofpush.<locals>.revenue_of(  s    4-"3444r"   rI   r   r`   T)r   u3   в финмодели нет колонки под r   r   r  r   u&    — считать не из чегоu    ост.rx   c                  J  > / n T H  nT" U5      nU(       d  M  T" U5      n[         R                   Vs/ s HB  oDR                  U;  d  M  UR                  UR                  S5      S:  d  M6  UR                  PMD     nnU(       d  M  U R                  X45        M     U $ s  snf )u9  Месяцы, где план Финтабло ЕСТЬ, но покрывает не все строки канона, ожидаемые
ненулевыми по финмодели. pick_revenue() — «всё или ничего»: если Наташа занесёт
одной командой plan_income.py только одну строку (например arenda=800000), касса
покажет выручку месяца равной этой одной строке, а уроки/хор/B2B молча обнулятся —
ложный кассовый разрыв (ревью Task 4, находка 3). Семантику pick_revenue не меняем
(«планки, если есть, иначе финмодель» — решение владелицы), только предупреждаем.r`   r   )r   r   r?   r   r   r   )	warnr%   r   model_dr   gonerk  rf  colss	         r    partial_plan_months!push.<locals>.partial_plan_months=  s     BrlG nG$&HHgHqg0EF'++VWV\V\^aJbefJfFAFFHDgtRJ'   hs   B B -B u6   ⚠️ расписание CRM недоступно (uB   ) — ЗП педагогов только по финмоделиc                 L   > U T:X  a  T$ [         R                  U T" U 5      5      $ r1   )REVENUE_OVERRIDEr   )r%   curr   ry  s    r    rev_valpush.<locals>.rev_val^  s&    )wQ)9)=)=b*R.)QQr"   c                    > U T:X  a  T$ S$ r   r2   )r%   REM_REVr  s    r    
_rem_ratiopush.<locals>._rem_ratiod  s    )w,,r"   c           	         > [        [        R                  [        T" U 5      T" U 5      5      5       VVVs0 s H  u  nu  p#UR                  U_M     snnn$ s  snnnf )u   {slug: значение для печати} за месяц — revenue_breakdown, проиндексированный
по slug, с гашением текущего месяца.)zipr   r   r   r?   )r%   r   ru  rv  r  rn  s       r    _rev_bdpush.<locals>._rev_bdg  sM     -0:KLY[L\^hik^l:m,no,nja"	,nooos   Ac                 .   > T" U5      U R                      $ r1   )r?   )r   r%   r  s     r    rev_line_valpush.<locals>.rev_line_vall  s    r{166""r"   c                 2   >^ [        UU4S jU  5       5      $ )Nc              3   6   >#    U  H  nT" UT5      v   M     g 7fr1   r2   )r4   r   r  r%   s     r    r7   0push.<locals>.rev_section_val.<locals>.<genexpr>p  s     61<2&&s   rx  )linesr%   r  s    `r    rev_section_valpush.<locals>.rev_section_valo  s    6666r"   c                    > T" U 5      nU(       a  [        UR                  5       5      OT" [        /U 5      nUT" U 5      -
  nUT" U 5      -  $ )u  Сверка «ВЫРУЧКА» с НЕЗАВИСИМЫМ источником, а не с суммой тех же самых строк
канона: если сверять revenue_of() с суммой revenue_lines(), результат тождественно
0 по построению (обе части — одно и то же вычисление) и не ловит регрессии
(ревью Task 4, находка 2). Поэтому:
  - месяц с планками Финтабло — сверяем с суммой ВСЕХ планок месяца (не только
    совпавших со slug'ом канона): если slug переименовали или планку завели
    вручную с опечаткой, тут появится расхождение, которое revenue_of() иначе
    бы тихо проглотил;
  - месяц-фолбэк на модель (планок нет) — сверяем со стр.18 «Итого выручка»:
    если в финмодель добавят новую доходную строку мимо канона, она попадёт
    в стр.18, но не в revenue_of(), и здесь это будет видно.
Текущий месяц гасим тем же REM_REV, что и остальные строки, иначе появится
мнимое расхождение размером с уже собранное за месяц.)r:   valuesROW_REVENUE)r%   r   independent_rawraw_diffrf  r  r`  ry  s       r    rev_unassignedpush.<locals>.rev_unassignedr  sJ     2,3:#gnn./K=RT@U"Z^3*R.((r"   c                    > U S   S SU S    3n[         R                  U T" U 5      5      nU T:  a"  TR                  U0 5      R                  SS5      $ U T:X  a  [        UTT   R                  SS5      5      $ U$ )u  Полная выручка месяца (база НДС), а НЕ «остаток» текущего месяца: закрытые
месяцы — по факту притока, текущий и будущие — по плану (прогноз либо финмодель).r   r   r  r   r   r`   )r  r   rb   )r%   mkplannedr  r   jmry  s      r    rev_fullpush.<locals>.rev_full  s     1c{!BqE7#"&&r:b>:888B#''<<9wR^S ABBr"   c                 l   > U [         :X  a"  [        T" X5      TR                  US5      5      $ T" X5      $ )uo   Полное значение строки по модели (до вычета уже оплаченного).r`   )LINE_TEACHERS_1_1r   r   )r   rrr%   crm_salr`  s      r    base_valpush.<locals>.base_val  s5    AEIZAZ|BrJB(<= 	B	r"   c                    >^  T" [         /T 5      T" [        /T 5      -
  T" [        /T 5      -
  [        UU 4S j[         5       5      -
  $ )u  Что осталось от «Итого расходы» после кредитов, налога модели и показанных строк.
Должно быть ~0 — это сверка, что разбивка ничего не потеряла.c              3   <   >#    U  H  u  pnT" UT5      v   M     g 7fr1   r2   )r4   _nmr  _bkr`  r%   s       r    r7   +push.<locals>.unassigned.<locals>.<genexpr>  s     ?Y\ScbRjjYs   )ROW_TOTAL_OUTROW_CREDITSROW_MODEL_TAXr:   	ALL_LINES)r%   r`  s   `r    
unassignedpush.<locals>.unassigned  sH     M?B'"k]B*??"m_VXBYY?Y??@ 	Ar"   c                    >^ ^ T T:  a7  TR                  T S   S ST S    30 5      m[        U4S j[         5       5      $ [        UU 4S j[         5       5      T" T 5      -   $ )u  Расходы месяца, принимаемые в базу УСН: показанные строки минус невычитаемые
(возврат тела займа). Кредиты сюда не входят — см. USN_NONDEDUCTIBLE выше.r   r   r  r   c              3   X   >#    U  H  nUS ;  d  M  TR                  US5      v   M!     g7f))r   r   r`   Nr   )r4   r   fs     r    r7   ,push.<locals>.tax_expense.<locals>.<genexpr>  s.      li#jj %quuQ}}is   
**c              3   n   >#    U  H*  u  pn[        U5      [        -  (       a  M  T" XT5      v   M,     g 7fr1   )setUSN_NONDEDUCTIBLE)r4   r   r  r  r  r%   s       r    r7   r    s3      79KBCb'$55 (8BB''9s   55)r   r:   	OUT_LINESr  )r%   r  r  r  r   r  s   `@r    tax_expensepush.<locals>.tax_expense  su     8BqE#;a1w/4A li l l l 79 7 79CBH 	Hr"   c                    > [        U TT5      $ r1   )rm   )r%   r  r  s    r    usn_rawpush.<locals>.usn_raw  s    2x55r"   c                 4   > [        U T5      [        U 5      -   $ r1   )ru   rD   )r%   r  s    r    nds_rawpush.<locals>.nds_raw  s    R*-@-DDDr"   r   r   r   r   c                 >   > UT:X  a  U TR                  US5      -  $ U $ r   r  )fullbucketr%   REMr  s      r    _rempush.<locals>._rem  s$    .0Citcggfc**ATAr"   c                 $   > T" T" XU5      X#5      $ r1   r2   )r   r  r  r%   r  r  s       r    line_valpush.<locals>.line_val  s    HTr*F77r"   c                 $   > T" T" U 5      SU 5      $ )Nr   r2   )r%   r  r  s    r    unassigned_valpush.<locals>.unassigned_val  s    JrN$A2FFr"   c                 $   > T" U" U 5      SU 5      $ )Nr   r2   )r%   cfr  s     r    
credit_valpush.<locals>.credit_val  s    BrFQSUVVr"   c                 $   > T" T" U 5      SU 5      $ Nr   r2   )r%   r  r  s    r    nds_valpush.<locals>.nds_val      GBK44r"   c                 $   > T" T" U 5      SU 5      $ r  r2   )r%   r  r  s    r    usn_valpush.<locals>.usn_val  r  r"   c                 2   >^ [        UU4S jU  5       5      $ )Nc              3   >   >#    U  H  u  pnT" XUT5      v   M     g 7fr1   r2   )r4   r   r  bkr  r%   s       r    r7   ,push.<locals>.section_val.<locals>.<genexpr>  s!     De
8BB++es   rx  )r  r%   r  s    `r    section_valpush.<locals>.section_val  s    DeDDDr"   c                    >^  [        UU 4S j[         5       5      T" T 5      -   T" T U5      -   T" T 5      -   T" T 5      -   [        R                  T S5      -
  $ )Nc              3   :   >#    U  H  u  pT" UT5      v   M     g 7fr1   r2   )r4   _secr  r  r%   s      r    r7   *push.<locals>.exp_total.<locals>.<genexpr>  s     Gh{tKr**hs   r   )r:   SECTIONSONE_OFFSr   )r%   r  r  r  r  r  r  s   ` r    	exp_totalpush.<locals>.exp_total  s`    GhGG.Y[J\\R$%'.r{35<R[ACK<<PRTUCVW 	Xr"   c           
   3   d   >#    U  H%  nT" [         /[        [        US S 5      45      v   M'     g 7f)NrI   )r  YEARr~   )r4   r   r`  s     r    r7   push.<locals>.<genexpr>  s,     P2K=4RV*=>>s   -0c              3   N   >#    U  H  nTU   R                  S S5      v   M     g7f)r   r   Nr  )r4   r   r   s     r    r7   r    s#     CFb$r(,,~q11F   "%c                 D   > T" U 5      (       a  T" U 5      $ T" U 5      T-  $ )u  rev_val с дисконтом attain (историческая собираемость план→факт по финмодели) —
но ТОЛЬКО для месяцев, посчитанных от финмодели. Если месяц уже прогнозируется по
планкам Финтабло — это собственная оценка Наташи, а не строка модели, и второй раз
дисконтировать её тем же attain нельзя: занижает прогноз дважды (ревью Task 4,
находка 4). Планки бывают и на текущий месяц (см. комментарий у rem_rev выше),
поэтому проверяем cur наравне с будущими.r2   )r%   rf  attainr  s    r    rev_val_realisticpush.<locals>.rev_val_realistic  s%     'rllwr{Df0DDr"   uL   КАССА — реальный остаток + план вперёд по u$    (кредиты и НДС явно)z;  c              3   h   #    U  H(  u  pU S [        U5      S 3R                  SS5      v   M*     g7f)z: r  r  N)roundr  )r4   rK   r   s      r    r7   r    s3     WJDAA3bq!-55c3??Js   02u$   Остаток на сегодня: r  r  z  ()c              3   N   >#    U  H  nTT   R                  US 5      v   M     g7fr   Nr  )r4   r   r   r   s     r    r7   r    s%     5\R[Qd2hll1a6H6HR[r  u4   Факт прибыли прошедших мес.: c              3   B   #    U  H  u  pUS S  SUS-   S3v   M     g 7f)NrI   =i  u   кr2   )r4   r   rv  s      r    r7   r    s)     Qr"1vha4y3s   uX    «ост.» = план месяца минус уже оплачено/полученоuK   ЗП педагогов = max(финмодель, расписание CRM)u    — uP   ⚠️ нет в финмодели (и потому не в прогнозе): , c              3   N   #    U  H  u  pUS  S[        U5      SS  3v   M     g7f)r   r  rI   Nstr)r4   r&   r   s      r    r7   r    s)      OweaBs81SVABZL!9ws   #%u   ⚠️ план Финтабло неполный (строки без планки обнулены, а не взяты из модели): z; c              3   x   #    U  H0  u  u  pnUS  S[        U5      SS  SSR                  U5       3v   M2     g7f)r   r  rI   Nu    — нет r  )r  rQ  )r4   r&   r   r   s       r    r7   r    sI      8PGN^Wae <>c(!CF12J<|\`\e\efk\l[m8nGNs   8:u   Прогноз, ₽u   ВЫРУЧКАz   uo   Не разнесено (сверка со стр.18 модели / суммой планок Финтабло)u0   УСН 15% Д−Р (аванс / годовой)u9   НДС 5% (1/3 выручки пред. квартала)c              3   8   >#    U  H  u  pU" T5      v   M     g 7fr1   r2   )r4   ru  r  r%   s      r    r7   r    s     4NurQrUUs   c                 \   > T" [        [        U5      5      R                  U S5      SU5      $ )Nr`   r   )dictr.   r   )r(   r%   r  s     r    credit_linepush.<locals>.credit_line  s,     DR)--dC8:oqsttr"   u   Кредиты и займыu   Разовые платежиuG   Не разнесено (сверка с «Итого расходы»)u   ИТОГО РАСХОДЫu)   ПРИБЫЛЬ ЗА МЕСЯЦ (план)u)   ОСТАТОК НА КОНЕЦ (план)u=   ПРИБЫЛЬ (реалистично: финмодель ×d   u=   %, планки Финтабло — без дисконта)u7   ОСТАТОК НА КОНЕЦ (реалистично)c              3   B   >#    U  H  u  pUS :  d  M  TU   v   M     g7fr  r2   r4   rL   rv  mls      r    r7   r  4  s     >ndaAEBqEn   u$   DRY-RUN (лист не трогаю)z | c              3   >   #    U  H  n[        U5      S S v   M     g 7f)Nr>  r   rO  s     r    r7   r  8  s     4!QSVCR[!s   u   остаток сегодня u#    | достижение плана u   % | разрыв(план): u   нетu:   ⚠️ кредиты без даты окончания: )filenameu
   КассаrF  )rowsr  c              3      >#    U  H7  nUS    S   T:X  d  M  [        UR                  S/ 5      =(       d    / 5      v   M9     g7f)
propertiessheetIdconditionalFormatsN)ry   r   )r4   r!  sids     r    r7   r  G  sB      5<aL/),3 :s155-r28b99<s
   A+Asheets
repeatCellr  userEnteredFormat)rY   cellfieldsdeleteConditionalFormatRule)r  indexrequestsA1A)redgreenbluezA1:
textFormatfontSizeri   )rY   formatB:numberFormatNUMBERz#,##0)typepatternrv   )boldr#  A2r+  gQ?gQ?g
ףp=
?)r+  foregroundColorCENTER)backgroundColorr"  horizontalAlignmentr0  LEFTg
ףp=
?g\(\?)r"  r/  gffffff?gQ?)r/  r"  )r+  italicgGz?gGz?g?r-  r   g)\(?updateDimensionPropertiesCOLUMNS)r  	dimension
startIndexendIndex	pixelSizei  )rY   r  r  addConditionalFormatRule)r  startRowIndexendRowIndexstartColumnIndexendColumnIndexNUMBER_LESSuserEnteredValue0)r)  r  )	conditionr$  )rangesbooleanRule)ruler  c              3   B   >#    U  H  u  pUS :  d  M  TU   v   M     g7fr  r2   r
  s      r    r7   r  t  s     :.$!AE1.r  c              3   B   >#    U  H  u  pUS :  d  M  TU   v   M     g7fr  r2   r
  s      r    r7   r  u  s!     A$7DA1q5%"Q%$7r  u   OK →u   | вкладка Кассаu   ⚠️ кредиты без даты окончания (платёж планируется бессрочно, уточни срок): u7    | достижение плана по выручке r   u   ПЛАН       остаток:u   | разрыв:u&   РЕАЛИСТИЧНО остаток:)>r-  r]  RuntimeErrorrQ  r   r  r   r   r   rz   r   r~   r   r   r   r  r   
alfa_loginr  	Exceptionr)  __name__r  r;   r   rb   r:   ry   r   r  r  r  r  REVENUE_SECTIONSr   r   r  r$   r  next	enumerateprintgspreadservice_accountSA_FILEopen_by_keySHEET_ID	worksheetWorksheetNotFoundadd_worksheetidfetch_sheet_metadatarY   batch_updateclearupdatechrordbatch_formatfreezer  r  )vdryr[  r\   	total_bal
bal_detailno_end_rev_plan_curr   futr&   r   r  crm_noter   r%   r  r  r  cur_planr   r  r  totr  closedplan_rev_pastr  r  bal_strpfpartialhdrrev_rowsec_rowssecr  r   valsrev_unaEXTRAextrar   r  r  r'   r   r)   _ar+   _si_ur(   una	itogo_rowprofitprof_rowendbalrv  end_rowprofit_realprof_real_rowend_realend_real_rowgap_prer   gcshwsmdncreset_nrowr  WREDgapgap_rr  r  rd  rj  rk  rf  r  r  r  rn  re  r  r  r   r  r  r  r  r   r  r  r  r`  r  r  r   r   r  r  r  rq  ry  r  r  r  r  r  r  r  sv             `   `                                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@r    pushr    s   ;D
D
!C
  S#[[-. / 	/ ?LFD`ae`f  gE  F  G  	G$JI "F4 F+ %%H5J
 !"I| 
:
35 
BRV
CsOM -]DHLLY\<]^GW#CEMD'PQTUVQWX[P\\]^abc^d]e  fL  M  N  	N
CY]	^Y]PUPQRHAc!fQRj\
"QGsNj
KY]	^B* HaT__./JNO$B,SQ%A??$OR-p
#7) )&	 	
AH H6E
 H
B||B,xB/DD  .6ll;XZ].^akloap.pH*+'||NC@73<ORYZ]R^^H^FRSVFWHBC"..*,*wr3 S1WCT"X\\"c2S889#M*,CB8GW55EX X CR[FPPPMM CFCCmS/2 E \\^_a\b[c  dH  I  J  NP  MQ  TW  X\  T]  M]  ]  ^DjjWJWWGKK7i8H7KLTTUXZ]^_cebfilmqirbrrsKK3&'2$T*::;hn	ohnbd%R^Q/#5\R[5\2\\
]hnB	oKKGQVRQQR SVXUY\_`d\eUef gKKBqE7rstxzw{  B  CG  H  xH  H  IKK^(0E($b: ;>@TCI=MN Ogyy Ow OOP QTVSWZ]^bZcScd 	e!#G ,.2ii 8PGN8P /PP QTVSWZ]^bZcScd 	e 	KKD	A&'KK&'",-SYsKK!"4%H4ReGBK&84%HHIUXY]U^7H&
USEN2U?5"#=>NNOD	"A9=>2E,q"-.D>4yys166(^,t34  ' 4884Ru^B'(4G8
7||  G  H  KR  R  	SD	"KKD	A&'QSZ[TV]^` aEh
U		#r"Z^_Z^TV%E2.4N4N1NNOOZ^_SEEM"HOOCI$>JBB?CDtU8BB344tDD4yys2$ZL4/0   EB,01DbU1R5\MDD14yys2$ZL4/0  u
 	KK/0cg3hcg]_U:b,;W5X4Xcg3hhiOOCI7BCC{3r1b"dC{CC8<="{4,--=4yys4&\NT)*	 D
 x45^b8c^bXZx||BPQ?R9S^b8ccdD	"04
5"E.$%%C
5
3xx^_beefD	"KK,-_c0d_cY[%	"l8S2T1T_c0ddesvw{s|gpIMN2eGBK)B"==>FNKK<=FGTWX\T]9Cq#**U3Z( KK<=CDPSTXPYgX\]X\RT5*2.2|1LLMX\K]KKPQVW]^aWaQbPc  da  b  c 03D		cHq(//%*- KKJKhVWhklphqYe>in>EG
45A%**4!445 .uY/?.@@cdijpqtjtducv w++2+>h*?A 	BNQUQZQZ[aQbbc		 	 '	2B		!BH\\,' %%C		 	 	"B	 52h< 567
9By#&6ATVX@Yexyz{E	UZ[]U^_U^PQ,#.JKU^__EOOZ'(HHJIIdDt9Ds3x#c("Q&'DAq)AOOvdV$
B?O0PQcU!D6$(^hcjEk4lm<$B1O"PQL64.#ABcU!D6#''+dDI#'A>W_4a 	b cU)(=v'FGgYavgY/L6SW.;YZ V^
_U]PQ s!D6!%!4.'+dDI2K LU]
_ i[$	{3vW[n?]^ hZqxj1lVUYN=[\  gYavgY/'+dDIZ`bfYg<i 	j!$ m_AdVM?;_cosVtGuv%& l^1TF<.9'+dDIZ`bfYgFi 	j' , II3QI+TDRV-WX
YCOOZ	$!$9A[\]&,'E 	F 
$Y`bnXoqXoST $'Qq,-SAOXoq2?M_adLeKf)gsvw/y 	& 			" 	 	 :)C.:D
ACAIh$7A4HE	(BFF9:  [		&!" 	#	*5+;*<<sty  {A  BE  {E  uF  tG  GH  I  J	
*DR,>@QSVSbZbc	
2DR9J4KM^`e`qiqrC
 
_4 P a%)*Trs7T*KDQRGL\L\K]  ^`  aaz,` 
p" &I O ? 9 ` E 2 4iCC=
 9d
5 1eN ^. $$ Hl#c(Q,GH `$
_$qs   %,> "A@	 A@A@	 ;AA2AAA2AA
 AA#AA(&AA-3AA2AA7AA<!AB
AB;AB$)AB
4AB"!AB 
)AB%6)AB*=AB/ AC' AC,
!AC1@A@	 @	
AA@AA@A@$@#"AAAAAB/1AC$C#AC$__main__z--dry)r`  ))nds)r   )F)b__doc__osr  r  r  r   r   urllib.requestr  rz   marginsrS   income_linesr   rO  HEREFIN_YEARr  pathrQ  rQ  rS  r  HORIZONr   r   r  r  USN_RATEUSN_MIN_RATEr  NDS_RATENDS_ACCRUE_FROMNDS_BASE_SHARE	plan_syncr
   r$   r   r=   r   r   r  r   r   r!   r.   r;   r@   rD   rG   rM   rO   rm   ru   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r%  r)  r*  numr   r-  r   categoryCAT_B2BrK  r   
model_rowsALL_REV_LINESr  r  r  r  
ROW_PROFITr  r  r  rZ  rS  r]  r  rJ  sysargv)r   r  r  lns   0000r    <module>r     s  * ; : : :    yy}}
'',,t.
/9
8
 d	$   D  ; ;s		',<AUZjkg
3/
1<
"
5
0
 19<  F *2+D  Aa1XYAbBZ\^	"3
 ,35 
5)$JV#)0Q %&$ 	7	 xxJ" =1JJ"**$<Q=>
=1JJ"**$<Q=>  24:A&&!,,':(  	rd,EF	bT3PQ	$2$8UV	;bTC`a	(RD:WX#  	$t-QR	%.RS	"'KL 
  	4rd<TU	'2$8PQ	B41IJ" 
 6	t-JK	RD*GH	RD*GH	,rd4QR	8  	6ST	@2$Hef	,"?\]	4RDB_`	$bT;XY   R? B $,<8KDeReR8<	
 

1[/ 
1;8I 
1=Zk 
1*
1!
1#$&=
1?@/
1STVi
1 !
1 $%&=
1 @A/
1 TVWc
1 	
1 !#$;	
1 >@	
1 SUVe	
1
 1
1
 46x
1
 BD_
1
 WYZi
1 $
1 ')*;
1 >@
1 SUVe
1 
1 !#$=
1 @B;
1 QSTs
1 (
1 +-.?
1 BDEX
1 []^o
1 $
1 ')*=
1 DSXi/
1	8DsN zW ! u >=
 ;H =s$   -LL&L	L	 !LL