21 with asymmetric time and local version

This commit is contained in:
msyu 2025-07-11 10:21:05 +03:00
parent e96eedece5
commit 2d270ef24f
9 changed files with 240 additions and 83 deletions

View File

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

View File

@ -120,7 +120,9 @@ select count(*) as cnt from agreement where 1=1
<c:table query=#qRead# recordsPerPage=#pageInfo.recordsPerPage# nStart=#pageInfo.nStart# titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray# class="worktable wide"> <c:table query=#qRead# recordsPerPage=#pageInfo.recordsPerPage# nStart=#pageInfo.nStart# titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray# class="worktable wide">
<c:column width="1%" sortable="false"><!---*** class="c" не пробрасывается ---> <c:column width="1%" sortable="false"><!---*** class="c" не пробрасывается --->
<!--- <c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity="agreement" fwx=#tr.fwx#/></c:th> --->
<c:th><!--- <a href="agreement.cfm?contract_id=&agreement_version="><img src="img/add.gif"/></a> ---></c:th> <c:th><!--- <a href="agreement.cfm?contract_id=&agreement_version="><img src="img/add.gif"/></a> ---></c:th>
<!--- <a href="agreement.cfm?contract_id=&agreement_version=&#tr.fwx#"> не работает --->
<c:td field="f_link_view_edit" class="c"/> <c:td field="f_link_view_edit" class="c"/>
</c:column> </c:column>
<c:column width="2%" field="agreement_version"><c:td class="r"/></c:column> <c:column width="2%" field="agreement_version"><c:td class="r"/></c:column>

View File

@ -265,7 +265,9 @@
</tr> </tr>
</cfoutput> </cfoutput>
</table> </table>
</cfif> </cfif>
При создании договора сразу создавать спецификацию и базовое соглашение
<layout:page section="extension" closeForm="Yes"/> <!--- *** правильно так? ---> <layout:page section="extension" closeForm="Yes"/> <!--- *** правильно так? --->
<layout:page section="footer"/> <layout:page section="footer"/>

View File

@ -1,3 +1,6 @@
2025-07-10 15:08:02
Оказывается, есть разница между "0 с 1 июля" и "ничего с 1 июля" - в текущей версии 0 с вероятностью 100 непрозрачен, а нулл с вероятностью 100 получается полностью прозрачен. Либо здесь несимметрия по времени должна быть
2025-06-17 09:07:46 2025-06-17 09:07:46
2025-06-16 10:58:02 2025-06-16 10:58:02
select select

View File

@ -10,6 +10,11 @@
<cfreturn (a GT 0)? a : ""/> <cfreturn (a GT 0)? a : ""/>
</cffunction> </cffunction>
<cffunction name="myNumFmt">
<cfargument name="a"/>
<cfreturn (isNumeric(a))? numberFormat(a,",.00") : ""/>
</cffunction>
<m:prepare_ls entity="specification_item" accessObject="" pageInfoOut="pageInfo" trackOut="tr"/> <m:prepare_ls entity="specification_item" accessObject="" pageInfoOut="pageInfo" trackOut="tr"/>
<!--- <m:filter_settings target="#pageInfo.entity#_ls"> <!--- <m:filter_settings target="#pageInfo.entity#_ls">
@ -87,10 +92,40 @@ from (
,0 ,0
,0 ,0
,0 ,0
,COALESCE(sum(siv.price*siv.quantity*COALESCE(a.probability_perc,0)/100/dayscale.days),0) ,COALESCE(sum(
+ COALESCE(sum(siv0.price*siv0.quantity*(100-COALESCE(a.probability_perc,0))/100/dayscale.days),0) case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
,sum(siv.price*siv.quantity*COALESCE(a.probability_perc,0)/100/dayscale.days) siv.price*siv.quantity*COALESCE(
,sum(siv0.price*siv0.quantity*(100-COALESCE(a.probability_perc,0))/100/dayscale.days) 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)
,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
else 0
end
)
,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
--else 0
end
)
,count(*) ,count(*)
from (SELECT dd::date as dt from (SELECT dd::date as dt
@ -100,32 +135,37 @@ from (
,'2029-12-31'::timestamp ,'2029-12-31'::timestamp
,'1 day'::interval) dd ,'1 day'::interval) dd
) dayscale ) 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)) 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)) AND siv.agreement_version=(select max(iiv.agreement_version) from specification_item_version iiv
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_item ii on (iiv.specification_item_uid=ii.specification_item_uid)
join specification isp on (ii.specification_id=isp.specification_id) 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) 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 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 (dayscale.dt >= iiv.dt_from /*AND (iiv.dt_to > dayscale.dt OR iiv.dt_to IS NULL)*/)))
/*AND ia.is_actual*/ /*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 a.agreement_version=siv.agreement_version)
join contract d on s.contract_id=d.contract_id join contract d on s.contract_id=d.contract_id
join contragent k on d.contragent_id=k.contragent_id join contragent k on d.contragent_id=k.contragent_id
join svc on (si.svc_id=svc.svc_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 -- если свежее соглашение действует, то впр
-- нам нужно, чтобы в прошлом (до 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_item ii on (iiv.specification_item_uid=ii.specification_item_uid)
join specification isp on (ii.specification_id=isp.specification_id) 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) 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 where iiv.specification_item_uid=si.specification_item_uid
AND ia.agreement_version < a.agreement_version AND ia.agreement_version < siv.agreement_version
AND ia.is_actual AND ia.is_actual /*именно действующее соглашение, принимаемое за факт*/
)) )
)
left outer join specification_item_version siv0 on (siv0.specification_item_uid=si.specification_item_uid 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 AND (siv0.dt_to >= dayscale.dt OR siv0.dt_to IS NULL))) 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 <m:filter_build filter=#pageInfo.settings.filter#/> where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
group by dayscale.dt group by dayscale.dt
) install_fix_payg ) install_fix_payg
@ -172,7 +212,9 @@ 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_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> <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/> <br/>
Дни и месяцы с нулевой суммой не показаны. Инсталл и ежемес могут генерировать отдельные строки на один день Дни и месяцы без данных не показаны.
Инсталл и ежемес могут генерировать отдельные строки на один день.
Вариант с локальной рабочей версией строки (инстанса)
<table class="worktable"> <table class="worktable">
<thead> <thead>
@ -192,13 +234,13 @@ select count(*) as cnt from specification_item where 1=1
<cfoutput query="qRead"> <cfoutput query="qRead">
<tr> <tr>
<td class="c">#dateFormat(dt,"DD.MM.YYYY")#</td> <td class="c">#dateFormat(dt,"DD.MM.YYYY")#</td>
<td class="r">#income_install#</td> <td class="r">#myNumFmt(income_install)#</td>
<td class="r">#inst1#</td> <td class="r">#myNumFmt(inst1)#</td>
<td class="r">#inst0#</td> <td class="r">#myNumFmt(inst0)#</td>
<td class="r">#income_recurring#</td> <td class="r">#myNumFmt(income_recurring)#</td>
<td class="r">#rec1#</td> <td class="r">#myNumFmt(rec1)#</td>
<td class="r">#rec0#</td> <td class="r">#myNumFmt(rec0)#</td>
<td class="r">#income#</td> <td class="r">#myNumFmt(income)#</td>
<td class="r">#cnt#</td> <td class="r">#cnt#</td>
</tr> </tr>
</cfoutput> </cfoutput>
@ -233,9 +275,9 @@ select count(*) as cnt from specification_item where 1=1
<cfoutput query="qMonthly"> <cfoutput query="qMonthly">
<tr> <tr>
<td class="c">#dateFormat(m,"MM.YYYY")#</td> <td class="c">#dateFormat(m,"MM.YYYY")#</td>
<td class="r">#nFmt(income_install)#</td> <td class="r">#myNumFmt(income_install)#</td>
<td class="r">#nFmt(income_recurring)#</td> <td class="r">#myNumFmt(income_recurring)#</td>
<td class="r">#nFmt(income)#</td> <td class="r">#myNumFmt(income)#</td>
</tr> </tr>
</cfoutput> </cfoutput>
</table> </table>
@ -243,3 +285,72 @@ select count(*) as cnt from specification_item where 1=1
</cfif> </cfif>
<layout:page section="footer"/> <layout:page section="footer"/>
<!---
-- select *
select
--DATE_TRUNC('month', dayscale.dt)::date as m,
dayscale.dt::date
--,a.agreement_version as v
,siv.agreement_version
,siv.dt_from::date
,siv.dt_to::date
,siv.quantity
,case when siv.dt_to >=dayscale.dt OR siv.dt_to IS NULL then siv.quantity else -100500 end as q
,a0.agreement_version as v0
,siv0.dt_from::date
,siv0.dt_to::date
,siv0.quantity
--,0 ,0 ,0
/*
,COALESCE(sum(siv.price*siv.quantity*COALESCE(a.probability_perc,0)/100/dayscale.days),0)
+ COALESCE(sum(siv0.price*siv0.quantity*(100-COALESCE(a.probability_perc,0))/100/dayscale.days),0)
,sum(siv.price*siv.quantity*COALESCE(a.probability_perc,0)/100/dayscale.days)
,sum(siv0.price*siv0.quantity*(100-COALESCE(a.probability_perc,0))/100/dayscale.days)
,count(*)
*/
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 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)
-- находим предыдущее действующее соглашение
-- если свежее соглашение действует, то впр
-- нам нужно, чтобы в прошлом (до 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 (dayscale.dt >= siv0.dt_from /*AND (siv0.dt_to >= dayscale.dt OR siv0.dt_to IS NULL)*/)
)
where d.contragent_id=4
--group by dayscale.dt
--->

View File

@ -10,6 +10,17 @@
<cfreturn (a GT 0)? a : ""/> <cfreturn (a GT 0)? a : ""/>
</cffunction> </cffunction>
<cffunction name="myNumFmt">
<cfargument name="a"/>
<cfreturn (isNumeric(a))? numberFormat(a,",.00") : ""/>
</cffunction>
<cffunction name="safeNum">
<cfargument name="a"/>
<cfreturn (isNumeric(a))? a : 0/>
</cffunction>
<m:prepare_ls entity="specification_item" accessObject="" pageInfoOut="pageInfo" trackOut="tr"/> <m:prepare_ls entity="specification_item" accessObject="" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls"> <m:filter_settings target="#pageInfo.entity#_ls">
@ -70,39 +81,64 @@ from (
select select
DATE_TRUNC('month', dayscale.dt)::date as m DATE_TRUNC('month', dayscale.dt)::date as m
,0 ,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) + COALESCE(siv0.price*siv0.quantity*(100-a.probability_perc)/100/dayscale.days, 0)
) )*/
from ,COALESCE(sum(
(SELECT dd::date as dt, DATE_PART('days', case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL siv.price*siv.quantity*COALESCE(
) days FROM generate_series case when a.is_actual then 100 else a.probability_perc end
( '2023-01-01'::timestamp ,0)/100/dayscale.days
, '2029-12-31'::timestamp /*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
, '1 day'::interval) dd) dayscale else 0 /*по окончании свежей сделки она дает нулевой вклад*/
join specification_item_version siv on (dayscale.dt >= siv.dt_from AND (siv.dt_to >= dayscale.dt OR siv.dt_to IS NULL)) 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_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 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 agreement a on (s.contract_id=a.contract_id AND a.agreement_version=siv.agreement_version)
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 contract d on s.contract_id=d.contract_id
join contragent k on d.contragent_id=k.contragent_id join contragent k on d.contragent_id=k.contragent_id
join svc on (si.svc_id=svc.svc_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) -- нам нужно, чтобы в прошлом (до dt_from свежего соглашения) свежак был прозрачен,
join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version) -- а в будущем (после dt_to) факт перетирался свежим соглашением
where iiv.specification_item_uid=si.specification_item_uid left outer join agreement a0 on (s.contract_id=a0.contract_id AND a0.agreement_version=(
AND ia.agreement_version < a.agreement_version select max(iiv.agreement_version) from specification_item_version iiv
AND ia.is_actual 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 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 <m:filter_build filter=#pageInfo.settings.filter#/> where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
group by DATE_TRUNC('month', dayscale.dt) group by DATE_TRUNC('month', dayscale.dt)
) install_fix_payg ) install_fix_payg
@ -142,8 +178,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_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> <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/> <br/>
Месяцы с нулевой суммой не показаны Месяцы без данных не показаны. Вариант с локальной рабочей версией строки (инстанса)
<table class="worktable"> <table class="worktable">
<thead> <thead>
@ -152,15 +187,22 @@ select count(*) as cnt from specification_item where 1=1
<th>Инсталл</th> <th>Инсталл</th>
<th>Ежемес</th> <th>Ежемес</th>
<th>Выручка</th> <th>Выручка</th>
<th>Прирост</th>
<th>Прирост ежемес</th>
</tr> </tr>
</thead> </thead>
<cfset income_old=0/>
<cfset income_recurring_old=0/>
<cfoutput query="qRead"> <cfoutput query="qRead">
<tr> <tr>
<td class="c">#dateFormat(m,"MM.YYYY")#</td> <td class="c">#dateFormat(m,"MM.YYYY")#</td>
<td class="r">#nFmt(income_install)#</td> <td class="r">#myNumFmt(income_install)#</td>
<td class="r">#nFmt(income_recurring)#</td> <td class="r">#myNumFmt(income_recurring)#</td>
<td class="r">#nFmt(income)#</td> <td class="r">#myNumFmt(income)#</td>
<td class="r">#myNumFmt(safeNum(income) - income_old)#</td>
<cfset income_old = safeNum(income)/>
<td class="r">#myNumFmt(income_recurring-income_recurring_old)#</td>
<cfset income_recurring_old = safeNum(income_recurring)/>
</tr> </tr>
</cfoutput> </cfoutput>
</table> </table>

View File

@ -193,7 +193,7 @@
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id) 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 where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as cost 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) 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 where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as cost_p order by siv.agreement_version desc limit 1) as cost_p
@ -233,11 +233,11 @@
</p> </p>
</cfoutput> </cfoutput>
(количество, цена, даты актуальности, версия/соглашение, имя для печати - для последней актуальной версии) (количество, цена, даты актуальности, версия/соглашение, имя для печати - для последней актуальной версии)
<span class="err">Внимание! При расчетах вероятность действительной версии принимается за 100%</span>
<table class="worktable"> <table class="worktable">
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th>Ключ строки</th> <th>Ключ строки</th>
<th>Код услуги</th> <th>Код услуги</th>
<th>Услуга</th> <th>Услуга</th>
@ -255,7 +255,6 @@
<th>Тек. версия</th> <th>Тек. версия</th>
<th>Дата с</th> <th>Дата с</th>
<th>Дата по</th> <th>Дата по</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>

View File

@ -232,7 +232,7 @@
<th>Услуга (для печати)</th> <th>Услуга (для печати)</th>
<th>Кол-во</th> <th>Кол-во</th>
<th>Цена</th> <th>Цена</th>
<th>Стоимость</th> <th>Стоимость без вер-ти</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>

View File

@ -22,10 +22,10 @@
select /*переделать выборку версий через group by*/ select /*переделать выборку версий через group by*/
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount"> <d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="contract_id" cfSqlType="CF_SQL_INTEGER">a.contract_id</d:field> <d:field title="contract_id" cfSqlType="CF_SQL_INTEGER">a.contract_id</d:field>
<d:field title="Н-р согл." cfSqlType="CF_SQL_INTEGER">a.agreement_version</d:field>
<d:field title="Ключ сделки">a.deal_uid</d:field> <d:field title="Ключ сделки">a.deal_uid</d:field>
<d:field title="Вер-ть%">a.probability_perc</d:field> <d:field title="Вер-ть%">a.probability_perc</d:field>
<d:field title="Соглашение">a.agreement</d:field> <d:field title="Сделка">a.agreement</d:field>
<d:field title="Соглашение">a.agreement_version</d:field>
<d:field title="Тип сделки">case when a.agreement_version = 0 then 'New sale' else 'Up sale' end as deal_type</d:field> <d:field title="Тип сделки">case when a.agreement_version = 0 then 'New sale' else 'Up sale' end as deal_type</d:field>
<!--- <d:field title="Дата соглашения">a.dt_specification_item</d:field> ---> <!--- <d:field title="Дата соглашения">a.dt_specification_item</d:field> --->
<!--- <d:field title="Описание">a.descr</d:field> ---> <!--- <d:field title="Описание">a.descr</d:field> --->
@ -145,8 +145,8 @@ select count(*) as cnt from specification_item where 1=1
<cfset queryAddColumn(qRead,'f_link_view_edit')/> <cfset queryAddColumn(qRead,'f_link_view_edit')/>
<cfset titleMap.f_link_view_edit={ordinal=#StructCount(titleMap)+1#}/><!--- *** Это легко забыть, потому что TitleMap никак не сцеплен с qRead. Напрашивается: упаковать их в одну обертку (но тогда обращение станет длиннее). Еще идея - назвать qRead и TitleMap так, чтобы была видна их связь. ---> <cfset titleMap.f_link_view_edit={ordinal=#StructCount(titleMap)+1#}/><!--- *** Это легко забыть, потому что TitleMap никак не сцеплен с qRead. Напрашивается: упаковать их в одну обертку (но тогда обращение станет длиннее). Еще идея - назвать qRead и TitleMap так, чтобы была видна их связь. --->
<!--- <cfdump var=#titleMap#/> ---> <!--- <cfdump var=#titleMap#/> --->
<cfset queryAddColumn(qRead,'f_deal_uid')/> <cfset queryAddColumn(qRead,'f_agreement_version')/>
<cfset titleMap.f_deal_uid=titleMap.deal_uid/> <cfset titleMap.f_agreement_version=titleMap.agreement_version/>
<cfset queryAddColumn(qRead,'f_specification_item_uid')/> <cfset queryAddColumn(qRead,'f_specification_item_uid')/>
<cfset titleMap.f_specification_item_uid=titleMap.specification_item_uid/> <cfset titleMap.f_specification_item_uid=titleMap.specification_item_uid/>
@ -169,8 +169,8 @@ select count(*) as cnt from specification_item where 1=1
<cfsavecontent variable="qRead.f_link_view_edit"> <cfsavecontent variable="qRead.f_link_view_edit">
<a href="specification_item_version.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#agreement_version#&#tr.fwx#" name="#specification_item_uid#" <cfif pageInfo.writePermitted()>title="редактировать" class="edit"<cfelse>title="просмотр" class="view"</cfif>></a> <a href="specification_item_version.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#agreement_version#&#tr.fwx#" name="#specification_item_uid#" <cfif pageInfo.writePermitted()>title="редактировать" class="edit"<cfelse>title="просмотр" class="view"</cfif>></a>
</cfsavecontent> </cfsavecontent>
<cfsavecontent variable="qRead.f_deal_uid"> <cfsavecontent variable="qRead.f_agreement_version">
<a href="agreement.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#">#deal_uid#</a> <a href="agreement.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#">#agreement# [#agreement_version#]</a>
</cfsavecontent> </cfsavecontent>
<cfsavecontent variable="qRead.f_specification_item_uid"> <cfsavecontent variable="qRead.f_specification_item_uid">
<a href="specification_item.cfm?specification_item_uid=#specification_item_uid#&#tr.fwx#">#specification_item_uid#</a> <a href="specification_item.cfm?specification_item_uid=#specification_item_uid#&#tr.fwx#">#specification_item_uid#</a>
@ -194,15 +194,13 @@ select count(*) as cnt from specification_item where 1=1
<c:th><!--- <a href="specification_item.cfm?contract_id=&specification_item_version="><img src="img/add.gif"/></a> ---></c:th> <c:th><!--- <a href="specification_item.cfm?contract_id=&specification_item_version="><img src="img/add.gif"/></a> ---></c:th>
<c:td field="f_link_view_edit" class="c"/> <c:td field="f_link_view_edit" class="c"/>
</c:column> </c:column>
<c:column width="7%" field="contragent"/>
<c:column width="8%" field="f_deal_uid"/> <c:column width="5%" field="f_contract"/>
<c:column width="2%" field="f_specification"/>
<c:column width="3%" field="f_agreement_version"/>
<c:column width="3%" field="deal_type"><c:td class="c"/></c:column> <c:column width="3%" field="deal_type"><c:td class="c"/></c:column>
<c:column width="8%" field="f_specification_item_uid"/> <c:column width="8%" field="f_specification_item_uid"/>
<c:column width="3%" field="probability_perc"><c:td class="r"/></c:column> <c:column width="3%" field="probability_perc"><c:td class="r"/></c:column>
<c:column width="2%" field="f_specification"/>
<c:column width="5%" field="f_contract"/>
<!--- <c:column width="5%" field="dt_contract" formatter=#function(dt){return dateformat(dt,"YYYY-MM-DD");}#><c:td class="c"/></c:column> --->
<c:column width="7%" field="contragent"/>
<c:column width="7%" field="specification_item_version"/> <c:column width="7%" field="specification_item_version"/>
<c:column width="1%" field="pricing_model_short"/> <c:column width="1%" field="pricing_model_short"/>
<c:column width="5%" field="dt_from" formatter=#function(dt){return dateformat(dt,"YYYY-MM-DD");}#><c:td class="c"/></c:column> <c:column width="5%" field="dt_from" formatter=#function(dt){return dateformat(dt,"YYYY-MM-DD");}#><c:td class="c"/></c:column>