diff --git a/shifts.ps1 b/shifts.ps1 index a0a2207..d9b68a3 100644 --- a/shifts.ps1 +++ b/shifts.ps1 @@ -1,18 +1,19 @@ param( [switch]$debug, - [switch]$clear + [switch]$clear, + [switch]$noplan ) if ($debug) { $script:debug = $debug } - +if($noplan) { + $script:noplan = $noplan +} $teamsName = "IT Support & Delivery" $scheduleGroupName = "IT SUPPORT" - -# App Registration details & Tenant ID $ClientId = "6cb76bbf-f253-4551-87a8-5e1f49d8ace3" $ClientSecret = "IQg8Q~JTBTDbrHyjKMc.KMSETtQoKWvUhnCr1aY1" $tenantid = "e81b4a31-e8ad-4df6-aa30-3bdcc1da2cdd" @@ -31,7 +32,6 @@ function Write-Debug { } } -#Naplánování konkrétní směny function Set-Shift { param( [string]$userId, @@ -55,19 +55,34 @@ function Set-Shift { } } - #$headers = @{ - # "MS-APP-ACTS-AS" = $userIdAdmin - # "Prefer" = "no-notification" - #} + if($script:noplan -eq $false) { + $newShift = New-MgTeamScheduleShift -TeamId $teamID -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } + Write-Debug("{0} {1}: setting {2}'s shift - {3} {4}-{5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shiftName, $StartDate, $EndDate) + } + else { + Write-Debug("{0} {1}: Not setting {2}'s shift - {3} {4}-{5} - running with -noplan" -f $dayDate, $dayDate.DayOfWeek, $mail, $shiftName, $StartDate, $EndDate) + $newshift = 0 + } + - $newShift = New-MgTeamScheduleShift -TeamId $teamID -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } - #Write-Debug ("SCHEDULING: {0} {1} - {2}" -f $newShift.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.Notes) - #("SCHEDULING: {0} {1} - {2}" -f $newShift.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.Notes) | Add-Content -Path $logPath - Write-Debug("{0} {1}: {2} {3} {4} {5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shiftName, $StartDate, $EndDate) - #$newShift = 0 return $newShift } +function Remove-Shift { + param( + [PSCustomObject]$shift, + [string]$teamID + ) + + if($script:noplan -eq $false) { + Write-Debug("{0} {1}: removing {2}'s shift - {2} {3}-{4}" -f $dayDate, $dayDate.DayOfWeek, $futureds_email, $shift.Notes, $shift.StartDateTime, $shift.EndDateTime) + Remove-MgTeamScheduleShift -ShiftId $shift.id -TeamId $teamID + } + else { + Write-Debug("{0} {1}: Not removing {2}'s shift - {2} {3}-{4} - running with -noplan" -f $dayDate, $dayDate.DayOfWeek, $futureds_email, $shift.Notes, $shift.StartDateTime, $shift.EndDateTime) + } +} + function Invoke-HasTimeOff { param( [string]$UID, @@ -77,7 +92,7 @@ function Invoke-HasTimeOff { foreach ($toff in $timeoff) { if($toff.UserId -eq $UID) { - Write-Debug("{0} {1}: {2} has time off at this time" -f $dayDate, $dayDate.DayOfWeek, $mail) + Write-Debug("{0} {1}: {2} has time off" -f $dayDate, $dayDate.DayOfWeek, $mail) return $true break } @@ -93,7 +108,7 @@ function Invoke-HasShift { foreach ($shift in $shifts) { if($shift.UserId -eq $UID) { - Write-Debug("{0} {1}: {2} has a shift at this time" -f $dayDate, $dayDate.DayOfWeek, $mail) + Write-Debug("{0} {1}: {2} has a shift already - {3} {4}-{5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime) return $true break } @@ -111,7 +126,7 @@ function Invoke-HasShiftorTimeOff { foreach ($shift in $shifts) { if($shift.UserId -eq $UID) { - Write-Debug("{0} {1}: {2} has a shift or time off at this time: {3} {4} {5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime) + Write-Debug("{0} {1}: {2} has a shift already - {3} {4}-{5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime) return $true break } @@ -119,7 +134,7 @@ function Invoke-HasShiftorTimeOff { foreach ($toff in $timeoff) { if($toff.UserId -eq $UID) { - Write-Debug("{0} {1}: {2} has a shift or time off at this time: {3} {4}" -f $dayDate, $dayDate.DayOfWeek, $mail, $toff.SharedTimeOff.StartDateTime, $Toff.SharedTimeOff.EndDateTime) + Write-Debug("{0} {1}: {2} has time off" -f $dayDate, $dayDate.DayOfWeek, $mail) return $true break } @@ -127,8 +142,6 @@ function Invoke-HasShiftorTimeOff { return $false } -#Microsoft auth - $body = @{ grant_type = "client_credentials" resource = "https://graph.microsoft.com" @@ -143,14 +156,10 @@ $token = $response.access_token Import-Module Microsoft.Graph.Teams Connect-MgGraph -AccessToken $($token | ConvertTo-SecureString -AsPlainText -Force) >> $null -# Dnešní datum a plán směn - -#$today = (Get-Date).Date -#$today = $today_old.AddYears(2) -$today = Get-Date -Day 25 -Month 1 -Year 2027 -Hour 9 -Minute 00 -Second 00 -Millisecond 00 - +# ---| SCHEDULE |--- $schedule = Get-Content -Path "./config.json" -Raw | ConvertFrom-Json +# ---| ALL MEMBERS SPECIFIED IN THE SCHEDULE |--- $allemails = $schedule.PSObject.Properties | ForEach-Object { if ($_.Name -in @("monday", "tuesday", "wednesday", "thursday", "friday")) { $_.Value.PSObject.Properties | ForEach-Object { @@ -163,189 +172,183 @@ $allemails = $schedule.PSObject.Properties | ForEach-Object { } } | Select-Object -Unique -#Časové rozmezí plánování +# --------------------------- | DATE SETTINGS | --------------------------- -#$Monday = $today.AddDays(1 - $today.DayOfWeek.value__) -#$Friday = $Monday.AddDays(4) -$daysahead = 5 +# ---| Today's date |--- +$today = (Get-Date).Date +# ---| Specific date |--- +#$today = Get-Date -Day 27 -Month 10 -Year 2025 -Hour 9 -Minute 00 -Second 00 -Millisecond 00 + +$daysahead = 14 #How many days ahead to plan +$timeoff_past_look = -7 #How many days to look into the past for the start of a multi-day time off + +# ---| Time span |--- $startSpanDate = Get-Date -Day $today.Day -Month $today.Month -Year $today.Year -Hour 9 -Minute 00 -Second 00 -Millisecond 00 $endSpanDate = Get-Date -Day $startSpanDate.AddDays($daysahead).Day -Month $startSpanDate.AddDays($daysahead).Month -Year $startSpanDate.AddDays($daysahead).Year -Hour 17 -Minute 00 -Second 00 -Millisecond 00 -#RLCZ maintenance +# --------------------------- | RLCZ MAINTENANCE SETTINGS | --------------------------- + $rlcz_mtnc_email = "jiri.kotlan@itego.cz" -$rlcz_shift_reduction = -3 +$rlcz_shift_reduction = -3 #How many hours does the next day shift get reduced by +# --------------------------- | MAIN SCRIPT | --------------------------- -# SKRIPT try { $team = Get-MgTeam -Property "id,displayName" | Where-Object -property displayName -value $teamsName -eq $group = Get-MgTeamScheduleSchedulingGroup -TeamId $team.id -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Where-Object -property displayName -value $scheduleGroupName -eq $allshifts = [object[]] (Get-MgTeamScheduleShift -TeamId $team.id -Filter "SharedShift/StartDateTime ge $($startSpanDate.toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }) - $timeoff_all = [object[]] (Get-MgTeamScheduleTimeOff -TeamId $team.id -Filter "SharedTimeOff/StartDateTime ge $($startSpanDate.toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Select-Object -Property *,@{name="Date";expression={$_.SharedTimeOff.StartDateTime.AddHours(1).Date}}) + $timeoff_all = [object[]] (Get-MgTeamScheduleTimeOff -TeamId $team.id -Filter "SharedTimeOff/StartDateTime ge $($startSpanDate.AddDays($timeoff_past_look).toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Select-Object -Property *,@{name="Date";expression={$_.SharedTimeOff.StartDateTime.AddHours(1).Date}}) - #return + # ---| SHIFT CLEARING with -clear |--- + if ($clear) { + foreach ($shift in $allshifts) { + if($shift.SharedShift.Notes -ne "RLCZ") { + Remove-Shift -shift $shift -teamID $team.Id + } + } + return + } - #$timeoff_today = $timeoff_all | Where-Object -Property Date -eq -Value $(Get-Date -Day 20 -Month 1 -Year 2027).Date - - #$spec_day = Get-Date -Day 27 -Month 1 -Year 2027 -Hour 9 -Minute 00 -Second 00 -Millisecond 00 - - #$rl_dateStart = $(get-date -Day $spec_day.Day -Month $spec_day.Month -Year $spec_day.Year -Hour 18 -Minute 00 -Second 00).AddHours(-1) - #$rl_dateEnd = $(get-date -Day $spec_day.Day -Month $spec_day.Month -Year $spec_day.Year -Hour 23 -Minute 00 -Second 00).AddHours(-1) - - #if (($dayDate.IsDaylightSavingTime()) -eq $true) { - # $rl_dateStart = $rl_dateStart.AddHours(-1) - # $rl_dateEnd = $rl_dateEnd.AddHours(-1) - #} - - #$params = @{ - # UserId = $userId = $(Get-MgUser -Filter "UserPrincipalName eq 'jiri.kotlan@itego.cz' or proxyAddresses/any(c:c eq 'smtp:jiri.kotlan@itego.cz')").Id - # schedulingGroupId = $group.Id - # sharedShift = @{ - # notes = ("RLCZ") - # startDateTime = [System.DateTime]::Parse($rl_dateStart.ToString("yyyy-MM-dd'T'HH:mm:ssZ")) - # endDateTime = [System.DateTime]::Parse($rl_dateEnd.ToString("yyyy-MM-dd'T'HH:mm:ssZ")) - # theme = "yellow" - # } - #} - - #New-MgTeamScheduleShift -TeamId $team.Id -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } - - #return - - #$headers = @{ - # "MS-APP-ACTS-AS" = $userIdAdmin - # "Prefer" = "no-notification" - #} - - - #if ($clear) { - # foreach ($shift in $allshifts) { - # Remove-MgTeamSchedu#leShift -TeamId $team.id -ShiftId $shift.id - # } -# -# return -# } - - - #Procházíme dny v časovém rozmezí + $timeSpan = New-TimeSpan -Start $startSpanDate -End $endSpanDate Write-Debug("Planning from {0} to {1}" -f $startSpanDate, $endSpanDate) + + # ---| DAY LOOP |--- for ($dayNumber = 0; $dayNumber -lt $timespan.Days; $dayNumber++) { $dayDate = $today.AddDays($dayNumber); - #Pokud jde o pracovní den, jinak se jde ihned na další den - if ($dayDate.DayOfWeek -notin @("Saturday", "Sunday")) { - #Inicializace dne + # ---| WEEKEND CHECK |--- + if($dayDate.DayOfWeek -in @("Saturday", "Sunday")) { + Write-Debug("{0} {1}: skipping weekend day" -f $dayDate, $dayDate.DayOfWeek) + continue + } + + # ---| NEW DAY INIT |--- + $ds_shift_inplace = $false + $ho_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ho' + $ds_email = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ds' + $os_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'os' + $ns_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ns' + + # ---| TIME SYNC |--- + $dateStart = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 9 -Minute 00 -Second 00).AddHours(-1) + $dateEnd = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 17 -Minute 00 -Second 00).AddHours(-1) + + if (($dayDate.IsDaylightSavingTime()) -eq $true) { + $dateStart = $dateStart.AddHours(-1) + $dateEnd = $dateEnd.AddHours(-1) + } + + $dayEnd = Get-Date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 23 -Minute 00 -Second 0 + $dayStart = $dayEnd.AddDays(-1) + + # ---| TODAY'S SHIFTS AND TIME OFF |--- + $shifts_today = [Object[]] $allshifts | Where-Object -Filter { + $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm") + } + + $timeoff_today = [Object[]] $timeoff_all | Where-Object { + $_.SharedTimeOff.StartDateTime.Date -le $dayStart.Date -and + $_.SharedTimeOff.EndDateTime.Date -ge $dayEnd.Date + } + + $manual_dayshifts = [Object[]] $shifts_today | Where-Object -Filter { ($_.SharedShift.Notes -eq "Home Office - Denní směna") -or ($_.SharedShift.Notes -eq "Office - Denní směna") } + + if ($null -eq $manual_dayshifts) { $ds_shift_inplace = $false - - #Množina emailů pro tento den v týdnu co mají mít home office - $ho_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ho' + Write-Debug("{0} {1}: day shift not yet set" -f $dayDate, $dayDate.DayOfWeek) + } + else { + $ds_shift_inplace = $true + Write-Debug("{0} {1}: day shift set already" -f $dayDate, $dayDate.DayOfWeek) + } - #Email a ID toho kdo má mít tento den denní směnu - $ds_email = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ds' + # ---| TEAM MEMBER LOOP |--- + foreach($email in $allemails) { + $userId = $(Get-MgUser -Filter "UserPrincipalName eq '$email' or proxyAddresses/any(c:c eq 'smtp:$email')").Id - #Emaily těch co jsou on-site u zákazníka - $os_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'os' + # ---| DAY SHIFT CHECK |--- + if($ds_shift_inplace -eq $false) { + if($email -eq $ds_email) { + Write-Debug("{0} {1}: checking {2} for day shift availability..." -f $dayDate, $dayDate.DayOfWeek, $email) - #Emaily těch co nemají mít dnes žádnou směnu - $ns_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ns' - - #Upravení času - $dateStart = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 9 -Minute 00 -Second 00).AddHours(-1) - $dateEnd = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 17 -Minute 00 -Second 00).AddHours(-1) - - if (($dayDate.IsDaylightSavingTime()) -eq $true) { - $dateStart = $dateStart.AddHours(-1) - $dateEnd = $dateEnd.AddHours(-1) - } - - $shifts_today = [Object[]] $allshifts | Where-Object -Filter { - $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm") - } - - #$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { - # ($_.SharedTimeOff.StartDateTime.Date -eq $dateStart.Date -or $_.SharedTimeOff.EndDateTime.Date -eq $dateEnd.Date) - #} - - $timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { - ($_.SharedTimeOff.EndDateTime.Date -eq $dateEnd.Date) - } - - # Tohle jsou všechny způsoby co jsem zkoušel, nikdy to nematchne, nikdy to nevidí dovolenou - - #$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.AddDays(1).ToString("yyyy-MM-dd HH:mm") -and $_.SharedTimeOff.EndDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.AddDays(-1).ToString("yyyy-MM-dd HH:mm") } - #$timeoff_today = [Object[]] $timeoff_all | Where-Object { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime -lt $dateEnd -and $_.SharedTimeOff.EndDateTime -gt $dateStart } - #$timeoff_today = $timeoff_all | Where-Object { $_.schedulingGroupId -eq $group.Id -and ([datetime]$_.SharedTimeOff.StartDateTime) -lt $dayEnd -and ([datetime]$_.SharedTimeOff.EndDateTime) -gt $dayStart } - #$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-ddT00:00:00Z") -and $_.SharedTimeOff.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.AddDays(1).ToString("yyyy-MM-ddT00:00:00Z") } - #$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-ddT00:00:00Z") -and $_.SharedTimeOff.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-ddT00:00:00Z") } - #Pokus o naplnění množiny manuálně daných denních směn pro tento den - $manual_dayshifts = [Object[]] $shifts_today | Where-Object -Filter { ($_.SharedShift.Notes -eq "Home Office - Denní směna") -or ($_.SharedShift.Notes -eq "Office - Denní směna") } - - if ($null -eq $manual_dayshifts) { - $ds_shift_inplace = $false - Write-Debug("{0} {1}: day shift not set" -f $dayDate, $dayDate.DayOfWeek) - foreach($shift in $manual_dayshifts) { - Write-Debug("{0}: {1}-{2}"-f $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime) - } - } - else { - $ds_shift_inplace = $true - Write-Debug("{0} {1}: day shift set already" -f $dayDate, $dayDate.DayOfWeek) - foreach($shift in $manual_dayshifts) { - Write-Debug("{0}: {1}-{2}"-f $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime) - } - } - - foreach($email in $allemails) { - $userId = $(Get-MgUser -Filter "UserPrincipalName eq '$email' or proxyAddresses/any(c:c eq 'smtp:$email')").Id - - if($ds_shift_inplace -eq $false) { - if($email -eq $ds_email) { - Write-Debug("{0} {1}: checking {2} for day shift availability..." -f $dayDate, $dayDate.DayOfWeek, $email) - foreach($toff in $timeoff_today) { - if($toff.UserId -eq $userId) { - Write-Debug("{0}: {1} {2}" -f $email, $toff.SharedTimeOff.StartDateTime, $toff.SharedTimeOff.EndDateTime) - } + # ---| IF DAY SHIFT CAN BE ASSIGNED TO THE PROPER MEMEBER |--- + if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { + # ---| HOME-OFFICE DAY SHIFT |--- + if ($email -in $ho_emails) { + $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email + $allshifts += [Object[]] $newshift + $ds_shift_inplace = $true + continue } - if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { - if ($email -in $ho_emails) { - $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email - $allshifts += [Object[]] $newshift - $ds_shift_inplace = $true + # ---| OFFICE DAY SHIFT |--- + else { + $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email + $allshifts += [Object[]] $newShift + $ds_shift_inplace = $true + continue + } + } + + # ---| DAY SHIFT REPLACEMENT CHECK |--- + else { + Write-Debug("{0} {1}: looking ahead for a day shift replacement" -f $dayDate, $dayDate.DayOfWeek) + $remainingdays = $timespan.Days - $dayNumber + + # ---| FUTURE DAYS LOOP |--- + for ($daysahead = 1; $daysahead -lt $remainingdays; $daysahead++) { + $futureday = $dayDate.AddDays($daysahead) + + # ---| WEEKEND CHECK |--- + if ($futureday.DayOfWeek -in @("Saturday", "Sunday")) { + Write-Debug(">>> {0} {1}: skipping weekend day" -f $futureday, $futureday.DayOfWeek, $futureds_email) continue } - else { - $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email - $allshifts += [Object[]] $newShift - $ds_shift_inplace = $true - continue - } - } - else { - #Budeme hledat ve zbývajících dnech zvoleného rozsahu - Write-Debug("{0} {1}: looking ahead for a day shift replacement" -f $dayDate, $dayDate.DayOfWeek) - $remainingdays = $timespan.Days - $dayNumber - for ($daysahead = 1; $daysahead -lt $remainingdays; $daysahead++) { - $futureday = $dayDate.AddDays($daysahead) - #Pokud jsme narazili na pracovní den... - if ($futureday.DayOfWeek -notin @("Saturday", "Sunday")) { - #...jdeme se podívat kdo má mít denní směnu - $futureds_email = $schedule.($futureday.DayOfWeek.ToString().ToLower()).'ds' - Write-Debug(">>> {0} {1}: {2} has it on that day" -f $futureday, $futureday.DayOfWeek, $futureds_email) - $futureds_id = $(Get-MgUser -Filter "UserPrincipalName eq '$futureds_email' or proxyAddresses/any(c:c eq 'smtp:$futureds_email')").Id - #Má další na řadě nastavenou na dnešek směnu? Pokud ne tak má denní a hledání ukončujeme, jinak se jde na další den - if((Invoke-HasTimeOff -UID $futureds_id -timeoff $timeoff_today -mail $futureds_email) -eq $false -and ($futureds_email -notin $os_emails) -and ($futureds_email -notin $ns_emails)) { - Write-Debug(">>> {0} {1}: {2} doesn't have time off, on site or no-shift on {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek) - if((Invoke-HasShift -UID $futureds_id -shifts $shifts_today -mail $futureds_email) -eq $false) { - Write-Debug(">>> {0} {1}: {2} ID: {3} doesn't have a shift on {4} {5}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $futureds_id, $dayDate, $dayDate.DayOfWeek) + + # ---| NEXT IN LINE FOR THE DAY-SHIFT |--- + $futureds_email = $schedule.($futureday.DayOfWeek.ToString().ToLower()).'ds' + $futureds_id = $(Get-MgUser -Filter "UserPrincipalName eq '$futureds_email' or proxyAddresses/any(c:c eq 'smtp:$futureds_email')").Id + Write-Debug(">>> {0} {1}: {2} has it on that day" -f $futureday, $futureday.DayOfWeek, $futureds_email) + + # ---| THE NEXT IN LINE FOR THE DAY-SHIFT DOESN'T HAVE TIME OFF, NO-SHIFT OR ON-SITE |--- + if((Invoke-HasTimeOff -UID $futureds_id -timeoff $timeoff_today -mail $futureds_email) -eq $false -and ($futureds_email -notin $os_emails) -and ($futureds_email -notin $ns_emails)) { + + # ---| NEXT IN LINE DOESN'T HAVE A SHIFT ALREADY |--- + if((Invoke-HasShift -UID $futureds_id -shifts $shifts_today -mail $futureds_email) -eq $false) { + + # ---| HOME-OFFICE DAY SHIFT |--- + if($futureds_email -in $ho_emails) { + $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email + $allshifts += [Object[]] $newshift + $ds_shift_inplace = $true + break + } + # ---| OFFICE DAY SHIFT |--- + else { + $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email + $allshifts += [Object[]] $newShift + $ds_shift_inplace = $true + break + } + } + # ---| NEXT IN LINE HAS A SHIFT ALREADY |--- + else { + # ---| LOOKING FOR THE SHIFT |--- + foreach ($shift in $shifts_today) { + if($shift.UserId -eq $futureds_id) { + # ---| REMOVE THE SHIFT |--- + Remove-Shift -shift $shift -teamID $team.Id + + # ---| HOME-OFFICE DAY SHIFT |--- if($futureds_email -in $ho_emails) { $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email $allshifts += [Object[]] $newshift $ds_shift_inplace = $true break } + # ---| OFFICE DAY SHIFT |--- else { $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email $allshifts += [Object[]] $newShift @@ -353,114 +356,99 @@ try { break } } - else { - Write-Debug(">>> {0} {1}: {2} has a shift on {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek) - foreach ($shift in $shifts_today) { - if($shift.UserId -eq $futureds_id) { - Write-Debug(">>> {0} {1}: removing shift {2} {3} {4} for {5}" -f $futureday, $futureday.DayOfWeek, $shift.Notes, $shift.StartDateTime, $shift.EndDateTime, $futureds_email) - Remove-MgTeamScheduleShift -ShiftId $shift.id -TeamId $team.Id - if($futureds_email -in $ho_emails) { - $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email - $allshifts += [Object[]] $newshift - $ds_shift_inplace = $true - break - } - else { - $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email - $allshifts += [Object[]] $newShift - $ds_shift_inplace = $true - break - } - } - } - } - } - else { - foreach($timeoff in $timeoff_today) { - if($timeoff.UserId -eq $futureds_id) { - Write-Debug(">>> {0} {1}: {2} has a shift on {3} {4} - {5} {6} {7}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek, $timeoff.SharedTimeOff.Notes, $timeoff.SharedTimeOff.StartDateTime, $timeoff.SharedTimeOff.EndDateTime) - } - } - - if($futureds_email -in $os_emails) { - Write-Debug(">>> {0} {1}: {2} is on the on-site list {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek) - } - - if($futureds_email -in $ns_emails) { - Write-Debug(">>> {0} {1}: {2} is on the no-shift list {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek) - } } } + } + # ---| IF THE DAY SHIFT IS SET, BREAK OUT OF THE FUTURE DAYS LOOP |--- + if($ds_shift_inplace -eq $true) { + break + } + # ---| MOVE ON TO THE NEXT FUTURE DAY IF NO CONDITION IS MET |--- continue } } } + } + # ---| END OF THE DAY SHIFT CHECK SECTION |--- + + # ---| UPDATE COLLECTION OF SHIFTS TODAY |--- + $shifts_today = [Object[]] $allshifts | Where-Object -Filter { + $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm") + } - $shifts_today = [Object[]] $allshifts | Where-Object -Filter { - $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm") - } - - if($email -in $os_emails) { - if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { - $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "On-site" -StartDate $dateStart -EndDate $dateEnd -color "gray" -teamID $team.id -mail $email - $allshifts += [Object[]] $newshift - continue - } - } - - if($email -in $ns_emails) { - continue - } - - if($email -eq $rlcz_mtnc_email) { - if ($dayDate.DayOfWeek -eq "Thursday") { - $yesterday = $dayDate.AddDays(-1) - $rlcz_shifts = [Object[]] $allshifts | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.Notes -eq "RLCZ" -and ($_.SharedShift.StartDateTime.Date -eq $yesterday.Date -or $_.SharedShift.EndDateTime.Date -eq $yesterday.Date) } - - if (Invoke-HasShift -UID $userId -shifts $rlcz_shifts -mail $email) { - if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { - if($email -in $ho_emails) { - $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "pink" -teamID $team.id -mail $email - $allshifts += [Object[]] $newshift - continue - } - else { - $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "blue" -teamID $team.id -mail $email - $allshifts += [Object[]] $newshift - continue - } - } - } - } - } - - if($email -in $ho_emails) { - if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { - $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd -color "pink" -teamID $team.id -mail $email - $allshifts += [Object[]] $newshift - continue - } - } - + # ---| ON-SITE SHIFT CHECK |--- + if($email -in $os_emails) { if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { - $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd -color "blue" -teamID $team.id -mail $email + $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "On-site" -StartDate $dateStart -EndDate $dateEnd -color "gray" -teamID $team.id -mail $email $allshifts += [Object[]] $newshift continue } } + + # ---| NO-SHIFT CHECK |--- + if($email -in $ns_emails) { + Write-Debug("{0} {1}: {2} has no-shift defined for today" -f $dayDate, $dayDate.DayOfWeek, $email) + continue + } + + # ---| RLCZ MAINTENANCE CHECK |--- + if($email -eq $rlcz_mtnc_email) { + if ($dayDate.DayOfWeek -eq "Thursday") { + $yesterday = $dayDate.AddDays(-1) + $rlcz_shifts = [Object[]] $allshifts | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.Notes -eq "RLCZ" -and ($_.SharedShift.StartDateTime.Date -eq $yesterday.Date -or $_.SharedShift.EndDateTime.Date -eq $yesterday.Date) } + + if (Invoke-HasShift -UID $userId -shifts $rlcz_shifts -mail $email) { + if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { + if($email -in $ho_emails) { + $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "pink" -teamID $team.id -mail $email + $allshifts += [Object[]] $newshift + continue + } + else { + $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "blue" -teamID $team.id -mail $email + $allshifts += [Object[]] $newshift + continue + } + } + } + } + } + + # ---| HOME-OFFICE CHECK |--- + if($email -in $ho_emails) { + if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { + $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd -color "pink" -teamID $team.id -mail $email + $allshifts += [Object[]] $newshift + continue + } + } + + # ---| OFFICE DEFAULT |--- + if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { + $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd -color "blue" -teamID $team.id -mail $email + $allshifts += [Object[]] $newshift + continue + } } } - $params = @{ - notifyTeam = $false - startDateTime = [System.DateTime]::Parse($startSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ")) - endDateTime = [System.DateTime]::Parse($endSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ")) + # ---| SCHEDULE SHARING |--- + if($script:noplan -eq $false) { + + $params = @{ + notifyTeam = $false + startDateTime = [System.DateTime]::Parse($startSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ")) + endDateTime = [System.DateTime]::Parse($endSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ")) + } + + Invoke-MgShareTeamSchedule -TeamId $team.Id -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } + ("SHARING: {0}" -f $scheduleGroupName) | Add-Content -Path $logPath + + } + else { + Write-Debug("Schedule not shared because of -noplan") } - - Invoke-MgShareTeamSchedule -TeamId $team.Id -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } - ("SHARING: {0}" -f $scheduleGroupName) | Add-Content -Path $logPath - } catch { $_