Departments and holidays

fred b

Titanium Partner
Advanced Certified
Joined
Feb 10, 2026
Messages
1
Reaction score
1
There should be a way to have all holidays point to 1 schedule. I have a customer with over 25 departments. Doing the holidays 25 times is very very time consuming, and more chanses for errors.

Maybe something like putting the holidays in Default department, then telling all other departments to use the Default departments schedule.

Or at a minimum being able to copy one departments schedule to all the other departments.
 
@VoIPTools has a free tool to bulk manage holidays! I highly recommend it!
 
  • Like
Reactions: VoIPTools
  • Like
Reactions: Evolute IT
The advantage of using the xapi is that it does not require our Relay, but the xapi does require an Enterprise license :(
 
  • Like
Reactions: Evolute IT
  • Like
Reactions: Evolute IT
hijacking this to not create a new thread since it regards departments and holidays.
I have a trunk with default destination an IVR assigned to Department A,
1. routes to a queue in department B
2. routes to a queue in department C

department B and C may have different holidays, from what I understood the holiday.cs script in the library would check against the department holiday schedule and play the prompt if there's a holiday scheduled in the department calendar.

However if I set an holiday for department C, the call drops with no audio played.
it only works if the holiday is assigned to department A, which is the first destination after the trunk receives the call.

is this the expected behavior?
 
@guidoq as I can see your colleague Gustavo opened a ticket at the Italian Support 20 min ago, about the same topic you mentioned here.
Lets continue at the ticket to see what is happening.
 
  • Like
Reactions: guidoq
it only works if the holiday is assigned to department A, which is the first destination after the trunk receives the call.
...
is this the expected behavior?
Yes, because: the original 3CX holiday.cs sees only the first destination (and the department of it) for the call on the trunk - which is in your case the IVR - and plays holiday audio if needed.
Please explain how a script triggered by the trunk trigger should know what happens after the IVR.

If that's truly the desired behavior, then something like holiday.cs (it must be different, the original would not work here) needs to be inserted separately after the IVR and before each queue. That's possible; that would be one solution.
 
Last edited:
  • Like
Reactions: Evolute IT
makes sense thanks, we'll keep using CFD's to manage these types of scenarios
 
  • Like
Reactions: NikosT_3CX
we'll keep using CFD's to manage these types of scenarios
or a call script (for each destination) - example for extension 830 as default destination (with department and holidays ...) and route to 805 on a holiday:
C#:
#nullable disable
using CallFlow;
using System;
using System.Threading.Tasks;
using TCX.Configuration;
using TCX.PBXAPI;

namespace dummy
{
    //this handler plays holiday prompt as specified for destination
    public class PlayDestinationHolidayPromptForExt830 : ScriptBase<PlayDestinationHolidayPromptForExt830>
    {
        public static string ExtensionToBeRoutedNormal    = "830";
        public static string ExtensionToBeRoutedOnHoliday = "805";
      
        public override async Task<bool> StartAsync()
        {
            //get the target DN
            var defaultDestination = PhoneSystem.Root.GetDNByNumber(ExtensionToBeRoutedNormal);

            if (defaultDestination != null)
            {
                var timeBasedroute = defaultDestination.GetTimeBasedRoutingInfo();
                //if destination is currently "on holiday" and holiday prompt is defined, we play it
                if (timeBasedroute.reason == CallControlAPI.DivertReason.Holiday && !string.IsNullOrWhiteSpace(timeBasedroute.holiday?.HolidayPrompt))
                {
                    await MyCall.AssureMedia()
                        .ContinueWith(x => MyCall.PlayPrompt(null, [timeBasedroute.holiday?.HolidayPrompt], PlayPromptOptions.Blocked))
                        .Unwrap();
                    // on holiday: route to a new destination
                    await MyCall.RouteToAsync(new RouteRequest
                        {
                            RouteTarget = new DestinationStruct(PhoneSystem.Root.GetDNByNumber(ExtensionToBeRoutedOnHoliday)),
                            TimeOut = TimeSpan.FromSeconds(60) //will ring until failure
                        }
                    );
                }
                else
                {
                    //route to the default destination
                    await MyCall.RouteToAsync(new RouteRequest
                        {
                            RouteTarget = new DestinationStruct(PhoneSystem.Root.GetDNByNumber(ExtensionToBeRoutedNormal)),
                            TimeOut = TimeSpan.FromSeconds(60) //will ring until failure
                        }
                    );
                }
              
            }
            return true;
        }
    }
}
 

Members Online Now

Forum statistics

Threads
111,834
Messages
589,287
Members
164,662
Latest member
DejanMDS