Импорт объектов каталога сразу в несколько разделов

Материал из Umicms
Перейти к:навигация, поиск

Актуально для версии 2.9

В некоторых системах 1С, номенклатурная позиция привязывается сразу к нескольким группам, а в файле import.xml, в узле Товар это будет представлено следующим образом:

<Группы>
  <Ид>0000390133</Ид>
  <Ид>0000390115</Ид>
  <Ид>0000490133</Ид>
  <Ид>0000490115</Ид>
  <Ид>0001090133</Ид>
  <Ид>0001090115</Ид>
</Группы>

В стандартных средствах системы, такой редкий функционал не поддерживается, но его можно реализовать кастоным образом. Чтобы решить данную задачу, необходимо настроить XSL-шаблон импорта: \xsl\import\custom\commerceML2.xsl и добавить дополнительный php-метод. Из оригинального файла \xsl\import\commerceML2.xsl, скопируем блок:

<xsl:template match="Товары/Товар">
... 
</xsl:template>

в файл \xsl\import\custom\commerceML2.xsl. После строк:

<xsl:if test="not(Группы/Ид)">
  <xsl:attribute name="parentId"><xsl:value-of select="$catalog-id" /></xsl:attribute>
  <xsl:attribute name="type-id">root-catalog-object-type</xsl:attribute>
</xsl:if>

добавим строки:

<groups>
  <xsl:apply-templates select="Группы/Ид" mode="groups" />
</groups>

Также, после шаблона "Товары/Товар", добавим еще один:

<xsl:template match="Ид" mode="groups" >
  <id><xsl:value-of select="." /></id>
</xsl:template>


Данные действия необходимы, чтобы в UmiDump'e, в узле page присутствовал блок groups, который мы обработаем в кастомном макросе.

Теперь в папку \classes\modules\exchange\ добавим файл custom_events.php следующего содержания:

<?php
new umiEventListener("exchangeOnUpdateElement", "exchange", "addVirtualCopy");
new umiEventListener("exchangeOnAddElement", "exchange", "addVirtualCopy");
?>

А в файл __custom.php, после слов //TODO: Write here your own macroses, добавим методы addVirtualCopy и isVirtualCopy:

public function addVirtualCopy($e) {

  if($e->getMode() == "after") {
    $hierarchy = umiHierarchy::getInstance();
    $element = $e->getRef('element');
    if (!$element instanceof umiHierarchyElement || $element->getMethod() != 'object') return false;
    $object_id = $element->objectId;
    $element_info = $e->getParam('element_info');
    $source_id = $e->getParam('source_id');
    $nl = $element_info->getElementsByTagName('groups');
    $nodGroups = $nl->length ? $nl->item(0) : null;
    
    if($nodGroups){
      $nl_id_groups = $nodGroups->getElementsByTagName('id');
      foreach($nl_id_groups as $key => $item){
        $commercML_id = $item->nodeValue;
        if($key == 0) continue;
        $parent_id = umiImportRelations::getInstance()->getNewIdRelation($source_id, $commercML_id);
        
        if(!$this->isVirtualCopy($object_id, $parent_id)){
        $hierarchy->copyElement($element->id, $parent_id);
        }
        
      }
    }
  }
}

public function isVirtualCopy($object_id, $parent_id) {
  $sql = "SELECT count(id) FROM `cms3_hierarchy` WHERE `rel` ='$parent_id' AND `obj_id` ='{$object_id}'";
  $result = l_mysql_query($sql);
  list($count) = mysql_fetch_row($result);
  return (boolean) $count;
}


В результате выполнения всех описанных выше действий, при импорте xml-данных в формате CommerceML 2.0, в дополнительных разделах будут созданы Виртуальные копии товаров.