public List GenerateData()

in agora/store_queue_monitoring_backend/src/Helpers/CheckoutGenerator.cs [120:212]


        public List<CheckoutHistory> GenerateData(DateTime startTime, DateTime? endTime = null, List<Checkout> updatedCheckouts = null, bool redistributeOnly = false)
        {
            lock (generateDataLock)
            {
                if (endTime == null)
                    endTime = DateTime.UtcNow;

                // Update checkouts if provided
                if (updatedCheckouts != null)
                {
                    foreach (var updatedCheckout in updatedCheckouts)
                    {
                        var existingCheckout = this.checkouts.FirstOrDefault(c => c.Id == updatedCheckout.Id);
                        if (existingCheckout != null)
                        {
                            existingCheckout.Type = updatedCheckout.Type;
                            existingCheckout.AvgProcessingTime = updatedCheckout.AvgProcessingTime;
                            if (existingCheckout.Closed != updatedCheckout.Closed)
                            {
                                if (updatedCheckout.Closed && existingCheckout.Customers.Count > 0)
                                {
                                    //redistribute customers to other open checkouts
                                    while (existingCheckout.Customers.Count > 0)
                                    {
                                        var checkout = GetCheckoutWithShortestQueue(existingCheckout.Id);
                                        if (checkout == null || existingCheckout.Customers.Count == 0)
                                            break;

                                        var cust = existingCheckout.Customers.Dequeue();
                                        checkout.Customers.Enqueue(cust);
                                    }
                                }
                                else if (!updatedCheckout.Closed)
                                {
                                    //redistribute customers to newly opened checkout
                                    var totalOpenCheckouts = updatedCheckouts.Where(x => !x.Closed).Count();
                                    var existingOpenCheckouts = this.checkouts.Where(c => !c.Closed).ToList();
                                    int totalQueueLength = existingOpenCheckouts.Sum(c => c.Customers.Count);
                                    int avgQueueLength = totalQueueLength / totalOpenCheckouts;

                                    while (existingCheckout.Customers.Count < avgQueueLength)
                                    {
                                        var maxQueueCheckout = existingOpenCheckouts.OrderByDescending(c => c.Customers.Count).First();
                                        if (maxQueueCheckout.Customers.Count <= avgQueueLength)
                                            break;
                                        existingCheckout.Customers.Enqueue(maxQueueCheckout.Customers.Dequeue());
                                    }
                                }
                            }
                            existingCheckout.Closed = updatedCheckout.Closed;
                        }
                    }
                }

                var checkoutHistories = new List<CheckoutHistory>();
                for (DateTime currentTime = startTime; currentTime <= endTime; currentTime = currentTime.AddSeconds(1))
                {
                    // Generate customers at the start of each minute if not redistributing only
                    if (currentTime.TimeOfDay.Seconds == 0 && !redistributeOnly)
                        GenerateCustomers(currentTime.TimeOfDay);

                    foreach (var checkout in checkouts)
                    {
                        // Process customers in the queue if not redistributing only
                        if (checkout.Customers.Count > 0 && !redistributeOnly)
                        {
                            var customer = checkout.Customers.Peek();
                            if (customer != null)
                            {
                                customer.CheckoutTime -= 1;
                                if (customer.CheckoutTime <= 0)
                                    checkout.Customers.Dequeue();
                            }
                        }

                        // Record checkout history at the start of each minute
                        if (currentTime.TimeOfDay.Seconds == 0)
                        {
                            var checkoutHistory = new CheckoutHistory
                            {
                                Timestamp = currentTime,
                                CheckoutId = checkout.Id,
                                CheckoutType = checkout.Type,
                                QueueLength = checkout.Customers.Count,
                                AverageWaitTimeSeconds = checkout.Customers.Count * checkout.AvgProcessingTime
                            };
                            checkoutHistories.Add(checkoutHistory);
                        }
                    }
                }
                return checkoutHistories;
            }
        }