PSI: Создание нового проекта с указанием обязательных полей

Вопросы, связанные с разработкой приложений для Microsoft Project

PSI: Создание нового проекта с указанием обязательных полей

Сообщение N1ght » 23 окт 2015, 15:35

Доброго времени суток, коллеги!
Возник очередной головняк, спущенный сверхов со словами "понятия не имею, может ли вообще так быть, но надо чтобы было"
Бекграунд.
Контора хочет вести в списке шарика данные по тендерам, причем, чтобы на определенном этапе (при определенном статусе внутри айтема списка) создавался проект в прожекте.
Я планирую наваять Custom WorkFlow Action, который бы дергал PSI-интерфейс для создания проекта. Касательно куска с WF мне еще только предстоит попытаться это сделать. Я подхожу, как совершенно нормальный адекватный разраб, а именно: ем слона по кусочкам.
Решил наваять консольную утилитку, которая через PSI-интерфейс создавала бы проект на сервере.
Суть проблемы:
Для создания проекта на проектном продакшен сервере требуется заполнять кастомные поля(которые представляют собой значения из таблиц подстановок для кастомных полей уровня проекта).
Что мне непонятно: Как именно мне забивать значения кастомных полей, чтобы проект все-таки создать. При попытке создания проекта без них совершенно естественно вылетает CustomFieldRequiredValueNotProvided exception.
Написал фанку, которая сопоставляет пользовательский ввод из айтема списка с значениями из соответствующих прожектовых таблиц подстановок и возвращает гуид этих вариантов.
Все вроде бы есть, но как именно мне напихать объект потенциального проекта этими полями, чтобы скормить фанке QueueCreateProject()?

PS. Разработка ведется для проектного сервера на базе MSPS'10 через его ASMX веб-сервисы (Project, QueueSystem, LookupFields)
N1ght
Белый пояс
 
Сообщения: 22
Зарегистрирован: 06 ноя 2014, 11:46
Откуда: Москва

Re: PSI: Создание нового проекта с указанием обязательных по

Сообщение oleksiy prosnitskyy » 23 окт 2015, 16:00

в 13 это делается через рп в дизайнере
oleksiy prosnitskyy
MVP
 
Сообщения: 1055
Зарегистрирован: 11 дек 2012, 21:16

Re: PSI: Создание нового проекта с указанием обязательных по

Сообщение Brise » 23 окт 2015, 18:04

N1ght писал(а):Что мне непонятно: Как именно мне забивать значения кастомных полей, чтобы проект все-таки создать. При попытке создания проекта без них совершенно естественно вылетает CustomFieldRequiredValueNotProvided exception.

В статье на MSDN, посвященной Project.QueueCreateProject, есть достаточно подробный пример с использованием пользовательских полей. И там даже есть характерный комментарий:
Код: Выделить всё
            // Comment-out the following line, to see an additional
            // CustomFieldRequiredValueNotProvided exception.
            projCF.CODE_VALUE = lookupTableMemberUid;
Brise
Синий пояс
 
Сообщения: 152
Зарегистрирован: 01 апр 2013, 07:52
Откуда: Санкт-Петербург

Re: PSI: Создание нового проекта с указанием обязательных по

Сообщение N1ght » 24 окт 2015, 08:01

2Алексей: Лёш, весь прикол в том, что в данном случае это самая что ни на есть интеграция с рподжекта с шариком и в стандартном функционале дизайнера такого нет.
2Brise: Спасибо, надо попробовать. Что-то я не заметил этого абзаца когда читал
N1ght
Белый пояс
 
Сообщения: 22
Зарегистрирован: 06 ноя 2014, 11:46
Откуда: Москва


Re: PSI: Создание нового проекта с указанием обязательных по

Сообщение N1ght » 26 окт 2015, 12:12

Приложу код.
Чет я уже буксовать начинаю.
Чувствую, что где-то что-то недоделал, но вот что...
Эксепшен теперь вылетает CustomFieldMustSpecifyEitherIDorUID

Код: Выделить всё
public struct NeccessaryCustomFields
        {
            public Guid CFGuid;
            public Guid CFValueGuid;
        }
static void Main(string[] args)
        {
            string projectName = "SomeProject";
            string projectDescription = "This is sample description";
            string contrAgent = "Заказчик";
            string direction = "внутренний";
            string projStatus = "инициатива";

            //Эти функции возвращают UID для Lookup table и UID искомого варианта значения
            GetLookupTableValueForStringProvided("Заказчики", contrAgent, out caLUUID, out caUID);
            GetLookupTableValueForStringProvided("Тип проекта", direction, out dLUUID, out dUID);
            GetLookupTableValueForStringProvided("Статус", projStatus, out sLUUID, out sUID);

            List<NeccessaryCustomFields> NCF = new List<NeccessaryCustomFields>();
            NCF.Add(new NeccessaryCustomFields { CFGuid = caLUUID, CFValueGuid = caUID });
            NCF.Add(new NeccessaryCustomFields { CFGuid = dLUUID, CFValueGuid = dUID });
            NCF.Add(new NeccessaryCustomFields { CFGuid = sLUUID, CFValueGuid = sUID });

            CreateProjectOnServer(projectName, projectDescription, NCF);
        }
        public static bool CreateProjectOnServer(string ProjectName, string ProjectDescription, List<NeccessaryCustomFields> CFList)
        {
            try
            {
                Guid jobID;
                ProjectWebSvc.Project projectSvc = new ProjectWebSvc.Project();
                ProjectWebSvc.ProjectDataSet projectDs = new ProjectWebSvc.ProjectDataSet();
                projectSvc.Url = PROJECT_SERVER_URI + PROJECT_SERVICE_PATH;
                projectSvc.UseDefaultCredentials = true;

                QueueSystemWebSvc.QueueSystem q = new QueueSystemWebSvc.QueueSystem();
                q.Url = PROJECT_SERVER_URI + QUEUESYSTEM_SERVICE_PATH;
                q.UseDefaultCredentials = true;

                ProjectWebSvc.ProjectDataSet.ProjectRow projectRow = projectDs.Project.NewProjectRow();
                projectRow.PROJ_UID = Guid.NewGuid();
                projectRow.PROJ_NAME = ProjectName;
                projectRow.WPROJ_DESCRIPTION = ProjectDescription;
                projectRow.PROJ_TYPE = (int)PSLibrary.Project.ProjectType.Project;

                projectDs.Project.AddProjectRow(projectRow);
                projectDs = PopulateProjectData(projectDs, CFList);
               
                jobID = Guid.NewGuid();
                projectSvc.QueueCreateProject(jobID, projectDs, false);
                WaitForQueue(q, jobID);
            }
#region Exception handling
            catch (SoapException ex)
            {
                //бла....бла....бла
            }
            catch (WebException ex)
            {
                //бла....бла....бла
            }
            catch (Exception ex)
            {
                //бла....бла....бла
            }
            finally
            {
                Console.ResetColor();
            }
#endregion
            return false;
        }

        public static ProjectWebSvc.ProjectDataSet PopulateProjectData(ProjectWebSvc.ProjectDataSet pDS, List<NeccessaryCustomFields> CFList)
        {
            //ProjectWebSvc.ProjectDataSet.ProjectCustomFieldsRow projCF = pDS.ProjectCustomFields.NewProjectCustomFieldsRow();
            foreach (NeccessaryCustomFields item in CFList)
            {
                ProjectWebSvc.ProjectDataSet.ProjectCustomFieldsRow projCF = pDS.ProjectCustomFields.NewProjectCustomFieldsRow();
                projCF.CUSTOM_FIELD_UID = item.CFGuid;
                projCF.PROJ_UID = pDS.Project[0].PROJ_UID;
                projCF.SetNUM_VALUENull();
                projCF.SetFLAG_VALUENull();
                projCF.SetDUR_VALUENull();
                projCF.SetDUR_FMTNull();
                projCF.SetDATE_VALUENull();
                projCF.SetTEXT_VALUENull();
                projCF.CODE_VALUE = item.CFValueGuid;

                pDS.ProjectCustomFields.AddProjectCustomFieldsRow(projCF);
            }
            return pDS;
        }
N1ght
Белый пояс
 
Сообщения: 22
Зарегистрирован: 06 ноя 2014, 11:46
Откуда: Москва

Re: PSI: Создание нового проекта с указанием обязательных по

Сообщение Brise » 26 окт 2015, 14:23

N1ght писал(а):Чувствую, что где-то что-то недоделал, но вот что...

Вообще, если код никак не отрабатывает, то рановато его разбивать на методы, потому что делать пример для форума станет неудобно ;)

N1ght писал(а):Эксепшен теперь вылетает CustomFieldMustSpecifyEitherIDorUID

Подозреваю, что сообщение связано с этой строчкой:
Код: Выделить всё
                projCF.CUSTOM_FIELD_UID = item.CFGuid;

А вот эти точно нужны?
Код: Выделить всё
                projCF.SetNUM_VALUENull();
                projCF.SetFLAG_VALUENull();
                projCF.SetDUR_VALUENull();
                projCF.SetDUR_FMTNull();
                projCF.SetDATE_VALUENull();
                projCF.SetTEXT_VALUENull();
Brise
Синий пояс
 
Сообщения: 152
Зарегистрирован: 01 апр 2013, 07:52
Откуда: Санкт-Петербург

Re: PSI: Создание нового проекта с указанием обязательных по

Сообщение N1ght » 26 окт 2015, 15:10

Brise писал(а):Вообще, если код никак не отрабатывает, то рановато его разбивать на методы, потому что делать пример для форума станет неудобно ;)

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

Brise писал(а):Подозреваю, что сообщение связано с этой строчкой:
Код: Выделить всё
                projCF.CUSTOM_FIELD_UID = item.CFGuid;

Решил заняться реверс-инжинирингом базы по уже существующему проекту. в итоге так и не понял откуда берется CUSTOM_FIELD_UID. Такое впечатление, что это просто уникальный идентификатор записи, который нужно просто сгенерировать новым Guid.NewGuid();


Brise писал(а):А вот эти точно нужны?
Код: Выделить всё
                projCF.SetNUM_VALUENull();
                ...

Нет, в принципе, совершенно не обязательно их задавать, однако в статье MSDN задание данных параметров считается gcs (good-coding style).
N1ght
Белый пояс
 
Сообщения: 22
Зарегистрирован: 06 ноя 2014, 11:46
Откуда: Москва

Re: PSI: Создание нового проекта с указанием обязательных по

Сообщение N1ght » 26 окт 2015, 15:48

Резюм:
Мне удалось программно создать проект на сервере.
Я был в итоге прав CUSTOM_FIELD_UID - это рядовой гуид записи для таблицы кастомных полей.
N1ght
Белый пояс
 
Сообщения: 22
Зарегистрирован: 06 ноя 2014, 11:46
Откуда: Москва


Вернуться в Разработка и программирование для Microsoft Project

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3