/// <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); } }