/// <summary>
        /// Calculate WIP trace and assign WIPin and WIPout qtys to LotActvities
        /// </summary>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        public void CalculateWIPTrace(DateTime startDate, DateTime endDate)
        {
            // Determine begin qty
            int beginWIP = LotActivities.Where(x => (x.Arrival == null || x.Arrival < startDate) && (x.Departure == null || x.Departure > startDate)).Count();

            WIPTrace.Add(new Tuple <DateTime, int>(startDate, beginWIP));

            wipCalculations = new List <Tuple <DateTime, int, LotActivity> >();

            // Add arrivals to WIPcalculations
            foreach (LotActivity activity in LotActivities.Where(x => x.Arrival != null && x.Arrival >= startDate && x.Arrival <= endDate))
            {
                wipCalculations.Add(new Tuple <DateTime, int, LotActivity>((DateTime)activity.Arrival, +1, activity));
            }

            // Add departures to WIPcalculations
            foreach (LotActivity activity in LotActivities.Where(x => x.Departure != null && x.Departure >= startDate && x.Departure <= endDate))
            {
                wipCalculations.Add(new Tuple <DateTime, int, LotActivity>((DateTime)activity.Departure, -1, activity));
            }

            int currentWIP = beginWIP;

            // Order WIP calculations on time
            wipCalculations = wipCalculations.OrderBy(x => x.Item1).ToList();

            // Loop through arrival and departure events and generate WIP Trace
            foreach (Tuple <DateTime, int, LotActivity> calc in wipCalculations)
            {
                if (calc.Item1 == WIPTrace.Last().Item1)
                {
                    WIPTrace.RemoveAt(WIPTrace.Count() - 1);
                }

                currentWIP += calc.Item2;

                WIPTrace.Add(new Tuple <DateTime, int>(calc.Item1, currentWIP));

                // Assign WIPin qty (right before arrival) to LotActivity
                if (calc.Item2 == 1)
                {
                    calc.Item3.WIPIn = currentWIP - 1;
                }
                // Assign WIPout qty (right after departure) to LotActivity
                else if (calc.Item2 == -1)
                {
                    calc.Item3.WIPOut = currentWIP;
                }
            }

            // Check if last WIP value is correct
            int endWIP = LotActivities.Where(x => (x.Departure == null || x.Departure > endDate) && (x.Arrival == null || x.Arrival < endDate)).Count();

            if (endWIP != WIPTrace.Last().Item2)
            {
                throw new Exception($"End WIP does not match Begin WIP + sum(WIP changes) for {WorkCenter}");
            }

            wipTraceTimes = WIPTrace.Select(x => x.Item1).ToList();
        }
Exemple #2
0
        public List <LotActivity> CalculateEPTs(List <LotActivity> lotActivities)
        {
            LotActivities = lotActivities.ToList();

            allSortedOnDeparture = LotActivities.OrderBy(x => x.Departure).ToList();

            subsetNoDeparture = LotActivities.Where(x => x.Arrival != null && x.Departure == null).ToList();

            subsetNoArrivalDeparture = LotActivities.Where(x => x.Arrival == null && x.Departure == null).ToList();

            DateTime?prevDepart = null;

            for (int i = 0; i < allSortedOnDeparture.Count; i++)
            {
                LotActivity act = allSortedOnDeparture[i];

                if (act.Departure != null && prevDepart != null && act.WIPIn > -1)
                {
                    TimeSpan ept = new TimeSpan();

                    // Calculate EPT
                    if (act.WIPIn > 0)
                    {
                        ept = (DateTime)act.Departure - (DateTime)prevDepart;
                    }
                    else if (act.WIPIn == 0)
                    {
                        ept = (DateTime)act.Departure - (DateTime)act.Arrival;
                    }

                    act.EPT = ept.TotalSeconds;

                    // Calculate overtaken lots (this operation is slow)
                    act.OvertakenLots = subsetNoArrivalDeparture.Count + subsetNoDeparture.Where(x => x.Arrival < act.Arrival).Count() + allSortedOnDeparture.GetRange(i, allSortedOnDeparture.Count - i).Where(x => x.Arrival < act.Arrival).Count();
                }
                prevDepart = act.Departure;
            }

            return(LotActivities);
        }