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
- Retrieve relationship definitions that identify which instance types reference the organization calendar.
- Deserialize
updatedBaseCalendarinto an OrganizationCalendar object. - 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.
- 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);
}
}
}