API: Пример работы с таймшитом

Создание таймшита

Таймшиты создаются автоматически при выполнении ряда запросов.

Получение Id таймшита на дату для пользователя:

[GET] https://api.workpoint.app/odata/TimeSheets/WP.GetIdForPeriod(date=2021-03-22,userId=fdcc3910-8fe0-400b-9805-51efd6ca504d)
Response:
{
  "value": "cd935d85-09ec-48fc-8103-7c0baa3afebc"
}

Функция WP.GetIdForPeriod в коллекции TimeSheets принимает два параметра: date и userId. Если на указанную дату таймшит еще не создан, то он создается (на период в соответствии с настройками периодов таймшитов). Возвращается Id таймшита.

Получение Id следующего/предыдущего таймшита:

[GET] https://api.workpoint.app/odata/TimeSheets(cd935d85-09ec-48fc-8103-7c0baa3afebc)/WP.GetNextTimeSheetId
Response:
{
  "value": "362acda4-dfd9-4429-9290-78a97f0e7e0f"
}

Функция WP.GetNextTimeSheetId и WP.GetPreviousTimeSheetId в сущности TimeSheet не требует параметров. Если следующий/предыдущий таймшит еще не создан, то он создается (на период в соответствии с настройками периодов таймшитов). Возвращается Id таймшита.

Получение таймшита

Получить таймшит или коллекцию таймшитов можно стандартными OData запросами.

Обратите внимание на вложенный expand — в данном примере сразу запрашивается коллекция строк и «ячеек» строк. Так же сразу можно «раскрыть» любые связанные сущности, например получить имя или код проекта по строкам:

[GET] https://api.workpoint.app/odata/TimeSheets(97b5c8bc-c411-4518-8927-953fe3e7a79c)?$expand=TimeSheetLines($expand=TimeAllocations)

Response:
{
    "rowVersion": "AAAAAAAADMQ=", // Версия
    "id": "97b5c8bc-c411-4518-8927-953fe3e7a79c", // ИД
    "created": "2021-02-22T08:55:46.6233881+03:00", // Дата создания
    "isActive": true, // Системный признак
    "dueDate": "2021-03-02", // Срок отправки
    "dateFrom": "2021-02-22", // Начало периода
    "dateTo": "2021-02-28", // Окончание периода
    "approvalStatusId": "0aefb600-42fb-4aa5-991c-d70dc7ac7b27", // ИД статуса согласования
    "submitted": null, // Дата отправки на согласования
    "approved": null, // Дата согласования
    "userId": "fdcc3910-8fe0-400b-9805-51efd6ca504d", // ИД пользователя
    "departmentId": "9468cd5c-ea04-4adb-a1d7-94b6b910ab2e", // ИД подразделения (в которое на момент создания ТШ входил пользователь)
    "approvalInstanceId": null, // ИД текущего процесса согласования
    "templateId": "e590d1c1-50e8-467b-a9b5-787cca869446", // ИД шаблона таймшита
    "name": "Иван Агафонов 22.02.2021-28.02.2021", // Наименование для отображения в списках
    "billableDuration": 3.00000, // Сумма оплачиваемых часов в таймшите
    "nonBillableDuration": 24.00000, // Сумма неоплачиваемых часов в таймшите
    "editAllowed": true, // Признак разрешения на редактирования (пользователем, который выполнил запрос)
    "deleteAllowed": true, // Признак разрешения на удаление 
    "submitAllowed": true, // Признак разрешения на отправку на согласование 
    "forceSubmitAllowed": true, // Признак разрешения на принудительную отправку на согласование (минуя правила)
    "reopenAllowed": false, // Признак разрешения на переоткрытие
    "executeAllowed": false, // Признак разрешения на согласование/отклонение
    "forceExecuteAllowed": false, // Признак разрешения на принудительное согласование/отклонение
    "schedule": [ // Коллекция дней с часами по расписанию для автора пользователя
        {
            "date": "2021-02-22",
            "duration": 8.00
        },
    ***
    ],
    "timeSheetLines": [ // Коллекция строк таймшита
        {
            "id": "172ab42a-bacd-459a-bfea-56056c8f9272",
            "created": "2021-02-22T09:13:55.3098618+03:00",
            "isActive": true,
            "rowVersion": "AAAAAAAADMU=",
            "date": null,
            "activityId": null, // ИД вида работ
            "billingRateId": null, // ИД тарифа
            "projectId": "6ce1f7e7-b88c-4106-8833-d4ac30d6ba15", // ИД проекта
            "projectTaskId": "87ddeadc-2793-4b79-a5aa-6774cd6e6e81", // ИД задачи
            "orderNumber": 0, // Порядковый номер
            // + CUSTOM FIELDS
            "timeAllocations": [ // Коллекция "ячеек" строки
                {
                    "id": "0164f849-611e-4f10-a813-b4a39172aecd",
                    "created": "2021-02-22T09:14:00.9419888+03:00",
                    "isActive": true
                    "date": "2021-02-22", // Дата ячейки
                    "duration": 3.00000, // Длительность работ в часах
                    "comments": "", // Текстовый комментарий
                    "invoiceLineId": null, // ИД линии счета
                    "timeOffRequestId": null, // ИД заявки на отсутствие 
                    // + CUSTOM FIELDS
                    
                }
            ]
        }
    ]
}

Обновление таймшита

Для обновления таймшита рекомендуется создавать отдельный объект, а не модифицировать полученный (поскольку требуется передавать только сохраняемые поля).

[PUT] https://api.workpoint.app/odata/TimeSheets(97b5c8bc-c411-4518-8927-953fe3e7a79c)
Body:
{
  "id": "97b5c8bc-c411-4518-8927-953fe3e7a79c", // ИД существующего ТШ
  "name": "Иван Агафонов 22.02.2021-28.02.2021", // Произвольная срока
  "rowVersion": "AAAAAAAADMI=", // Актуальная версия
  "timeSheetLines": [ // Массив строк таймшита
    {
      "id": "172ab42a-bacd-459a-bfea-56056c8f9272",
      "timeAllocations": [ // Массив ячеек по строке
        {
          "id": "0164f849-611e-4f10-a813-b4a39172aecd",
          "duration": 3.25, // Длительность в часах
          "comments": "", // Текстовый комментарий
          "date": "2021-02-22" // Дата
        }
      ],
      "projectId": "6ce1f7e7-b88c-4106-8833-d4ac30d6ba15", // ИД проекта
      "activityId": "8c0d731b-fc11-4ac1-ba23-566f8b33f848", // ИД Вида работ
      "projectTaskId": "87ddeadc-2793-4b79-a5aa-6774cd6e6e81", // ИД задачи проекта
      "orderNumber": 0 // Порядковый номер строки
    }
  ]
}

Объект TimeSheet:

  • id — идентификатор (GUID).
  • name — строка.
  • rowVersion — актуальная версия таймшита. Если будет отличаться от сохраненной — будет исключение, после обновления автоматически генерируется новая версия.
  • timeSheetLines — массив строк, в примере одна строка.


Объект TimeSheetLine:

  • id — идентификатор (GUID).
  • projectId, projectTaskId, activityId — идентификаторы выбранных аналитик (проекта, задачи и вида работ). Обратите внимание, что передается не объект (project, activity...), а id объекта (projectId, activityId...).
  • orderNumber: порядковый номер строки. Нумерация должна быть от 0 и должна быть строго последовательной. Это проверяется сервером и если нумерация нарушена — будет исключение.
  • timeAllocations — коллекция «ячеек» строки.

Объект TimeAllocation:

  • id — идентификатор (GUID).
  • date — дата ячейки.
  • comments — текстовый комментарий
  • duration — длительность работ в часах.

Cвязанныt коллекциb, в данном случае timeSheetLines и timeAllocations, при обновлении таймшита будут обновлены автоматически, т.е. можно убрать из массивов некоторые объекты, добавить новые, обновить существующие и сервер сам обновит коллекции в БД оптимальным способом.

Вспомогательные функции

Получение списка проектов, доступных для списания времени
Функция сущности таймшита WP.GetProject принимает опциональный параметр organizationId (используется для фильтрации) и возвращает список проектов, на которые можно списывать время:

[GET] https://api.workpoint.app/odata/TimeSheets(d374d1cb-6baf-46c5-9343-234b555d6240)/WP.GetProjects
[GET] ***/WP.GetProjects(organizationId=4c32331b-2c8c-47fa-a1d6-734f4ab8f508)
Response:
{ "value": [ { "id": "31db2084-03c6-45f7-b46b-8f59ab197db9", // ИД проекта "name": "Тех. поддержка Сибур 2019", // Наименование проекта "code": "SUP-02-2021", // Код проекта "organizationId": "8bac8ce0-5963-434a-8d35-a01ec71c5232", // ИД организации (клиента) "organizationName": "Сибур", // Имя организации "billingTypeCode": "TM" // Тип биллинга проекта (код: TM, NonBillable, FixedBid) }, *** ] }

Получение списка задач, доступных для списания времени
Функция сущности таймшита WP.GetProjectTasks принимает обязательный параметр projectId и возвращает список задач, на которые можно списывать время:

[GET] https://api.workpoint.app/odata/TimeSheets(d374d1cb-6baf-46c5-9343-234b555d6240)/WP.GetProjectTasks(projectId=3fa44ea0-df3b-47f0-bc62-fea3554c6c3c)
Response:
{
    "value": [
        {
            "id": "38191214-6139-4350-98f6-669cfe4f00a2", // ИД задачи
            "name": "Исследование", // Имя задачи
            "number": 0, // Номер в ветке
            "structNumber": "1", // Структурный номер (1.1.1)
            "indent": 1, // Уровень задачи
            "leadTaskId": "2d72ec17-e712-4759-822f-a938ba7780ad", // ИД ведущей задачи (если null, то это главная задача проекта)
            "projectId": "3fa44ea0-df3b-47f0-bc62-fea3554c6c3c", // ИД проекта
            "allowEntry": true // Признак доступности писания времени
        },
       
       ***
    ]
}

В списке может быть передана задача, даже если она «закрыта» или на неё нет назначений (т.е. на неё нельзя списывать время), но она ведущая для другой задачи, на которую доступно списание времени. Такая задача имеет свойства allowEntry = false и они необходимы для формирования "дерева" задач, если это требуется.