Skip to main content

ProjectManagementService.SyncCalendarAsync

Reference

Task SyncCalendarAsync(Guid calendarId, string updatedBaseCalendar)

Re-synchronizes related calendars when an organization/base calendar is updated. The method accepts the id of the base calendar and a JSON payload (string) containing the updated base calendar object (serialized OrganizationCalendar). It updates working hours, non working hours first/last hour and merges non‑working hours into each related calendar.

Purpose

Keep calendars that reference a shared/base organization calendar in sync when the base calendar changes:

  • Replace FirstHour, LastHour, Working Hours and Non working Hours with values from base calendar.
  • Merge non-recurring holidays.

Parameters

  • calendarId — Guid of the base/organization calendar instance that was updated.
  • updatedBaseCalendar — JSON string representing the updated OrganizationCalendar (expected shape matches API.Contracts.OrganizationCalendar).

Returns

This method does not return a value.

High-level algorithm

  1. Retrieve relationship definitions that identify which instance types reference the organization calendar.
  2. Deserialize updatedBaseCalendar into an OrganizationCalendar object.
  3. For each relationship:
    • Fetch related instances (GetRelatedInstancesAsync) using the relation name and the target instance type; request the calendar schedule attribute('PMSCalendarSchedule').
    • For each related instance:
      • Read and deserialize its calendar schedule.
      • Overwrite FirstHour/LastHour/WorkingHours/Non Working Hours from base calendar.
      • Merge Holidays
      • Serialize updated calendar and prepare Instance object with 'PMSCalendarSchedule' set to updated JSON.
  4. Continue for all relationships.

Sample usage (server-side program)

// given calendarId and updatedBaseCalendarJson (string)
await ProjectManagementService.SyncCalendarAsync(calendarId, updatedBaseCalendarJson);

Sync Calendar in Pre Update Trigger

using Prorigo.Protrak.API.Contracts;
using Prorigo.Protrak.API.Services;
using Prorigo.Protrak.Programs;
using System.Linq;
using System.Threading.Tasks;
using Attribute = Prorigo.Protrak.API.Contracts.Attribute;

namespace Prorigo.Customization.Programs
{
public class SyncCalendar : IPreUpdateTriggerProgramAsync
{
public IProjectManagementService ProjectManagementService { get; set; }

private readonly string ATTRIBUTE_PMS_CALENDAR_SCHEDULE = "PMSCalendarSchedule";

public async Task<ProgramResult> RunAsync(Instance instance)
{
bool programResult = true;

var attrPMSCalendarSchedule = GetAttribute(instance, ATTRIBUTE_PMS_CALENDAR_SCHEDULE);
if (attrPMSCalendarSchedule != null && attrPMSCalendarSchedule.TextValue != null)
{
await ProjectManagementService.SyncCalendarAsync(instance.Id, attrPMSCalendarSchedule.TextValue);
}
if (programResult)
{
return new ProgramResult() { IsSuccess = true, Errors = null };
}
else
{
return new ProgramResult() { IsSuccess = false, Errors = new string[] { "Sample error message" } };
}
}

private static Attribute GetAttribute(Instance instance, string attributeName)
{
return instance.Attributes.FirstOrDefault(a => a.Name == attributeName);
}
}
}