表单预选

决条件:您必须熟悉教程中使用的语法 并且已经创建了一个扩展.

学习:预选搜索标准,预选对象在创建时或在转换上

水平:高级

域:PHPAutomationConstrain

最低版本:2.5.0

搜索预设

当您编辑团队并开始添加成员时,这些人的搜索将自动在团队的组织上进行过滤。这是一个特殊的示例,适用于所有带有组织的类。当您使用组织字段编辑任何对象A并开始添加相关对象B时,将使用组织A的组织自动过滤这些对象B的搜索。

创建预设

如果您在编辑用户请求时创建新的提交人人员,则该人员组织将被用户请求组织预先填充。

这种魔力在95%的情况下都是有效的,但是总有一些极端的情况,现在可以通过在上下文上使用某些特定的依赖完成这种自动行为来解决。由于...,可以做到这一点。

新的API方法

职能描述
PrefillSearchForm(&$aContextParam)在相关对象的搜索框架中预设字段
PrefillCreationForm(&$aContextParam)在对象创建表单中预置字段
PrefillTransitionForm(&$aContextParam)预设转换表单中的字段

您可以在不同情况下输入这些功能

  • 从菜单功能
  • 在间接LinkedSet属性上添加对象时(n:n关系)
  • 在编辑另一个对象(1:n关系)时,通过ExternalKey属性附近的+按钮
  • 在编辑LinkedSet属性(n:1关系)时从在线编辑模式

预选搜索表单

这是在Source对象类上定义的,以在相关对象的每个搜索帧中预设字段,因此,在相同的方法搜索对象类上的依赖中,我们将预设不同的搜索搜索。

上下文参数描述
$aContextParam['dest_class']提供搜索的类
$ aContextParam ['filter']提供过滤器(DBObjectSearch)对象
$ aContextParam ['user']提供所连接的用户的登录名字符串
$ aContextParam ['origin']可以是控制台或门户

 
class:Contract

/** Example of how on the Contract class, the Search has been modified to search for: * Services from the Provider only * Contacts and Documents from both the Customer and the Provider **/ public function PrefillSearchForm(&$aContextParam) { // If we want to search for objects of class 'Service' or a sub-class of 'Service' if($aContextParam['dest_class'] == 'Service' || ($aContextParam['dest_class'], 'Service')) { // If 'org_id' is an existing attribute of that searched class // and 'provider_id' of the source Contract is not empty if(MetaModel::IsValidAttCode($aContextParam['dest_class'],'org_id') && !($this->Get('provider_id'))) { // We remove any criteria set by the default search $aContextParam['filter']->ResetCondition(); // We set a criteria on the 'org_id' of the searched class with the Contract provider value $aContextParam['filter']->AddCondition('org_id', $this->Get('provider_id')); } } // If we want to search for objects of class or sub-classes of 'Contact' or 'Document' elseif (($aContextParam['dest_class'] == 'Contact' || ($aContextParam['dest_class'], 'Contact')) || ($aContextParam['dest_class'] == 'Document' || ($aContextParam['dest_class'], 'Document'))) { // If 'org_id' is an existing attribute of that searched class // Defensive programming in case the data model of remote classes is changed. if(MetaModel::IsValidAttCode($aContextParam['dest_class'],'org_id')) { $aOrgIds = (); if(!($this->Get('provider_id'))) $aOrgIds[] = $this->Get('provider_id'); if(!($this->Get('org_id'))) $aOrgIds[] = $this->Get('org_id'); // if 'provider_id' or 'org_id' of the source Contract are not empty // This test is not needed when org_id and provider_id are mandatory on the Contract class if(($aOrgIds)>0) { // We set a criteria on 'org_id' with multiple selected values (IN parameter) $aContextParam['filter']->ResetCondition(); $aContextParam['filter']->AddCondition('org_id', $aOrgIds , 'IN'); } } } }

预选创作表单

类的Creation表单中的预选字段

  • 自动机制已经完成其工作,因此,如果对象是从另一个创建的,则可以预先设置字段。
  • 如果用户提交了表单,则此引用当前将在数据库中创建的对象。
上下文参数描述
$ aContextParam ['user']提供所连接的用户的登录名字符串
$ aContextParam ['origin']可以是控制台或门户
$aContextParam['source_obj']仅在创建外部键对象时修复(例如,从人员对象创建的新团队对象)

例子1

在此示例中,我们从ServiceSubcategory创建一个RequestTemplate,我们不仅要预设自动完成的servicesubcategory_id,而且要预设可以从servicesubcategory_id猜到的servicesubcategory_id

class:RequestTemplate

public function PrefillCreationForm(&$aContextParam) { $id = $this->Get('servicesubcategory_id'); if ($id != 0) { // Get the original object itself $oSubcategoryObject = MetaModel::GetObject('ServiceSubCategory', $id, false); // Prefill other data with original object fields value $this->Set('service_id',$oSubcategoryObject->Get('service_id')); } }

例子2

在此示例中,我们创建了一个新的合同,并希望使用当前日期预置start_date,并使用用户组织预置provider_id。

class:CustomerContract

public function PrefillCreationForm(&$aContextParam) { // Preset the starting date of the contract with the current date // if not already set by Object Copier for eg. if(($this->Get('start_date'))) { $this->Set('start_date',());} // Get the current user as the parameter only provides the login $oUser = UserRights::GetUserObject(); // Preset the Provider of the contract as the organization of the current user // Be cautious ''org_id'' was added to the User class in 2.5.0 only $this->Set('provider_id',$oUser->Get('org_id')); }

例子3

在此示例中,我们创建一个新的UserRequest,并希望使用连接的用户的联系人_id来预置caller-id。

class:UserRequest

public function PrefillCreationForm(&$aContextParam) { // Get the current user as the parameter only provides the login $oUser = UserRights::GetUserObject(); // Prefill field caller with the contact of user $this->SetIfNull('caller_id', $oUser->Get('contactid')); return true; }

内部构造

当使用指向类A的AttributeLinkedSet从类B对象调用类A对象的创建表单时,类[“ default”]参数将提供类B对象的ID,并使用类A ExternalKey的代码属性B类: <itop>/pages/UI.php?operation=new&class=RequestTemplate&c[menu]=ServiceSubcategory&default[servicesubcategory_id]=16

预选转换表单

要在转换表单中预设值:

  • 在此阶段,尚未执行转换。
  • $ this引用当前将应用转换的对象。
上下文参数描述
$ aContextParam ['expected_attributes'] [''attribute_code']在表单中的属性上提供显示标志
$ aContextParam ['origin']可以是控制台或门户
$aContextParam['stimulus']提供所施加的刺激

本示例实现了“分派对我而言”的逻辑:

  • 如果我未分配给我分派或重新给分派分配了工单,并且我是该工单派遣到的团队的一部分,那么当我输入转换表单时,我的姓名将预设为“工单”。我可以分派。
class:UserRequest

public function PrefillTransitionForm(&$aContextParam) { $oPerson = UserRights::GetContactObject(); // If we have a Person associated with the current User // and we are in an assignment transition if ($oPerson && ($aContextParam['stimulus'] == 'ev_assign' || $aContextParam['stimulus'] == 'ev_reassign')) { $iTicketAgentId = $this->Get('agent_id'); $iPersonId = $oPerson->GetKey(); // If the agent is not already the current user if ( $iTicketAgentId != $iPersonId ) { // Check if the current Contact can be assigned to this ticket // = There is a team and Contact is part of that team $iTicketTeamId = $this->Get('team_id'); $oTeamLinkSet = $oPerson->Get('team_list'); $bIsInTeam = false; while($oTeamLink = $oTeamLinkSet->Fetch()) { // We don't use GetKey as it would return the key of the link object $iTeam = $oTeamLink->Get('team_id'); if ($iTicketTeamId == $iTeam) { $bIsInTeam = true; } } if($bIsInTeam) { $this->Set('agent_id',$iPersonId); //As we modified a potential MUST CHANGE value, we'll take care of it by removing this flag if(('agent_id', $aContextParam['expected_attributes'])) { $aContextParam['expected_attributes']['agent_id'] = ~OPT_ATT_MUSTCHANGE & $aContextParam['expected_attributes']['agent_id']; } } } } }

使最后一个功能到“变更处理人员_id字段上的标志”,是为了删除“ re-变更”处理人员上处理人员上的“ must-变更” UI控制(因为我们已通过编程方式对其进行了更改)。如果您忘记了它,UI将要求您再次输入变更和处理人员,并且不会让您自行设置。

已知限制:

  1. 当使用名称用户预设处理人员时,也将在下面的工单的详细信息中完成该操作,就好像变更已经完成但不正确(显示混乱)一样;如果取消了转换,则先前的处理人员将返回,如预期。
  2. 对于用户,可以通过回退先前的处理人员来绕过“ must-change”标志。 UI不会看到它,并且后​​端未测试“ must-change”。

将职能集成到XML中

如何在XML数据模型定义中声明上述职能的示例

  <class id="RequestTemplate" _delta="must_exist">
        <methods>
            <method id="PrefillCreationForm" _delta="define">
                <static>false</static>
                <access>public</access>
                <type>Overload-DBObject</type>
                <arguments>
                    <argument id="1">
                        <type>reference</type>
                        <mandatory>true</mandatory>
                    </argument>
                </arguments>
                <code><![CDATA[public function PrefillCreationForm(&$aContextParam)
              {       // code of the function    }]]>
                </ code>
            </method>
        </methods>
    </class>

原贴链接:https://www.itophub.io/wiki/page?id=2_7_0%3Acustomization%3Aform_prefill


Form Prefill

Prerequisite: You must be familiar with the Syntax used in Tutorials and have already created an extension.

learning:
Prefill search criterion, prefill an object at creation or on transition
level:
Advanced
domains:
PHPAutomationConstrain
min version:
2.5.0

Search preset

When you edit a Team and start to add Members, then the search of those Persons is automatically filtered on the Organization of the Team. This was a particular example, which apply on all classes with an organization. When you edit any object A with an Organization field and start to add related objects B, the search of those objects B is automatically filtered with the Organization of the Object A.

Creation preset

If you create a new Caller person while editing a User Request, that Person Organization will be prefilled with the User Request Organization.

This magic is valid in 95% of the cases, but there are always corner cases, which can now be addressed by completing this automatic behavior with some specific one depending on the context. This can be done thanks to…

New API methods

FunctionDescription
PrefillSearchForm(&$aContextParam)to preset fields in the search frame of related objects
PrefillCreationForm(&$aContextParam)to preset fields in an object creation form
PrefillTransitionForm(&$aContextParam)to preset fields in a transition form

You may enter those functions in different situations

  • From a menu / action

  • While adding objects on an Indirect LinkedSet attribute (n:n relationship)

  • From the + button near an ExternalKey attribute while editing another object (1:n relationship)

  • From the edit in line mode when editing a LinkedSet attribute (n:1 relationship)

Prefill Search Form

This is defined on the Source object class to preset fields in each search frame of related objects, so within the same method, depending on the search object class, we will preset different search criteria.

Context ParameterDescription
$aContextParam['dest_class']provide the Searched class
$aContextParam['filter']provide the filter (DBObjectSearch) object
$aContextParam['user']provides the login string of the connected user
$aContextParam['origin']can be either console or portal

Example

class:Contract
 

/** Example of how on the Contract class, the Search has been modified to search for: * Services from the Provider only * Contacts and Documents from both the Customer and the Provider **/ public function PrefillSearchForm(&$aContextParam) { // If we want to search for objects of class 'Service' or a sub-class of 'Service' if($aContextParam['dest_class'] == 'Service' || ($aContextParam['dest_class'], 'Service')) { // If 'org_id' is an existing attribute of that searched class // and 'provider_id' of the source Contract is not empty if(MetaModel::IsValidAttCode($aContextParam['dest_class'],'org_id') && !($this->Get('provider_id'))) { // We remove any criteria set by the default search $aContextParam['filter']->ResetCondition(); // We set a criteria on the 'org_id' of the searched class with the Contract provider value $aContextParam['filter']->AddCondition('org_id', $this->Get('provider_id')); } } // If we want to search for objects of class or sub-classes of 'Contact' or 'Document' elseif (($aContextParam['dest_class'] == 'Contact' || ($aContextParam['dest_class'], 'Contact')) || ($aContextParam['dest_class'] == 'Document' || ($aContextParam['dest_class'], 'Document'))) { // If 'org_id' is an existing attribute of that searched class // Defensive programming in case the data model of remote classes is changed. if(MetaModel::IsValidAttCode($aContextParam['dest_class'],'org_id')) { $aOrgIds = (); if(!($this->Get('provider_id'))) $aOrgIds[] = $this->Get('provider_id'); if(!($this->Get('org_id'))) $aOrgIds[] = $this->Get('org_id'); // if 'provider_id' or 'org_id' of the source Contract are not empty // This test is not needed when org_id and provider_id are mandatory on the Contract class if(($aOrgIds)>0) { // We set a criteria on 'org_id' with multiple selected values (IN parameter) $aContextParam['filter']->ResetCondition(); $aContextParam['filter']->AddCondition('org_id', $aOrgIds , 'IN'); } } } }

Prefill Creation Form

Prefill fields in the Creation form of a class

  • The automatic mechanism has already done its work, so fields can be preset already, if the object is created from another one.

  • $this reference the current object which is about to be created in Database, if the user submit the form.

Context ParameterDescription
$aContextParam['user']provides the login string of the connected user
$aContextParam['origin']can be either console or portal
$aContextParam['source_obj']fixed only when creating an external key object (for example, a new Team object created from a Person object)

Example 1

In this example, we create a RequestTemplate from a ServiceSubcategory, and we want to not only preset the servicesubcategory_id, which is done automatically, but also the service_id which can be guessed from theservicesubcategory_id

class:RequestTemplate
 

public function PrefillCreationForm(&$aContextParam) { $id = $this->Get('servicesubcategory_id'); if ($id != 0) { // Get the original object itself $oSubcategoryObject = MetaModel::GetObject('ServiceSubCategory', $id, false); // Prefill other data with original object fields value $this->Set('service_id',$oSubcategoryObject->Get('service_id')); } }

Example 2

In this example, we create a new Contract and we want to preset the start_datewith current date and the provider_id with the user organization.

class:CustomerContract
 

public function PrefillCreationForm(&$aContextParam) { // Preset the starting date of the contract with the current date // if not already set by Object Copier for eg. if(($this->Get('start_date'))) { $this->Set('start_date',());} // Get the current user as the parameter only provides the login $oUser = UserRights::GetUserObject(); // Preset the Provider of the contract as the organization of the current user // Be cautious ''org_id'' was added to the User class in 2.5.0 only $this->Set('provider_id',$oUser->Get('org_id')); }

Example 3

In this example, we create a new UserRequest and we want to preset the caller id with the contact_id of the connected user.

class:UserRequest
 

public function PrefillCreationForm(&$aContextParam) { // Get the current user as the parameter only provides the login $oUser = UserRights::GetUserObject(); // Prefill field caller with the contact of user $this->SetIfNull('caller_id', $oUser->Get('contactid')); return true; }

Internals

When the creation form of a class A object is invoked from a class B object with a AttributeLinkedSet pointing to class A, the Context[“default”] parameter provides the id of the class B object, with the code attribute of the class A ExternalKey pointing to class B: <itop>/pages/UI.php?operation=new&class=RequestTemplate&c[menu]=ServiceSubcategory&default[servicesubcategory_id]=16

Prefill Transition Form

To preset values in a transition form:

  • At this stage the transition is not yet performed.

  • $this reference the current object on which the transition will be applied.

Context ParameterDescription
$aContextParam['expected_attributes']['attribute_code']provides display flags on attributes in the form
$aContextParam['origin']can be either console or portal
$aContextParam['stimulus']provide the applied stimulus

This example implements a “pre-assign to me” logic:

  • If I assign or re-assign a ticket, which is not assigned to me and I am part of the team to which this ticket is dispatched, then when I enter the transition form, my name is preset as the 'agent'. I can change it.

class:UserRequest
 

public function PrefillTransitionForm(&$aContextParam) { $oPerson = UserRights::GetContactObject(); // If we have a Person associated with the current User // and we are in an assignment transition if ($oPerson && ($aContextParam['stimulus'] == 'ev_assign' || $aContextParam['stimulus'] == 'ev_reassign')) { $iTicketAgentId = $this->Get('agent_id'); $iPersonId = $oPerson->GetKey(); // If the agent is not already the current user if ( $iTicketAgentId != $iPersonId ) { // Check if the current Contact can be assigned to this ticket // = There is a team and Contact is part of that team $iTicketTeamId = $this->Get('team_id'); $oTeamLinkSet = $oPerson->Get('team_list'); $bIsInTeam = false; while($oTeamLink = $oTeamLinkSet->Fetch()) { // We don't use GetKey as it would return the key of the link object $iTeam = $oTeamLink->Get('team_id'); if ($iTicketTeamId == $iTeam) { $bIsInTeam = true; } } if($bIsInTeam) { $this->Set('agent_id',$iPersonId); //As we modified a potential MUST CHANGE value, we'll take care of it by removing this flag if(('agent_id', $aContextParam['expected_attributes'])) { $aContextParam['expected_attributes']['agent_id'] = ~OPT_ATT_MUSTCHANGE & $aContextParam['expected_attributes']['agent_id']; } } } } }

The last action to “change the flags on the agent_id field”, is made to remove the “must-change” UI control on the agent on the “re-assign” transition (as we changed it programmatically). If you forget it, the UI will ask you to change the agent again and won't let you set yourself.

Known limitations:

  1. when the agent is preset with the user name, it is also done in the details of the ticket below as if the change was done already which is not true (confusing display), if the transition is cancelled, the previous agent is back, as expected.

  2. It is possible for the user to bypass the “must-change” flag in case of preset, by setting back the previous agent. It won't be seen by the UI and “must-change” is not tested on the back-end.

Integrate a function within XML

Example of how to declare the above function within XML datamodel definition

    <class id="RequestTemplate" _delta="must_exist">
        <methods>
            <method id="PrefillCreationForm" _delta="define">
                <static>false</static>
                <access>public</access>
                <type>Overload-DBObject</type>
                <arguments>
                    <argument id="1">
                        <type>reference</type>
                        <mandatory>true</mandatory>
                    </argument>
                </arguments>
                <code><![CDATA[public function PrefillCreationForm(&$aContextParam)
              {       // code of the function    }]]>
                </ code>
            </method>
        </methods>
    </class>
标签:
由 superadmin 在 2020/08/27, 17:25 创建
    

需要帮助?

如果您需要有关XWiki的帮助,可以联系:

深圳市艾拓先锋企业管理咨询有限公司