...

Методы работы с планом проекта и проектными задачами, связями между ними

Тема в разделе "Примеры сценариев", создана пользователем mochalov, 22 авг 2024.

Метки:
  1. mochalov

    mochalov Участник

    В релизе 2024.7 были добавлены методы работы с календарным планом проекта и связями между задачами в TS SDK.
    Описаны типы и методы работы с ними
    https://tssdk.elma365.com/ru/2024.5/interfaces/_03_globals_.applicationproject.html
    https://tssdk.elma365.com/ru/2024.7/interfaces/_01_items_.applicationprojectitem.html
    https://tssdk.elma365.com/ru/2024.7/interfaces/_01_items_.applicationprojectplanelementitem.html
    https://tssdk.elma365.com/ru/2024.7/interfaces/_01_items_.applicationprojectitemref.html
    Ранее для создания планов проектов скриптом необходимо было создавать элементы приложений и учитывать связи между приложениями раздела. При работе реализованных таким образом скриптов часто сталкивались с ограничением производительности при отработке процессов.
    Новые методы работают с учетом архитектуры раздела, создают необходимые связки между элементами приложений и позволяют работать или с черновиком плана проекта или производить публикацию плана из скрипта.
    Также возможна работа с связями между задачами плана проекта, ранее эта возможность отсутствовала.

    Ниже прикреплю пример создания двух задач календарного плана и связей между ними
    Код:
    
    async function createNewPlan(): Promise<void> {//все то же самое, но получаем план проекта не на основании Черновика, а создаем новый
            
    const draft await Context.data._project!.createDraft();//создание черновика плана проекта
            
    if (draft){
                
    let elem1 draft.elements.create();//создание элемента в черновике плана. далее задание параметров создаваемой задачи
                
    elem1.data.__name 'elem1';
                
    elem1.data._element_type elem1.fields._element_type.variants.task;//тип задачи
                
    elem1.data._control elem1.fields._control.variants.not_required//поле "Контроль"
                
    elem1.data._start_date = new(TDate);
                
    elem1.data._end_date = new(TDate);
                
    elem1.data._end_date elem1.data._end_date.addDate(0,0,5);
                
    elem1.data._responsible await System.users.getCurrentUser();
                
    elem1.data._gantt_order 0;//порядок элемента на диаграмме ганта, обязательное поле. Если создаем циклом или дописываем элементы к существующему плану, обязательно должны вычислить порядковый номер последнего элемента в плане
                
    draft.elements.save(elem1);//сохранение элемента
                
    Context.data.debug '0';

                
    let elem2 draft.elements.create();//вторая задачка. аналогично предыдущему элементу
                
    elem2.data.__name 'elem2';
                
    elem2.data._control elem2.fields._control.variants.not_required;
                
    elem2.data._element_type elem1.fields._element_type.variants.task;
                
    elem2.data._start_date = new(TDate);
                
    elem2.data._end_date = new(TDate);
                
    elem2.data._end_date elem2.data._end_date.addDate(0,0,6);
                
    elem2.data._responsible await System.users.getCurrentUser();
                
    elem2.data._gantt_order 1;
                
    draft.elements.save(elem2);
                
    Context.data.debug '1';

                const 
    draftLink await draft.links.create();//создание переменной для хранения связей между элементами плана проекта
                
    draftLink.data.sourceElementId elem1.data.__id;//ид задачи-источника
                
    draftLink.data.targetElementId elem2.data.__id;//ид задачи-последователя
                
    draftLink.data.direction draftLink.fields.direction.variants[0];//направление связи. работает через указание конкретного индекса варианта как массива. возможно поправим позже
                
    draft.links.save(draftLink);//сохранение созданных связей
             
                
    await draft.save();//сохранение черновика плана проекта. в этот момент он появляется в системе и формируется как новая версия плана проекта со всеми элементами и связями, которые мы создали в скрипте
                
    Context.data.debug '2';
                
    await draft.publish();//публикация плана проекта. если не применим функцию, то план останется в статусе "Черновик"
                
    Context.data.debug '3';
            }
    }


    Данный функционал может иметь довольно широкое применение, например:
    - Создание календарного плана проекта на основании параметров проекта - реализация конструктора планов
    - Создание плана проекта на основании параметров Сделки
    - Расширение функционала генерации планов проектов по шаблону
    - Дополнение календарного плана задачами по результатам проектных совещаний на основании протокола
    - Миграция планов проектов из сторонних систем
    - Реализация кастомных виджетов и пользовательских отчетов с отображением связей между задачами
    и другое.

    Пример генерации плана проекта на 1000 элементов:
    Код:
    
    async function gen1k(): Promise<void> {
               const 
    draft await Context.data._project!.createDraft();
               const 
    responsible await System.users.getCurrentUser();
            if (
    draft){
                for (
    let i =0i<1000i++){
                
    let elem draft.elements.create();
                
    elem.data.__name 'elem1';
                
    elem.data._element_type elem.fields._element_type.variants.task;
                
    elem.data._control elem.fields._control.variants.not_required;
                
    elem.data._start_date = new(TDate);
                
    elem.data._end_date elem.data._start_date.addDate(0,0,i);
                
    elem.data._end_date = new(TDate);
                
    elem.data._end_date elem.data._end_date.addDate(0,0,i+2);
                
    elem.data._responsible responsible;
                
    elem.data._gantt_order i;
                
    draft.elements.save(elem);
                
    Context.data.debug '0';
                }
                
    await draft.save();
            }
    }
    Последнее редактирование: 23 авг 2024