From 2d270ef24f6b210877b89bbe287df01b4523bbfa Mon Sep 17 00:00:00 2001 From: msyu Date: Fri, 11 Jul 2025 10:21:05 +0300 Subject: [PATCH] 21 with asymmetric time and local version --- Application.cfc | 2 +- agreement_ls.cfm | 2 + contract.cfm | 4 +- etc/spec.txt | 3 + income_daily_rpt.cfm | 171 +++++++++++++++++++++++++++++++------- income_monthly_rpt.cfm | 108 ++++++++++++++++-------- specification.cfm | 7 +- specification_item.cfm | 2 +- specification_item_ls.cfm | 24 +++--- 9 files changed, 240 insertions(+), 83 deletions(-) diff --git a/Application.cfc b/Application.cfc index ce4cfa3..e85ed3f 100644 --- a/Application.cfc +++ b/Application.cfc @@ -69,7 +69,7 @@ - + diff --git a/agreement_ls.cfm b/agreement_ls.cfm index f6f1373..f17e7d4 100644 --- a/agreement_ls.cfm +++ b/agreement_ls.cfm @@ -120,7 +120,9 @@ select count(*) as cnt from agreement where 1=1 + + diff --git a/contract.cfm b/contract.cfm index 624700b..547bd1b 100644 --- a/contract.cfm +++ b/contract.cfm @@ -265,7 +265,9 @@ - + + +При создании договора сразу создавать спецификацию и базовое соглашение \ No newline at end of file diff --git a/etc/spec.txt b/etc/spec.txt index b35f840..c3484d9 100644 --- a/etc/spec.txt +++ b/etc/spec.txt @@ -1,3 +1,6 @@ +2025-07-10 15:08:02 +Оказывается, есть разница между "0 с 1 июля" и "ничего с 1 июля" - в текущей версии 0 с вероятностью 100 непрозрачен, а нулл с вероятностью 100 получается полностью прозрачен. Либо здесь несимметрия по времени должна быть + 2025-06-17 09:07:46 2025-06-16 10:58:02 select diff --git a/income_daily_rpt.cfm b/income_daily_rpt.cfm index 5e3c29e..4d5fb9d 100644 --- a/income_daily_rpt.cfm +++ b/income_daily_rpt.cfm @@ -10,6 +10,11 @@ + + + + + \ No newline at end of file diff --git a/income_monthly_rpt.cfm b/income_monthly_rpt.cfm index 865b650..e21ad8a 100644 --- a/income_monthly_rpt.cfm +++ b/income_monthly_rpt.cfm @@ -10,6 +10,17 @@ + + + + + + + + + + + @@ -70,39 +81,64 @@ from ( select DATE_TRUNC('month', dayscale.dt)::date as m ,0 - ,sum(siv.price*siv.quantity*a.probability_perc/100/dayscale.days + /*,sum(siv.price*siv.quantity*a.probability_perc/100/dayscale.days + COALESCE(siv0.price*siv0.quantity*(100-a.probability_perc)/100/dayscale.days, 0) - ) - from - (SELECT dd::date as dt, DATE_PART('days', - DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL - ) days FROM generate_series - ( '2023-01-01'::timestamp - , '2029-12-31'::timestamp - , '1 day'::interval) dd) dayscale - join specification_item_version siv on (dayscale.dt >= siv.dt_from AND (siv.dt_to >= dayscale.dt OR siv.dt_to IS NULL)) + )*/ + ,COALESCE(sum( + case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then + siv.price*siv.quantity*COALESCE( + case when a.is_actual then 100 else a.probability_perc end + ,0)/100/dayscale.days + /*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/ + else 0 /*по окончании свежей сделки она дает нулевой вклад*/ + end + ),0) + + COALESCE(sum( + case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then 0 else + siv0.price*siv0.quantity*(100-COALESCE( + case when a.is_actual then 100 else a.probability_perc end + ,0))/100/dayscale.days + /*по окончании свежей сделки*/ + end + ),0) + from (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) days + FROM generate_series( + '2023-01-01'::timestamp + ,'2029-12-31'::timestamp + ,'1 day'::interval) dd + ) dayscale + left outer join specification_item_version siv on (dayscale.dt >= siv.dt_from /*AND (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL)*/ + AND siv.agreement_version=(select max(iiv.agreement_version) from specification_item_version iiv + join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid) + join specification isp on (ii.specification_id=isp.specification_id) + join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version) + where iiv.specification_item_uid=siv.specification_item_uid + AND (dayscale.dt >= iiv.dt_from /*AND (iiv.dt_to > dayscale.dt OR iiv.dt_to IS NULL)*/))) + /*AND ia.is_actual*/ /*свежее соглашение не обязано быть действующим*/ join specification_item si on (siv.specification_item_uid=si.specification_item_uid AND si.pricing_model_id in (2,3)) - join specification s on (si.specification_id=s.specification_id ) - join agreement a on (s.contract_id=a.contract_id AND siv.agreement_version=a.agreement_version AND a.agreement_version=(select max(iiv.agreement_version) from specification_item_version iiv - join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid) - join specification isp on (ii.specification_id=isp.specification_id) - join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version) - where iiv.specification_item_uid=si.specification_item_uid - --AND ia.is_actual - )) + join specification s on (si.specification_id=s.specification_id) + join agreement a on (s.contract_id=a.contract_id AND a.agreement_version=siv.agreement_version) join contract d on s.contract_id=d.contract_id join contragent k on d.contragent_id=k.contragent_id join svc on (si.svc_id=svc.svc_id) - left outer join agreement a0 on (s.contract_id=a0.contract_id /*AND siv.agreement_version=a0.agreement_version*/ AND a0.agreement_version=(select max(iiv.agreement_version) from specification_item_version iiv - join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid) - join specification isp on (ii.specification_id=isp.specification_id) - join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version) - where iiv.specification_item_uid=si.specification_item_uid - AND ia.agreement_version < a.agreement_version - AND ia.is_actual - )) + -- находим предыдущее действующее соглашение + -- если свежее соглашение действует, то впр + -- нам нужно, чтобы в прошлом (до dt_from свежего соглашения) свежак был прозрачен, + -- а в будущем (после dt_to) факт перетирался свежим соглашением + left outer join agreement a0 on (s.contract_id=a0.contract_id AND a0.agreement_version=( + select max(iiv.agreement_version) from specification_item_version iiv + join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid) + join specification isp on (ii.specification_id=isp.specification_id) + join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version) + where iiv.specification_item_uid=si.specification_item_uid + AND ia.agreement_version < siv.agreement_version + AND ia.is_actual /*именно действующее соглашение, принимаемое за факт*/ + ) + ) left outer join specification_item_version siv0 on (siv0.specification_item_uid=si.specification_item_uid - AND siv0.agreement_version=a0.agreement_version) + AND siv0.agreement_version=a0.agreement_version AND (dayscale.dt >= siv0.dt_from /*AND (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL)*/) + ) where 1=1 group by DATE_TRUNC('month', dayscale.dt) ) install_fix_payg @@ -142,8 +178,7 @@ select count(*) as cnt from specification_item where 1=1
- Месяцы с нулевой суммой не показаны - + Месяцы без данных не показаны. Вариант с локальной рабочей версией строки (инстанса) @@ -152,15 +187,22 @@ select count(*) as cnt from specification_item where 1=1 + + - + + - - - + + + + + + +
Инсталл Ежемес ВыручкаПриростПрирост ежемес
#dateFormat(m,"MM.YYYY")##nFmt(income_install)##nFmt(income_recurring)##nFmt(income)##myNumFmt(income_install)##myNumFmt(income_recurring)##myNumFmt(income)##myNumFmt(safeNum(income) - income_old)##myNumFmt(income_recurring-income_recurring_old)#
diff --git a/specification.cfm b/specification.cfm index 4f9965c..aaa5724 100644 --- a/specification.cfm +++ b/specification.cfm @@ -193,7 +193,7 @@ join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id) where siv.specification_item_uid=i.specification_item_uid AND a.is_actual order by siv.agreement_version desc limit 1) as cost - ,(select siv.price*siv.quantity*a.probability_perc/100 from specification_item_version siv + ,(select siv.price*siv.quantity*(case when a.is_actual then 100 else a.probability_perc end)/100 from specification_item_version siv join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id) where siv.specification_item_uid=i.specification_item_uid AND a.is_actual order by siv.agreement_version desc limit 1) as cost_p @@ -233,11 +233,11 @@

(количество, цена, даты актуальности, версия/соглашение, имя для печати - для последней актуальной версии) + Внимание! При расчетах вероятность действительной версии принимается за 100% - - + @@ -255,7 +255,6 @@ - diff --git a/specification_item.cfm b/specification_item.cfm index 3ec952d..1870642 100644 --- a/specification_item.cfm +++ b/specification_item.cfm @@ -232,7 +232,7 @@ - + diff --git a/specification_item_ls.cfm b/specification_item_ls.cfm index ced9f16..bd8d7df 100644 --- a/specification_item_ls.cfm +++ b/specification_item_ls.cfm @@ -22,10 +22,10 @@ select /*переделать выборку версий через group by*/ a.contract_id - a.agreement_version a.deal_uid a.probability_perc - a.agreement + a.agreement + a.agreement_version case when a.agreement_version = 0 then 'New sale' else 'Up sale' end as deal_type @@ -145,8 +145,8 @@ select count(*) as cnt from specification_item where 1=1 - - + + @@ -169,8 +169,8 @@ select count(*) as cnt from specification_item where 1=1 title="редактировать" class="edit"title="просмотр" class="view"> - - #deal_uid# + + #agreement# [#agreement_version#] #specification_item_uid# @@ -194,15 +194,13 @@ select count(*) as cnt from specification_item where 1=1 - - + + + + - - - - - +
Ключ строки Код услуги УслугаТек. версия Дата с Дата по
Услуга (для печати) Кол-во ЦенаСтоимостьСтоимость без вер-ти