22 bug fix
This commit is contained in:
parent
2d270ef24f
commit
a58d6e666c
@ -60,6 +60,10 @@
|
||||
<!--- request.ROOT_USR_ID=1 not used --->
|
||||
<cfset request.ANONYMOUS_USR_ID=2/>
|
||||
<cfset request.GUEST_USR_ID=3/>
|
||||
|
||||
|
||||
<cfset DAYSCALE_START = '2024-01-01'/>
|
||||
<cfset DAYSCALE_FINISH = '2026-12-31'/>
|
||||
|
||||
<!--- global settings --->
|
||||
|
||||
@ -69,13 +73,15 @@
|
||||
<!--- <cfset this.datasources["#this.datasource#"]=getDS("#this.datasource#","datasource_#this.datasource#")/> --->
|
||||
|
||||
<cfset request.RECORDS_PER_PAGE=500/>
|
||||
<cfset request.APP_VERSION="0.00.021"/>
|
||||
<cfset request.APP_VERSION="0.00.022"/>
|
||||
|
||||
<cflock scope="application" type="readonly" timeout=3>
|
||||
<cfset request.APP_NAME=this.Name/>
|
||||
</cflock>
|
||||
|
||||
|
||||
|
||||
<cfset local = {} />
|
||||
<cfset local = {} /> <!--- между прочим, эта переменная будет видна во включенных included страницах --->
|
||||
|
||||
<cfset local.basePath = getDirectoryFromPath(
|
||||
getCurrentTemplatePath()
|
||||
|
325
detail_daily_rpt.cfm
Normal file
325
detail_daily_rpt.cfm
Normal file
@ -0,0 +1,325 @@
|
||||
<cfsilent>
|
||||
<cfimport prefix="m" taglib="lib"/>
|
||||
<cfimport prefix="c" taglib="lib/controls"/>
|
||||
<cfimport prefix="d" taglib="lib/data"/>
|
||||
<cfimport prefix="layout" taglib="layout"/>
|
||||
</cfsilent><m:silent silent="No">
|
||||
|
||||
<cffunction name="hideNonPositive">
|
||||
<cfargument name="a"/>
|
||||
<cfreturn (a GT 0)? a : ""/>
|
||||
</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:filter_settings target="#pageInfo.entity#_ls">
|
||||
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.specification_item_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
|
||||
</m:filter_settings> --->
|
||||
<!--- <cfset pageInfo.settings.filter=#filter#/> --->
|
||||
|
||||
|
||||
<cfquery name="qRead" datasource="#request.DS#">
|
||||
<!--- select
|
||||
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
||||
<d:field title="Месяц" cfSqlType="CF_SQL_TIMESTAMP">m</d:field>
|
||||
<d:field title="Дата" cfSqlType="CF_SQL_TIMESTAMP">dt</d:field>
|
||||
<d:field title="Инсталл" cfSqlType="CF_SQL_NUMERIC">income_install</d:field>
|
||||
<d:field title="Инсталл" cfSqlType="CF_SQL_NUMERIC">inst1</d:field>
|
||||
<d:field title="Инсталл" cfSqlType="CF_SQL_NUMERIC">inst0</d:field>
|
||||
<d:field title="Ежемес" cfSqlType="CF_SQL_NUMERIC">income_recurring</d:field>
|
||||
<d:field title="Ежемес+" cfSqlType="CF_SQL_NUMERIC">rec1+rec0 as rec</d:field>
|
||||
<d:field title="Ежемес" cfSqlType="CF_SQL_NUMERIC">rec1</d:field>
|
||||
<d:field title="Ежемес" cfSqlType="CF_SQL_NUMERIC">rec0</d:field>
|
||||
<d:field title="Выручка" cfSqlType="CF_SQL_NUMERIC">income_install+income_recurring as income</d:field>
|
||||
<d:field title="cnt" cfSqlType="CF_SQL_NUMERIC">cnt</d:field>
|
||||
</d:field_set>
|
||||
from ( --->
|
||||
select
|
||||
--install
|
||||
DATE_TRUNC('month', dayscale.dt)::date as m
|
||||
,dayscale.dt::date
|
||||
,siv.price as price_i
|
||||
,siv.quantity as quantity_i
|
||||
,siv0.price as price0_i
|
||||
,siv0.quantity as quantity0_i
|
||||
,a.is_actual as is_actual_i
|
||||
,a.probability_perc as p_i
|
||||
,(100-COALESCE(a.probability_perc,0)) as p_i_rest
|
||||
,siv.specification_item_uid as si_uid_i
|
||||
,siv.agreement_version as av_i
|
||||
,siv0.specification_item_uid as si_uid0_i
|
||||
,siv0.agreement_version as av0_i
|
||||
,null as price_f
|
||||
,null as quantity_f
|
||||
,null as price0_f
|
||||
,null as quantity0_f
|
||||
,null as is_actual_f
|
||||
,null as p_f
|
||||
,null as p_f_rest
|
||||
,null as cost_f
|
||||
,null as cost_month_f
|
||||
,null as dt_from_f
|
||||
,null as dt_to_f
|
||||
,null as dt_from0_f
|
||||
,null as dt_to0_f
|
||||
,null as si_uid_f
|
||||
,null as av_f
|
||||
,null as si_uid0_f
|
||||
,null as av0_f
|
||||
|
||||
from (SELECT dd::date as dt FROM generate_series(
|
||||
'#DAYSCALE_START#'::timestamp
|
||||
,'#DAYSCALE_FINISH#'::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 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
|
||||
|
||||
union all
|
||||
|
||||
--fix and payg
|
||||
select
|
||||
DATE_TRUNC('month', dayscale.dt)::date as m
|
||||
,dayscale.dt::date
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.price
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.quantity
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.price
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.quantity
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,a.is_actual as is_actual_f
|
||||
,a.probability_perc as p_f
|
||||
,(100-COALESCE(a.probability_perc,0)) as p_f_rest
|
||||
|
||||
,case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.price/dayscale.monthdays*siv.quantity*a.probability_perc/100
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
+
|
||||
COALESCE(case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.price/dayscale.monthdays*siv0.quantity*(100- a.probability_perc)/100
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
,case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.price*siv.quantity*a.probability_perc/100
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
+
|
||||
COALESCE(case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.price*siv0.quantity*(100- a.probability_perc)/100
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
,siv.dt_from
|
||||
,siv.dt_to
|
||||
,siv0.dt_from
|
||||
,siv0.dt_to
|
||||
,siv.specification_item_uid
|
||||
,siv.agreement_version
|
||||
,siv0.specification_item_uid
|
||||
,siv0.agreement_version
|
||||
|
||||
|
||||
from (SELECT dd::date as dt
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays
|
||||
FROM generate_series(
|
||||
'#DAYSCALE_START#'::timestamp
|
||||
,'#DAYSCALE_FINISH#'::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 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
|
||||
|
||||
order by dt
|
||||
|
||||
</cfquery>
|
||||
<!--- <cfdump var=#pageInfo.settings.filter#/> --->
|
||||
|
||||
|
||||
|
||||
|
||||
<!--- <cfquery name="qCountTotal" datasource="#request.DS#">
|
||||
select count(*) as cnt from specification_item where 1=1
|
||||
</cfquery> --->
|
||||
|
||||
</m:silent><!---
|
||||
-----------------------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------------------
|
||||
---><cfif isDefined("output_xls")>
|
||||
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
|
||||
<cfabort/>
|
||||
</cfif><cfif isDefined("output_json")>
|
||||
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
|
||||
<cfabort/>
|
||||
</cfif><!---
|
||||
---><layout:page section="header" pageInfo=#pageInfo#>
|
||||
|
||||
<layout:attribute name="title">
|
||||
<cfoutput><b>Выручка по дням 2023-01-01 .. 2029-12-31</b></cfoutput>
|
||||
</layout:attribute>
|
||||
<!--- <layout:attribute name="controls">
|
||||
skip filter link, filter is not implemented
|
||||
<layout:language_switch/>
|
||||
</layout:attribute> --->
|
||||
</layout:page>
|
||||
|
||||
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
|
||||
|
||||
<!--- <cfdump var=#qRead#/><cfabort/> --->
|
||||
|
||||
|
||||
<div style="display:inline-block; vertical-align:top;">
|
||||
<cfoutput><b>#qRead.recordCount#</b> записей</cfoutput>
|
||||
<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>
|
||||
<tr>
|
||||
<th>Дата</th>
|
||||
<!--- <th>Инсталл</th> --->
|
||||
<th>Инсталл рабочая</th>
|
||||
<th>Инсталл базовая</th>
|
||||
<!--- <th>Ежемес</th> --->
|
||||
<th>Ежемес рабочая</th>
|
||||
<th>Ежемес базовая</th>
|
||||
<th>Ежемес</th>
|
||||
<!--- <th>Выручка</th>
|
||||
<th>cnt</th> --->
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<cfoutput query="qRead" group="dt">
|
||||
<tr>
|
||||
<td class="c">#dateFormat(dt,"YYYY-MM-DD")#</td>
|
||||
<!--- <td class="r">#myNumFmt(income_install)#</td> --->
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid_i#&agreement_version=#av_i#&#tr.fwx#">
|
||||
<cfif len(si_uid_i)>(#myNumFmt(price_i)#*#quantity_i#*#p_i#%(#p_i_rest#%)</cfif>
|
||||
</a><br/>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid0_i#&agreement_version=#av0_i#&#tr.fwx#">
|
||||
<cfif len(si_uid0_i)>#myNumFmt(price0_i)#*#quantity0_i#</cfif>
|
||||
</a><br/>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<cfif len(si_uid_f)>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid_f#&agreement_version=#av_f#&#tr.fwx#">
|
||||
[#av_f#]
|
||||
#myNumFmt(price_f)#*#quantity_f#*#p_f#%(#p_f_rest#%)
|
||||
#dateFormat(dt_from_f,'YYYY-MM-DD')# - #dateFormat(dt_to_f,'YYYY-MM-DD')#
|
||||
</a><br/>
|
||||
</cfif>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<cfif len(si_uid0_f)>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid0_f#&agreement_version=#av0_f#&#tr.fwx#">
|
||||
[#av0_f#]
|
||||
#myNumFmt(price0_f)#*#quantity0_f#
|
||||
#dateFormat(dt_from0_f,'YYYY-MM-DD')# - #dateFormat(dt_to0_f,'YYYY-MM-DD')#
|
||||
</a><br/>
|
||||
</cfif>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="r"><cfoutput>#myNumFmt(cost_month_f)# | #myNumFmt(cost_f)#</cfoutput></td>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</cfif>
|
||||
<layout:page section="footer"/>
|
@ -18,6 +18,7 @@
|
||||
<c:menu_item acl="" page="specification_item_ls.cfm" label="Экземпляры услуг"/>
|
||||
<li class="menu-title">Отчеты</li>
|
||||
<c:menu_item acl="" page="income_data.cfm" label="Исходные данные для прогноза"/>
|
||||
<c:menu_item acl="" page="detail_daily_rpt.cfm" label="Детализация по дням"/>
|
||||
<c:menu_item acl="" page="income_daily_rpt.cfm" label="Выручка по дням"/>
|
||||
<c:menu_item acl="" page="income_monthly_rpt.cfm" label="Выручка по месяцам"/>
|
||||
|
||||
|
@ -53,8 +53,8 @@ from (
|
||||
,0 as rec0
|
||||
,count(*) as cnt
|
||||
from (SELECT dd::date as dt FROM generate_series(
|
||||
'2023-01-01'::timestamp
|
||||
,'2029-12-31'::timestamp
|
||||
'#DAYSCALE_START#'::timestamp
|
||||
,'#DAYSCALE_FINISH#'::timestamp
|
||||
,'1 day'::interval) dd
|
||||
) dayscale
|
||||
left outer join specification_item_version siv on (dayscale.dt=siv.dt_from)
|
||||
@ -92,7 +92,7 @@ from (
|
||||
,0
|
||||
,0
|
||||
,0
|
||||
,COALESCE(sum(
|
||||
<!--- ,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
|
||||
@ -108,12 +108,28 @@ from (
|
||||
,0))/100/dayscale.days
|
||||
/*по окончании свежей сделки*/
|
||||
end
|
||||
),0)
|
||||
),0) --->
|
||||
|
||||
,sum(
|
||||
COALESCE(case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.price*siv.quantity*(
|
||||
case when a.is_actual then 100 else a.probability_perc end
|
||||
)/100/dayscale.monthdays
|
||||
else 0 /*по окончании рабочей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
+
|
||||
COALESCE(case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.price/dayscale.monthdays*siv0.quantity*(100- COALESCE(
|
||||
case when a.is_actual then 100 else a.probability_perc end
|
||||
,0))/100
|
||||
else 0 /*по окончании базовой сделки она дает нулевой вклад*/
|
||||
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
|
||||
,0)/100/dayscale.monthdays
|
||||
else 0
|
||||
end
|
||||
)
|
||||
@ -122,17 +138,16 @@ from (
|
||||
.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
|
||||
,0))/100/dayscale.monthdays
|
||||
end
|
||||
)
|
||||
,count(*)
|
||||
|
||||
from (SELECT dd::date as dt
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) days
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays
|
||||
FROM generate_series(
|
||||
'2023-01-01'::timestamp
|
||||
,'2029-12-31'::timestamp
|
||||
'#DAYSCALE_START#'::timestamp
|
||||
,'#DAYSCALE_FINISH#'::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)*/
|
||||
|
416
income_daily_rpt.old.cfm
Normal file
416
income_daily_rpt.old.cfm
Normal file
@ -0,0 +1,416 @@
|
||||
<cfsilent>
|
||||
<cfimport prefix="m" taglib="lib"/>
|
||||
<cfimport prefix="c" taglib="lib/controls"/>
|
||||
<cfimport prefix="d" taglib="lib/data"/>
|
||||
<cfimport prefix="layout" taglib="layout"/>
|
||||
</cfsilent><m:silent silent="No">
|
||||
|
||||
<cffunction name="hideNonPositive">
|
||||
<cfargument name="a"/>
|
||||
<cfreturn (a GT 0)? a : ""/>
|
||||
</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:filter_settings target="#pageInfo.entity#_ls">
|
||||
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.specification_item_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
|
||||
</m:filter_settings> --->
|
||||
<!--- <cfset pageInfo.settings.filter=#filter#/> --->
|
||||
|
||||
|
||||
<cfquery name="qRead" datasource="#request.DS#">
|
||||
<!--- select
|
||||
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
||||
<d:field title="Месяц" cfSqlType="CF_SQL_TIMESTAMP">m</d:field>
|
||||
<d:field title="Дата" cfSqlType="CF_SQL_TIMESTAMP">dt</d:field>
|
||||
<d:field title="Инсталл" cfSqlType="CF_SQL_NUMERIC">income_install</d:field>
|
||||
<d:field title="Инсталл" cfSqlType="CF_SQL_NUMERIC">inst1</d:field>
|
||||
<d:field title="Инсталл" cfSqlType="CF_SQL_NUMERIC">inst0</d:field>
|
||||
<d:field title="Ежемес" cfSqlType="CF_SQL_NUMERIC">income_recurring</d:field>
|
||||
<d:field title="Ежемес+" cfSqlType="CF_SQL_NUMERIC">rec1+rec0 as rec</d:field>
|
||||
<d:field title="Ежемес" cfSqlType="CF_SQL_NUMERIC">rec1</d:field>
|
||||
<d:field title="Ежемес" cfSqlType="CF_SQL_NUMERIC">rec0</d:field>
|
||||
<d:field title="Выручка" cfSqlType="CF_SQL_NUMERIC">income_install+income_recurring as income</d:field>
|
||||
<d:field title="cnt" cfSqlType="CF_SQL_NUMERIC">cnt</d:field>
|
||||
</d:field_set>
|
||||
from ( --->
|
||||
select
|
||||
--install
|
||||
DATE_TRUNC('month', dayscale.dt)::date as m
|
||||
,dayscale.dt::date
|
||||
,siv.price as price_i
|
||||
,siv.quantity as quantity_i
|
||||
,siv0.price as price0_i
|
||||
,siv0.quantity as quantity0_i
|
||||
,a.is_actual as is_actual_i
|
||||
,a.probability_perc as p_i
|
||||
,(100-COALESCE(a.probability_perc,0))/100 as p_i_rest
|
||||
,siv.specification_item_uid as si_uid_i
|
||||
,siv.agreement_version as av_i
|
||||
,siv0.specification_item_uid as si_uid0_i
|
||||
,siv0.agreement_version as av0_i
|
||||
,null as price_f
|
||||
,null as quantity_f
|
||||
,null as price0_f
|
||||
,null as quantity0_f
|
||||
,null as is_actual_f
|
||||
,null as p_f
|
||||
,null as p_f_rest
|
||||
,null as sum_f
|
||||
,null as dt_from_f
|
||||
,null as dt_to_f
|
||||
,null as dt_from0_f
|
||||
,null as dt_to0_f
|
||||
,null as si_uid_f
|
||||
,null as av_f
|
||||
,null as si_uid0_f
|
||||
,null as av0_f
|
||||
|
||||
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 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
|
||||
|
||||
union all
|
||||
|
||||
--fix and payg
|
||||
select
|
||||
DATE_TRUNC('month', dayscale.dt)::date as m
|
||||
,dayscale.dt::date
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,null
|
||||
,case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.price
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.quantity
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.price
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.quantity
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
,a.is_actual as is_actual_f
|
||||
,a.probability_perc as p_f
|
||||
,(100-COALESCE(a.probability_perc,0))/100 as p_f_rest
|
||||
|
||||
,case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.price/dayscale.days*siv.quantity*a.probability_perc/100
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
+
|
||||
COALESCE(case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv.price/dayscale.days*siv.quantity*(100- a.probability_perc)/100
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
,siv.dt_from
|
||||
,siv.dt_to
|
||||
,siv0.dt_from
|
||||
,siv0.dt_to
|
||||
,siv.specification_item_uid
|
||||
,siv.agreement_version
|
||||
,siv0.specification_item_uid
|
||||
,siv0.agreement_version
|
||||
|
||||
|
||||
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 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
|
||||
|
||||
order by dt
|
||||
|
||||
</cfquery>
|
||||
<!--- <cfdump var=#pageInfo.settings.filter#/> --->
|
||||
|
||||
|
||||
|
||||
|
||||
<!--- <cfquery name="qCountTotal" datasource="#request.DS#">
|
||||
select count(*) as cnt from specification_item where 1=1
|
||||
</cfquery> --->
|
||||
|
||||
</m:silent><!---
|
||||
-----------------------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------------------
|
||||
---><cfif isDefined("output_xls")>
|
||||
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
|
||||
<cfabort/>
|
||||
</cfif><cfif isDefined("output_json")>
|
||||
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
|
||||
<cfabort/>
|
||||
</cfif><!---
|
||||
---><layout:page section="header" pageInfo=#pageInfo#>
|
||||
|
||||
<layout:attribute name="title">
|
||||
<cfoutput><b>Выручка по дням 2023-01-01 .. 2029-12-31</b></cfoutput>
|
||||
</layout:attribute>
|
||||
<!--- <layout:attribute name="controls">
|
||||
skip filter link, filter is not implemented
|
||||
<layout:language_switch/>
|
||||
</layout:attribute> --->
|
||||
</layout:page>
|
||||
|
||||
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
|
||||
|
||||
<!--- <cfdump var=#qRead#/><cfabort/> --->
|
||||
|
||||
|
||||
<div style="display:inline-block; vertical-align:top;">
|
||||
<cfoutput><b>#qRead.recordCount#</b> записей</cfoutput>
|
||||
<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>
|
||||
<tr>
|
||||
<th>Дата</th>
|
||||
<!--- <th>Инсталл</th> --->
|
||||
<th>Инсталл рабочая</th>
|
||||
<th>Инсталл базовая</th>
|
||||
<!--- <th>Ежемес</th> --->
|
||||
<th>Ежемес рабочая</th>
|
||||
<th>Ежемес базовая</th>
|
||||
<th>Ежемес</th>
|
||||
<!--- <th>Выручка</th>
|
||||
<th>cnt</th> --->
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<cfoutput query="qRead" group="dt">
|
||||
<tr>
|
||||
<td class="c">#dateFormat(dt,"YYYY-MM-DD")#</td>
|
||||
<!--- <td class="r">#myNumFmt(income_install)#</td> --->
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid_i#&agreement_version=#av_i#&#tr.fwx#">
|
||||
#myNumFmt(price_i)#*#quantity_i#*#p_i#(#p_i_rest#)
|
||||
</a>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid0_i#&agreement_version=#av0_i#&#tr.fwx#">
|
||||
#myNumFmt(price0_i)#*#quantity0_i#
|
||||
</a>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid_f#&agreement_version=#av_f#&#tr.fwx#">
|
||||
#myNumFmt(price_f)#*#quantity_f#*#p_f#(#p_f_rest#)
|
||||
#dateFormat(dt_from_f,'YYYY-MM-DD')# - #dateFormat(dt_to_f,'YYYY-MM-DD')#
|
||||
</a>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="l">
|
||||
<cfoutput>
|
||||
<a href="specification_item_version.cfm?specification_item_uid=#si_uid0_f#&agreement_version=#av0_f#&#tr.fwx#">
|
||||
#myNumFmt(price0_f)#*#quantity0_f#
|
||||
#dateFormat(dt_from0_f,'YYYY-MM-DD')# - #dateFormat(dt_to0_f,'YYYY-MM-DD')#
|
||||
</a>
|
||||
</cfoutput>
|
||||
</td>
|
||||
<td class="r"><cfoutput>#myNumFmt(sum_f)#</cfoutput></td>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<cfabort/>
|
||||
|
||||
|
||||
<div style="display:inline-block; vertical-align:top;">
|
||||
|
||||
<cfquery dbtype="query" name="qMonthly">
|
||||
select m
|
||||
, sum(income_install) as income_install
|
||||
, sum(income_recurring) as income_recurring
|
||||
, sum(income) as income
|
||||
from qRead
|
||||
group by m
|
||||
order by m
|
||||
</cfquery>
|
||||
<br/>
|
||||
Суммировано по месяцам:
|
||||
<table class="worktable">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Месяц</th>
|
||||
<th>Инсталл</th>
|
||||
<th>Ежемес</th>
|
||||
<th>Выручка</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<cfoutput query="qMonthly">
|
||||
<tr>
|
||||
<td class="c">#dateFormat(m,"MM.YYYY")#</td>
|
||||
<td class="r">#myNumFmt(income_install)#</td>
|
||||
<td class="r">#myNumFmt(income_recurring)#</td>
|
||||
<td class="r">#myNumFmt(income)#</td>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</cfif>
|
||||
<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
|
||||
--->
|
@ -46,9 +46,9 @@ from (
|
||||
) as income_install
|
||||
,0 as income_recurring
|
||||
from
|
||||
(SELECT dd::date as dt FROM generate_series
|
||||
( '2023-01-01'::timestamp
|
||||
, '2029-12-31'::timestamp
|
||||
(SELECT dd::date as dt FROM generate_series (
|
||||
'#DAYSCALE_START#'::timestamp
|
||||
,'#DAYSCALE_FINISH#'::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))
|
||||
@ -81,14 +81,14 @@ from (
|
||||
select
|
||||
DATE_TRUNC('month', dayscale.dt)::date as m
|
||||
,0
|
||||
/*,sum(siv.price*siv.quantity*a.probability_perc/100/dayscale.days
|
||||
+ COALESCE(siv0.price*siv0.quantity*(100-a.probability_perc)/100/dayscale.days, 0)
|
||||
/*,sum(siv.price*siv.quantity*a.probability_perc/100/dayscale.monthdays
|
||||
+ COALESCE(siv0.price*siv0.quantity*(100-a.probability_perc)/100/dayscale.monthdays, 0)
|
||||
)*/
|
||||
,COALESCE(sum(
|
||||
<!--- ,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
|
||||
,0)/100/dayscale.monthdays
|
||||
/*до окончания свежей сделки она суммируется с прошлой актуальной по правилу вероятностей, считая вероятность актуальной за сделки за 1*/
|
||||
else 0 /*по окончании свежей сделки она дает нулевой вклад*/
|
||||
end
|
||||
@ -97,15 +97,30 @@ from (
|
||||
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
|
||||
,0))/100/dayscale.monthdays
|
||||
/*по окончании свежей сделки*/
|
||||
end
|
||||
),0)
|
||||
),0) --->
|
||||
,sum(
|
||||
COALESCE(case when (siv.dt_to > dayscale.dt OR siv.dt_to IS NULL) then
|
||||
siv.price*siv.quantity*(
|
||||
case when a.is_actual then 100 else a.probability_perc end
|
||||
)/100/dayscale.monthdays
|
||||
else 0 /*по окончании рабочей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
+
|
||||
COALESCE(case when (siv0.dt_to > dayscale.dt OR siv0.dt_to IS NULL) then
|
||||
siv0.price/dayscale.monthdays*siv0.quantity*(100- COALESCE(
|
||||
case when a.is_actual then 100 else a.probability_perc end
|
||||
,0))/100
|
||||
else 0 /*по окончании базовой сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
)
|
||||
from (SELECT dd::date as dt
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) days
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays
|
||||
FROM generate_series(
|
||||
'2023-01-01'::timestamp
|
||||
,'2029-12-31'::timestamp
|
||||
'#DAYSCALE_START#'::timestamp
|
||||
,'#DAYSCALE_FINISH#'::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)*/
|
||||
@ -196,12 +211,12 @@ select count(*) as cnt from specification_item where 1=1
|
||||
<cfoutput query="qRead">
|
||||
<tr>
|
||||
<td class="c">#dateFormat(m,"MM.YYYY")#</td>
|
||||
<td class="r">#myNumFmt(income_install)#</td>
|
||||
<td class="r">#myNumFmt(income_recurring)#</td>
|
||||
<td class="r">#myNumFmt(income)#</td>
|
||||
<td class="r">#myNumFmt(safeNum(income) - income_old)#</td>
|
||||
<td class="r"><cfif income_install NEQ 0>#myNumFmt(income_install)#</cfif></td>
|
||||
<td class="r"><cfif income_recurring NEQ 0>#myNumFmt(income_recurring)#</cfif></td>
|
||||
<td class="r"><cfif income NEQ 0>#myNumFmt(income)#</cfif></td>
|
||||
<td class="r"><cfif safeNum(income) - income_old NEQ 0>#myNumFmt(safeNum(income) - income_old)#</cfif></td>
|
||||
<cfset income_old = safeNum(income)/>
|
||||
<td class="r">#myNumFmt(income_recurring-income_recurring_old)#</td>
|
||||
<td class="r"><cfif income_recurring-income_recurring_old NEQ 0>#myNumFmt(income_recurring-income_recurring_old)#</cfif></td>
|
||||
<cfset income_recurring_old = safeNum(income_recurring)/>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
|
Loading…
Reference in New Issue
Block a user