예제 #1
0
        public override MaintenanceObject GetEntity(IRepository repository)
        {
            MaintenanceObject replaceObject = null;

            if (ReplaceObjectId != null)
            {
                replaceObject = repository.Get <MaintenanceObject>(ReplaceObjectId.Value);
            }

            var newObject = new MaintenanceObject(
                repository.Get <ObjectGroup>(GroupId),
                TechIndex,
                StartOperating,
                Period == null? new Period(DateTime.Now):new Period(Period.Value),
                LastMaintenance == null? null: LastMaintenance.Select(x => x.GetEntity(repository)),
                replaceObject
                );

            newObject.Plant = repository.Get <Plant>(PlantId.Value);
            newObject.Site  = Site;

            if (ParentId != null)
            {
                var parent = repository.Get <MaintenanceObject>(ParentId.Value);
                parent.AddChild(newObject);

                repository.Save(parent);
            }



            return(newObject);
        }
예제 #2
0
        /// <summary>
        /// Завершить неоконченное обслуживание
        /// </summary>
        /// <param name="end"></param>
        public void FinalizeMaintenance(DateTime end)
        {
            if (CurrentOperatingState == OperatingState.Maintenance)
            {
                //Сохраняем дату завершения обслуживания
                CurrentMaintenance.EndMaintenance = end;

                //Взять интересующий интервал по типу обслуживания
                var targetInterval = Intervals.SingleOrDefault(x => x.MaintenanceType == CurrentMaintenance.MaintenanceType);


                /* Выбрать интервалы для сброса. Сюда попадает интересующий нас интервал и более мелкие.
                 * Т.е. Если проводится Средний ремонт, то сбрасываются Средний, Текущий и Обслуживание.
                 */

                //todo В данном случае выбираетя более мелкий интервал по минимальной наработке.
                var intervalsForReset = Intervals.Where(
                    x => x.MinUsage <= targetInterval.MinUsage)
                                        .ToDictionary(i => i.MaintenanceType);

                //Если последнего обслуживания нет, то добавляем его
                if (lastMaintenance.All(x => x.MaintenanceType != CurrentMaintenance.MaintenanceType))
                {
                    var newLastMaintenance = new LastMaintenance(
                        CurrentMaintenance.MaintenanceType,
                        end,
                        UsageFromStartup
                        );
                    newLastMaintenance.Object = this;

                    lastMaintenance.Add(newLastMaintenance);
                }

                //Сбрасываем данные по последнему обслуживанию
                lastMaintenance.ToList().ForEach(last =>
                {
                    if (intervalsForReset.ContainsKey(last.MaintenanceType))
                    {
                        last.Reset(end);
                    }
                });

                //todo здесь нужно взять последнее состояние до ремонта и восстановить его
                ChangeOperatingState(OperatingState.Operating, end);
                CurrentMaintenance = null;
            }
        }
예제 #3
0
        /// <summary>
        /// Удалить обслуживание
        /// </summary>
        /// <param name="entity"></param>
        public void RemoveMaintenance(MaintenanceActual entity)
        {
            var lastMaintenanceMap = LastMaintenance.ToDictionary(x => x.MaintenanceType.Id);

            //восстанавливаем данные из снимка
            entity.Snapshot.ToList().ForEach(x =>
            {
                var last = lastMaintenanceMap[x.MaintenanceType.Id];

                last.UsageFromLastMaintenance = x.UsageFromLastMaintenance;
                last.LastMaintenanceDate      = x.LastMaintenanceDate;
            });

            //если это текущее обслуживание, то сбрасываем его
            if (!entity.IsFinalized() && CurrentMaintenance == entity)
            {
                CurrentMaintenance = null;
            }

            maintenance.Remove(entity);
        }
예제 #4
0
        /// <summary>
        /// Установка следующего обслуживания(данные для индикатора следующего ремонта)
        /// </summary>
        public void SetNextMaintenance()
        {
            //чтобы рассчитать следующее обслуживание нужно сравнить по всем обслуживаниям разницу наработки норма-факт и взять меньшую разницу
            var intervals = Intervals.ToList();

            intervals.Sort();

            var intervalsMap = intervals.ToDictionary(x => x.MaintenanceType.Id);
            var lastUsageMap = LastMaintenance.ToDictionary(x => x.MaintenanceType.Id, x => x.UsageFromLastMaintenance);

            MaintenanceType next    = null;
            int?            fact    = 0;
            int?            norm    = 0;
            int?            normMax = 0;

            intervals.ForEach(interval =>
            {
                var usage = lastUsageMap[interval.MaintenanceType.Id];
                if (
                    next == null ||
                    //сравниваем значения как по величине так и по модулю, на случай если ремонт пропущен и разница минусовая
                    (interval.MinUsage - usage < norm - fact &&
                     Math.Abs(interval.MinUsage.Value - usage.Value) < Math.Abs(norm.Value - fact.Value))
                    )
                {
                    next    = interval.MaintenanceType;
                    norm    = interval.MinUsage;
                    normMax = interval.MaxUsage;
                    fact    = usage;
                }
            });

            NextMaintenance  = next;
            NextUsageFact    = fact;
            NextUsageNorm    = norm;
            NextUsageNormMax = normMax;
        }
예제 #5
0
        /// <summary>
        /// Спланировать работы по обслуживанию
        /// </summary>
        /// <param name="period">Период планирования</param>
        /// <param name="offer">Предложение обслуживания</param>
        /// <param name="offerReason">Причина предложения</param>
        public void PlanningMaintenance(Period period, MaintenanceType offer = null, MaintenanceReason offerReason = null)
        {
            //если оборудование не эксплуатируется, то ничего не планируем
            if (CurrentOperatingState != OperatingState.Operating)
            {
                return;
            }


            //проверяем предыдущий период если план невыполнен то переносим в след период
            var prevPlan = plans.FirstOrDefault(x => x.MaintenanceDate >= period.Prev().Start() && x.MaintenanceDate <= period.Prev().End());

            if (prevPlan != null && !maintenance.Any(x => x.StartMaintenance >= period.Prev().Start() && x.StartMaintenance <= period.Prev().End()))
            {
                plans.Add(new MaintenancePlan(
                              this,
                              prevPlan.MaintenanceType,
                              period.Start(),
                              true,
                              false,
                              prevPlan.OfferReason
                              ));

                return;
            }

            ///сортируем интервалы по величине ремонта (самый крупный будет первым)
            var intervals = Intervals.ToList();

            intervals.Sort();

            var intervalsMap = intervals.ToDictionary(x => x.MaintenanceType.Id);
            var lastDateMap  = LastMaintenance.ToDictionary(x => x.MaintenanceType.Id, x => x.LastMaintenanceDate);
            var lastUsageMap = LastMaintenance.ToDictionary(x => x.MaintenanceType.Id, x => x.UsageFromLastMaintenance);

            var hours = period.Hours();

            intervals.Any(interval =>
            {
                var type = interval.MaintenanceType.Id;

                if (!lastUsageMap.ContainsKey(type))
                {
                    var newLast = new LastMaintenance(interval.MaintenanceType, null, null)
                    {
                        Object = this
                    };

                    lastMaintenance.Add(newLast);
                    lastUsageMap.Add(type, 0);
                    lastDateMap.Add(type, null);
                }

                //проверка по наработке
                if (interval.MinUsage != null)
                {
                    var fork        = interval.MaxUsage - interval.MinUsage;
                    var targetUsage = fork >= 5000 ? interval.MinUsage.Value + fork / 2 : interval.MinUsage.Value;

                    if (lastUsageMap[type].Value >= targetUsage)
                    {
                        //дата проведения обслуживания
                        var date = period.Start().AddDays((interval.MinUsage.Value - lastUsageMap[type].Value) / 24);

                        //если дата ремонта выходит за пределы периода, то устонавливаем её в пределы периода
                        if (date > period.End())
                        {
                            date = period.End();
                        }
                        if (date < period.Start())
                        {
                            date = period.Start();
                        }

                        plans.Add(new MaintenancePlan(this, interval.MaintenanceType, date));

                        return(true);
                    }
                }

                //проверка по времени
                if (interval.PeriodQuantity != null)
                {
                    //todo сделать проверку интервалов по времени
                }

                //проверка по предложению
                if (offer != null && offer.Id == type)
                {
                    plans.Add(new MaintenancePlan(this, interval.MaintenanceType, period.Start(), false, true, offerReason));

                    return(true);
                }

                return(false);
            });
        }
예제 #6
0
        /// <summary>
        /// Откатить отчёт
        /// </summary>
        public void DiscardReport()
        {
            //Если оборудование демонтировано, то  отчёт не откатываем
            if (CurrentOperatingState == OperatingState.UnMounted)
            {
                return;
            }

            var CurrentPeriod = Report.Period;
            var PrevPeriod    = CurrentPeriod.Prev();

            Report.Period = PrevPeriod;


            //восстанавливаем план
            var plan = plans.FirstOrDefault(x => x.MaintenanceDate >= CurrentPeriod.Start() && x.MaintenanceDate <= CurrentPeriod.End());

            if (plan != null)
            {
                //если было предложение то восстанавливаем его
                if (plan.IsOffer)
                {
                    Report.OfferForPlan   = plan.MaintenanceType;
                    Report.ReasonForOffer = plan.OfferReason;
                }
                plans.Remove(plan);
            }


            //Востанавливаем наработку
            var prevUsageAfter = usage.Where(x => x.EndUsage == PrevPeriod.End() && x.StartUsage > PrevPeriod.Start()).FirstOrDefault();

            if (prevUsageAfter != null) //наработка после ремонта
            {
                RemoveUsage(prevUsageAfter);
            }
            Report.UsageAfterMaintenance = prevUsageAfter?.Usage ?? 0;


            var prevMaintenance = maintenance.Where(x => x.StartMaintenance >= PrevPeriod.Start()).FirstOrDefault();

            if (prevMaintenance != null)
            {
                Report.ActualMaintenanceType = prevMaintenance.MaintenanceType;
                Report.StartMaintenance      = prevMaintenance.StartMaintenance;
                Report.EndMaintenance        = prevMaintenance.EndMaintenance;
                RemoveMaintenance(prevMaintenance);
            }

            var notFinalized = maintenance.Where(x => x.EndMaintenance >= PrevPeriod.Start() && x.StartMaintenance < PrevPeriod.Start()).FirstOrDefault();

            if (notFinalized != null)
            {
                var lastMaintenanceMap = LastMaintenance.ToDictionary(x => x.MaintenanceType.Id);
                notFinalized.Snapshot.ToList().ForEach(x =>
                {
                    var last = lastMaintenanceMap[x.MaintenanceType.Id];
                    last.UsageFromLastMaintenance = x.UsageFromLastMaintenance;
                    last.LastMaintenanceDate      = x.LastMaintenanceDate;
                });

                Report.ActualMaintenanceType = notFinalized.MaintenanceType;
                Report.EndMaintenance        = notFinalized.EndMaintenance;
                Report.StartMaintenance      = notFinalized.StartMaintenance;

                notFinalized.EndMaintenance = null;
                CurrentMaintenance          = notFinalized;
            }

            var prevUsageBefore = usage.Where(x => x.StartUsage == PrevPeriod.Start()).FirstOrDefault();

            if (prevUsageBefore != null)//наработка до ремонта
            {
                RemoveUsage(prevUsageBefore);
            }
            Report.UsageBeforeMaintenance = prevUsageBefore?.Usage ?? 0;


            if (Parent != null)
            {
                var parentUsage = Parent.usage.Where(x => x.StartUsage >= PrevPeriod.Start() && x.EndUsage <= PrevPeriod.End()).Sum(x => x.Usage);
                Report.UsageParent = parentUsage;
            }
            else
            {
                Report.UsageParent = 0;
            }

            if (Children.Any())
            {
                Children.ToList().ForEach(x =>
                {
                    if (x.Report.Period.period == CurrentPeriod.period)
                    {
                        x.Report.UsageParent = 0;
                    }
                });
            }


            //восстанавливаем состояние

            var lastState = operatingStates.FirstOrDefault(x => x.StartDate >= PrevPeriod.Start());

            operatingStates.Where(x => x.StartDate >= PrevPeriod.Start()).ToList().ForEach(x => operatingStates.Remove(x));

            if (CurrentMaintenance != null)
            {
                CurrentOperatingState = OperatingState.Maintenance;
            }
            else if (lastState != null && lastState.State == OperatingState.Reserve)
            {
                CurrentOperatingState = OperatingState.Reserve;
            }
            else
            {
                CurrentOperatingState = operatingStates.OrderBy(x => x.StartDate).LastOrDefault()?.State ?? OperatingState.Operating;
            }

            Report.State = CurrentOperatingState.Value;

            SetNextMaintenance();
        }
예제 #7
0
        /// <summary>
        /// Применить отчёт (добавить информацию о ремонтах и наработке в соответствующие журналы) и сформировать план на след. период
        /// </summary>
        public void ApplyReport()
        {
            //Если оборудование демонтировано, то  отчёт не проводим
            if (CurrentOperatingState == OperatingState.UnMounted)
            {
                return;
            }

            if (CurrentOperatingState == null)
            {
                ChangeOperatingState(OperatingState.Operating, Report.Period.Start());
            }

            if (!LastMaintenance.Any())
            {
                Intervals.ToList().ForEach(x =>
                {
                    lastMaintenance.Add(new LastMaintenance(
                                            x.MaintenanceType,
                                            null,
                                            x.MinUsage != null ? (int?)0 : null
                                            )
                    {
                        Object = this
                    });
                });
            }

            var CurrentPeriod = Report.Period;
            var NextPeriod    = CurrentPeriod.Next();


            // 1 Добавить наработку до ремонта, а если его не было, то за весь период
            if (Report.UsageBeforeMaintenance != 0)
            {
                AddUsage(CurrentPeriod.Start(), Report.StartMaintenance ?? CurrentPeriod.End(), Report.UsageBeforeMaintenance);
            }

            //2 Добавить информацию о ремонте, если он был.

            // Если был неоконченный ремонт, то завершить его
            if (CurrentMaintenance != null)
            {
                //Бывает что начинают один вид ремонта, а по факту выполняется другой
                CurrentMaintenance.MaintenanceType = Report.ActualMaintenanceType;

                if (Report.EndMaintenance != null)
                {
                    FinalizeMaintenance(Report.EndMaintenance.Value);
                }
            }
            // Если новый ремонт, то добавляем его в журнал ремонтов
            else if (Report.ActualMaintenanceType != null && Report.StartMaintenance != null)
            {
                AddMaintenance(Report.ActualMaintenanceType, Report.StartMaintenance.Value, Report.EndMaintenance, Report.UnplannedReason);
            }

            //3 если ремонт окончен и наработка после ремонта есть то добавляем её в журнал наработки
            if (Report.EndMaintenance != null && Report.UsageAfterMaintenance != 0)
            {
                AddUsage(Report.EndMaintenance.Value, CurrentPeriod.End(), Report.UsageAfterMaintenance);
            }



            /*Устанавливаем наработку для детей*/
            if (Children.Any())
            {
                Children.ToList().ForEach(child =>
                {
                    if (child.Report.Period.period == CurrentPeriod.period)
                    {
                        var allUsage                        = Report.UsageBeforeMaintenance + Report.UsageAfterMaintenance;
                        child.Report.UsageParent            = allUsage;
                        child.Report.UsageBeforeMaintenance = allUsage;
                    }
                });
            }

            //Если состояние поменялось и это было не обслуживание, то меняем состояние
            if (Report.State != OperatingState.Maintenance && CurrentOperatingState != OperatingState.Maintenance && CurrentOperatingState != Report.State)
            {
                ChangeOperatingState(Report.State, CurrentPeriod.Start());
            }

            //Планируем следующий период
            PlanningMaintenance(NextPeriod, Report.OfferForPlan, Report.ReasonForOffer);
            //Рассчитываем следующее обслуживание
            SetNextMaintenance();


            /* Очищение информации в отчёте для следующего месяца */

            // Если ремонт окончен, то обнуляем информацию по фактическому ремонту
            if (Report.EndMaintenance != null)
            {
                Report.ActualMaintenanceType = null;
                Report.UnplannedReason       = null;
                Report.StartMaintenance      = null;
                Report.EndMaintenance        = null;
            }

            Report.OfferForPlan   = null;
            Report.ReasonForOffer = null;



            //Устанавливаем состояние на следующий период. Если Текущее состояние резерв, то сбрасываем его на обслуживание, потому что механики вручную вносят резерв
            Report.State = CurrentOperatingState.Value == OperatingState.Reserve ? OperatingState.Operating : CurrentOperatingState.Value;

            if (Report.State == OperatingState.Operating)
            {
                Report.UsageBeforeMaintenance = NextPeriod.Hours();
            }
            else
            {
                Report.UsageBeforeMaintenance = 0;
            }

            //Если есть родитель и у него проведена наработка, то устонавливаем её
            if (Parent != null && Parent.Report.Period.period > NextPeriod.period)
            {
                var parentUsage = Parent.usage.Where(x => x.StartUsage >= NextPeriod.Start() && x.EndUsage <= NextPeriod.End()).Sum(x => x.Usage);
                Report.UsageParent            = parentUsage;
                Report.UsageBeforeMaintenance = parentUsage;
            }
            else
            {
                Report.UsageParent = 0;
            }

            Report.UsageAfterMaintenance = 0;



            //Переходим на следующий период
            Report.Period = NextPeriod;
        }
예제 #8
0
        public override void Merge(MaintenanceObject entity, IRepository repository)
        {
            entity.TechIndex = TechIndex;
            entity.Plant     = repository.Get <Plant>(PlantId.Value);
            entity.Site      = Site;
            entity.Group     = repository.Get <ObjectGroup>(GroupId);
            SetSpecifications(entity, repository);

            //Если введена дата ввода в эксплуатацию, то вводим в эксплуатацию
            if (entity.CurrentOperatingState == OperatingState.Mounted && StartOperating != null)
            {
                var period = Period == null ? new Period(DateTime.Now) : new Period(Period.Value);
                entity.PutIntoOperating(StartOperating.Value, period);
            }

            //Если родитель был
            if (entity.Parent != null)
            {
                //Если родитель получен
                if (ParentId != null)
                {
                    //Если полученный родитель не равен тому, который был
                    if (ParentId != entity.Parent.Id)
                    {
                        var newParent = repository.Get <MaintenanceObject>(ParentId.Value);
                        entity.ClearParent();
                        newParent.AddChild(entity);
                        repository.Save(newParent);
                    }
                }
                //Если родитель был, но его убрали
                else
                {
                    entity.ClearParent();
                }
            }
            //Если родителя небыло
            else
            {
                //Если родитель был установлен
                if (ParentId != null)
                {
                    var parent = repository.Get <MaintenanceObject>(ParentId.Value);
                    parent.AddChild(entity);

                    repository.Save(parent);
                }
            }

            var dtoMap = LastMaintenance.ToDictionary(x => x.MaintenanceTypeId);

            entity.LastMaintenance.ToList().ForEach(last =>
            {
                if (dtoMap.ContainsKey(last.MaintenanceType.Id))
                {
                    var _dto = dtoMap[last.MaintenanceType.Id];
                    last.LastMaintenanceDate      = _dto.LastMaintenanceDate;
                    last.UsageFromLastMaintenance = _dto.UsageFromLastMaintenance;
                }
            });

            entity.SetNextMaintenance();
        }