Beispiel #1
0
        /// <summary>
        /// This method will start the planning process and handle's the polling to the backend. When the planning is done or stopped/cancelled
        /// the async task will stop and return the <see cref="PlanningTask"/> object.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <param name="pollingInterval"></param>
        /// <returns></returns>
        public async Task <PlanningTask> Plan(PlanningRequest request, CancellationToken cancellationToken, TimeSpan?pollingInterval = null)
        {
            var pollingTimeSpan = pollingInterval ?? TimeSpan.FromSeconds(5);

            ClearAccessToken();

            PlanningTask planningTask = null;

            try
            {
                planningTask = await api.PostPlanning(request, cancellationToken);

                PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask));
                do
                {
                    await Task.Delay(pollingTimeSpan, cancellationToken);

                    planningTask = await api.GetPlanning(planningTask.Id, cancellationToken);

                    PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask));
                }while (planningTask.IsInProgress() && !cancellationToken.IsCancellationRequested);

                if (cancellationToken.IsCancellationRequested)
                {
                    //Let's try to stop the planning task on the server as well.
                    try
                    {
                        var task = api.StopPlanning(planningTask.Id, CancellationToken.None);
                        await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(4)));
                    }
                    catch (Exception)
                    {
                        //Ignore this exception
                    }

                    planningTask.Status = PlanningTaskStatus.Canceled;
                    PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask));
                }

                return(planningTask);
            }
            catch (ApiException e)
            {
                throw new Exception(e.Content);
            }
            catch (TaskCanceledException e)
            {
                if (planningTask == null)
                {
                    planningTask = new PlanningTask();
                }

                planningTask.Status    = PlanningTaskStatus.Canceled;
                planningTask.Exception = e;

                PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask));

                return(planningTask);
            }
        }
        public async Task <IActionResult> AddRoom([FromBody] PlanningRequest request)
        {
            return(await Task.Run(() =>
            {
                if (request?.Cards == null)
                {
                    return (ActionResult)BadRequest();
                }

                var validCards = request.Cards
                                 .Where(card => !string.IsNullOrEmpty(card.Display) && !string.IsNullOrEmpty(card.Value))
                                 .ToArray();
                if (!validCards.Any())
                {
                    return (ActionResult)BadRequest();
                }

                var room = new PlanningRoom
                {
                    Cards = new HashSet <PlanningCard>(validCards),
                    Users = new HashSet <PlanningUser>(new[]
                    {
                        new PlanningUser()
                        {
                            Name = request.OwnerName,
                            Role = UserRole.Owner,
                            Id = Guid.NewGuid()
                        }
                    })
                };
                roomRepository.Insert(room);
                return Ok(room);
            }));
        }
Beispiel #3
0
 /// <summary>
 /// This method will start the planning process and handle's the polling to the backend. When the planning is done
 /// the async task will stop and return the <see cref="PlanningTask"/> object.
 /// </summary>
 /// <param name="request"></param>
 /// <param name="pollingInterval"></param>
 /// <returns></returns>
 public Task <PlanningTask> Plan(PlanningRequest request, TimeSpan?pollingInterval = null)
 {
     return(Plan(request, CancellationToken.None, pollingInterval));
 }
Beispiel #4
0
        private static PlanningRequest GetPlanningRequest(PlanningMode mode)
        {
            var request = new PlanningRequest()
            {
                Mode = mode,

                //Set NearbyLocationTravelTimeThreshold (in minutes) to cluster planitems that are 'close by' other already planned items
                //AND there is still some time left to fill
                NearbyLocationTravelTimeThreshold = 15,

                //There can be multiple resources to plan for
                Resources = new List <Resource>
                {
                    //Employee #1
                    new Resource
                    {
                        //Make sure you give every resource a unique Id. (keep a hold of it, you need to use it later to map the planning back to your own structure)
                        Id = Guid.NewGuid(),

                        //Every moment a resource is availible for planning must be added as a Window.
                        Windows = new List <Window>
                        {
                            //This employee is availible on 3 specific dates from 9:00 to 17:00
                            new Window(new DateTime(2000, 1, 1, 9, 0, 0), TimeSpan.FromHours(8)),
                            new Window(new DateTime(2000, 1, 2, 9, 0, 0), TimeSpan.FromHours(8)),
                            new Window(new DateTime(2000, 1, 3, 9, 0, 0), TimeSpan.FromHours(8)),
                        },

                        //Employee is classified to operate a Flux Capacitor 9000
                        Qualifications = new List <ResourceQualification>
                        {
                            FluxCapacitor9000
                        },

                        //Employee starts every day from his home in Haarlem
                        StartLocation = HaarlemCity
                    }
                },

                //Create planning for January (1th to 31th)
                PlanningWindow = new Window(new DateTime(2000, 1, 1, 8, 0, 0), TimeSpan.FromDays(31)),

                //These items need to be planned (for Options mode only one plan item is allowed)
                PendingPlanItems = new List <PlanItem>
                {
                    //Something to be planned
                    new PlanItem
                    {
                        Id = Guid.NewGuid(),

                        //For 1 hour
                        Duration = TimeSpan.FromHours(1),

                        //On
                        WindowsConfigs = new List <WindowConfig>
                        {
                            new WindowConfig
                            {
                                //Every monday
                                DayOfWeek = DayOfWeek.Monday,

                                //Between 8:00 and 20:00
                                Start = new TimeSpan(08, 00, 00),
                                End   = new TimeSpan(20, 00, 00)
                            }
                        },

                        //At Haarlem location
                        Location = HaarlemCity,

                        //Employees that can be assigned to this item must be able to operate a Flux Capacitor
                        ResourceQualifications = new List <ResourceQualification>
                        {
                            FluxCapacitor9000
                        }
                    }
                }
            };

            return(request);
        }
Beispiel #5
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("| TaskPlanning.Client.Sample Console |");
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("");
            Console.WriteLine("0. Regular (plan until full)");
            Console.WriteLine("1. Options (show all availible options for a single planitem)");
            Console.WriteLine("");

            Console.Write(">");
            var key = Console.ReadKey();

            Console.WriteLine("");

            var mode = (PlanningMode)int.Parse(key.KeyChar.ToString());

            //Create your client using your private access key
            var accessKey = string.Empty;

            if (File.Exists("AccessKey.txt"))
            {
                accessKey = File.ReadAllText("AccessKey.txt");
            }

            TaskPlanningClient client;

            try
            {
                client = await TaskPlanningClient.Create(accessKey);

                client.PlanningTaskUpdated += Client_PlanningTaskUpdated;
            }
            catch (TaskPlanning.Client.InvalidAccessKeyException ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }

            PlanningRequest request = GetPlanningRequest(mode);

            if (mode == PlanningMode.Options)
            {
                //When requesting options only one planitem is alowed.
                request.PendingPlanItems = new List <PlanItem> {
                    request.PendingPlanItems.First()
                };

                //In order to retrieve a list of possibilities in an existing planning you must provide
                //existing planned items per resource using the PrePlannedItems list
                var employee = request.Resources.First();
                employee.PrePlannedItems.Add(new PlanItemResult
                {
                    Item = new PlanItem {
                        Duration = TimeSpan.FromHours(1), Location = HaarlemCity
                    },
                    Window = new Window(new DateTime(2000, 1, 1, 9, 0, 0), TimeSpan.FromHours(1))
                });
            }

            PlanningTask planning = await client.Plan(request, TimeSpan.FromMilliseconds(500));

            if (planning.Status == PlanningTaskStatus.Success)
            {
                if (mode == PlanningMode.Regular)
                {
                    Console.WriteLine("Planned successfully:");
                    foreach (var planned in planning.Planning.PlannedItems)
                    {
                        Console.WriteLine($"{planned.Item.Id} on {planned.Window.Start}");
                    }

                    Console.WriteLine("");

                    Console.WriteLine("Not planned:");
                    foreach (var notPlanned in planning.Planning.FailedToPlanItems)
                    {
                        Console.WriteLine($"{notPlanned.Item.Id} ({notPlanned.FailedReasonText})");
                    }
                }
                else if (mode == PlanningMode.Options)
                {
                    Console.WriteLine($"Possible options for {planning.Planning.PlannedItems.FirstOrDefault()?.Item.Id}");
                    foreach (var planned in planning.Planning.PlannedItems)
                    {
                        Console.WriteLine($"{planned.Window.Start}");
                    }
                }
            }
            else
            {
                Console.WriteLine($"Whoops! something went wrong: {planning.Status}");
                Console.WriteLine(planning.Exception.Message);
            }
        }