Дерево страниц
Skip to end of metadata
Go to start of metadata

Постановка задачи

Создать два поля на форме РКК:

  • Организация. Выбор внешней организации
  • Документ из системы. Выбор договора в зависимости от значения в поле "Организация". Выбранный договор/доп. соглашение должен открываться по ссылке
Инструмент: Палитра XML
Статус

ГОТОВО

РазделДействия
Комментарий

Реализация

<Сопроводительная информация>


Поле организации

В схему, по которой открывается основная форма, добавить свойство "organization" 

<actor name="organization">
	<storage-field name="organization"/>
</actor>

Поле с гиперссылкой на объект

Создание объекта

Схема объекта

Создать схему, которая будет описывать объект. Обязательные св-ва:

  • tnUnid - идентификатор объекта
  • tnName - информация об объекте

schema name="documentLink"
<schemas xmlns="http://www.intertrust.ru/schema/palette/tn-schema">
  <schema name="documentLink">
    <string name="tnUnid" temporal = "true"/>
    <string name="tnName" temporal = "true"/>
  </schema>
</schemas>

Отображение объекта

Форма используется, если выбранное значение записывается в поле, в данном примере это не понадобится

Создать форму для отображения объекта

form id="documentLinkForm"
<?xml version='1.0' encoding='UTF-8'?>
<ui xmlns="http://www.intertrust.ru/schema/palette/tn-ui">
  <form schema-ref="documentLink" id="documentLinkForm" projection="default">
    <properties>
      <hide condition-union="AND">
        <negative-condition-ref ref="digest"/>
      </hide>
    </properties>
    <component>
      <field attribute-ref="tnName">
        <properties>
          <read-only condition-union="AND">
            <condition>true</condition>
          </read-only>
        </properties>
        <appearance importance="normal"/>
      </field>
    </component>
  </form>
</ui>

Создание схемы объекта на форме/диалоге

Создать схему, которая будет описывать объект на форме/диалоге. Обязательные св-ва:

  • orgName - краткое название организации, полученное из документа
  • document - информация об объекте
  • id - идентификатор объекта
  • description - описание объекта. Пример: Договор поставки №34 от 11.12.2023
  • Link - ссылка на объект

schema name="CMDocumentByOrg"
<?xml version='1.0' encoding='UTF-8'?>
<schemas xmlns="http://www.intertrust.ru/schema/palette/tn-schema">
	<schema name="CMDocumentByOrg">
		<!-- Краткое название организации выбранной организации -->
		<string name="orgName" computed="true">
			<storage-field name="CMDocumentOrgName" />
			<calc-values>
				<script event="open" lang="SPEL">
					<![CDATA[!#isObjectContains(#parentnode, 'organization')? null:#parentnode.organization== null ? null:#parentnode.organization.getOrganizationName()]]>
				</script>
			</calc-values>
		</string>

		<schema-ref name="document" ref="documentLink" temporal="true"/>

		<string name="id">
			<storage-field name="CMDocumentID"/>
		</string>

		<string name="description">
			<storage-field name="CMDocumentDescription"/>
		</string>

		<hyperlink computed="true"name="Link">
			<storage-field name="CMDocumentLink"/>
			<calc-values>
				<script lang="SPEL" event="open">
					<![CDATA[id == null ? null : T(ru.intertrust.cmj.af.misc.HyperLink).createHyperLink(description + '~#' + T(ru.intertrust.cmj.ws.base.servlet.ServletUrlHolder).getServerUrlStr() + '/ids/' + id +'~#newTab~#local')]]>
				</script>
			</calc-values>
		</hyperlink>
	</schema>
</schemas>

Подключение поля

В схему, по которой открывается основная форма, добавить объектное свойство

<schema-ref name="CMDocumentBase" ref="CMDocumentByOrg"/>

Создание объектных справочников

Создание кастомной коллекции

Создать коллекцию, которая отберет объекты. Среди получаемых колонок обязательно указать:

  • id - идентификатор объекта
  • Module - идентификатор модуля объекта
  • orgName - краткое наименование организации
  • self_1 -  открывающий тег "<id>" для дальнейшего использования в формированиии ссылки на объект в бине
  • self_2 -  тип разделителя ":" для дальнейшего использования в формированиии ссылки на объект в бине
  • self_3 -  закрыващий тег "</>" для дальнейшего использования в формированиии ссылки на объект в бине
  • tag_tnunid - открывающий тег "<tnUnid>" для дальнейшего использования в формированиии ссылки на объект в бине

collection name="ContractsLite_(active)"
<collection name="ContractsLite_(active)" idField="id" replace="runtime">
    <prototype>
        <![CDATA[SELECT id,
						created_date,
						Module,
						'<id>' 	   as self_1,
						':'		   as self_2,
						'</>'	   as self_3,
						'<tnUnid>' as tag_tnunid,
					 	orgName,       
						regNumber,
						subject	
						FROM ... WHERE 1 = 1 ::where-clause]]>
    </prototype>
    <counting-prototype>
        <![CDATA[SELECT COUNT(*) FROM (SELECT ... FROM ...) s WHERE 1 = 1 ::where-clause]]>
    </counting-prototype>
    <filter name="MODULE">
        <criteria placeholder="where-clause">
            <![CDATA[
                    Module = {0}
                ]]>
        </criteria>
    </filter>
    <filter name="self">
        <criteria placeholder="where-clause">
            <![CDATA[
                    Module = {0} and id = {1}
                ]]>
        </criteria>
    </filter>
</collection> 

Создание бина кастомной коллекции

Создать бин коллекции, в котором описать возвращаемые поля:

  • objectLink - формирование ссылки на объект
  • orgName - краткое наименование организации, с указанием сортировки

ContractsLite_(active)Metadata
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
       default-lazy-init="true">

    <bean id="ContractsLite_(active)Metadata"
          class="ru.intertrust.cm_sochi.srv.connector.sochi.collections.CollectionMetadataNew"
          p:caseSensitiveFieldNames="true" p:searchArea="ContractsLite_uicoll">
        <constructor-arg>
            <list value-type="ru.intertrust.cm_sochi.srv.connector.sochi.collections.Field">
                <bean class="ru.intertrust.cm_sochi.srv.connector.sochi.collections.Field" p:name="self">
                    <property name="virtualField">
                        <bean class="ru.intertrust.cm_sochi.srv.connector.sochi.collections.BuildVirtualField">
                            <property name="realFields">
                                <list>
                                    <value>self_1</value>
                                    <value>Module</value>
                                    <value>self_2</value>
                                    <value>id</value>
                                    <value>created_date</value>
                                    <value>self_3</value>
                                </list>
                            </property>
                            <property name="pattern" value="<id>([0-9]{16}):([0-9A-F]{32})</>"/>
                            <property name="separator" value=""/>
                            <property name="emptySeparator" value="true"/>
                        </bean>
                    </property>
                </bean>
				<!-- Описание объекта -->
                <bean class="ru.intertrust.cm_sochi.srv.connector.sochi.collections.Field" p:name="objectLink">
                    <property name="virtualField">
                        <bean class="ru.intertrust.cm_sochi.srv.connector.sochi.collections.BuildVirtualField">
                            <property name="realFields">
                                <list>
                                    <value>tag_tnunid</value>
                                    <value>Module</value>
                                    <value>self_2</value>
                                    <value>id</value>
                                    <value>created_date</value>
                                    <value>self_3</value>

                                    <value>self_1</value>
                                    <value>Module</value>
                                    <value>self_2</value>
                                    <value>id</value>
                                    <value>created_date</value>
                                    <value>self_3</value>
                                </list>
                            </property>
                            <property name="separator" value=""/>
                            <property name="emptySeparator" value="true"/>
                        </bean>
                    </property>
                </bean>
			    <!-- Сортировка по краткому названию организации -->	
                <bean class="ru.intertrust.cm_sochi.srv.connector.sochi.collections.Field" p:name="orgName" p:sortOrder="ASCENDING"/>
            </list>
        </constructor-arg>
    </bean>
</beans>

Создание типа элемента коллекции

Создать тип элемента коллекции "tnUnid" с аналогичным названием тега в бине и комплексный тип элемента коллекции "objectLink" с аналогичным названием поля в бине.

<?xml version='1.0' encoding='UTF-8'?>
<catalog xmlns="http://www.intertrust.ru/schema/palette/cat-ui">
 	<column name="tnUnid" extends="string"/>
    <complex-column name="objectLink" extends="object">
        <column-ref ref="tnUnid"/>
    </complex-column>
</catalog> 

Создание дескриптора

Создать дескриптор, с подключением к кастомной коллекции. Название колонок аналогично полям бина и колонкам кастомной коллекции.

custom-descriptor id="dp-example-contracts-active-by-org"
<?xml version='1.0' encoding='UTF-8'?>
<catalog xmlns="http://www.intertrust.ru/schema/palette/cat-ui">
    <custom-descriptor ident="ContractsLite" view="(active)" id="contracts-active-by-org" name="Договоры - Действующие" style="default">
        <builder name="ru.intertrust.cm_sochi.srv.uicollections.UiBuilder"/>
        <table>
            <columns>
                <column-ref ref="self"/>
                <column-ref ref="objectLink"/>
                <column-ref ref="orgName" filter="true" sort-asc="true" sort-desc="true" category="true"/>
                <column-ref ref="regNumber" filter="true" sort-asc="true" sort-desc="true"/>
                <column-ref ref="subject" filter="true" sort-asc="true" sort-desc="true"/>
            </columns>
        </table>
    </custom-descriptor>
</catalog>

Создание программной коллекции

Создать программную коллекцию и подключить дескриптор.

view id="contracts-active-by-org"
<?xml version='1.0' encoding='UTF-8'?>
<catalog xmlns="http://www.intertrust.ru/schema/palette/cat-ui">
	<view parent-ref="ProgrammedNavigator" id="contracts-active-by-org" name="${catalog.view.contracts-active-by-org.name:Договоры - Действующие}" position="10015">
		<descriptor-ref ref="contracts-active-by-org"/>
		<source>
			<module ident="ContractsLite"/>
		</source>
	</view>
</catalog>

Создание справочника

Создать справочник Произвольная коллекция и подключить программную коллекцию.

<?xml version='1.0' encoding='UTF-8'?>
<ui xmlns="http://www.intertrust.ru/schema/palette/tn-ui">
	<directories>
		<custom-collection name="${ui.directories.custom-collection.contracts-active-by-org.name:Договоры}" id="dirContractsActiveByOrg">
			<view-ref ref="contracts-active-by-org"/>
		</custom-collection>
	</directories>
</ui> 


Диалог выбора объекта

Создание схемы диалога выбора объекта

Создать схему наследник с "Dialog", которая будет описывать диалог выбора объекта

  • CMDocumentBase - объектное поле 
  • orgName - краткое название организации, полученное из объекта

schema name="CMDocumentByOrgDialog"
<?xml version='1.0' encoding='UTF-8'?>
<schemas xmlns="http://www.intertrust.ru/schema/palette/tn-schema">
	<schema name="CMDocumentByOrgDialog" extends="Dialog" recalc="true">
		<schema-ref name="CMDocumentBase" ref="CMDocumentByOrg"/>
		<string name="orgName" computed="true" temporal="true">
			<calc-values>
				<script event="open" lang="SPEL">
					<![CDATA[#this.CMDocumentBase==null?'':#this.CMDocumentBase.orgName]]>
				</script>
			</calc-values>
		</string>
	</schema>
</schemas>

Форма диалога выбора объекта

Создать форму на базе схемы диалога выбора объекта.

Подключить справочник "Выбор из кастомной коллекции по ключу", в качестве ключа указать OrgName

form id="CMDocumentByOrgDialogUI"
<?xml version='1.0' encoding='UTF-8'?>
<ui xmlns="http://www.intertrust.ru/schema/palette/tn-ui">
    <form schema-ref="CMDocumentByOrgDialog" id="CMDocumentByOrgDialogUI" name="${ui.form.CMDocumentByOrgDialogUI.name:Выбор документа}" projection="default">
        <appearance>
            <dialog-mode width="50" unit="percent"/>
        </appearance>
        <properties>
            <hide condition-union="AND">
                <negative-condition-ref ref="dialog"/>
            </hide>
        </properties>
        <component>
            <field attribute-ref="CMDocumentBase.orgName" recalc="true">
                <properties>
                    <hide>
                        <condition>true</condition>
                    </hide>
                </properties>
            </field>
            <field attribute-ref="CMDocumentBase.document">
               <appearance open-mode="grid" digest-mode="grid" importance="normal" widget="grid"/>
                <directories>
                    <directory-category-custom-coll ref="dirContractsActiveByOrg" attribute-ref="orgName"/>
                </directories>
            </field>
            <button name="${ui.form.CMDocumentByOrgDialogUI.submit:Подтвердить}">
                <action>
                    <system name="submit"/>
                </action>
            </button>
        </component>
    </form>
</ui>


UI-интерфейс

Подключение к форме

На форме создать группу полей:

  • объектное поле CMDocumentBase
  • кнопка с действием change-subobject и указанной схемой с параметрами "CMDocumentByOrgDialog"
  • скрытое поле, указывающее на свойство "CMDocumentBase.orgName". В нём указывается recalc.

section
... <section id="select_cm_document_by_org" group="true">
	<appearance field-layout="horizontal"/>
	<component>
		<section id="select_cm_document_by_org_left" group="true">
			<appearance field-layout="horizontal">
				<dialog-mode width="49" unit="percent"/>
			</appearance>
			<component>
				<field attribute-ref="organization" name="${ui.form.organization.name:Организация:}" recalc="true">
					<directories>
						<directory-ref ref="FOREIGN_ORGS"/>
					</directories>
					<appearance>
						<label-style>
							<style id="tunBorderedField"/>
						</label-style>
					</appearance>
				</field>
			</component>
		</section>
		<section id="select_cm_document_by_org_center" group="true">
			<component>
				<field attribute-ref="empty">
					<appearance>
						<label-style field-unit="symbol" field-width="2"/>
					</appearance>
				</field>
			</component>
		</section>
		<section id="select_cm_document_by_org_right" group="true">
			<appearance field-layout="horizontal"/>
			<component>
				<field attribute-ref="CMDocumentBase.Link" alias="CMDocumentBase.description" name="${ui.form.CMDocumentBase.name:Договор:}">
					<appearance importance="normal" multiline="false" open-form="newTab">
						<limit height="1" max-size="1" max-height-scroll="1"/>
						<label-style label-unit="symbol" label-width="10">
							<style id="tunBorderedField"/>
						</label-style>
					</appearance>
				</field>
				<section id="select_cm_document_button" group="true">
					<properties>
						<hide>
							<condition-ref ref="read"/>
						</hide>
					</properties>
					<component>
						<button name="${ui.form.button.CMDocumentByOrgDialog.name:+}">
							<appearance>
								<label-style>
									<style id="tunBtn"/>
								</label-style>
							</appearance>
							<action>
								<custom>
									<change-subobject schema-ref="CMDocumentByOrgDialog"/>
								</custom>
							</action>
						</button>
					</component>
				</section>
				<field attribute-ref="CMDocumentBase.orgName" recalc="true">
					<properties>
						<hide>
							<condition>true</condition>
						</hide>
					</properties>
				</field>
			</component>
		</section>
	</component>
</section>
 ...

Доработка обработчика событий

При нажатии на кнопку будет показан диалог с отфильтрованными документами по названию организации.

После выбора отправится запрос на обновление, который надо обработать в custom-event-handler.

custom-event-handler
importClass(Packages.ru.intertrust.cmj.af.misc.AFDate);
importClass(Packages.ru.intertrust.cmj.rest.tuning.TuningHelper);
importClass(Packages.ru.intertrust.cmj.tunable.object.common.TunableObjectHelper);
importClass(Packages.ru.intertrust.cmj.tunable.object.history.TunableHistoryHelper);
importClass(Packages.ru.intertrust.cmj.af.core.AFCMDomino);
importClass(Packages.ru.intertrust.cmj.af.core.AFSession);
importClass(Packages.ru.intertrust.cmj.af.utils.BeansUtils);
importClass(Packages.ru.intertrust.cmj.af.utils.Utils);
importClass(Packages.ru.intertrust.cmj.af.misc.HyperLink);
importClass(Packages.ru.intertrust.cmj.dp.DPApplication);
importClass(Packages.ru.intertrust.cmj.af.tuning.impl.AFInstanceSimpleImpl);
importClass(Packages.ru.intertrust.cmj.af.tuning.impl.AFInstanceObjectImpl);
importClass(Packages.ru.intertrust.cmj.af.tuning.impl.AFInstanceArrayImpl);
importClass(Packages.ru.intertrust.cmj.af.tuning.TuningApplication);
importClass(Packages.ru.intertrust.cmj.dp.DPMContracts);
importPackage(Packages.java.util);
importPackage(Packages.java.lang);
importClass(Packages.java.util.List);
importClass(Packages.java.util.Arrays);

function recalc(object, changedField) {
	var appdp = AFSession.get().getApplication(DPApplication.class);
  	
  	/*Заполнение объектного поля из диалога выбора документа*/
	if (changedField == 'CMDocumentBase.orgName') {

		var documentByOrgLink = values.get("CMDocumentBase");
		var document = documentByOrgLink.getValues().get("document");

        if (document != null) {
            var documentUnid = null;
		    if (document.getValues().get("tnUnid") != null) {
			    documentUnid = document.getValues().get("tnUnid").getValue();
		    }

            var rkk = appdp.getEntityByUNID(documentUnid);
			fillCMDocumentBase(object, rkk);
		}
	}
  	/*...*/
}

/*Заполнение объектного поля*/
function fillCMDocumentBase(object, rkk) {
	var values = object.tuning().getValues();
	var documentID = rkk.getUNID();
	var regNumber = getRegNumber(object);
	var reqType = document.getType();
	var regDate = rkk.registration().getDate();
	var regDateStr = AFDate.fromJavaDate(regDate).toString();
	var description = reqType + " №" + regNumber + " от " + regDateStr;
	TunableObjectHelper.putAFInstanceValue(object.tuning(), "CMDocumentBase.id", documentID);
	TunableObjectHelper.putAFInstanceValue(object.tuning(), "CMDocumentBase.description", description);
}

/*Вычисление регистрационного номера*/
function getRegNumber(rkk) {
	var regNumber = "";
	regNumber = rkk.registration().getRegisteredInfo() != null ? rkk.registration().getRegisteredInfo().getNumber().toString() : "";
	return regNumber;
}

/*Получение UNID-объекта из ссылки*/
function getIdFromHref(href) {
	var index = href.lastIndexOf("/", href.length()) + 1;
	if (index < 0) {
		return href;
	} else {
		return href.substring(index);
	}
}