spec/specification_item_param.cfm
2025-06-02 16:16:51 +03:00

351 lines
18 KiB
Plaintext
Raw Permalink 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="specification_item_param" key="specification_item_param_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="#pageInfo.entity#" datasource="#request.DS#" output="d" status="status">
<d:param field="specification_item_param_id" type="integer" key autoincrement/>
<d:param field="specification_item_id" type="integer" required/>
<d:param field="service_param_id" type="integer" required/> <!---если там конкретизирован param_id, брать его оттуда--->
<d:param field="quantity" type="numeric" forNull=""/>
<d:param field="price" type="numeric" forNull=""/>
<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>
<!--- <cfdump var=#d#/> --->
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.specification_item_param_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- *** Тут прошла пренеприятнейшая коллизия между параметром, определенным для абстрактной и конкретной услуг.
И вынос разрешения этой неопределенности из селектов в код только добавил путаницы --->
<!---Компонент и вариант компонента по версии service_param, то есть шаблона --->
<cfquery name="qServiceParam" datasource="#request.DS#">
select sp.param_id, sp.service_id, sp.service_param_id, ac.param_class_id
,p.param, p.param_short, p.precision, spp.min_price, c.param_class, u.measure_short
,g.area_code, a.code as abstract_service_code, m.code as modifier_code, p.code as param_code
from service_param sp
left outer join service s on (sp.service_id=s.service_id)
left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id)
left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id)
left outer join area g on a.area_id=g.area_id
left outer join modifier m on (s.modifier_id=m.modifier_id)
left outer join param p on (sp.param_id=p.param_id)
left outer join measure u on (p.measure_id=u.measure_id)
left outer join param_class c on (ac.param_class_id=c.param_class_id)
left outer join service_param_price spp on (sp.service_param_id=spp.service_param_id)
where sp.service_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.service_param_id#" null=#!isNumeric(d.service_param_id)#/>
</cfquery>
<!---*** к размышлению: обе таблицы смотрят на service разными путями, возможно ли противоречие? есть ли в этом избыточность? можно ли ее устранить?--->
<cfquery name="qSpecificationItem" datasource="#request.DS#">
select f.specification_id, f.specification,
a.code as abstract_service_code, a.abstract_service_id, a.abstract_service,
s.service_id,
m.modifier_id, m.modifier, m.code as modifier_code
from specification_item si
left outer join service s on (si.service_id=s.service_id)
left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id)
left outer join specification f on (si.specification_id=f.specification_id)
left outer join modifier m on (s.modifier_id=m.modifier_id)
where si.specification_item_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.specification_item_id#" null=#!isNumeric(d.specification_item_id)#/>
</cfquery>
<!---
попробуем построить корректный запрос с наследованием
Всегда более конкретный атрибут имеет приоритет перед более абстрактным. Возможна ли неоднозначность? Например, единицу измерения брать из компонента (класса) в варианте (реализации) услуги или варианта компонента в шаблоне? Кажется, что компонент всегда имеет приоритет перед классом (классом), а где они используются - это второй вопрос. Делу может помочь построение вью, реализующих полиморфизм, так, чтобы в коде об этом не думать.--->
<!---в данном случае компонент (класс) задается неоднозначно - либо из service_param, либо из компонента
Аналогично, сам вариант компонента может быть задан в шаблоне, а может быть конкретизирован в экземпляре услуги--->
<!---Результат: при обновлении шаблона часть полей экземпляра поменяется, а часть нет, по неочевидному правилу--->
<!---*** компонент используется как шаблон и еще как-то?--->
<cfquery name="qDecoration" datasource="#request.DS#">
select sp.param_id, c.param_class, p.param, p.param_short, p.precision,
spp.min_price, spp.service_param_price_id,
a.code as abstract_service_code, a.abstract_service, m.modifier, n.specification,
g.area_code,
m.code as modifier_code, p.code as param_code
,au.login as creator, au.shortname as creator_shortname, mu.login as updater, mu.shortname as updater_shortname
from specification_item_param sip
left outer join service_param sp on (sip.service_param_id=sp.service_param_id)
left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id)
-- варианты
-- вариант компонента задан в шаблоне, тогда он не должен быть задан в экземпляре, и в шаблоне не должен быть задан класс (компонент)
-- в шалоне задан компонент, тогда в экземпляре должен быть задан его вариант
-- запрещенные комбинации:
-- в шаблоне задан класс, но в экземпляре не задан вариант компонента
-- в шаблоне задан класс, но в экземпляре задан член другого класса
-- в шаблоне задан вариант компонента (не задан класс, это контролируется ограничением), но в экземпляре тоже задан компонент
-- ...
left outer join param p on (sp.param_id=p.param_id) -- *** выглядит неэффективно. Также создаст ошибку при -1 в sip.param_id
left outer join param_class c on (ac.param_class_id=c.param_class_id) -- это конкретная запись экземпляра,
-- поэтому вариант компонента всегда известен, и класс берем от него,
-- не нужно задумываться, какой класс определен в шаблоне
left outer join service_param_price spp on /***/
(sp.service_param_id=spp.service_param_id) -- параллельные сущности со specification_item_param
left outer join service s on (sp.service_id=s.service_id)
left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id)
left outer join area g on (a.area_id=g.area_id)
left outer join specification_item si on (sip.specification_item_id=si.specification_item_id)
left outer join specification n on (si.specification_id=n.specification_id)
left outer join modifier m on (s.modifier_id=m.modifier_id)
left outer join usr au on (sip.creator_id=au.usr_id)
left outer join usr mu on (sip.updater_id=mu.usr_id)
where sip.specification_item_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.specification_item_param_id#" null=#!isNumeric(d.specification_item_param_id)#/>
</cfquery><!--- <cfdump var=#d#/><cfdump var=#qServiceParam#/> --->
<!---
<cfdump var=#qSpecificationItem#/>
<cfdump var=#qDecoration#/> --->
<!---
шаблон: класс шаблон: компонент экземпляр:компонент разрешено
0 0 0 0
0 0 1 0
0 1 0 1
0 1 1 0
1 0 0 0
1 0 1 1
1 1 0 0
1 1 1 0
оказывается, есть всего 2 разрешенные комбинации из 8
--->
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Вариант компонента <b>#qDecoration.param_class#/#qDecoration.param#</b>
экземпляра услуги
<b>
#qDecoration.abstract_service_code# #qDecoration.abstract_service#
<cfif len(qDecoration.modifier)> / #qDecoration.modifier#</cfif>
</b>
<b>(#qDecoration.specification#)</b>
<cfif d.specification_item_param_id GT 0>
<!---<b>#d.specification_item_param#</b>--->
[#d.specification_item_param_id#]
</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="specification_item_param_id" value="#d.specification_item_param_id#"/>
<input type="hidden" name="specification_item_id" value="#d.specification_item_id#"/>
<input type="hidden" name="service_param_id" value="#d.service_param_id#"/>
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<!--- <cfset m_param = ""/>--->
<cfset m_measure = ""/>
<cfset m_price = #d.price#/>
<!--- <cfdump var=#qServiceParam#/>
<cfdump var=#qDecoration#/>--->
<cfif !isNumeric(d.price)>
<cfset m_price = #qServiceParam.min_price#/>
</cfif>***
<!---<cfdump var=#qServiceParam#/>--->
<div class="tr">
<div class="th">Спецификация</div>
<div class="td">
<a href="specification.cfm?specification_id=#qSpecificationItem.specification_id#&#tr.fwx#">
#qSpecificationItem.specification#
</a>
</div>
</div>
<div class="tr">
<div class="th">Услуга</div>
<div class="td">
<a href="abstract_service.cfm?abstract_service_id=#qSpecificationItem.abstract_service_id#&#tr.fwx#">
#qSpecificationItem.abstract_service_code#
</a>
&nbsp;&nbsp;&nbsp;
<a href="service.cfm?service_id=#qSpecificationItem.service_id#&#tr.fwx#">
#qSpecificationItem.abstract_service#/#qSpecificationItem.modifier#
</a>
</div>
</div>
<!--- Как только мы имеем возможность взять поле более чем из одной сущности, начинается ад--->
<div class="tr">
<div class="th">Компонент</div>
<div class="td">
<cfif qServiceParam.param_class_id GT 0>
<a href="param_class.cfm?param_class_id=#qServiceParam.param_class_id#&#tr.fwx#">#qServiceParam.param_class#</a>
(
<a href="service_param.cfm?service_param_id=#d.service_param_id#&#tr.fwx#">шаблон</a>
в определении услуги <a href="service.cfm?service_id=#qSpecificationItem.service_id#&#tr.fwx#">#qSpecificationItem.abstract_service_code# #qSpecificationItem.abstract_service# / #qSpecificationItem.modifier#</a>
)
<cfelse>
#qDecoration.param_class#
</cfif>
</div>
</div>
<div class="tr">
<div class="th">Вариант компонента</div>
<div class="td">
<cfif qServiceParam.param_id GT 0>
<a href="param.cfm?param_id=#qServiceParam.param_id#&#tr.fwx#">
#qServiceParam.param# (#qServiceParam.param_short#)
</a>
<a href="service_param.cfm?service_param_id=#qServiceParam.service_param_id#&#tr.fwx#">
#request.skuCode(qServiceParam.area_code,qServiceParam.abstract_service_code,qServiceParam.modifier_code,qServiceParam.param_code)#
</a>
<cfelse>
#qDecoration.param# (#qDecoration.param_short#)
</cfif>
</div>
</div>
<!--- <div class="tr">
<div class="th" style="width:10%">Вариант компонента</div>
<div class="td">
<!---
Если в service_param фиксирован param_id, нужно просто его взять оттуда (нередактируемый), (param_id не заполнять)
Если там фиксирован класс, нужно предоставить вариант компонента на выбор
Единица измерения берется из варианта компонента
--->
<cfif qServiceParam.param_id GT 0>***
<!---*******************************************************************************--->
<cfquery name="qParam" datasource="#request.DS#">
select p.param, p.precision, m.measure_short
from param p
left outer join param_class c on (p.param_class_id=c.param_class_id)
left outer join measure m on (coalesce(p.measure_id,c.measure_id)=m.measure_id)
where p.param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#qServiceParam.param_id#"/>
</cfquery>
<!---<cfdump var=#qParam#/>--->
#qParam.param#
<cfset m_measure = #qParam.measure_short#/>
<!---#qParam.measure_short#--->
<cfelse> +++
<cfquery name="qParamList" datasource="#request.DS#">
select p.param_id, p.param, c.param_class, m.measure_short
from param p
join param_class c on (p.param_class_id=c.param_class_id)
left outer join measure m on (coalesce(p.measure_id, c.measure_id)=m.measure_id)
where p.param_class_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#qServiceParam.param_class_id#"/>
order by 3,2
</cfquery>
<c:combo
query=#qParamList#
combo="param_id"
id="param_id"
key="param_id"
selected="#d.param_id#"
displayf="##param## ##measure_short##"
empty=""
class=""
onchange="document.getElementById('price').value=''; submit();"
/>
</cfif>
<!--- <cfdump var=#qServiceParam#/>
<cfdump var=#d#/>--->
<cfif d.param_id GT 0>
<a href="param.cfm?param_id=#d.param_id#&#tr.fwx#">
<img src="img/edit.gif"/>
</a> здесь выбирается вариант компонента. Если вариантов нет, создавать единственный вариант не нужно
</cfif>
<cfif qServiceParam.param_id GT 0>
<a href="param.cfm?param_id=#qServiceParam.param_id#&#tr.fwx#">
<img src="img/edit.gif"/>
</a>
<a href="service.cfm?service_id=#qServiceParam.service_id#&#tr.fwx#">(из шаблона - варианта услуги)</a>
</cfif>
</div>
</div> --->
<div class="tr">
<div class="th">Количество</div>
<div class="td">
<input type="text" name="quantity" value="#d.quantity#" size="5"/> <!--- #m_measure# ---> <!---*** <cftry>#round(d.quantity,qDecoration.precision)#<cfcatch type="ANY"></cfcatch></cftry> --->
#qServiceParam.measure_short#
<i>(для оплаты по потреблению заполняется при биллинге)</i>
</div>
</div>
<div class="tr">
<div class="th">Цена без НДС</div>
<div class="td">
<input type="text" name="price" id="price" value="#m_price#" size="10"/> ₽
&nbsp;
&nbsp;
&nbsp;
<a href="service_param_price.cfm?service_param_price_id=#qDecoration.service_param_price_id#&service_param_id=#d.service_param_id#&param_id=#qServiceParam.param_id#&#tr.fwx#">
Базовая цена без НДС:
</a>
<cfif isNumeric(qDecoration.min_price)>#qDecoration.min_price# ₽<cfelse>не задана</cfif>
<!--- *** неуклюже (сбор ИД с невнятных запросов), но не хочется разбираться --->
</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>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<layout:page section="footer"/>