Миграция документов в новый реестр в Alvex

При использовании реестров документов в Alvex у многих возникает вопрос:

Если сначала вы решили использовать стандартные типы реестров документов, а через пару месяцев захотели сделать свои типы, добавив в них по паре новых полей, то как перенести документы, накопившиеся за несколько месяцев, из старых реестров в новые?

Переносить вручную (удалять из одного реестра и создавать в другом) десятки документов не хочется. Но ни Alfresco, ни Alvex не предоставляют стандартных средств перемещения документов между реестрами. Что же делать?

Для массового переноса документов нам понадобятся: Рассмотрим случай переноса партнерских соглашений из стандартного реестра договоров (тип alvexdt:agreement) в новый реестр типа alvexcourse_docs:document_partner_agreement (пример модели: 
https://github.com/ITDSystems/alvex-courses-extras/blob/master/2013-06-07/custom-register-example/config/repo/alfresco/extension/models/alvex-course-examples-model.xml). Новый тип унаследован от базового alvexdt:agreement (задается в тэге parent при создании типа) и расширяет его несколькими новыми свойствами. Данные в старом реестре:


Новый пустой реестр:


  1. Устанавливаем JavaScript Console в соответствии с инструкцией.
  2. Заходим в систему под учетной записью администратора и открываем JavaScript Console в админке.
  3. Пишем и запускаем скрипт:
// Получаем название сайта с реестрами и контейнер с реестрами, вместо 'office' подставьте название своего сайта
var site = siteService.getSite('office');
var cont = site.getContainer('dataLists');
 
// Для проверки введенных данных выводим на экран названия всех полученных реестров сайта
for each( list in cont.children )
print( list.properties.title );

Получаем примерно такой результат:


Убираем из скрипта строки вывода на экран списка названий реестров и указываем, из какого реестра в какой мигрировать документы. Чтобы не ошибиться - снова выводим названия выбранных реестров на экран.
// Получаем название сайта с реестрами и контейнер с реестрами, вместо 'office' подставьте название своего сайта
var site = siteService.getSite('office');
var cont = site.getContainer('dataLists');
 
// Указываем, из какого реестра мигрировать документы (srcList) и в какой реестр их мигрировать (dstList), указываем номер реестра в соответствии с выводом в прошлом скрипте (нумерация начинается с 0)
var srcList = cont.children[0];
var dstList = cont.children[1];
 
// Выводим названия выбранных реестров для проверки. srcList - реестр типа alvexdt:agreement, из которого мигрируем документы, dstList - реестр типа alvexcourse_docs:document_partner_agreement, в который мигрируем документы
print( "Source: " + srcList.properties.title );
print( "Dest: " + dstList.properties.title );

Результат:


Если реестры перепутаны, или в результате выполнения скрипта появилась ошибка Cannot read "properties" from undefined, значит вы неправильно указали номера реестров и, возможно, реестра с таким номером вообще не существует. Попробуйте поменять номера, выполняя скрипт несколько раз, пока не получите правильное сочетание реестров.

Далее копируем все документы из первого реестра во второй:
// Получаем название сайта с реестрами и контейнер с реестрами, вместо 'office' подставьте название своего сайта
var site = siteService.getSite('office');
var cont = site.getContainer('dataLists'); 
 
// Указываем, из какого реестра мигрировать документы (srcList) и в какой реестр их мигрировать (dstList), указываем номер реестра в соответствии с вашим случаем
var srcList = cont.children[0];
var dstList = cont.children[1];
 
// Копируем все документы из srcList в dstList
for each( item in srcList.children )
{ 

    // Создаем пустой документ в новом реестре
    var node = dstList.createNode(null, "alvexcourse_docs:document_partner_agreement");
 
    // Копируем все ассоциации текущего документа в старом реестре в новый документ
    for (assoc in item.assocs)
        for each(i in item.assocs[assoc])
            node.createAssociation(i, assoc );
 
    // Копируем все свойства текущего документа в старом реестре в новый документ
    for(prop in item.properties)
        node.properties[prop] = item.properties[prop];
 
    // Сохраняем новый документ
    node.save();  
}


В нашем случае мигрируют все свойства и ассоциации, какие только есть. Новые незаполненные поля остаются пустыми.

В результате выполнения скрипта старый реестр не удаляется, так что можете поэксперименировать несколько раз, а исходный реестр удалить вручную, когда убедитесь, что все документы правда переместились.

Можно переносить документы и в произвольные новые реестры, которые никак не связаны с (не наследуются от) базовых типов реестров Alvex, но это сложнее, требует явного перечисления всех свойств, которые нужно перенести в новый реестр, в скрипте, и мы не рассматриваем эту задачу в этом посте.

Пример скрипта можно взять с Github: https://github.com/ITDSystems/alvex-courses-extras/blob/master/2013-06-07/registry-migration/doc-reg-migrate-sample.js. Пример модели нового реестра выложен там же. Подробнее о создании своих типов реестров, а также скрипты для решения других часто встречающихся вопросов: на обучающих курсах Alvex (http://www.alvexcore.com/ru/services/consulting/) ;)
151