public static Recurrence[] GetRecurrences(string serviceBrokerGuid, string groupName, string labServerGuid, string clientGuid, DateTime startTime, DateTime endTime) { TimeBlock range = new TimeBlock(startTime, endTime); List<Recurrence> recurrences = new List<Recurrence>(); DbConnection connection = FactoryDB.GetConnection(); // create sql command // command executes the "RetrieveRecurrenceIDs" stored procedure DbCommand cmd = FactoryDB.CreateCommand("Recurrences_Retrieve", connection); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@sbGuid", serviceBrokerGuid, DbType.AnsiString, 50)); cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@group", groupName, DbType.String, 256)); cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@lsGuid", labServerGuid, DbType.AnsiString, 50)); cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@clientGuid", clientGuid, DbType.AnsiString, 50)); cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@start", DateUtil.SpecifyUTC(startTime), DbType.DateTime)); cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@end", DateUtil.SpecifyUTC(endTime), DbType.DateTime)); try { DbDataReader dataReader = null; Recurrence recur = null; connection.Open(); //recurrence_id,resource_id,recurrence_type,day_mask,recurrence_start_date,recurrence_num_days //recurrence_start_offset,recurrence_end_offset, quantum dataReader = cmd.ExecuteReader(); while (dataReader.Read()) { recur = new Recurrence(); recur.recurrenceId = dataReader.GetInt32(0); recur.resourceId = dataReader.GetInt32(1); recur.recurrenceType = (Recurrence.RecurrenceType)dataReader.GetInt32(2); recur.dayMask = dataReader.GetByte(3); recur.startDate = DateUtil.SpecifyUTC(dataReader.GetDateTime(4)); recur.numDays = dataReader.GetInt32(5); recur.startOffset = TimeSpan.FromSeconds((double)dataReader.GetInt32(6)); recur.endOffset = TimeSpan.FromSeconds((double)dataReader.GetInt32(7)); recur.quantum = dataReader.GetInt32(8); TimeBlock[] blocks = recur.GetTimeBlocks(); foreach (TimeBlock tb in blocks) { if (range.Intersects(tb)) { recurrences.Add(recur); break; } } } dataReader.Close(); } catch (Exception ex) { throw new Exception("Exception thrown in get recurrences", ex); } finally { connection.Close(); } return recurrences.ToArray(); }
private void renderTimePeriods(HtmlTextWriter output, DateTime date, IEnumerable periods) { TimeBlock validTime = new TimeBlock(date.AddHours((int)minTOD.Hours), date.AddHours((int)maxTOD.TotalHours)); if (periods != null) { IEnumerator enumTP = null; try { enumTP = periods.GetEnumerator(); enumTP.MoveNext(); TimePeriod first = (TimePeriod)enumTP.Current; if (first.Start > validTime.Start) { renderVoidTime(output, Convert.ToInt32((first.Start - validTime.Start).TotalSeconds)); } } catch (Exception ex) { } finally { enumTP.Reset(); } foreach (TimePeriod tp in periods) { if (validTime.Intersects(tp)) { TimeBlock valid = validTime.Intersection(tp); if (tp.quantum == 0) { renderScheduledTime(output, valid); } else { int cellDur = 0; int tDur = valid.Duration; DateTime cur = valid.Start; DateTime end = valid.End; while (cur < end) { cellDur = defaultCellDuration -(cur.TimeOfDay.Minutes % defaultCellDuration); if(cellDur < defaultCellDuration) cellDur += defaultCellDuration; if ((end - cur.AddMinutes(cellDur)).TotalMinutes < (defaultCellDuration/2)) { cellDur += Convert.ToInt32((end - cur.AddMinutes(cellDur)).TotalMinutes ); } cellDur = (cur.AddMinutes(cellDur) <= end) ? cellDur : (int)(end - cur).TotalMinutes; renderAvailableTime(output, cur, tDur, tp.quantum, cellDur * 60, false); cur = cur.AddMinutes(cellDur); tDur = tDur - (cellDur * 60); //cellDur = (cur.TimeOfDay.Minutes % defaultCellDuration) + defaultCellDuration; //cellDur = (cur.AddMinutes(cellDur) <= end) ? cellDur : (int)(end - cur).TotalMinutes; //renderAvailableTime(output, cur, tDur, tp.quantum, cellDur * 60, false); //cur = cur.AddMinutes(cellDur); //tDur = tDur - (cellDur * 60); } } } } } }
/// <summary> /// Returns an Boolean indicating whether a particular reservation from a USS is confirmed and added to the database in LSS successfully. If it fails, exception will be throw out indicating /// the reason for rejection. /// </summary> /// <param name="serviceBrokerGuid"></param> /// <param name="groupName"></param> /// <param name="ussGuid"></param> /// <param name="labServerGuid"></param> /// <param name="clientGuid"></param> /// <param name="startTime"></param>the local time of LSS /// <param name="endTime"></param>the local time of LSS /// <returns></returns>the notification whether the reservation is confirmed. If not, notification will give a reason public static string ConfirmReservation(string serviceBrokerGuid, string groupName, string ussGuid, string labServerGuid, string clientGuid, DateTime startTime, DateTime endTime) { string notification = null; try { //get the experiment configuration int eID = DBManager.ListExperimentInfoIDByExperiment(labServerGuid, clientGuid); LssExperimentInfo exInfo = GetExperimentInfos(new int[] { eID })[0]; int preTime = exInfo.prepareTime; int recTime = exInfo.recoverTime; int minTime = exInfo.minimumTime; //check whether the reservation is executable if (((TimeSpan)endTime.Subtract(startTime)).TotalMinutes < minTime) { notification = "The reservation time is less than the minimum time the experiment required"; return notification; } //the start time for the experiment equipment DateTime expStartTime = startTime.AddMinutes(-preTime); //the end time for the experiment equipment DateTime expEndTime = endTime.AddMinutes(recTime); Recurrence[] recurrences = DBManager.GetRecurrences(serviceBrokerGuid, groupName, labServerGuid, clientGuid, startTime, endTime); if ((recurrences == null) || (recurrences.Length == 0)) { notification = "This experiment is not available to your group during this time."; return notification; } else if (recurrences.Length > 1) { notification = "More than one recurrence was found for this request. Please choose another time."; return notification; } else { TimeBlock[] reserved = DBManager.ListReservationTimeBlocks(recurrences[0].resourceId, expStartTime, expEndTime); bool ok = true; if ((reserved != null) && (reserved.Length > 0)) { // Need to process the reservations to make suggestions notification = "This reservation time is not available now, please adjust your reservation time."; TimeBlock check = new TimeBlock(expStartTime, expEndTime); foreach (TimeBlock tb in reserved) { TimeBlock intersection = check.Intersection(tb); if (intersection != null) { TimeSpan span = TimeSpan.FromSeconds(intersection.Duration); if(intersection.Start < expEndTime) notification += @"<br />Adjust the time by starting " + span.TotalMinutes + " minutes earlier, or make the duration shorter by " + span.TotalMinutes + " minutes."; if (intersection.End > expStartTime) notification += @"<br />Adjust the time by starting " + span.TotalMinutes + " minutes later."; } } return notification; } //add the reservation to to reservationInfo table int status = AddReservationInfo(serviceBrokerGuid, groupName, ussGuid, labServerGuid, clientGuid, startTime.ToUniversalTime(), endTime.ToUniversalTime(), 0); if (status > 0) { notification = "The reservation is confirmed successfully"; if (exInfo.contactEmail != null && exInfo.contactEmail.Length > 0) { // Send a mail Message StringBuilder message = new StringBuilder(); MailMessage mail = new MailMessage(); mail.To = exInfo.contactEmail; mail.From = ConfigurationSettings.AppSettings["genericFromMailAddress"]; mail.Subject = "New Reservation: " + exInfo.labClientName; message.Append("A new reservation for " + exInfo.labClientName + " version: " + exInfo.labClientVersion); message.AppendLine(" on " + exInfo.labServerName + " has been made."); message.AppendLine("\tGroup: " + groupName + " ServiceBroker: " + serviceBrokerGuid); message.Append("\tFrom: " + DateUtil.ToUserTime(startTime, CultureInfo.CurrentCulture, DateUtil.LocalTzOffset)); message.AppendLine("\t\tTo: " + DateUtil.ToUserTime(endTime, CultureInfo.CurrentCulture, DateUtil.LocalTzOffset)); message.AppendLine("\tDateFormat: " + CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + " \tUTC Offset: " + (DateUtil.LocalTzOffset / 60.0)); message.AppendLine(); mail.Body = message.ToString(); SmtpMail.SmtpServer = "127.0.0.1"; try { SmtpMail.Send(mail); } catch (Exception ex) { // Report detailed SMTP Errors StringBuilder smtpErrorMsg = new StringBuilder(); smtpErrorMsg.Append("Exception: " + ex.Message); //check the InnerException if (ex.InnerException != null) { smtpErrorMsg.Append("<br>Inner Exceptions:"); while (ex.InnerException != null) { smtpErrorMsg.Append("<br>" + ex.InnerException.Message); ex = ex.InnerException; } Utilities.WriteLog(smtpErrorMsg.ToString()); } } } } else notification = "Error: AddReservation status = " + status; return notification; } } catch (Exception ex) { return ex.Message; } return notification; }
public int MakeReservation(string serviceBrokerGuid, string groupName, string ussGuid, string labServerGuid, string clientGuid, DateTime startTime, DateTime endTime, ref StringBuilder notification) { int status = -1; Recurrence[] recurrences = GetRecurrences(serviceBrokerGuid, groupName, labServerGuid, clientGuid, startTime, endTime); if ((recurrences == null) || (recurrences.Length == 0)) { notification.AppendLine("This experiment is not available to your group during this time."); return status; } else if (recurrences.Length > 1) { notification.Append("More than one recurrence was found for this request. Please choose another time."); return status; } else { TimeBlock[] reserved = ListReservationTimeBlocks(recurrences[0].resourceId, startTime, endTime); bool ok = true; if ((reserved != null) && (reserved.Length > 0)) { // Need to process the reservations to make suggestions notification.AppendLine("This reservation time is not available now, please adjust your reservation time."); TimeBlock check = new TimeBlock(startTime, endTime); foreach (TimeBlock tb in reserved) { TimeBlock intersection = check.Intersection(tb); if (intersection != null) { TimeSpan span = TimeSpan.FromSeconds(intersection.Duration); if (intersection.Start < endTime) notification.AppendLine(@"<br />Adjust the time by starting " + span.TotalMinutes + " minutes earlier, or make the duration shorter by " + span.TotalMinutes + " minutes."); if (intersection.End > startTime) notification.AppendLine(@"<br />Adjust the time by starting " + span.TotalMinutes + " minutes later."); } } return 0; } //add the reservation to to reservationInfo table status = AddReservationInfo(serviceBrokerGuid, groupName, ussGuid, labServerGuid, clientGuid, recurrences[0].resourceId,startTime.ToUniversalTime(), endTime.ToUniversalTime(), 0); } return status; }
protected override void PerformDataBinding(IEnumerable schedulingData) { // don't bind in design mode if (DesignMode) { return; } base.PerformDataBinding(schedulingData); // Verify data exists. if (schedulingData != null) { TimeSpan tmpTS; TimeSpan oneDay = TimeSpan.FromDays(1); maxTOD = TimeSpan.Zero.Subtract(TimeSpan.FromMinutes(userTZ)); minTOD = oneDay; foreach (ITimeBlock tb in schedulingData) { tmpTS = tb.Start.AddMinutes(userTZ).TimeOfDay; if (minTOD > tmpTS) minTOD = tmpTS; tmpTS = tmpTS.Add(TimeSpan.FromSeconds(tb.Duration)); if (tmpTS.TotalHours < 24) { if (maxTOD < tmpTS) { maxTOD = tmpTS; } } else if (tmpTS.TotalHours == 24) { maxTOD = tmpTS; } else { minTOD = TimeSpan.Zero; maxTOD = TimeSpan.FromHours(24); break; } } if (bindReservations) { // should be Reservations reservations = new List<Reservation>(); foreach (Reservation r in schedulingData) { reservations.Add(r); } } else { // should be TimePeriods TimeBlock range = new TimeBlock(StartTime, EndTime); periods = new List<TimePeriod>(); foreach (TimePeriod tp in schedulingData) { if(range.Contains(tp)){ periods.Add(tp); } else if (range.Intersects(tp)) { TimeBlock tmpTB = range.Intersection(tp); periods.Add(new TimePeriod(tmpTB.Start, tmpTB.Duration, tp.quantum)); } } TimeBlock[] scheduledTBs = TimeBlock.Remaining(new TimeBlock[] { range }, periods.ToArray()); if (scheduledTBs != null && scheduledTBs.Length > 0) { periods.AddRange(TimePeriod.MakeArray(scheduledTBs, 0)); } periods.Sort(); } } else { minTOD = TimeSpan.Zero; maxTOD = TimeSpan.FromHours(24); periods = new List<TimePeriod>(); periods.Add(new TimePeriod(StartTime, EndTime, 0)); } }
public static TimeBlock Union(ITimeBlock a, ITimeBlock b) { TimeBlock tb = null; if(TimeBlock.HasUnion(a,b)) tb = new TimeBlock(a.Start <= b.Start ? a.Start : b.Start,a.End >= b.End ?a.End:b.End); return tb; }
public int Split(ITimeBlock subBlock, ref TimeBlock intersection, ref TimeBlock previous, ref TimeBlock remaining) { int status = 0; intersection = null; previous = null; remaining = null; if (Intersects(subBlock)) { intersection = Intersection(subBlock); if (startTime < intersection.Start) { previous = new TimeBlock(startTime, intersection.Start); status |= 1; } else if (intersection.Start > subBlock.Start) { previous = new TimeBlock(subBlock.Start, intersection.Start); status |= 2; } if (End > intersection.End) { remaining = new TimeBlock(intersection.End, End); status |= 4; } else if (subBlock.End > intersection.End) { remaining = new TimeBlock(intersection.End, subBlock.End); status |= 8; } } return status; }
public TimeBlock[] GetTimeBlocks(DateTime start, DateTime end) { // Bounds check if (start >= End || end <= Start) { return null; } List<TimeBlock> list = new List<TimeBlock>(); TimeBlock range = new TimeBlock(start >= Start ? start : Start, end.Ticks <= End.Ticks ? end : End); if (recurrenceType == RecurrenceType.SingleBlock) { list.Add(range); } else { TimeSpan day = TimeSpan.FromDays(1.0); int dayOffset = Convert.ToInt32(start.Subtract(startDate).TotalDays); int endDay = Convert.ToInt32(end.Subtract(startDate).TotalDays); endDay = numDays <= endDay ? numDays : endDay; DateTime work = startDate.Add(TimeSpan.FromDays(dayOffset -1)); DateTime eDate = startDate.Add(TimeSpan.FromDays(endDay +1)); TimeBlock chunk = null; if (recurrenceType == RecurrenceType.Daily) { while (work < eDate) { chunk = range.Intersection(new TimeBlock(work.Add(startOffset),work.Add(endOffset))); if(chunk != null) list.Add(chunk); work = work.Add(day); } } else if (recurrenceType == RecurrenceType.Weekly) { while (work < eDate) { if (DateUtil.CheckDayMask(work.DayOfWeek, dayMask)) { chunk = range.Intersection(new TimeBlock(work.Add(startOffset), work.Add(endOffset))); if (chunk != null) list.Add(chunk); } work = work.Add(day); } } } return list.ToArray(); }
public TimeBlock[] GetTimeBlocks() { List<TimeBlock> list = new List<TimeBlock>(); TimeBlock chunk = null; TimeSpan day = TimeSpan.FromDays(1.0); DateTime endDate = startDate.AddDays(numDays); switch ((RecurrenceType)recurrenceType) { case RecurrenceType.SingleBlock: chunk = new TimeBlock(Start,Duration); list.Add(chunk); break; case RecurrenceType.Daily: DateTime work = startDate.Add(startOffset); for (int i = 0; i < numDays; i++) { chunk = new TimeBlock(work,(int) (endOffset - startOffset).TotalSeconds); if(chunk.End <= endDate) list.Add(chunk); work = work.AddDays(1.0); } break; case RecurrenceType.Weekly: DateTime wwork = startDate; for (int i = 0; i < numDays; i++) { if (DateUtil.CheckDayMask(wwork.DayOfWeek, dayMask)) { chunk = new TimeBlock(); chunk.startTime = wwork.Add(startOffset); chunk.duration = (int) (endOffset - startOffset).TotalSeconds; if(chunk.End <= endDate) list.Add(chunk); } wwork = wwork.AddDays(1.0); } break; default: break; } return list.ToArray(); }
protected override void PerformDataBinding(IEnumerable schedulingData) { // don't bind in design mode if (DesignMode) { return; } base.PerformDataBinding(schedulingData); MinTOD = TimeSpan.Zero; MaxTOD = oneDay; // Verify data exists. if (schedulingData != null) { if (NumDays == 1) { TimeSpan tmpTS; TimeSpan tmpMinTOD = oneDay; //Check the first timeBlock IEnumerator eTB = schedulingData.GetEnumerator(); if (eTB.MoveNext()) { tmpTS = (( TimeBlock)eTB.Current).Start.AddMinutes(userTZ).TimeOfDay; if (tmpMinTOD > tmpTS) { tmpMinTOD = tmpTS; MinTOD = tmpMinTOD; } } } if (bindReservations) { // should be Reservations reservations = new List<Reservation>(); foreach (Reservation r in schedulingData) { reservations.Add(r); } } else { // should be TimePeriods TimeBlock range = new TimeBlock(StartTime, EndTime); periods = new List<TimePeriod>(); foreach (TimePeriod tp in schedulingData) { if(range.Contains(tp)){ periods.Add(tp); } else if (range.Intersects(tp)) { TimeBlock tmpTB = range.Intersection(tp); periods.Add(new TimePeriod(tmpTB.Start, tmpTB.Duration, tp.quantum)); } } TimeBlock[] scheduledTBs = TimeBlock.Remaining(new TimeBlock[] { range }, periods.ToArray()); if (scheduledTBs != null && scheduledTBs.Length > 0) { periods.AddRange(TimePeriod.MakeArray(scheduledTBs, 0)); } periods.Sort(); } } else { periods = new List<TimePeriod>(); periods.Add(new TimePeriod(StartTime, EndTime, 0)); } }
private int renderScheduledTime(HtmlTextWriter output, ITimeBlock tb) { int duration = 0; if (tb.End < endOfDay) duration = tb.Duration; else duration = new TimeBlock(tb.Start, endOfDay).Duration; if (duration > 0) { output.Write("<tr>"); int height = Convert.ToInt32((((hourHeight * duration) / 3600.0))); //output.AddAttribute("onclick", "javascript:" + Page.ClientScript.GetPostBackEventReference(this, startTime.ToString("s"))); #if useStyle output.AddStyleAttribute(HtmlTextWriterStyle.Padding, zero.ToString()); output.AddStyleAttribute(HtmlTextWriterStyle.Margin, zero.ToString()); output.AddStyleAttribute("background-color", ColorTranslator.ToHtml(scheduledColor)); output.AddStyleAttribute("cursor", "hand"); //output.AddStyleAttribute("border-bottom", "1px solid " + ColorTranslator.ToHtml(BorderColor)); #endif output.AddAttribute("class", reservedClass); output.AddStyleAttribute("height", adjustHeight(height) + "px"); if (browserMode > 0) { output.AddStyleAttribute("border-bottom", "1px solid " + ColorTranslator.ToHtml(BorderColor)); output.AddStyleAttribute("background-color", ColorTranslator.ToHtml(scheduledColor)); } output.AddAttribute("title", tb.Start.AddMinutes(userTZ).TimeOfDay.ToString() + " - " + tb.End.AddMinutes(userTZ).ToString()); output.RenderBeginTag("td"); output.RenderEndTag(); output.WriteLine("</tr>"); } return duration; }
private void renderTimePeriods(HtmlTextWriter output, DateTime date, List<TimePeriod> periods) { TimeBlock validTime = new TimeBlock(date.AddHours((int)minTOD.Hours), endTime); TimeBlock valid; DateTime cur = DateTime.MinValue; DateTime end = DateTime.MinValue; if (periods != null && periods.Count >0) { try { TimePeriod first = periods[0]; if (first.Start > validTime.Start) { renderVoidTime(output, Convert.ToInt32((first.Start - validTime.Start).TotalSeconds)); } } catch (Exception ex) { throw ex; } foreach (TimePeriod tp in periods) { if (validTime.Intersects(tp)) { valid = validTime.Intersection(tp); cur = valid.Start; end = valid.End; if (tp.quantum == 0) { renderScheduledTime(output, valid); } else { int cellDur = 0; int tDur = valid.Duration; while (cur < end && cur < endOfDay) { cellDur = defaultCellDuration -( cur.TimeOfDay.Minutes % defaultCellDuration); if(cellDur < defaultCellDuration) cellDur += defaultCellDuration; if ((end - cur.AddMinutes(cellDur)).TotalMinutes < (defaultCellDuration/2)) { cellDur += Convert.ToInt32((end - cur.AddMinutes(cellDur)).TotalMinutes ); } cellDur = (cur.AddMinutes(cellDur) <= endOfDay) ? cellDur : (int)(endOfDay - cur).TotalMinutes; renderAvailableTime(output, cur, tDur, tp.quantum, cellDur * 60, false); cur = cur.AddMinutes(cellDur); tDur = tDur - (cellDur * 60); } } } } // End of foreach period if (end < endOfDay) { renderScheduledTime(output, new TimeBlock(end,endOfDay)); } } }