Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: event update http 400 due to description #190

Merged
merged 2 commits into from
Sep 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions sync-timeoffs/SyncTimeOffs.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,22 @@ async function syncTimeOffs() {
}


/** Example how to utilize the unsyncTimeOffs_() function.
*
*/
async function unsyncExample() {
await unsyncTimeOffs_('P32', '[email protected]', 0);
}

/** Utility function to unsynchronize certain events and delete the associated absence from Personio.
*
* @note This is a destructive operation, USE WITH UTMOST CARE!
*
* @param title The event title (only events whose title includes this string are de-synced).
* @param email (optional) The email of the user whose events are to be deleted.
* @param deleteConfig (optional) Specify 2 to also delete matching Personio time-offs which aren't linked to any Google calendar event, or specify 1 to only delete matching non-synced Personio time-offs, or 0 to only de-sync events.
*/
async function unsyncTimeOffs_(title) {
async function unsyncTimeOffs_(title, email, deleteConfig) {

const scriptLock = LockService.getScriptLock();
if (!scriptLock.tryLock(5000)) {
Expand All @@ -215,6 +224,9 @@ async function unsyncTimeOffs_(title) {
.map(d => d.trim());

const emailWhiteList = getEmailWhiteList_();
if (email) {
emailWhiteList.push(email);
}
const isEmailAllowed = email => (!emailWhiteList.length || emailWhiteList.includes(email))
&& allowedDomains.includes(email.substring(email.lastIndexOf('@') + 1));

Expand Down Expand Up @@ -254,6 +266,7 @@ async function unsyncTimeOffs_(title) {
for (const employee of employees) {

const email = employee.attributes.email.value;
const employeeId = employee.attributes.id.value;

// we keep operating if handling calendar of a single user fails
try {
Expand All @@ -266,9 +279,13 @@ async function unsyncTimeOffs_(title) {
return false;
}

const allEvents = await queryCalendarEvents_(calendar, 'primary', fetchTimeMin, fetchTimeMax);
Util.shuffleArray(allEvents);
const timeOffs = deleteConfig ? (await queryPersonioTimeOffs_(personio, fetchTimeMin, fetchTimeMax, employeeId)) : {};
now = Date.now();
if (now >= deadlineTs) {
return false;
}

const allEvents = await queryCalendarEvents_(calendar, 'primary', fetchTimeMin, fetchTimeMax);
for (const event of allEvents) {
const timeOffId = +event.extendedProperties?.private?.timeOffId;
if (timeOffId && (event.summary || '').includes(title)) {
Expand All @@ -277,6 +294,11 @@ async function unsyncTimeOffs_(title) {
break;
}

delete timeOffs[timeOffId];
if (deleteConfig === 1) {
continue;
}

try {
await deletePersonioTimeOff_(personio, {id: timeOffId});
} catch (e) {
Expand All @@ -289,6 +311,22 @@ async function unsyncTimeOffs_(title) {
Logger.log('De-synced event "%s" at %s for user %s', event.summary, event.start.dateTime || event.start.date, email);
}
}

for (const timeOff of Object.values(timeOffs)) {
let now = Date.now();
if (now >= deadlineTs) {
break;
}

if ((timeOff.comment || '').includes(title)) {
try {
await deletePersonioTimeOff_(personio, timeOff);
Logger.log('Deleted time-off "%s" at %s for user %s', timeOff.comment, timeOff.startAt, email);
} catch (e) {
Logger.log('Failed to remove time-off of user %s: %s', email, timeOff);
}
}
}
} catch (e) {
Logger.log('Failed to unsync matching time-offs/out-of-offices of user %s: %s', email, e);
firstError = firstError || e;
Expand Down Expand Up @@ -1040,6 +1078,12 @@ function createEventFromTimeOff_(timeOffTypeConfig, timeOff) {

/** Generate and add a link to the Personio Absence Calendar page for the specified TimeOffPeriod to this event. */
function updateEventPersonioDeepLink_(event, timeOff) {

if (event.eventType && event.eventType !== 'default') {
// outOfOffice and similar special events don't support the `description` field
return;
}

const employeeIdSafe = (+timeOff.employeeId).toFixed(0);
const timeOffTypeId = (+timeOff.typeId).toFixed(0);
const year = (+timeOff.startAt.year).toFixed(0);
Expand Down
Loading