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 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>
<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: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>
<!--- <a href="agreement.cfm?contract_id=&agreement_version=&#tr.fwx#"> не работает --->
<c:td field="f_link_view_edit" class="c"/>
</c:column>
<c:column width="2%" field="agreement_version"><c:td class="r"/></c:column>

View File

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

View File

@ -10,6 +10,11 @@
<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">
@ -87,10 +92,40 @@ from (
,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)
,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)
,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(*)
from (SELECT dd::date as dt
@ -100,32 +135,37 @@ from (
,'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))
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 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
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=si.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*/
))
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)
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 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
))
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)))
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#/>
group by dayscale.dt
) 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_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>
@ -192,13 +234,13 @@ select count(*) as cnt from specification_item where 1=1
<cfoutput query="qRead">
<tr>
<td class="c">#dateFormat(dt,"DD.MM.YYYY")#</td>
<td class="r">#income_install#</td>
<td class="r">#inst1#</td>
<td class="r">#inst0#</td>
<td class="r">#income_recurring#</td>
<td class="r">#rec1#</td>
<td class="r">#rec0#</td>
<td class="r">#income#</td>
<td class="r">#myNumFmt(income_install)#</td>
<td class="r">#myNumFmt(inst1)#</td>
<td class="r">#myNumFmt(inst0)#</td>
<td class="r">#myNumFmt(income_recurring)#</td>
<td class="r">#myNumFmt(rec1)#</td>
<td class="r">#myNumFmt(rec0)#</td>
<td class="r">#myNumFmt(income)#</td>
<td class="r">#cnt#</td>
</tr>
</cfoutput>
@ -233,9 +275,9 @@ select count(*) as cnt from specification_item where 1=1
<cfoutput query="qMonthly">
<tr>
<td class="c">#dateFormat(m,"MM.YYYY")#</td>
<td class="r">#nFmt(income_install)#</td>
<td class="r">#nFmt(income_recurring)#</td>
<td class="r">#nFmt(income)#</td>
<td class="r">#myNumFmt(income_install)#</td>
<td class="r">#myNumFmt(income_recurring)#</td>
<td class="r">#myNumFmt(income)#</td>
</tr>
</cfoutput>
</table>
@ -243,3 +285,72 @@ select count(*) as cnt from specification_item where 1=1
</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
--->

View File

@ -10,6 +10,17 @@
<cfreturn (a GT 0)? a : ""/>
</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:filter_settings target="#pageInfo.entity#_ls">
@ -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 <m:filter_build filter=#pageInfo.settings.filter#/>
group by DATE_TRUNC('month', dayscale.dt)
) 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_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>
@ -152,15 +187,22 @@ select count(*) as cnt from specification_item where 1=1
<th>Инсталл</th>
<th>Ежемес</th>
<th>Выручка</th>
<th>Прирост</th>
<th>Прирост ежемес</th>
</tr>
</thead>
<cfset income_old=0/>
<cfset income_recurring_old=0/>
<cfoutput query="qRead">
<tr>
<td class="c">#dateFormat(m,"MM.YYYY")#</td>
<td class="r">#nFmt(income_install)#</td>
<td class="r">#nFmt(income_recurring)#</td>
<td class="r">#nFmt(income)#</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>
<cfset income_old = safeNum(income)/>
<td class="r">#myNumFmt(income_recurring-income_recurring_old)#</td>
<cfset income_recurring_old = safeNum(income_recurring)/>
</tr>
</cfoutput>
</table>

View File

@ -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 @@
</p>
</cfoutput>
(количество, цена, даты актуальности, версия/соглашение, имя для печати - для последней актуальной версии)
<span class="err">Внимание! При расчетах вероятность действительной версии принимается за 100%</span>
<table class="worktable">
<thead>
<tr>
<th></th>
<th></th>
<th>Ключ строки</th>
<th>Код услуги</th>
<th>Услуга</th>
@ -255,7 +255,6 @@
<th>Тек. версия</th>
<th>Дата с</th>
<th>Дата по</th>
<th></th>
</tr>
</thead>

View File

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

View File

@ -22,10 +22,10 @@
select /*переделать выборку версий через group by*/
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<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.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="Дата соглашения">a.dt_specification_item</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 titleMap.f_link_view_edit={ordinal=#StructCount(titleMap)+1#}/><!--- *** Это легко забыть, потому что TitleMap никак не сцеплен с qRead. Напрашивается: упаковать их в одну обертку (но тогда обращение станет длиннее). Еще идея - назвать qRead и TitleMap так, чтобы была видна их связь. --->
<!--- <cfdump var=#titleMap#/> --->
<cfset queryAddColumn(qRead,'f_deal_uid')/>
<cfset titleMap.f_deal_uid=titleMap.deal_uid/>
<cfset queryAddColumn(qRead,'f_agreement_version')/>
<cfset titleMap.f_agreement_version=titleMap.agreement_version/>
<cfset queryAddColumn(qRead,'f_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">
<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 variable="qRead.f_deal_uid">
<a href="agreement.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#">#deal_uid#</a>
<cfsavecontent variable="qRead.f_agreement_version">
<a href="agreement.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#">#agreement# [#agreement_version#]</a>
</cfsavecontent>
<cfsavecontent variable="qRead.f_specification_item_uid">
<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:td field="f_link_view_edit" class="c"/>
</c:column>
<c:column width="8%" field="f_deal_uid"/>
<c:column width="7%" field="contragent"/>
<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="8%" field="f_specification_item_uid"/>
<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="3%" field="probability_perc"><c:td class="r"/></c:column>
<c:column width="7%" field="specification_item_version"/>
<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>