protected override void _Execute(params object[] args) { // if editing is process in optimize and edit page - cancel editing if (_optimizePage.IsEditingInProgress) { ((ICancelDataObjectEditing)_optimizePage).CancelObjectEditing(); } // create collection of orders to delete Collection <Order> ordersToDelete = _GetOrdersFromSelection(); // Include any paired orders if (App.Current.Project.Schedules.ActiveSchedule != null) { Schedule schedule = App.Current.Project.Schedules.ActiveSchedule; ordersToDelete = RoutingCmdHelpers.GetOrdersIncludingPairs(schedule, ordersToDelete) as Collection <Order>; } if (0 < ordersToDelete.Count) { bool doProcess = true; if (Settings.Default.IsAllwaysAskBeforeDeletingEnabled) { // show warning dialog doProcess = DeletingWarningHelper.Execute(ordersToDelete); } if (doProcess) { // call base Execute() to unassign orders if necessary base._Execute(ordersToDelete); } } }
protected bool _CheckRoutingParams(Schedule schedule, ICollection <Route> routes, ICollection <Order> orders) { bool isValid = false; // check orders count if (orders.Count < 1) { App.Current.Messenger.AddError((string)App.Current.FindResource("Error_InvalidOrdersNum")); } // check routes count else if (routes.Count < 1) { App.Current.Messenger.AddError((string)App.Current.FindResource("Error_InvalidRoutesNum")); } // validate objects else { List <DataObject> invalidObjects = new List <DataObject>(); invalidObjects.AddRange(RoutingCmdHelpers.ValidateObjects <Order>(orders)); invalidObjects.AddRange(RoutingCmdHelpers.ValidateObjects <Route>(routes)); if (invalidObjects.Count > 0) { _ShowSolveValidationResult(invalidObjects.ToArray()); } else { isValid = true; } } return((isValid) ? ConstraintViolationsChecker.Check(schedule, routes, orders) : false); }
/// <summary> /// Execute command. /// </summary> /// <param name="args"> /// Command args. /// Routes to generate shapes. /// </param> protected override void _Execute(params object[] args) { try { List <Route> routesWithoutGeometry = args[0] as List <Route>; Debug.Assert(routesWithoutGeometry != null); _DoGenerateRoutesShapes(routesWithoutGeometry); } catch (RouteException e) { if (e.InvalidObjects != null) // if exception throw because any Routes or Orders are invalid { _ShowSolveValidationResult(e.InvalidObjects); } else { App.Current.Messenger.AddError(RoutingCmdHelpers.FormatRoutingExceptionMsg(e)); } } catch (Exception e) { Logger.Error(e); if ((e is LicenseException) || (e is AuthenticationException) || (e is CommunicationException)) { CommonHelpers.AddRoutingErrorMessage(e); } else { throw; } } }
/// <summary> /// Starts operation process. /// </summary> /// <param name="args">Operation args.</param> /// <exception cref="Exception">Throws if any unhandles exception occurs in method.</exception> protected override void _Execute(params object[] args) { try { // Get current schedule. if (_schedulePage == null) { _schedulePage = (OptimizeAndEditPage)App.Current.MainWindow.GetPage(PagePaths.SchedulePagePath); } Schedule schedule = _schedulePage.CurrentSchedule; ICollection <Order> selectedOrders = _GetOrdersWhichCanBeUnassignedFromSelection(_schedulePage.SelectedItems); ICollection <Order> orders = RoutingCmdHelpers.GetOrdersIncludingPairs(schedule, selectedOrders); ICollection <Route> routes = ViolationsHelper.GetRouteForUnassignOrders(schedule, orders); if (_CheckRoutingParams(schedule, routes, orders)) { SolveOptions options = new SolveOptions(); options.GenerateDirections = App.Current.MapDisplay.TrueRoute; options.FailOnInvalidOrderGeoLocation = false; _SetOperationStartedStatus((string)App.Current.FindResource(UNASSIGN_ORDERS), (DateTime)schedule.PlannedDate); OperationsIds.Add(App.Current.Solver.UnassignOrdersAsync(schedule, orders, options)); // set solve started message string infoMessage = RoutingMessagesHelper.GetUnassignOperationStartedMessage(orders); if (!string.IsNullOrEmpty(infoMessage)) { App.Current.Messenger.AddInfo(infoMessage); } } } catch (RouteException e) { if (e.InvalidObjects != null) // if exception throw because any Routes or Orders are invalid { _ShowSolveValidationResult(e.InvalidObjects); } else { _ShowErrorMsg(RoutingCmdHelpers.FormatRoutingExceptionMsg(e)); } } catch (Exception e) { Logger.Error(e); if ((e is LicenseException) || (e is AuthenticationException) || (e is CommunicationException)) { CommonHelpers.AddRoutingErrorMessage(e); } else { throw; } } }
/// <summary> /// Method unassignes orders from schedule /// </summary> /// <param name="orders"></param> /// <param name="schedule"></param> private void _UnassignOrdersFromSchedule(Schedule schedule, ICollection <Order> orders) { try { ICollection <Order> ordersWithPairs = RoutingCmdHelpers.GetOrdersIncludingPairs(schedule, orders); // Create routes collection. ICollection <Route> routes = ViolationsHelper.GetRouteForUnassignOrders(schedule, ordersWithPairs); if (_CheckRoutingParams(schedule, ordersWithPairs, routes)) { SolveOptions options = new SolveOptions(); options.GenerateDirections = App.Current.MapDisplay.TrueRoute; options.FailOnInvalidOrderGeoLocation = false; string infoMessage = _FormatSuccessUnassigningStartedMessage(schedule, _schedulesToUnassign); // Set operation info status. _SetOperationStartedStatus(infoMessage, (DateTime)schedule.PlannedDate); // Start solve operation. App.Current.Solver.UnassignOrdersAsync(schedule, ordersWithPairs, options); } else // If routing operation was not started - clean collections and unlock UI. { _CleanUp(); _UnlockUI(); } } catch (RouteException e) { App.Current.Messenger.AddError(RoutingCmdHelpers.FormatRoutingExceptionMsg(e)); App.Current.Messenger.AddError(string.Format(OperationIsFailedMessage, schedule)); // Save already edited schedules. _UpdateOptimizeAndEditPageSchedules(); _CleanUp(); _UnlockUI(); } catch (Exception ex) { // Save already edited schedules. _UpdateOptimizeAndEditPageSchedules(); _CleanUp(); _UnlockUI(); if ((ex is LicenseException) || (ex is AuthenticationException) || (ex is CommunicationException)) { CommonHelpers.AddRoutingErrorMessage(ex); } else { throw; } } }
/// <summary> /// Handles exception thrown from a solve operation. /// </summary> /// <param name="exception">The exception thrown from a solve operation.</param> private void _HandleSolveError(Exception exception) { Debug.Assert(exception != null); var routeException = exception as RouteException; if (routeException != null) { if (routeException.InvalidObjects != null) { // exception was thrown because any Routes or Orders are invalid. _ShowSolveValidationResult(routeException.InvalidObjects); } else { _ShowErrorMsg(RoutingCmdHelpers.FormatRoutingExceptionMsg(routeException)); } return; } // If we have error in sync response - show it. var restException = exception as RestException; if (restException != null) { var details = new List <MessageDetail>(); // If exception has details- process them. if (restException.Details != null) { foreach (var detail in restException.Details) { var detailMessage = GuidsReplacer.ReplaceGuids(detail, App.Current.Project); details.Add(new MessageDetail(MessageType.Error, detailMessage)); } } // Process exception message. var message = GuidsReplacer.ReplaceGuids(exception.Message, App.Current.Project); // Show error in messenger. App.Current.Messenger.AddError(message, details); return; } Logger.Error(exception); CommonHelpers.AddRoutingErrorMessage(exception); }
/// <summary> /// Creates collection of message detail when solve operation failed /// </summary> /// <param name="schedule"></param> /// <param name="info"></param> /// <param name="result"></param> /// <returns></returns> private ICollection <MessageDetail> _GetErrorFailedDetails(AsyncOperationInfo info, SolveResult result) { Debug.Assert(info != null); Debug.Assert(result != null); // Create details. ICollection <MessageDetail> details = null; if (0 < result.Violations.Count) { details = ViolationMessageBuilder.GetViolationDetails(info.Schedule, info, result.Violations); } else { // Create details from solver error message. details = new Collection <MessageDetail>(); details.Add(new MessageDetail(MessageType.Error, RoutingCmdHelpers.FormatSolverErrorMsg(result))); } return(details); }
/// <summary> /// Method checks params of routing operation and show warning message with details if parameters are invalid /// </summary> /// <param name="schedule"></param> /// <param name="orders"></param> /// <param name="routes"></param> /// <returns></returns> private bool _CheckRoutingParams(Schedule schedule, ICollection <Order> orders, ICollection <Route> routes) { bool isValid = false; List <DataObject> invalidObjects = new List <DataObject>(); invalidObjects.AddRange(RoutingCmdHelpers.ValidateObjects <Order>(orders)); invalidObjects.AddRange(RoutingCmdHelpers.ValidateObjects <Route>(routes)); if (invalidObjects.Count > 0) { RoutingSolveValidator validator = new RoutingSolveValidator(); ICollection <MessageDetail> details = validator.GetValidateMessageDetail(invalidObjects.ToArray()); string invalidOperationTitle = ((string)App.Current.FindResource("SolveValidationOperationInvalid")); App.Current.Messenger.AddMessage(MessageType.Error, invalidOperationTitle, details); } else { isValid = true; } return(isValid); }
/// <summary> /// Saves new schedule if it's build correctly or show error message. /// </summary> /// <param name="res">Solve result.</param> /// <param name="schedule">Schedule.</param> /// <param name="info">Operation info.</param> protected void _SaveSchedule(SolveResult res, Schedule schedule, AsyncOperationInfo info) { // if solver returns "failed" if (res.IsFailed) { // show result message(s) string message = string.Format( (string)App.Current.FindResource(ROUTING_OPERATION_FAILED), schedule.PlannedDate.Value.ToShortDateString()); ICollection <MessageDetail> details = null; if (0 < res.Violations.Count) { details = ViolationMessageBuilder.GetViolationDetails(schedule, info, res.Violations); } // Create details from solver error message. else { details = new Collection <MessageDetail>(); var errorMessage = RoutingCmdHelpers.FormatSolverErrorMsg(res); // If we have error message - add message detail. if (errorMessage.Length != 0) { details.Add(new MessageDetail(MessageType.Error, errorMessage)); } } App.Current.Messenger.AddError(message, details); } else { // set unassigned orders if (null != schedule.UnassignedOrders) { schedule.UnassignedOrders.Dispose(); } // save route results Project project = App.Current.Project; project.Save(); schedule.UnassignedOrders = project.Orders.SearchUnassignedOrders(schedule, true); // In case operation is Build Routes we should create "Original Schedule" if doesn't exist yet. // Schedule must be current. if (info.OperationType == SolveOperationType.BuildRoutes) { if (schedule.Type == ScheduleType.BuildRoutesSnapshot) { // update current schedule (according to CR133526) _UpdateSchedule(ScheduleType.Current, schedule, (string)App.Current.FindResource("CurrentScheduleName")); // update build routes snapshot name schedule.Name = _FormatBuildRoutesSnapshotName(); } else { // update build routes snapshot _UpdateSchedule(ScheduleType.BuildRoutesSnapshot, schedule, _FormatBuildRoutesSnapshotName()); } // save changes project.Save(); } // Show result message(s). if (0 < res.Violations.Count) { _ShowPartialSuccessOperationResults(res.Violations, schedule, info); } else { // If operation type is Assign To Routes // show that Order was assigned to that Route if (info.OperationType.Equals(SolveOperationType.AssignOrders)) { _ShowSuccessfullyAssignedOrders(schedule, info); } else { App.Current.Messenger.AddInfo( _FormatSuccessSolveCompletedMsg(schedule, info)); } } } OptimizeAndEditPage page = (OptimizeAndEditPage)((MainWindow)App.Current.MainWindow).GetPage(PagePaths.SchedulePagePath); if (null != page) { page.OnScheduleChanged(schedule); } }
/// <summary> /// Excecutes command. /// </summary> /// <param name="args"></param> protected override void _Execute(params object[] args) { try { OptimizeAndEditPage schedulePage = (OptimizeAndEditPage)App.Current.MainWindow.GetPage(PagePaths.SchedulePagePath); Schedule schedule = schedulePage.CurrentSchedule; // Get selected orders. Collection <Order> selectedOrders = _GetOrdersWhichCanBeMovedFromSelection(schedulePage.SelectedItems); selectedOrders = RoutingCmdHelpers.GetOrdersIncludingPairs(schedule, selectedOrders) as Collection <Order>; bool keepViolOrdrsUnassigned = false; Debug.Assert(args[0] != null); ICollection <Route> targetRoutes = args[0] as ICollection <Route>; Debug.Assert(targetRoutes != null); string routeName = args[1] as string; if (_CheckRoutingParams(schedule, targetRoutes, selectedOrders)) { SolveOptions options = new SolveOptions(); options.GenerateDirections = App.Current.MapDisplay.TrueRoute; options.FailOnInvalidOrderGeoLocation = false; _SetOperationStartedStatus((string)App.Current.FindResource(ASSIGN_ORDERS), (DateTime)schedule.PlannedDate); // Start "Assign to best other route" operation. OperationsIds.Add(App.Current.Solver.AssignOrdersAsync(schedule, selectedOrders, targetRoutes, null, keepViolOrdrsUnassigned, options)); // Set solve started message string infoMessage = RoutingMessagesHelper.GetAssignOperationStartedMessage(selectedOrders, routeName); if (!string.IsNullOrEmpty(infoMessage)) { App.Current.Messenger.AddInfo(infoMessage); } } } catch (RouteException e) { if (e.InvalidObjects != null) // If exception throw because any Routes or Orders are invalid { _ShowSolveValidationResult(e.InvalidObjects); } else { _ShowErrorMsg(RoutingCmdHelpers.FormatRoutingExceptionMsg(e)); } } catch (Exception e) { Logger.Error(e); if ((e is LicenseException) || (e is AuthenticationException) || (e is CommunicationException)) { CommonHelpers.AddRoutingErrorMessage(e); } else { throw; } } }
protected override void _Execute(params object[] args) { try { ICollection <Route> routes = _GetRoutesFromSelection(_schedulePage.SelectedItems); // get unlocked routes from selected routes // and all orders assigned to converting routes List <Order> orders = new List <Order>(); foreach (Route route in routes) { if (!route.IsLocked) { // get assigned orders List <Order> routeOrders = new List <Order>(); foreach (Stop stop in route.Stops) { if (stop.StopType == StopType.Order) { routeOrders.Add(stop.AssociatedObject as Order); } } orders.AddRange(routeOrders); } } // get current schedule Schedule schedule = _schedulePage.CurrentSchedule; if (_CheckRoutingParams(schedule, routes, orders)) { SolveOptions options = new SolveOptions(); options.GenerateDirections = App.Current.MapDisplay.TrueRoute; options.FailOnInvalidOrderGeoLocation = false; _SetOperationStartedStatus((string)App.Current.FindResource("SequenceRoutes"), (DateTime)schedule.PlannedDate); OperationsIds.Add(App.Current.Solver.SequenceRoutesAsync(schedule, routes, options)); // set solve started message string infoMessage = _FormatSuccesSolveStartedMsg(schedule, routes.Count); if (!string.IsNullOrEmpty(infoMessage)) { App.Current.Messenger.AddInfo(infoMessage); } } } catch (RouteException e) { if (e.InvalidObjects != null) // if exception throw because any Routes or Orders are invalid { _ShowSolveValidationResult(e.InvalidObjects); } else { _ShowErrorMsg(RoutingCmdHelpers.FormatRoutingExceptionMsg(e)); } } catch (Exception e) { Logger.Error(e); if ((e is LicenseException) || (e is AuthenticationException) || (e is CommunicationException)) { CommonHelpers.AddRoutingErrorMessage(e); } else { throw; } } }
protected override void _Execute(params object[] args) { AsyncOperationInfo info = null; // Check whether operation can be started. if (!_CanBuildRoutesBeStarted(out info)) // If BuildRoutes operation cannot be started - show warning and return. { Debug.Assert(info != null); // Must be defined in _CanBuildRoutesBeStarted method. App.Current.MainWindow.MessageWindow.AddWarning( string.Format((string)App.Current.FindResource(ALREADY_BUILDING_ROUTES_MESSAGE_RESOURCE), info.Schedule.PlannedDate.Value.ToShortDateString())); return; } try { Schedule schedule = _optimizeAndEditPage.CurrentSchedule; var inputParams = _GetBuildRoutesParameters(schedule); var routes = inputParams.TargetRoutes; var orders = inputParams.OrdersToAssign; if (_CheckRoutingParams(schedule, routes, orders)) { SolveOptions options = new SolveOptions(); options.GenerateDirections = App.Current.MapDisplay.TrueRoute; options.FailOnInvalidOrderGeoLocation = false; _SetOperationStartedStatus((string)App.Current.FindResource(BUILD_ROUTES_STRING), (DateTime)schedule.PlannedDate); OperationsIds.Add(App.Current.Solver.BuildRoutesAsync( schedule, options, inputParams)); // set solve started message string infoMessage = _FormatSuccesSolveStartedMsg(schedule, inputParams); if (!string.IsNullOrEmpty(infoMessage)) { App.Current.Messenger.AddInfo(infoMessage); } } } catch (RouteException e) { if (e.InvalidObjects != null) // if exception throw because any Routes or Orders are invalid { _ShowSolveValidationResult(e.InvalidObjects); } else { _ShowErrorMsg(RoutingCmdHelpers.FormatRoutingExceptionMsg(e)); } } catch (Exception e) { Logger.Error(e); if ((e is LicenseException) || (e is AuthenticationException) || (e is CommunicationException)) { CommonHelpers.AddRoutingErrorMessage(e); } else { throw; } } }
/// <summary> /// Overrided method for move orders. It will be called in parent class /// </summary> /// <param name="args"></param> protected override void _ProcessOrders(params object[] args) { Collection <Order> ordersToAssign = args[0] as Collection <Order>; DateTime targetDate = (DateTime)args[1]; Debug.Assert(targetDate != null); Debug.Assert(ordersToAssign != null); // Include any paired orders ICollection <Schedule> currentSchedules = App.Current.Project.Schedules.Search(App.Current.CurrentDate); if (currentSchedules != null && currentSchedules.Count > 0) { Schedule schedule = currentSchedules.ElementAt(0); // Ensure unassigned orders is up to date schedule.UnassignedOrders = null; OptimizeAndEditHelpers.FixSchedule(App.Current.Project, schedule); ordersToAssign = RoutingCmdHelpers.GetOrdersIncludingPairs(schedule, ordersToAssign) as Collection <Order>; } // Change orders planned date foreach (Order order in ordersToAssign) { order.PlannedDate = targetDate; } App.Current.Project.Save(); // add info message to MessageWindow string infoMessage = string.Format((string)App.Current.FindResource("DropOnDateCmdSuccessText"), ordersToAssign.Count, App.Current.CurrentDate.ToShortDateString(), targetDate.ToShortDateString()); App.Current.Messenger.AddInfo(infoMessage); // clear unassigned orders for all schedule in current date foreach (Schedule schedule in currentSchedules) { if (schedule.UnassignedOrders != null) { schedule.UnassignedOrders.Dispose(); schedule.UnassignedOrders = null; } } // clear unassigned orders for all schedule in target date ICollection <Schedule> targetSchedules = App.Current.Project.Schedules.Search(targetDate); foreach (Schedule schedule in targetSchedules) { if (schedule.UnassignedOrders != null) { schedule.UnassignedOrders.Dispose(); schedule.UnassignedOrders = null; } } OptimizeAndEditPage optimizeAndEditPage = (OptimizeAndEditPage)App.Current.MainWindow.GetPage(PagePaths.SchedulePagePath); if (ordersToAssign[0].PlannedDate != optimizeAndEditPage.CurrentSchedule.PlannedDate) { optimizeAndEditPage.DeleteStoredSelection(optimizeAndEditPage.CurrentSchedule.PlannedDate.Value); } // schedule has changed - all views should be refreshed optimizeAndEditPage.OnScheduleChanged(optimizeAndEditPage.CurrentSchedule); // update days statuses DayStatusesManager.Instance.UpdateDayStatus(App.Current.CurrentDate); DayStatusesManager.Instance.UpdateDayStatus(targetDate); // clear selection in OptimizeAndEditPage optimizeAndEditPage.SelectedItems.Clear(); }
/// <summary> /// Starts command executing. /// </summary> /// <param name="args">Command args.</param> protected override void _Execute(params object[] args) { // Get OptimizeAndEdit page. OptimizeAndEditPage schedulePage = ((MainWindow)App.Current.MainWindow).GetPage(PagePaths.SchedulePagePath) as OptimizeAndEditPage; Debug.Assert(schedulePage != null); // If editing is in progress - try to save editing. if (schedulePage.IsEditingInProgress) { // If editing cannot be saved - cancel editing. if (!schedulePage.SaveEditedItem()) { schedulePage.CancelObjectEditing(); } } // Orders to assign. Collection <Order> ordersToAssign = (Collection <Order>)args[0]; Debug.Assert(ordersToAssign != null); // Target object. Object target = (Object)args[1]; // Include paired orders unless we are moving one order within the same route bool movingSingleOrderInPair = false; if (ordersToAssign.Count == 1 && (target is Stop)) { Route targetRoute = (target as Stop).Route; Order orderToAssign = ordersToAssign.ElementAt(0); foreach (Stop stop in targetRoute.Stops) { Order associatedOrder = stop.AssociatedObject as Order; if (associatedOrder == null) { continue; } if (associatedOrder == orderToAssign) { movingSingleOrderInPair = true; break; } } } if (!movingSingleOrderInPair) { ordersToAssign = RoutingCmdHelpers.GetOrdersIncludingPairs(schedulePage.CurrentSchedule, ordersToAssign) as Collection <Order>; } int?sequence = null; if (target is Stop) { // Set sequence only if there is a single order to assign. if (ordersToAssign.Count == 1) { sequence = (target as Stop).SequenceNumber; } else // Otherwise change target to route. For more details see CR161083. { target = (target as Stop).Route; } } // Get target routes. ICollection <Route> targetRoutes = _CreateTargetRoutes(target); try { // If target routes count is 0 - orders must be unassigned. if (targetRoutes.Count == 0) { // Start unassigning orders. _UnassignOrders(ordersToAssign); } else { // Start moving orders. _MoveOrders(ordersToAssign, targetRoutes, sequence); } } catch (RouteException e) { if (e.InvalidObjects != null) // If exception throw because any Routes or Orders are invalid. { _ShowSolveValidationResult(e.InvalidObjects); } else { _ShowErrorMsg(RoutingCmdHelpers.FormatRoutingExceptionMsg(e)); } } catch (Exception e) { Logger.Error(e); if ((e is LicenseException) || (e is AuthenticationException) || (e is CommunicationException)) { CommonHelpers.AddRoutingErrorMessage(e); } else { throw; } } }