019 fine debug

This commit is contained in:
msyu 2025-06-30 10:31:42 +03:00
parent 1c96679c29
commit e96eedece5
6 changed files with 117 additions and 12 deletions

View File

@ -69,7 +69,7 @@
<!--- <cfset this.datasources["#this.datasource#"]=getDS("#this.datasource#","datasource_#this.datasource#")/> --->
<cfset request.RECORDS_PER_PAGE=500/>
<cfset request.APP_VERSION="0.00.018"/>
<cfset request.APP_VERSION="0.00.019"/>
<cflock scope="application" type="readonly" timeout=3>
<cfset request.APP_NAME=this.Name/>

90
etc/db/3.sql Normal file
View File

@ -0,0 +1,90 @@
/*
Для инсталла
- если в новой версии дата изменилась, то кажется, что прогноз нужно отнести на новую дату
- Если прежняя версия была действующей: кажется, что все действующие версии нужно оставить в прогнозе (потому что это уже факт)
а новую версию включить в прогноз с вероятностью
? Должен ли инсталл вести себя одинаково с 1-дневными ежемесами (похоже на критерий корректности модели)
Версии инсталла не интерферируют с действующими. Все действующие записываются в факт, из недействующих берется последняя
Версии ежемеса интерферируют с действующими, и для пересекающихся дат суммируются по правилу вероятностей с последней действующей
(вероятность которой автоматически принимается за 100%)
Почему тогда мы в ежемесе убираем из прогноза предыдущие действующие версии? скажем, у нас была версия на весь январь и весь март,
отмеченные как действующие
Сценарий: ежемес только март, ежемес только апрель.
Сценарий: завершение открытой услуги с dt_to
Интерференция между ежемесами - насущная необходимость. Самый важный сценарий - действующая услуга, без окончания, и новая версия с некоторой даты.
Причина криводиффа: идея закрыть действующую и запустить новую. Кажется некорректным по сравнению с формулой сложения вероятностей,
потому что на время пересечения будет просадка, которую непонятно, как компенсировать.
Как считать инсталл. Казалось бы, более простой вариант. Было состояние А. Стало состояние Б. Кажется, новая модель только частично
корректна - а именно, когда даты пересекаются, именно за счет пересечения (усреднение происходит на каждую дату). Проверить с непересекающимися диапазонами.
Например, у меня есть услуга в течение месяца, закрытая по дате, факт. Мы делаем такую же версию на следующий месяц. Что это означает?
Что мы отменили факт? (задним числом?) Мы хотим эту версию учитывать в ополнение_ к факту? А если цепочка таких фактов?
Или учитывать все факты с вероятностью 100%?
*** Тест: поставить последней услуге флаг Действует (соглашению)
Сбивает с толку еще то, что цепочка версий и цепочка временных диапазонов кажутся параллельными,
монотонной последовательности версий как бы должна соответствовать монотонная цепочка интервалов (хотя бы для тех версий, которые учитываем)
Идея с диффами кажется ошибочной. Мы в этом случае пытаемся синтезировать сами не знаем что.
Важно: наши версии не являются коррекциями, они отражают изменения ожиданий (прогноза), а постфактум - изменение факта!
Если есть продолженный ежемес, с некоторого числа мы создаем допродажу с определенной версией. Сначала она суммируется по вероятности, потом полностью перетирает старую.
Эта версия влияет на результат только со своей dt_from (мы еще не исследовали случай, когда это dt_from зайдет в прошлое)
Для продолженного "факта" мы, очевидно, допускаем модификацию в будущем (будущее в смысле версий или в смысле дат? в смысле дат), -
допродажу, завершение
Затея: полностью повторить для инсталла поведение 1-дневных закрытых ежемесов
Прозрение (может быть): каждая сделка - это скорее изменение, чем версия. По крайней мере, мы говорим о допродаже
Кто-то скажет, какая разница. А разница - хранить дельту или результат. Вопрос, можно ли корректно и компактно сохранить дельту?
Как часто нам понадобится отменять предыдущее значение?
Если для создания дельты нам нужно больше 1 записи
- сразу окажется, что 1 результата можно достичь разными путями (неоднозначность дельты)
*/
select
--install
dayscale.dt::date
,(siv.price*siv.quantity*COALESCE(a.probability_perc,0)/100) as inst1
,(siv0.price*siv0.quantity*(100-COALESCE(a.probability_perc,0))/100) as inst0
,(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) as max_a_v
,a.*
--,a0.*
,siv.*
from (SELECT dd::date as dt 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)
left outer join specification_item si on (siv.specification_item_uid=si.specification_item_uid AND si.pricing_model_id in (1))
left outer join specification s on (si.specification_id=s.specification_id)
left outer 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 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 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)
)
left outer join specification_item_version siv0 on (siv0.specification_item_uid=si.specification_item_uid
AND siv0.agreement_version=a0.agreement_version AND (dayscale.dt=siv0.dt_from))
where d.contragent_id=3

BIN
img/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
img/favicon1.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -52,10 +52,10 @@ from (
,'2029-12-31'::timestamp
,'1 day'::interval) dd
) dayscale
join specification_item_version siv on (dayscale.dt=siv.dt_from)
join specification_item si on (siv.specification_item_uid=si.specification_item_uid AND si.pricing_model_id in (1))
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
left outer join specification_item_version siv on (dayscale.dt=siv.dt_from)
left outer join specification_item si on (siv.specification_item_uid=si.specification_item_uid AND si.pricing_model_id in (1))
left outer join specification s on (si.specification_id=s.specification_id)
left outer 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)
@ -103,7 +103,7 @@ from (
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))
left outer join specification_item si on (siv.specification_item_uid=si.specification_item_uid AND si.pricing_model_id in (2,3))
left outer join specification s on (si.specification_id=s.specification_id )
left join agreement a on (s.contract_id=a.contract_id AND siv.agreement_version=a.agreement_version
left outer 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)
@ -172,7 +172,7 @@ select count(*) as cnt from specification_item where 1=1
<a href="?output_xls" title="экспорт в Excel" style="margin:.5em; height:100%;" target="_blank"><img src="img/xls.gif" style="vertical-align:text-bottom;"/></a>
<a href="?output_json" title="экспорт в json" style="margin:.5em; height:100%;" target="_blank"><img src="img/json.svg" style="vertical-align:text-bottom;" width="13" height="13"/></a>
<br/>
Дни и месяцы с нулевой суммой не показаны
Дни и месяцы с нулевой суммой не показаны. Инсталл и ежемес могут генерировать отдельные строки на один день
<table class="worktable">
<thead>

View File

@ -62,7 +62,7 @@
<d:param field="specification_item_uid" type="guid" key/>
<d:param field="agreement_version" type="integer" key/> <!--- init=#qLastVersion.agreement_version# --->
<d:param field="specification_item_version" type="varchar" size="1023" init="#qLastVersion.specification_item_version#" preprocessor=#cleanInput#/>
<d:param field="specification_item_version" type="varchar" size="1023" init="#qLastVersion.specification_item_version#" preprocessor=#cleanInput#/><!--- неудачное название, это имя данной записи, перетирающее имя услуги из справочника --->
<d:param field="quantity" type="numeric" init=#qLastVersion.quantity#/>
<d:param field="price" type="numeric" init=#qLastVersion.price# preprocessor=#request.stripWhiteSpace#/>
<d:param field="dt_from" type="timestamp" format="yyyy-MM-dd" forNull="" init="#qAgreement.dt_agreement#"/> <!--- !!! Important yyyy-MM-dd NOT YYYY-MM-DD --->
@ -103,10 +103,24 @@
where i.specification_item_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#d.specification_item_uid#" null=#!IsValid('guid',d.specification_item_uid)#/>
</cfquery>
<cfquery name="qAgreement" datasource="#request.DS#">
select
iv.agreement_version, a.probability_perc, a.is_actual
from specification_item_version iv
join specification_item si on (iv.specification_item_uid=si.specification_item_uid)
join specification s on (si.specification_id=s.specification_id)
join agreement a on (iv.agreement_version=a.agreement_version and s.contract_id=a.contract_id)
where iv.specification_item_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#d.specification_item_uid#" null=#!isValid('guid', d.specification_item_uid)#/>
AND iv.agreement_version=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.agreement_version#" null=#!isValid('integer', d.agreement_version)#/>
</cfquery>
<cfquery name="qVersion" datasource="#request.DS#">
select
iv.agreement_version
iv.agreement_version, a.probability_perc, a.is_actual
from specification_item_version iv
join specification_item si on (iv.specification_item_uid=si.specification_item_uid)
join specification s on (si.specification_id=s.specification_id)
join agreement a on (iv.agreement_version=a.agreement_version and s.contract_id=a.contract_id)
where iv.specification_item_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#d.specification_item_uid#" null=#!isValid('guid', d.specification_item_uid)#/>
order by 1
</cfquery>
@ -186,7 +200,7 @@
<!--- *** можно придумать коструктор ссылок с декоратором tr.fwx --->
<cfif d.agreement_version GE 0>
<a href="agreement.cfm?agreement_version=#d.agreement_version#&contract_id=#qSpecificationItem.contract_id#&#tr.fwx#">
#d.agreement_version#
#d.agreement_version# (#qAgreement.probability_perc#% <cfif qAgreement.is_actual GT 0><img src="img/ok.png"title="Действует"/></cfif>)
</a>
</cfif>
<a href="agreement.cfm?contract_id=#qSpecificationItem.contract_id#&#tr.fwx#">
@ -239,9 +253,10 @@
<layout:detail_line title="Версии">
<cfoutput query=#qVersion#>
<cfif qVersion.agreement_version EQ d.agreement_version>
<b>#agreement_version#</b>
<b>#agreement_version# (#qAgreement.probability_perc#% <cfif qAgreement.is_actual GT 0><img src="img/ok.png"title="Действует"/></cfif>)</b>
<cfelse>
<a href="specification_item_version.cfm?specification_item_uid=#d.specification_item_uid#&agreement_version=#agreement_version#&track=#tr.self#">#agreement_version#</a>
<a href="specification_item_version.cfm?specification_item_uid=#d.specification_item_uid#&agreement_version=#agreement_version#&track=#tr.self#">#agreement_version# (#probability_perc#%
<cfif is_actual GT 0><img src="img/ok.png"title="Действует"/></cfif>)</a>
</cfif>
&nbsp;
</cfoutput>