261 lines
13 KiB
Plaintext
261 lines
13 KiB
Plaintext
<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="plain2HtmClean">
|
||
<cfargument name="s" type="string"/>
|
||
<cfreturn request.plain2htm(request.cleanHtm(s))/>
|
||
</cffunction>
|
||
|
||
<cffunction name="cleanInput">
|
||
<cfargument name="s" type="string"/>
|
||
<cfreturn htmlEditFormat(s)/>
|
||
</cffunction>
|
||
|
||
<m:prepare_detail entity="agreement" key="undefined" pageInfoOut="pageInfo"/><!--- для составного ключа key бесполезен, но инициализировать пустой строкой не получается из-за cfparam name="#ATTRIBUTES.key#" default="-1" в prepare_detail --->
|
||
<cfparam name="contract_id" type="integer"/>
|
||
<cfquery name="qInitVersion"><!--- *** надо бы только при сохранении, а так возможен конфликт --->
|
||
select coalesce(max(agreement_version)+1,0) as next_version
|
||
from agreement
|
||
where contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#contract_id#"/>
|
||
</cfquery>
|
||
|
||
<d:bean readonly=#!pageInfo.writePermitted()# table="#pageInfo.entity#" datasource="#request.DS#" output="d" status="status">
|
||
<d:param field="contract_id" type="integer" key/><!--- поле с атрибутом key не участвует в update --->
|
||
<!--- формировать номер версии нам придется самостоятельно --->
|
||
<d:param field="agreement_version" type="integer" key init=#qInitVersion.next_version#/><!--- поле с атрибутом key не участвует в update --->
|
||
|
||
<d:param field="agreement" type="varchar" size="255" preprocessor=#cleanInput# init=#qInitVersion.next_version#/>
|
||
<d:param field="dt_agreement" type="timestamp" format="yyyy-MM-dd" init=#Now()#/>
|
||
<d:param field="is_actual" type="bit" init="0" default="0"/>
|
||
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
|
||
|
||
<d:param field="creator_id" type="integer" value="#request.usr_id#" skipUpdate/>
|
||
<d:param field="updater_id" type="integer" value="#request.usr_id#" />
|
||
<d:param field="dt_created" type="timestamp" value="#Now()#" skipUpdate/>
|
||
<d:param field="dt_updated" type="timestamp" value="#Now()#"/>
|
||
</d:bean>
|
||
|
||
<m:dispatch_detail
|
||
usePRG="No"<!---*** --->
|
||
pageInfo=#pageInfo#
|
||
id=""<!--- для составного ключа --->
|
||
queryString="contract_id=#d.contract_id#&agreement_version=#d.agreement_version#"
|
||
status=#pageInfo.status#
|
||
trackOut="tr"
|
||
idAttributesOut="id"
|
||
/>
|
||
|
||
<!--- decoration --->
|
||
<cfquery name="qDecoration" datasource="#request.DS#">
|
||
select
|
||
a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname
|
||
from agreement e
|
||
left outer join usr a on (e.creator_id=a.usr_id)
|
||
left outer join usr m on (e.updater_id=m.usr_id)
|
||
where e.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value=#d.contract_id# null=#!isValid('integer',d.contract_id)#/>
|
||
AND e.agreement_version=<cfqueryparam cfsqltype="cf_sql_integer" value=#d.agreement_version# null=#!isValid('integer',d.agreement_version)#/>
|
||
</cfquery>
|
||
|
||
<cfquery name="qContract" datasource="#request.DS#">
|
||
select d.contract_id, d.contract, d.dt_contract, c.contragent_id, c.contragent
|
||
from contract d
|
||
left outer join contragent c on (d.contragent_id=c.contragent_id)
|
||
where d.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contract_id#"/>
|
||
</cfquery>
|
||
|
||
</m:silent><!---
|
||
------------------------------------------------------------------------------------------------------------------------
|
||
------------------------------------------------------------------------------------------------------------------------
|
||
------------------------------------------------------------------------------------------------------------------------
|
||
------------------------------------------------------------------------------------------------------------------------
|
||
------------------------------------------------------------------------------------------------------------------------
|
||
---><layout:page section="header" pageInfo=#pageInfo#>
|
||
<layout:attribute name="title">
|
||
<cfoutput>
|
||
Соглашение
|
||
<cfif d.agreement_version GE 0>
|
||
<b>#d.agreement#</b>
|
||
[#d.agreement_version#]
|
||
</cfif>
|
||
</cfoutput>
|
||
</layout:attribute>
|
||
</layout:page>
|
||
|
||
<cfif status.errorState GT 0>
|
||
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
|
||
</cfif>
|
||
|
||
<cfoutput>
|
||
<input type="hidden" name="contract_id" value="#d.contract_id#"/>
|
||
<input type="hidden" name="agreement_version" value="#d.agreement_version#"/>
|
||
<input type="hidden" name="track" value="#tr.self#"/>
|
||
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
|
||
|
||
<div class="detail">
|
||
|
||
|
||
|
||
|
||
<div class="tr">
|
||
<div class="th">Договор</div>
|
||
<div class="td">
|
||
<a href="contract.cfm?contract_id=#d.contract_id#&#tr.fwx#">#qContract.contract# #dateFormat(qContract.dt_contract,'DD.MM.YYYY')#</a>
|
||
а как у нас поведет себя трек для составных ключей?
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tr">
|
||
<div class="th">Номер версии</div>
|
||
<div class="td">
|
||
#d.agreement_version# (некорректно, в одном месте версией называется номер, а в другом сущность, и это отразилось в именовании таблиц и полей)
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tr">
|
||
<div class="th">Соглашение (номер для печати)</div>
|
||
<div class="td">
|
||
<input type="text" name="agreement" value="#d.agreement#" size="15"/>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tr">
|
||
<div class="th">Дата соглашения</div>
|
||
<div class="td">
|
||
<input type="date" name="dt_agreement" id="dt_agreement" value="#dateFormat(d.dt_agreement,'YYYY-MM-DD')#"/>
|
||
<button type="button" onclick="document.getElementById('dt_agreement').value='#DateFormat(Now(), 'YYYY-MM-DD')#';">Сегодня</button>
|
||
<i>для упрощения можно позволить соглашению иметь обратную силу - то есть просто не проверять, что дата изменения строки спецификации не раньше даты соглашения</i>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tr">
|
||
<div class="th">Действует</div>
|
||
<div class="td">
|
||
<input type="checkbox" name="is_actual" value="1"<cfif d.is_actual GT 0> checked</cfif>/>
|
||
<i>если соглашение действует, это означает ровно то, что его правки учитываются при формировании спецификации на любую дату</i>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tr">
|
||
<div class="th">Описание</div>
|
||
<div class="td">
|
||
<textarea name="descr" rows="3" cols="100">#request.htm2plain(d.descr)#</textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tr">
|
||
<div class="th">Создано</div>
|
||
<div class="td">
|
||
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
|
||
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
|
||
|
||
Изменено
|
||
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
|
||
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
Соглашение просто объединяет правки строк спецификации в пакет и оформляет их документом (в случае с допником). То есть версии строк существуют не сами по себе, а связаны с конкретным соглашением. Между прочим, это означает, что в рамках одного доп. соглашения мы не можем сделать 2 изменения строки, например 2 разные цены с разных дат - нужно оформлять отдельными допниками.
|
||
Можно назвать нулевое соглашение базовым, а остальные дополнительными. (наверное, можно было бы синтезировать базовое соглашение с NULL номером, но NULL проблематично включить в первичный ключ, а любое специальное значение будет нарушать внешний ключ)
|
||
|
||
Дата соглашения не имеет никакого отношения к датам актуальности строк (это чисто формальное поле)
|
||
Предполагается, что даты актуальности строк согласованы с номерами версий (можно обнаруживать и репортить ошибки)
|
||
|
||
Поскольку соглашение не может дважды изменить строку спецификации, можно говорить о версии спецификации в соответствии с соглашением
|
||
|
||
Есть ли у нас понятие текущего соглашения?
|
||
Есть ли понятие действующего соглашения, или у нас все действуют, или строки из недействующего соглашения не должны участвовать в цепочке (тогда, видимо, не удастся активировать соглашение задним числом, цепочка может разрушиться)
|
||
Если к соглашению нет измененных строк спецификации, в нем нет большого смысла (но изменения строк надо к чему-то приписывать).
|
||
Надо было начать с моделирования данных в таблицах, до интерфейса?
|
||
</cfoutput>
|
||
|
||
<layout:page section="extension" closeForm="Yes"/>
|
||
|
||
<!--- для identity проверка существования записи простая, а тут как? В принципе, бин должен экспортировать флаг существования записи --->
|
||
<cfif d.agreement_version GE 0>
|
||
<cfquery name="qItem" datasource="#request.DS#">
|
||
select
|
||
iv.specification_item_uid
|
||
,iv.agreement_version /*лучше читается, когда все одинаково берется из резалтсета*/
|
||
,i.svc_id
|
||
,svc.svc
|
||
,svc.code
|
||
,iv.specification_item_version /*it is printable name not number*/
|
||
,iv.quantity
|
||
,iv.price
|
||
,iv.dt_from
|
||
,iv.dt_to
|
||
,i.specification_id
|
||
,s.specification
|
||
,s.contract_id
|
||
,d.contract
|
||
,d.dt_contract
|
||
,d.contragent_id
|
||
,k.contragent
|
||
from specification_item_version iv
|
||
join specification_item i on (iv.specification_item_uid=i.specification_item_uid)
|
||
join specification s on (i.specification_id=s.specification_id)
|
||
join contract d on (s.contract_id=d.contract_id)
|
||
join contragent k on (d.contragent_id=k.contragent_id)
|
||
left outer join svc on (i.svc_id=svc.svc_id)
|
||
where s.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contract_id#"/>
|
||
AND iv.agreement_version=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.agreement_version#"/>
|
||
order by i.specification_id
|
||
</cfquery>
|
||
|
||
<cfoutput>
|
||
<p>
|
||
Строки спецификаций (#qItem.recordCount#)
|
||
</p>
|
||
</cfoutput>
|
||
<table class="worktable">
|
||
<thead>
|
||
<tr>
|
||
<th></th>
|
||
<th>Стабильный ключ строки</th>
|
||
<th>Услуга</th>
|
||
<th>Код услуги</th>
|
||
<th>Имя для печати</th>
|
||
<th>Дата с</th>
|
||
<th>Дата по</th>
|
||
<th>Кол-во</th>
|
||
<th>Цена</th>
|
||
<th>Спецификация</th>
|
||
<th>Договор</th>
|
||
<th>Контрагент</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<cfoutput query="qItem">
|
||
<tr>
|
||
<td>
|
||
<a href="specification_item_version.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#agreement_version#&#tr.fwx#" class=<cfif pageInfo.writePermitted()>"edit"<cfelse>"view"</cfif>></a>
|
||
</td>
|
||
<td>#specification_item_uid#</td>
|
||
<td>#svc#</td>
|
||
<td>#code#</td>
|
||
<td>#specification_item_version#</td>
|
||
<td>#dateFormat(dt_from,'DD.MM.YYYY')#</td>
|
||
<td>#dateFormat(dt_to,'DD.MM.YYYY')#</td>
|
||
<td>#quantity#</td>
|
||
<td>#price#</td>
|
||
<td><a href="specification.cfm?specification_id=#specification_id#&#tr.fwx#">#specification#</a></td>
|
||
<td>#contract# #dateFormat(dt_contract,'DD.MM.YYYY')#</td>
|
||
<td>#contragent#</td>
|
||
<td class="c">
|
||
<cfif pageInfo.writePermitted()>
|
||
<a href="specification_item_version_del.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#agreement_version#&#tr.fwx#" class="del"></a>
|
||
</cfif>
|
||
</td>
|
||
</tr>
|
||
</cfoutput>
|
||
</table>
|
||
|
||
</cfif>
|
||
|
||
|
||
<layout:page section="footer"/>
|