spec/agreement.cfm
2025-06-09 07:08:56 +03:00

261 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#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"/>