SPOC 与合作伙伴

SPOC 与合作伙伴。

本文档介绍如何在 iTop 中为中介公司(合作伙伴)配置工单处理,使其能够代表最终客户在门户中创建和管理工单。更多详细内容请参考 iTop 官方文档

前提条件

场景

假设您的公司是 IT 服务提供商,部分最终客户不直接与您联系,而是通过一家中介公司。该中介公司在您的 iTop 门户中代表最终客户进行操作。

  • 中介公司代表客户报告特定服务的事件
  • 中介公司可能为多个客户扮演该角色
  • 最终客户也可以自行报告事件或请求
  • 中介公司只能查看他们创建的工单,不能查看其客户的其他工单(可能包含敏感信息)

数据模型变更

中介的客户

需要为每个中介公司存储其服务的客户,以及为每个客户服务的具体服务。在本教程中,假设给定客户购买的特定服务最多外包给一个中介。

通过在 lnkCustomerContractToService 类上添加记录中介公司的外键来实现:

<class id="lnkCustomerContractToService">
  <fields>
    <field id="managed_by_id" xsi:type="AttributeExternalKey" _delta="define">
      <sql>managed_by_id</sql>
      <target_class>Organization</target_class>
      <filter/>
      <dependencies/>
      <is_null_allowed>true</is_null_allowed>
      <on_target_delete>DEL_MANUAL</on_target_delete>
      <allow_target_creation>false</allow_target_creation>
    </field>
  </fields>
</class>

工单的请求者

由于中介代表客户创建工单,需要修改 Ticket 类上 caller_id 的过滤器,使其可以是:

  • 客户组织中的任何人
  • 或客户组织中管理某服务的中介组织中的任何人
<class id="Ticket">
  <fields>
    <field id="caller_id" xsi:type="AttributeExternalKey" _delta="must_exist">
      <filter _delta="redefine"><![CDATA[
        SELECT Person WHERE org_id = :this->org_id
        UNION
        SELECT Person AS p 
          JOIN Organization AS i ON p.org_id=i.id 
          JOIN lnkCustomerContractToService AS lnk ON lnk.managed_by_id = i.id
          JOIN CustomerContract AS cc ON lnk.customercontract_id = cc.id
          WHERE cc.org_id = :this->org_id
      ]]></filter>
    </field>
  </fields>
</class>

建议的服务

可以限制数据模型中仅呈现基于客户和请求者的有效服务:

<class id="UserRequest">
  <fields>
    <field id="service_id" xsi:type="AttributeExternalKey" _delta="must_exist">
      <filter _delta="redefine"><![CDATA[
        SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id 
          JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id
          WHERE cc.org_id = :this->org_id AND s.status != 'obsolete'
          AND l1.managed_by_id = 0
        UNION
        SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id 
          JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id
          JOIN Organization AS i ON l1.managed_by_id = i.id
          JOIN Person AS p ON p.org_id = i.id
          WHERE cc.org_id = :this->org_id AND s.status != 'obsolete'
          AND p.id = :this->caller_id
      ]]></filter>
      <dependencies>
        <attribute id="org_id"/>
        <attribute id="caller_id" _delta="define"/>
      </dependencies>
    </field>
  </fields>
</class>

自定义用户门户

对于中介公司,需要使其能够在创建用户请求之前选择客户。通过为具有特定角色的门户用户创建新的 BrowseBrick 来实现。

  • 普通最终用户仍使用 mosaic 视图
  • 中介用户使用列表浏览模式查看其各种客户
  • 然后中介用户在工单创建表单中选择服务和服务子目录

新用户角色

创建一个没有特定访问权限的新角色,命名为 Portal Multi Contract User

<user_rights>
  <profiles>
    <profile id="912" _delta="define">
      <name>Portal Multi Contract User</name>
      <description>Users with this profile are allowed to create UserRequest on iTop Portal in the name of customers that they serve</description>
      <groups/>
    </profile>
  </profiles>
</user_rights>

新 BrowseBrick

新的 browseBrick 必须限制为 Portal Multi Contract User 角色:

<brick id="intermediate-customers" xsi:type="Combodo\iTop\Portal\Brick\ManageBrick" _delta="define">
  <active>true</active>
  <width>6</width>
  <rank><default>60</default></rank>
  <title><default>Brick:Portal:IntermediateCustomers:Title</default></title>
  <description>Brick:Portal:IntermediateCustomers:Title+</description>
  <visible>
    <home>false</home>
    <navigation_menu>false</navigation_menu>
  </visible>
  <decoration_class><default>far fa-handshake fc-3x</default></decoration_class>
  <oql><![CDATA[SELECT Organization]]></oql>
  <export><export_default_fields>true</export_default_fields></export>
  <fields>
    <field id="org_id_friendlyname"/>
    <field id="start_date"/>
    <field id="end_date"/>
  </fields>
  <grouping>
    <tabs>
      <groups>
        <group id="all">
          <rank>2</rank>
          <title>Brick:Portal:Licences:Tab:All</title>
          <condition><![CDATA[SELECT Organization]]></condition>
        </group>
      </groups>
    </tabs>
  </grouping>
  <security>
    <allowed_profiles><![CDATA[SELECT URP_Profiles WHERE name = 'Portal Multi Contract User']]></allowed_profiles>
  </security>
</brick>

移除旧 BrowseBrick 的访问权限

旧 BrowseBrick 必须拒绝新角色访问:

<brick id="services" xsi:type="Combodo\iTop\Portal\Brick\BrowseBrick" _delta="must_exist">
  <security _delta="define">
    <denied_profiles><![CDATA[SELECT URP_Profiles WHERE name = 'Portal Multi Contract User']]></denied_profiles>
  </security>
</brick>

重新设计范围

需要重新设计范围:

<classes>
  <class id="Organization" _delta="must_exist">
    <scopes>
      <scope id="intermediate" _delta="define">
        <oql_view><![CDATA[SELECT Organization AS O WHERE (O.managed_by_id = :current_contact->org_id) OR (O.id = :current_contact->org_id)]]></oql_view>
        <allowed_profiles>
          <allowed_profile id="Portal Multi Contract User"/>
        </allowed_profiles>
      </scope>
    </scopes>
  </class>
  <class id="Contact" _delta="must_exist">
    <scopes>
      <scope id="intermediate" _delta="define">
        <oql_view><![CDATA[SELECT Contact AS C JOIN Organization AS O ON C.org_id = O.id WHERE C.status='active' AND (O.managed_by_id = :current_contact->org_id) OR (O.id = :current_contact->org_id)]]></oql_view>
        <oql_edit><![CDATA[SELECT Contact AS C WHERE C.org_id = :current_contact->org_id]]></oql_edit>
        <allowed_profiles>
          <allowed_profile id="Portal Multi Contract User"/>
        </allowed_profiles>
      </scope>
    </scopes>
  </class>
  <class id="Service" _delta="must_exist">
    <scopes>
      <scope id="intermediate" _delta="define">
        <oql_view><![CDATA[SELECT Service]]></oql_view>
        <allowed_profiles>
          <allowed_profile id="Portal Multi Contract User"/>
        </allowed_profiles>
      </scope>
    </scopes>
  </class>
  <class id="ServiceSubcategory" _delta="must_exist">
    <scopes>
      <scope id="intermediate" _delta="define">
        <oql_view><![CDATA[SELECT ServiceSubcategory]]></oql_view>
        <allowed_profiles>
          <allowed_profile id="Portal Multi Contract User"/>
        </allowed_profiles>
      </scope>
    </scopes>
  </class>
  <class id="UserRequest" _delta="must_exist">
    <scopes>
      <scope id="portal-partner-user" _delta="define">
        <oql_view><![CDATA[SELECT UserRequest AS T JOIN Organization AS O ON T.org_id = O.id WHERE (O.managed_by_id = :current_contact->org_id) OR (O.id=:current_contact->org_id)]]></oql_view>
        <oql_edit><![CDATA[SELECT UserRequest AS T]]></oql_edit>
        <allowed_profiles>
          <allowed_profile id="Portal Multi Contract User"/>
        </allowed_profiles>
      </scope>
      <scope id="in-contact" _delta="define">
        <oql_view><![CDATA[SELECT UserRequest AS T 
          JOIN lnkContactToTicket AS l ON l.ticket_id = T.id 
          WHERE l.contact_id = :current_contact_id ]]></oql_view>
        <oql_edit><![CDATA[SELECT UserRequest AS T]]></oql_edit>
      </scope>
      <scope id="mine" _delta="define">
        <oql_view><![CDATA[SELECT UserRequest AS T 
          WHERE T.agent_id = :current_contact_id  OR T.caller_id = :current_contact_id]]></oql_view>
        <oql_edit><![CDATA[SELECT UserRequest]]></oql_edit>
      </scope>
    </scopes>
  </class>
</classes>

原文:https://www.itophub.io/wiki/page?id=3_2_0:customization:spoc

版本:3_2_0/customization/spoc.txt · Last modified: 2024/09/10 10:25 by 127.0.0.1