Example #1
0
        private static IEnumerable <Message> GetSchedules(Schedule schedule, Excel.Workbook book)
        {
            var messages = new List <Message>();

            Excel.Worksheet sheet        = book.Worksheets["Trains"] as Excel.Worksheet;
            var             r            = 2;
            Train           currentTrain = null;
            string          trainId      = null;
            VehicleSchedule currentLoco  = null;
            Dictionary <string, VehicleSchedule> locoSchedules = new Dictionary <string, VehicleSchedule>();
            Dictionary <string, DriverDuty>      driverDuties  = new Dictionary <string, DriverDuty>();

            while (true)
            {
                var row = (Array)sheet.get_Range(Cell("A", r), Cell("K", r)).Cells.Value;
                if (row.GetValue(1, 1) == null)
                {
                    break;
                }
                else
                {
                    var type = row.Value(9).ToUpperInvariant();
                    switch (type)
                    {
                    case "TRAINDEF":
                        trainId = row.Value(8);
                        var train = schedule.Timetable.Train(trainId);
                        if (train.IsNone)
                        {
                            messages.Add(Message.Error(CultureInfo.CurrentCulture, $"Train {trainId} cannot be found."));
                            break;
                        }
                        currentTrain = train.Value;
                        break;

                    case "LOCOMOTIVE":
                        var locoId = row.Value(8);
                        if (locoId != null)
                        {
                            if (!locoSchedules.ContainsKey(locoId))
                            {
                                locoSchedules.Add(locoId, VehicleSchedule.Loco(locoId));
                            }
                            currentLoco = locoSchedules[locoId];
                            if (currentTrain != null)
                            {
                                var locoMessages         = new List <Message>();
                                var fromStationSignature = row.Value(3);
                                var toStationSignature   = row.Value(4);
                                var fromTime             = Time.Parse(row.Value(5));
                                var toTime = Time.Parse(row.Value(6));

                                //if (lt2 < lt1) lt2 = lt2.AddDays(1); // TODO: Handle over midnight times, if necessary
                                var(fromCall, fromIndex) = currentTrain.FindBetweenArrivlAndBeparture(fromStationSignature, fromTime);
                                var(toCall, toIndex)     = currentTrain.FindBetweenArrivlAndBeparture(toStationSignature, toTime);

                                if (fromCall.IsNone)
                                {
                                    locoMessages.Add(Message.Error(CultureInfo.CurrentCulture, Resources.Strings.LocoAtStationWithDepartureDoNotRefersToAnExistingTimeInTrain, locoId, fromStationSignature, fromTime, currentTrain));
                                }
                                if (toCall.IsNone)
                                {
                                    locoMessages.Add(Message.Error(CultureInfo.CurrentCulture, Resources.Strings.LocoAtStationWithArrivalDoNotRefersToAnExistingTimeInTrain, locoId, fromStationSignature, toTime, currentTrain));
                                }
                                if (fromIndex >= toIndex)
                                {
                                    locoMessages.Add(Message.Error(CultureInfo.CurrentCulture, Resources.Strings.LocoInTrainHasWrongTimingEndStartionIsBeforeStartStation, locoId, currentTrain, fromTime, toTime));
                                }
                                messages.AddRange(locoMessages);
                                if (locoMessages.CanContinue())
                                {
                                    TrainPart trainPart = new TrainPart(currentTrain, fromIndex, toIndex);
                                    currentLoco.Add(trainPart);
                                }
                            }
                        }
                        break;

                    case "TRAINSET":
                        var trainsetId = row.Value(8);
                        break;

                    case "JOB":
                        var jobId = row.Value(8);
                        if (jobId != null)
                        {
                            var jobMessages = new List <Message>();
                            if (currentTrain is null)
                            {
                                messages.Add(Message.Error(CultureInfo.CurrentCulture, $"There is not a current train for job {jobId}."));
                                break;
                            }
                            if (currentLoco is null)
                            {
                                messages.Add(Message.Error(CultureInfo.CurrentCulture, $"There is not a current loco for job {jobId}."));
                                break;
                            }
                            if (!driverDuties.ContainsKey(jobId))
                            {
                                driverDuties.Add(jobId, new DriverDuty(jobId));
                            }
                            var currentLocoSchedule = locoSchedules.Values.SingleOrDefault(l => l.Identity == currentLoco.Identity);
                            if (currentLocoSchedule is null)
                            {
                                messages.Add(Message.Error(CultureInfo.CurrentCulture, $"Job {jobId} referse no a nonexisting loco schedule {currentLoco}."));
                                break;
                            }
                            var dt1 = Time.Parse(row.Value(5));
                            var dt2 = Time.Parse(row.Value(6));
                            if (dt2 < dt1)
                            {
                                dt2 = dt2.AddDays(1);
                            }
                            var part = currentLocoSchedule.Parts.Select((value, index) => (value, index)).SingleOrDefault(p => p.value.Train.Number == currentTrain.Number && (p.value.From.Arrival == dt1 || p.value.From.Departure == dt1 || dt1 < currentLocoSchedule.Parts.First().From.Arrival) && (p.value.To.Arrival == dt2 || p.value.To.Departure == dt2 || dt2 > currentLocoSchedule.Parts.Last().To.Departure));
                            if (part.value == null)
                            {
                                jobMessages.Add(Message.Error($"Error in train {currentTrain} for job {jobId}."));
                            }
                            if (jobMessages.CanContinue())
                            {
                                driverDuties[jobId].Add(new VehicleSchedulePart(currentLocoSchedule, part.index, part.index));
                                messages.AddRange(jobMessages);
                            }
                        }
                        break;

                    case "GROUP":
                        if (currentTrain != null)
                        {
                            currentTrain.Category = row.Value(8);
                        }
                        break;

                    default:
                        break;
                    }
                }
                r++;
            }
            foreach (var loco in locoSchedules.Values)
            {
                schedule.AddLocoSchedule(loco);
            }
            foreach (var duty in driverDuties.Values)
            {
                schedule.AddDriverDuty(duty);
            }
            return(messages);
        }