iTop ITSM & CMDB по-русски

Помогите создать свой модуль Customer


#1

Привет.
Я пытаюсь создать новый модуль “Customer” клиенты. Файлы сгенерил, добавил код.

в тулките на вкладке DataModel Consistency говорит о неизвестных значениях:

Unknown attribute code 'org_id' in the list of reconciliation keys (Expecting a value in name, status, friendlyname)
Unknown attribute code 'org_name' in the list of reconciliation keys (Expecting a value in name, status, friendlyname)
Unknown attribute code 'org_id' from ZList 'details' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'email' from ZList 'details' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'phone' from ZList 'details' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'notify' from ZList 'details' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'function' from ZList 'details' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'org_id' from ZList 'list' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'email' from ZList 'list' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'phone' from ZList 'list' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'function' from ZList 'list' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'org_id' from ZList 'standard_search' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'email' from ZList 'standard_search' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'phone' from ZList 'standard_search' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'notify' from ZList 'standard_search' (Expecting a value in {name, status, friendlyname})
Unknown attribute code 'function' from ZList 'standard_search' (Expecting a value in {name, status, friendlyname})

все делаю по инструкции https://wiki.openitop.org/doku.php?id=2_1_0:customization:add-class-sample
Подскажите пожалуйста, в чем может быть причина?


Создание, изменение и удаление типов КЕ
#2

Привет, @igsao10! К сожалению, экстрасенсов не форуме нет, так что код модели данных в студию)


#3

форматирование теги xml сжирает, и получается белиберда…сюда можно файл прикрепить?


#4

@igsao10, для размещения кода есть специальная кнопка </>. Вставляешь код, выделяешь, нажимаешь и получаешь:

<class id="Server">
  <fields>
    <field id="notes" xsi:type="AttributeText" _delta="define">
      <sql>notes</sql>
      <default_value/>
      <is_null_allowed>true</is_null_allowed>
    </field>
  </fields>
 </class>

#5
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
  <constants>
  </constants>
  <classes>
 <class id="Customer" _delta="delete_">
      <parent>cmdAbstractObject</parent>
      <properties>
        <category>bizmodel,searchable,structure</category>
        <abstract>true</abstract>
        <key_type>autoincrement</key_type>
        <db_table>customer</db_table>
        <db_key_field>id</db_key_field>
        <db_final_class_field/>
        <naming>
          <format>%1$s</format>
          <attributes>
            <attribute id="name"/>
          </attributes>
        </naming>
        <display_template/>
        <icon>images/client.png</icon>
        <reconciliation>
          <attributes>
            <attribute id="name"/>
            <attribute id="org_id"/>
            <attribute id="org_name"/>
          </attributes>
        </reconciliation>
      </properties>
      <fields>
        <field id="name" xsi:type="AttributeString">
          <sql>name</sql>
          <default_value/>
          <is_null_allowed>false</is_null_allowed>
        </field>
        <field id="status" xsi:type="AttributeEnum">
          <values>
           <value>active</value>
           <value>inactive</value>
          </values>
           <sql>status</sql>
           <default_value>active</default_value>
           <is_null_allowed>false</is_null_allowed>
           <display_style>list</display_style>
         </field>
      </fields>
      <methods/>
      <presentation>
        <details>
          <items>
            <item id="name">
              <rank>10</rank>
            </item>
            <item id="status">
              <rank>20</rank>
            </item>
            <item id="org_id">
              <rank>30</rank>
            </item>
            <item id="email">
              <rank>40</rank>
            </item>
            <item id="phone">
              <rank>50</rank>
            </item>
            <item id="notify">
              <rank>60</rank>
            </item>
            <item id="function">
              <rank>70</rank>
            </item>
          </items>
        </details>
        <search>
          <items>
            <item id="name">
              <rank>10</rank>
            </item>
            <item id="status">
              <rank>20</rank>
            </item>
            <item id="org_id">
              <rank>30</rank>
            </item>
            <item id="email">
              <rank>40</rank>
            </item>
            <item id="phone">
              <rank>50</rank>
            </item>
            <item id="notify">
              <rank>60</rank>
            </item>
            <item id="function">
              <rank>70</rank>
            </item>
          </items>
        </search>
        <list>
          <items>
            <item id="status">
              <rank>10</rank>
            </item>
            <item id="org_id">
              <rank>20</rank>
            </item>
            <item id="email">
              <rank>30</rank>
            </item>
            <item id="phone">
              <rank>40</rank>
            </item>
            <item id="function">
              <rank>50</rank>
            </item>
          </items>
        </list>
      </presentation>
     </class>
  </classes>
  <menus>
  </menus>
</itop_design>

Точно. спасибо:)


#6

Перенёс все сообщения в отдельную тему.


#7

А теперь давай по порядку.
Во-первый, что твой модуль должен делать?


#8

Название модуля: Клиенты
Модуль должен входить в состав КЕ "Контакты"
Заполнение формы при создании нового клиента:
Имя, Идентификатор(типо B000001), Адрес, email, уведомления(да, нет), менеджер клиета(выбор из персон)
модуль “клиенты” должен включать вкладки: программные решения, тикеты.
Полное описание позже добавлю…
но пока переделал код, однако не компилил еще, вот что получилось

<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
  <constants>
  </constants>
  <classes>
  <class id="Customer" _delta="define">
      <parent>Contact</parent>
      <properties>
        <category>bizmodel,searchable,structure</category>
        <abstract>false</abstract>
        <key_type>autoincrement</key_type>
        <db_table>customer</db_table>
        <db_key_field>id</db_key_field>
        <db_final_class_field/>
        <naming>
          <format>%1$s %2$s</format>
          <attributes>
            <attribute id="name"/>
            <attribute id="b_name"/>
          </attributes>
        </naming>
        <display_template/>
        <icon>images/customer.png</icon>
        <reconciliation>
          <attributes>
            <attribute id="b_name"/>
            <attribute id="name"/>
            <attribute id="org_id"/>
            <attribute id="org_name"/>
            <attribute id="email"/>
            <attribute id="node_id"/>
          </attributes>
        </reconciliation>
      </properties>
      <fields>
        <field id="b_name" xsi:type="AttributeString">
          <sql>b_name</sql>
          <default_value/>
          <is_null_allowed>false</is_null_allowed>
        </field>
        <field id="node_id" xsi:type="AttributeString">
          <sql>node_id</sql>
          <default_value/>
          <is_null_allowed>true</is_null_allowed>
        </field>
        <field id="mobile_phone" xsi:type="AttributeString">
          <sql>mobile_phone</sql>
          <default_value/>
          <is_null_allowed>true</is_null_allowed>
        </field>
        <field id="manager_id" xsi:type="AttributeExternalKey">
          <filter><![CDATA[SELECT Person]]></filter>
          <dependencies>
            <attribute id="org_id"/>
          </dependencies>
          <sql>manager_id</sql>
          <target_class>Person</target_class>
          <is_null_allowed>true</is_null_allowed>
          <on_target_delete>DEL_MANUAL</on_target_delete>
        </field>
        <field id="manager_name" xsi:type="AttributeExternalField">
          <extkey_attcode>manager_id</extkey_attcode>
          <target_attcode>name</target_attcode>
        </field>
        <field id="tickets_list" xsi:type="AttributeLinkedSet">
          <linked_class>Ticket</linked_class>
          <ext_key_to_me>caller_id</ext_key_to_me>
          <edit_mode>add_only</edit_mode>
          <count_min>0</count_min>
          <count_max>0</count_max>
        </field>
      </fields>
      <methods/>
      <presentation>
        <details>
          <items>
            <item id="tickets_list">
              <rank>10</rank>
            </item>
            <item id="cis_list">
              <rank>20</rank>
            </item>
            <item id="col:col1">
              <rank>30</rank>
              <items>
                <item id="fieldset:Customer:info">
                  <rank>10</rank>
                  <items>
                    <item id="name">
                      <rank>10</rank>
                    </item>
                    <item id="b_name">
                      <rank>20</rank>
                    </item>
                    <item id="org_id">
                      <rank>30</rank>
                    </item>
                    <item id="status">
                      <rank>40</rank>
                    </item>
                    <item id="manager_id">
                      <rank>50</rank>
                    </item>
                    <item id="node_id">
                      <rank>60</rank>
                    </item>
                  </items>
                </item>
              </items>
            </item>
            <item id="col:col2">
              <rank>40</rank>
              <items>
                <item id="fieldset:Customer:notifiy">
                  <rank>10</rank>
                  <items>
                    <item id="email">
                      <rank>10</rank>
                    </item>
                    <item id="notify">
                      <rank>20</rank>
                    </item>
                    <item id="phone">
                      <rank>30</rank>
                    </item>
                    <item id="mobile_phone">
                      <rank>40</rank>
                    </item>
                  </items>
                </item>
              </items>
            </item>
          </items>
        </details>
        <search>
          <items>
            <item id="name">
              <rank>10</rank>
            </item>
            <item id="b_name">
              <rank>20</rank>
            </item>
            <item id="org_id">
              <rank>30</rank>
            </item>
            <item id="status">
              <rank>40</rank>
            </item>
            <item id="email">
              <rank>50</rank>
            </item>
            <item id="phone">
              <rank>60</rank>
            </item>
            <item id="node_id">
              <rank>70</rank>
            </item>
            <item id="manager_id">
              <rank>80</rank>
            </item>
            <item id="mobile_phone">
              <rank>90</rank>
            </item>
            <item id="notify">
              <rank>100</rank>
            </item>
          </items>
        </search>
        <list>
          <items>
            <item id="b_name">
              <rank>10</rank>
            </item>
            <item id="org_id">
              <rank>20</rank>
            </item>
            <item id="status">
              <rank>30</rank>
            </item>
            <item id="email">
              <rank>40</rank>
            </item>
            <item id="phone">
              <rank>50</rank>
            </item>
          </items>
        </list>
      </presentation>
    </class>
  </classes>
  <menus>
  </menus>
</itop_design>

#9

Получилось! Модуль создался.


Пока работает нормально.
теперь надо подумать, как настроить триггер, чтобы при регистрации инцидента по какому-нибудь сервису, он отправлял уведомления клиентам, имеющим связь с этим сервисом


#10

Теперь хочется клиентов привязать к услугам. это возможно сделать?


#11

Стоп, стоп, стоп! Пахнет очередным велосипедом.
Зачем это всё? Чем не устраивает стандартный функционал “Клиенты - Услуги - Тикеты - Оповещения”?


#12

Первоначальную настройку по [этому гайду][1] делал?

UPD: Какие-то проблемы у них сейчас с сайтом документации.
[1]: https://wiki.openitop.org/doku.php?id=2_1_0:implementation:start


#13

у меня что-то ничего не работает по предоставленной ссылке


#14

а тут имеется ввиду применить стандартный функционал к моему созданному модулю клиенты?)


#15

Я имею ввиду не городить огород с собственными модулями, а использовать стандартный функционал.
Какую бизнес-задачу должен решить модуь?

Сайт с доками и у меня пропал. Надеюсь, скоро починят.


#16

С стандартом функционале какая КЕ понимается как клиенты?
У нас в компании очень много клиентов, и заводить их как персон не хочется. клиентов мы разносим по организациям (организация в нашем понимании - это сервисный комплекс, в который входят физ.устройства, вирту, устройства и т.п.), в каждой организации заводим услуги, к которым привязываем клиентов. создаем триггер на регистрацию инцидента. при создании инцидента, клиентам этой организации должно отправляться уведомление


#18

В iTop все, кто получает, оказывает или участвует в оказании услуг являются организациями. Это базовый принцип, на котором построена вся остальная логика работы. Все остальные КЕ привязаны к организациям.

Клиентов нужно заводить в организациях.

Вы - тоже организация. У вас есть принадлежащие вам услуги. Для того, чтобы связать вас, ваши услуги и клиентов, создается Договор с заказчиком. В нем в указываются поставщик услуг, заказчик услуг, сами услуги и SLA для них. После этого можно регистрировать тикеты.
Есть один очень важный момент. При установке iTop просил выбрать режим работы модуля услуг:

  • Service Management for Enterprises (предприятие)
  • Service Management for Service Providers (провайдер)

Если коротко, первый вариант нужно выбрать, если все услуги оказываются разным клиентам на одном и том же оборудовании. Второй вариант - если для каждого клиента используется свой программно-аппаратный комплекс. Я как-то по незнанию выбрал не тот вариант, потом пришлось переустанавливать систему.

И тут выясняется реальный смысл всего))) То есть главная задача - уведомить всех клиентов о падении услуги, а не только того, который создал обращение. Получается, во всем написанном выше пользы мало. Ушел думать…


#19

Продолжаем)
Оповещение можно отправить только контакту (т.е. персоне или команде). То есть для каждой организации-клиента нужно создать своего ответственного и добавить его в Договор с заказчиком во вкладку Контакты. Теперь при создании оповещения в поле “Кому” нужно указать такой запрос:

SELECT Contact AS p
 JOIN lnkContactToContract AS l1 ON l1.contact_id = p.id
 JOIN CustomerContract AS cc ON l1.contract_id = cc.id
 JOIN lnkCustomerContractToService AS l2 ON l2.customercontract_id = cc.id
 WHERE l2.service_id = :this->service

Он выбирает контакты, связанные с договорами, которые связаны с упавшей услугой.

Конечно, звучит всё страшновато) Но это проще, чем написание своего модуля. Кроме того, наполнение системы - мероприятие разовое, и для этого можно использовать импорт из CSV. А вот поддержка собственного модуля будет необходима всегда, после любого обновления iTop. Используя базовый функционал, вероятность того, что обновление iTop всё поломает, гораздо ниже.


#20

Я же точно так же могу сделать селект и из Customer, Разве не так?


#21

Конечно можешь.

SELECT Customer AS c 
 JOIN lnkCustomerToService AS ln ON ln.customer_id = c.id
 WHERE  ln.service_id = :this->service_id

Как-то так. Это псевдокод, я не понял, как lnkCustomerToService реализована.