public static StartReservationItem CreateStartReservationItem(HttpContextBase context, IProvider provider, IReservationItem rsv) { var now = DateTime.Now; var item = new StartReservationItem { ReservationID = rsv.ReservationID, ResourceID = rsv.ResourceID, ResourceName = rsv.ResourceName, ReservedByClientID = rsv.ClientID, ReservedByClientName = string.Format("{0} {1}", rsv.FName, rsv.LName) }; var currentUser = context.CurrentUser(provider); if (rsv.ClientIDBegin.HasValue) { if (rsv.ClientIDBegin.Value > 0) { IClient startedBy = provider.Data.Client.GetClient(rsv.ClientIDBegin.Value); item.StartedByClientID = startedBy.ClientID; item.StartedByClientName = string.Format("{0} {1}", startedBy.FName, startedBy.LName); } else { item.StartedByClientID = 0; item.StartedByClientName = string.Empty; } } else { item.StartedByClientID = currentUser.ClientID; item.StartedByClientName = string.Format("{0} {1}", currentUser.FName, currentUser.LName); } var reservationItem = provider.Scheduler.Reservation.GetReservationWithInvitees(rsv.ReservationID); var helper = new SchedulerContextHelper(context, provider); var args = ReservationStateArgs.Create(reservationItem, helper.GetReservationClient(reservationItem), now); var stateUtil = ReservationStateUtility.Create(now); ReservationState state = stateUtil.GetReservationState(args); item.Startable = stateUtil.IsStartable(state); item.NotStartableMessage = GetNotStartableMessage(state); var inst = ActionInstances.Find(ActionType.Interlock, rsv.ResourceID); item.HasInterlock = inst != null; var res = provider.Scheduler.Resource.GetResource(rsv.ResourceID); item.ReturnUrl = GetResourceUrl(context, res); return(item); }
private void ReservationStateTester(int resourceId, int reserverClientId, int currentClientId, int inviteeClientId, int activityId, DateTime beginDateTime, int duration, bool inlab, bool canDelete, bool canModify) { var now = DateTime.Now; DateTime endDateTime = beginDateTime.AddMinutes(duration); IReservationItem rsv = GetMockReservation(123456, resourceId, reserverClientId, activityId, beginDateTime, endDateTime, null, null); ReservationStateArgs args = GetReservationStateArgs(rsv, currentClientId, inviteeClientId, inlab, now); ReservationState state = ReservationStateUtility.Create(now).GetReservationState(args); bool actual; actual = SchedulerUtility.CanDeleteReservation(state, args, now); Assert.AreEqual(canDelete, actual); actual = SchedulerUtility.CanModifyReservation(state, args, now); Assert.AreEqual(canModify, actual); }
public string GetReservationAction(HttpContextBase context) { SchedulerContextHelper helper = GetContextHelper(context); context.Session.Remove("ActiveReservationMessage"); context.Session.Remove("ShowStartConfirmationDialog"); var now = DateTime.Now; var util = Reservations.Create(Provider, now); var requestedState = GetReservationState(context); var rsv = helper.GetReservation(); var res = helper.GetResource(rsv.ResourceID); var client = helper.GetReservationClient(rsv); var args = ReservationStateArgs.Create(rsv, client, now); var state = ReservationStateUtility.Create(now).GetReservationState(args); var currentView = GetView(context); var currentUser = context.CurrentUser(Provider); bool confirm = false; int reservationId = 0; helper.AppendLog($"ReservationController.GetReservationAction: reservationId = {rsv.ReservationID}, requestedState = {requestedState}, state = {state}, currentView = {currentView}"); switch (requestedState) { case ReservationState.StartOnly: case ReservationState.StartOrDelete: // If there are previous unended reservations, then ask for confirmation var endable = Provider.Scheduler.Reservation.SelectEndableReservations(rsv.ResourceID); if (endable.Count() > 0) { var endableReservations = string.Join(",", endable.Select(x => x.ReservationID)); context.Session["ActiveReservationMessage"] = $"[Previous ReservationID: {endableReservations}, Current ReservationID: {rsv.ReservationID}]"; confirm = true; reservationId = rsv.ReservationID; } else { util.Start(rsv, helper.GetReservationClient(rsv), currentUser.ClientID); } break; case ReservationState.Endable: // End reservation if (state == ReservationState.Endable) { util.End(rsv, DateTime.Now, currentUser.ClientID); } else { string actualBeginDateTime = rsv.ActualBeginDateTime.HasValue ? rsv.ActualBeginDateTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : "null"; throw new InvalidOperationException($"ReservationID {rsv.ReservationID} state is {state}, not Endable. ActualBeginDateTime: {actualBeginDateTime}"); } break; case ReservationState.PastSelf: if (currentView == ViewType.DayView || currentView == ViewType.WeekView) { context.SetWeekStartDate(rsv.BeginDateTime.Date); } return(SchedulerUtility.GetReturnUrl("ReservationRunNotes.aspx", PathInfo.Create(res), context.Request.SelectedLocationPath(), rsv.ReservationID, context.Request.SelectedDate())); case ReservationState.Other: case ReservationState.Invited: case ReservationState.PastOther: return(SchedulerUtility.GetReturnUrl("Contact.aspx", PathInfo.Create(res), context.Request.SelectedLocationPath(), rsv.ReservationID, context.Request.SelectedDate())); default: // invalid state detected! // throw new NotImplementedException($"ReservationState = {state} is not implemented"); context.Session["ErrorMessage"] = $"The current reservation state, {state}, is invalid. No actions are defined for this state. [RequestedState = {requestedState}, ReservationID = {reservationId}]"; var vars = new Dictionary <string, object> { ["current state"] = state, ["requested state"] = requestedState, ["reservationId"] = reservationId, ["tool_engineer"] = args.IsToolEngineer, ["inlab"] = args.IsInLab, ["reserver"] = args.IsReserver, ["invited"] = args.IsInvited, ["authorized"] = args.IsAuthorized, ["before_mct"] = args.IsBeforeMinCancelTime(), ["startable"] = args.IsStartable() }; helper.SendDebugEmail("ReservationController.GetReservationAction", "Invalid state detected!", "Invalid state detected!", vars); return(SchedulerUtility.Create(Provider).GetReservationViewReturnUrl(currentView, false, reservationId)); } string result = SchedulerUtility.Create(Provider).GetReservationViewReturnUrl(currentView, confirm, reservationId); return(result); }
public ReservationState GetReservationCell(CustomTableCell rsvCell, IReservationItem rsv, ReservationClient client, IEnumerable <IReservationProcessInfo> reservationProcessInfos, IEnumerable <IReservationInviteeItem> invitees, LocationPathInfo locationPath, ViewType view, DateTime now) { int reservationId = rsv.ReservationID; int resourceId = rsv.ResourceID; // Reservation State var args = ReservationStateArgs.Create(rsv, client, now); var state = ReservationStateUtility.Create(now).GetReservationState(args); // Tooltip Caption and Text string caption = Reservations.GetReservationCaption(state); string toolTip = Reservations.Create(Provider, now).GetReservationToolTip(rsv, state, reservationProcessInfos, invitees); rsvCell.Attributes["data-tooltip"] = toolTip; rsvCell.Attributes["data-caption"] = caption; // Remove the create reservation link if it was added. if (rsvCell.Controls.Count > 0) { rsvCell.Controls.Clear(); } // BackGround color and cursor - set by CSS rsvCell.CssClass = state.ToString(); var div = new HtmlGenericControl("div"); div.Attributes.Add("class", "reservation-container"); var cellText = rsv.DisplayName; if (rsv.RecurrenceID.GetValueOrDefault(-1) > 0) { cellText += " [R]"; } // Reservation Text Literal litReserver = new Literal { Text = $"<div class=\"cell-text\">{cellText}</div>" }; div.Controls.Add(litReserver); // Delete Button // 2/11/05 - GPR: allow tool engineers to cancel any non-started, non-repair reservation in the future ClientAuthLevel userAuth = args.UserAuth; PathInfo path = PathInfo.Create(rsv.BuildingID, rsv.LabID, rsv.ProcessTechID, rsv.ResourceID); string navurl; //if (state == ReservationState.Editable || state == ReservationState.StartOrDelete || state == ReservationState.StartOnly || (userAuth == ClientAuthLevel.ToolEngineer && DateTime.Now < rsv.BeginDateTime && rsv.ActualBeginDateTime == null && state != ReservationState.Repair)) // [2020-09-18 jg] StartOnly should not allow delete and NotInLab should allow delete if (CanDeleteReservation(state, args, now)) { navurl = UrlUtility.GetDeleteReservationUrl(rsv.ReservationID, rsvCell.CellDate, state, view); var hypDelete = new HyperLink { NavigateUrl = NavigateUrl(navurl, path, locationPath), ImageUrl = "~/images/deleteGrid.gif", CssClass = "ReservDelete" }; hypDelete.Attributes["data-tooltip"] = "Click to cancel reservation"; hypDelete.Attributes["data-caption"] = "Cancel this reservation"; div.Controls.Add(hypDelete); rsvCell.HorizontalAlign = HorizontalAlign.Left; rsvCell.VerticalAlign = VerticalAlign.Top; } // 2011/04/03 Modify button // [2020-09-18 jg] StartOnly should not allow modification (also NotInLab should not allow modification) //if (state == ReservationState.Editable || state == ReservationState.StartOrDelete || state == ReservationState.StartOnly) if (CanModifyReservation(state, args, now)) { navurl = UrlUtility.GetModifyReservationUrl(rsv.ReservationID, rsvCell.CellDate, state, view); var hypModify = new HyperLink { NavigateUrl = NavigateUrl(navurl, path, locationPath), ImageUrl = "~/images/edit.png", CssClass = "ReservModify" }; hypModify.Attributes["data-tooltip"] = "Click to modify reservation"; hypModify.Attributes["data-caption"] = "Modify this reservation"; div.Controls.Add(hypModify); rsvCell.HorizontalAlign = HorizontalAlign.Left; rsvCell.VerticalAlign = VerticalAlign.Top; } rsvCell.Controls.Add(div); return(state); }