public void TestConnectionException() { // arrange var inner = new Exception(); var entry = new TimeEntryInfo(); // act var exception = new CrudException(OperationType.Create, entry, inner); // assert Assert.That(exception.InnerException, Is.EqualTo(inner)); Assert.That(exception.CorrespondingObject, Is.EqualTo(entry)); Assert.That(exception.OperationType, Is.EqualTo(OperationType.Create)); }
/// <summary> /// Updates an appointment to the values of a redmine time entry /// </summary> /// <param name="item">The appointment item</param> /// <param name="timeEntry">The redmine time entry</param> /// <param name="issue">The issue that belongs to the timeentry. Can be <code>null</code> if the issue is not known.</param> public static void UpdateAppointmentFromTimeEntry(this AppointmentItem item, TimeEntryInfo timeEntry, IssueInfo issue) { // create new calendar item item.CreateAppointmentLocation(timeEntry.IssueInfo.Id.Value, issue); item.Subject = timeEntry.Name; item.Start = timeEntry.StartDateTime; var endTime = timeEntry.EndDateTime; if (timeEntry.IssueInfo.Id != Settings.Default.RedmineUseOvertimeIssue) { item.End = timeEntry.EndDateTime; } else { // In case of the overtime issue, we cannot take the actual hours property for determining the end time, because hours is 0. item.End = endTime; } if (timeEntry.IssueInfo.Id != Settings.Default.RedmineUseOvertimeIssue && Math.Abs((endTime - item.End).TotalMinutes) > 5) { item.AppendToBody("Die Von/Bis-Zeit dieses Elements wurde geändert, da sie nicht mit dem 'Stunden'-Feld aus Redmine übereinstimmte."); Log.WarnFormat("The end time of the time entry was changed, because it was not consistent with the provided duration. "); } // create user properties item.UpdateAppointmentFields( timeEntry.Id, timeEntry.ProjectInfo.Id.Value, timeEntry.IssueInfo.Id.Value, timeEntry.ActivityInfo.Id.Value, timeEntry.UpdateTime); if (timeEntry.IssueInfo.Id != Settings.Default.RedmineUseOvertimeIssue) { item.SetAppointmentState(AppointmentState.Synchronized); } else { item.SetAppointmentState(AppointmentState.SynchronizedOvertime); } }
/// <summary> /// Method to create an object from the given time entry /// </summary> /// <param name="item">the time entry</param> /// <returns>the object created</returns> public TimeEntryInfo CreateObject(TimeEntryInfo item) { try { // create the time entry to send to redmine var timeEntry = this.CreateTimeEntryFromInfoObject(item); // write the object to redmine var createdObject = this._redmineApi.CreateObject(timeEntry); // update object and return it item.Id = createdObject.Id; if (createdObject.Project != null) { item.ProjectInfo = new ProjectInfo() { Id = createdObject.Project.Id, Name = createdObject.Project.Name }; } return(item); } catch (RedmineException redmineException) { var typeNumber = redmineException.HResult; if (redmineException.Message.Contains("Die zugrunde liegende Verbindung wurde geschlossen")) { throw new ConnectionException(redmineException) { IdentifierNumber = typeNumber }; } else { throw new CrudException(OperationType.Create, item, redmineException) { IdentifierNumber = typeNumber }; } } }
/// <summary> /// Checks whether the appointment is different to the time entry /// </summary> /// <param name="item">The item</param> /// <param name="timeEntry">The time entry</param> /// <returns>True if the item is modified</returns> public static bool CheckItemIsModified(this AppointmentItem item, TimeEntryInfo timeEntry) { // create new calendar item var startTime = timeEntry.StartDateTime; var endTime = timeEntry.EndDateTime; if (!string.Equals(item.Subject, timeEntry.Name)) { return(true); } if (item.Start != startTime || item.End != endTime) { return(true); } var issueId = item.GetIssueId(); if (issueId != timeEntry.IssueInfo.Id) { return(true); } return(false); }
public void CreateAndDeleteTimeEntry() { // arrange var manager = new RedmineManagerInstance(Url, ApiKey); var activityInfo = manager.GetTotalActivityInfoList(new DataSourceParameter()).First(a => a.IsDefault); var issueInfo = manager.GetIssueInfoList(new DataSourceParameter() { Limit = 1 }).First(); var projectInfo = new ProjectInfo() { Id = issueInfo.ProjectId, Name = issueInfo.ProjectShortName }; var timeEntryInfo = new TimeEntryInfo() { Id = null, Name = "CreateAndDeleteTest", StartDateTime = new DateTime(2016, 7, 8, 10, 0, 0), EndDateTime = new DateTime(2016, 7, 8, 12, 15, 0, 0), UpdateTime = new DateTime(2017, 2, 14), ActivityInfo = activityInfo, IssueInfo = issueInfo, ProjectInfo = projectInfo, }; // act var created = manager.CreateObject(timeEntryInfo); var createdId = created.Id; // assert Assert.That(createdId, Is.Not.Null); // act manager.DeleteTimeEntry(createdId, new DataSourceParameter()); }
/// <summary> /// Method to update the given object with the data contained in the object. The object has the id set, all other values should be updated /// </summary> /// <param name="entry">the entry to update</param> /// <returns>the time entry info of the updated object</returns> public TimeEntryInfo UpdateObject(TimeEntryInfo entry) { this._timeEntries.RemoveAll(e => object.Equals(e.Id, entry.Id)); this._timeEntries.Add(entry); return(entry); }
/// <summary> /// Initializes a new instance of the <see cref="CrudException"/> class. /// </summary> /// <param name="type">the type of operation performed</param> /// <param name="correspondingObject"> /// The object to be created. /// </param> /// <param name="innerException">the inner exception</param> public CrudException(OperationType type, TimeEntryInfo correspondingObject, Exception innerException) : base(MessageText, innerException) { this.OperationType = type; this.CorrespondingObject = correspondingObject; }
/// <summary> /// Method to create the a time entry from the info object /// </summary> /// <param name="item">the time entry info to update the infos from</param> /// <returns>the time entry which can be sent to redmine</returns> internal TimeEntry CreateTimeEntryFromInfoObject(TimeEntryInfo item) { // get base info var user = this.GetCurrentUser(); var activityInfo = item.ActivityInfo; var issueInfo = item.IssueInfo; // create new time entry for redmine var timeEntry = new TimeEntry { Activity = new IdentifiableName { Id = activityInfo.Id.Value, Name = activityInfo.Name }, Issue = new IdentifiableName { Id = issueInfo.Id.Value, Name = issueInfo.Name }, User = new IdentifiableName { Id = user.Id.Value }, Comments = item.Name, CreatedOn = DateTime.Now, UpdatedOn = item.UpdateTime, SpentOn = item.StartDateTime.Date, Hours = 0 }; // create start and end time custom fields var startTimeField = new IssueCustomField { Name = "Start", Id = 1 }; var startTimeValue = new CustomFieldValue { Info = item.StartDateTime.ToString("HH:mm") }; startTimeField.Values = new List <CustomFieldValue> { startTimeValue }; timeEntry.CustomFields = new List <IssueCustomField> { startTimeField }; var endTimeField = new IssueCustomField { Name = "End", Id = 2 }; var endTimeValue = new CustomFieldValue { Info = item.EndDateTime.ToString("HH:mm") }; endTimeField.Values = new List <CustomFieldValue> { endTimeValue }; timeEntry.CustomFields.Add(endTimeField); // set the hours if (issueInfo.Id != Settings.Default.RedmineUseOvertimeIssue) { timeEntry.Hours = (decimal)(item.EndDateTime - item.StartDateTime).TotalHours; } // set the Id if there is already one if (item.Id != null) { timeEntry.Id = item.Id.Value; } return(timeEntry); }