示例#1
0
        /// <summary>
        /// Update the WorkOrder's Status based on the status from (last) visit
        /// </summary>
        /// <param name="visit">The visit that will trigger the Workorder's status change</param>
        /// <param name="currentUserRole">The user requesting the status change</param>
        public void UpdateStatus(UserRole currentUserRole, Visit visit = null, bool doForce = false)
        {
            if (currentUserRole == null)
            {
                throw new ArgumentNullException(nameof(currentUserRole));
            }

            #region check transition NotReady => VisitNeeded
            if (Status == WorkStatusType.NotReady)
            {
                var doStatusChange = false;
                // rule: check all data is complete
                doStatusChange = ((WorkSpecificationId > 0 || WorkSpecification != null) &&
                                  (LocationId > 0 || Location != null) &&
                                  (TaskInfos.Any()));

                // rule: No visit exists yet or last visit has status closed with redo.
                var closedVisit = Visits.OrderByDescending(v => v.WindowStart)
                                  .FirstOrDefault();
                var isLastVisitClosedWithRedo = doForce || (closedVisit?.ResultCode != null &&
                                                            closedVisit.Status == VisitStatusType.Closed &&
                                                            closedVisit.ResultCode.Outcome == ResultCodeOutcomeType.Redo);
                doStatusChange = doStatusChange &&
                                 (!Visits.Any() || isLastVisitClosedWithRedo);
                if (doStatusChange)
                {
                    ChangeStatusTo(WorkStatusType.VisitNeeded, currentUserRole);
                }
            }
            #endregion

            #region check transition VisitNeeded => VisitOpen (or Aborted)
            if (Status == WorkStatusType.VisitNeeded)
            {
                // rule: at least one visit and last visit not in status closed
                var lastVisit = Visits.OrderByDescending(v => v.WindowStart)
                                .FirstOrDefault(v => v.Status != VisitStatusType.Closed);

                // rule: there is an appointment booked
                if (lastVisit != null && lastVisit.IsAppointmentBooked)
                {
                    ChangeStatusTo(WorkStatusType.VisitOpen, currentUserRole);
                }
            }
            #endregion

            #region check transition VisitOpen => Closed (or Aborted)
            if (Status == WorkStatusType.VisitOpen)
            {
                // (OR) rule: at least one ans last visit is closed with outcome done
                var lastVisit = Visits.OrderByDescending(v => v.WindowStart)
                                .FirstOrDefault(v => v.Status == VisitStatusType.Closed);
                if (lastVisit?.ResultCode != null &&
                    lastVisit.ResultCode.Outcome == ResultCodeOutcomeType.Done)
                {
                    ChangeStatusTo(WorkStatusType.Closed, currentUserRole);
                }
                else
                {
                    // (OR) rule: last remark booking with result code abort
                    var lastRemark = WorkOrderRemarks.OfType <BookingRemark>()
                                     .OrderByDescending(br => br.EnteredDate)
                                     .FirstOrDefault();
                    if (lastRemark?.ResultCode != null &&
                        lastRemark.ResultCode.Outcome == ResultCodeOutcomeType.Abort)
                    {
                        ChangeStatusTo(WorkStatusType.Closed, currentUserRole);
                    }
                }
            }
            #endregion

            // TODO Alain still relevatnt?
            #region check if the supplied visit is the last one in workorder
            if (visit != null)
            {
                var lastVisit = Visits.OrderByDescending(v => v.PlannedStart).First();
                if (visit.Id != lastVisit.Id)
                {
                    return;
                }

                if (visit.Status == VisitStatusType.Closed)
                {
                    if (visit.ResultCode == null)
                    {
                        throw new NotSupportedException(Translations.WorkOrderResultCodeRequired);
                    }
                    switch (visit.ResultCode.Outcome)
                    {
                    case ResultCodeOutcomeType.Abort:
                        ChangeStatusTo(WorkStatusType.Aborted, currentUserRole);
                        break;

                    case ResultCodeOutcomeType.Redo:
                        ChangeStatusTo(WorkStatusType.VisitNeeded, currentUserRole);
                        break;

                    case ResultCodeOutcomeType.Done:
                        ChangeStatusTo(WorkStatusType.Closed, currentUserRole);
                        break;
                    }
                }
                if (visit.Status == VisitStatusType.Aborted)
                {
                    ChangeStatusTo(WorkStatusType.Aborted, currentUserRole);
                }
            }
            #endregion
        }