public void UpdateStatusDueToAppointmentBooking(Visit bookedVisit, BookingRemark bookingRemark, UserRole userRole) { if (bookingRemark == null) { return; } // preconditions if (Status != WorkStatusType.VisitNeeded && Status != WorkStatusType.VisitOpen) { return; } if (bookedVisit != null || bookingRemark.ResultCode.Outcome != ResultCodeOutcomeType.Done) { WorkOrderRemarks.Add(bookingRemark); } // check when status VISIT_NEEDED if (Status == WorkStatusType.VisitNeeded) { if (bookingRemark.ResultCode.Outcome == ResultCodeOutcomeType.Done) { if (bookedVisit != null) { var visit = Visits.FirstOrDefault(v => v.Id == bookedVisit.Id); if (visit == null) { Visits.Add(bookedVisit); } else { visit.AppointmentWindowId = bookedVisit.AppointmentWindowId; visit.AppointmentWindow = bookedVisit.AppointmentWindow; visit.WindowStart = bookedVisit.WindowStart; visit.WindowEnd = bookedVisit.WindowEnd; } } } if (bookingRemark.ResultCode.Outcome == ResultCodeOutcomeType.Abort) { ChangeStatusTo(WorkStatusType.Closed, userRole); } } // check when status VISIT_OPEN if (Status == WorkStatusType.VisitOpen) { var visit = Visits.OrderByDescending(v => v.WindowStart) .FirstOrDefault(); if (visit != null && visit.SuperState == VisitSuperStateType.Provisional) { if (bookingRemark.ResultCode.Outcome == ResultCodeOutcomeType.Done && bookedVisit != null) { visit.AppointmentWindowId = bookedVisit.AppointmentWindowId; visit.AppointmentWindow = bookedVisit.AppointmentWindow; visit.WindowStart = bookedVisit.WindowStart; visit.WindowEnd = bookedVisit.WindowEnd; } if (bookingRemark.ResultCode.Outcome == ResultCodeOutcomeType.Abort) { visit.ChangeStatusTo(VisitStatusType.Closed, userRole); ChangeStatusTo(WorkStatusType.Closed, userRole); } } } }
public void SnapshotVisits() { lock (_imageSync) { if (!TrackResults) { return; } var visits1 = Visits.ToArray(); if (visits1.Length == 0) { return; } long time = Environment.TickCount; Task <Bitmap> t = new Task <Bitmap>(v => { var fileId = time; try { var visits = v as KeyValuePair <BlockCoordinates, int>[]; int valMax = Visits.OrderByDescending(kvp => kvp.Value).First().Value; int valMin = visits.OrderBy(kvp => kvp.Value).First().Value; int xMin = visits.OrderBy(kvp => kvp.Key.X).First().Key.X; int xMax = visits.OrderByDescending(kvp => kvp.Key.X).First().Key.X; int xd = Math.Abs(xMax - xMin); int zMin = visits.OrderBy(kvp => kvp.Key.Z).First().Key.Z; int zMax = visits.OrderByDescending(kvp => kvp.Key.Z).First().Key.Z; int zd = Math.Abs(zMax - zMin); int zMov = zMin < 0 ? Math.Abs(zMin) : zMin * -1; int xMov = xMin < 0 ? Math.Abs(xMin) : xMin * -1; //Bitmap bitmap = new Bitmap(xd + 1, zd + 1, PixelFormat.Format32bppArgb); Bitmap bitmap = new Bitmap(GetWidth(), GetHeight(), PixelFormat.Format32bppArgb); foreach (var visit in visits) { try { double logBase = 4; double min = Math.Abs(Math.Ceiling(Math.Log(1, logBase))); if (visit.Value == 0) { continue; } //bitmap.SetPixel(visit.Key.X + xMov, visit.Key.Z + zMov, new ColorHeatMap().GetColorForValue(visit.Value, valMax)); bitmap.SetPixel(visit.Key.X + xMov, visit.Key.Z + zMov, new ColorHeatMap().GetColorForValue(Math.Log(visit.Value, logBase) + min, Math.Log(valMax, logBase) + min)); //bitmap.SetPixel(visit.Key.X + xMov, visit.Key.Z + zMov, CreateHeatColor(Math.Log(visit.Value, logBase) + min, Math.Log(valMax, logBase) + min)); //bitmap.SetPixel(visit.Key.X + xMov, visit.Key.Z + zMov, CreateHeatColor(Math.Log(visit.Value + 3), Math.Log(valMax + 3))); //bitmap.SetPixel(visit.Key.X + xMov, visit.Key.Z + zMov, CreateHeatColor(Math.Pow(visit.Value, 10), Math.Pow(valMax, 10))); //bitmap.SetPixel(visit.Key.X + xMov, visit.Key.Z + zMov, CreateHeatColor(visit.Value, valMax)); } catch (Exception e) { Log.Error($"{xd}, {zd}, {xMin}, {zMin}, {xMax}, {zMax}, X={visit.Key.X}, Z={visit.Key.Z}, {xMov}, {zMov}", e); break; } } //byte[] bytes = new byte[xd*zd*4]; //int i = 0; //for (int x = 0; x < xd; x++) //{ // for (int z = 0; z < zd; z++) // { // bytes[i++*4] = image[x, z]; // } //} //var interval = valMax/zd; //for (int i = 0; i < zd; i++) //{ // //var value = (i * interval) + 3; // //var max = valMax; // var value = Math.Log((i*interval) + 3); // var max = Math.Log(valMax); // bitmap.SetPixel(0, i, CreateHeatColor((int) value, (decimal) max)); // bitmap.SetPixel(1, i, CreateHeatColor((int) value, (decimal) max)); //} //using (Graphics g = Graphics.FromImage(bitmap)) //{ // int tz = 0; // for (int i = 10 - 1; i >= 0; i--) // { // var d = i*(valMax/10); // g.DrawString($"{d}={Math.Log(d) :##.00}", new Font("Arial", 8), new SolidBrush(Color.White), 2, (tz++)*zd/10f); // requires font, brush etc // } //} using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawString($"MiNET skylight calculation\nTime (ms): {fileId - StartTimeInMilliseconds:N0}\n{_chunkCount:N0} chunks with {(_chunkCount*16*16*256):N0} blocks\n{visits.Sum(pair => pair.Value):N0} visits", new Font("Arial", 8), new SolidBrush(Color.White), 1, 0); // requires font, brush etc } //Directory.CreateDirectory(@"D:\Temp\Light\"); //lock (_imageSync) //{ // bitmap.Save(@"D:\Temp\Light\test-" + $"{fileId :00000}.bmp", ImageFormat.Bmp); //} //bitmap.Dispose(); //GC.Collect(); //foreach (var visit in visits) //{ // Log.Debug($"Visit {visit.Key} {visit.Value} times"); //} Log.Debug($"Made a total of {visits.Sum(pair => pair.Value):N0} visits"); return(bitmap); } catch (Exception e) { Log.Error("Rendering", e); } return(null); }, visits1); RenderingTasks.Add(t); } }
/// <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 }