/// <summary> /// Gets the timesheet model to be inserted in database. /// </summary> /// <param name="timesheetDate">The timesheet date to be save.</param> /// <param name="timesheetViewModel">The timesheet view model.</param> /// <param name="userObjectId">The logged-in user object Id.</param> /// <returns>The timesheet entity model.</returns> public TimesheetEntity MapForCreateModel(DateTime timesheetDate, TimesheetDetails timesheetViewModel, Guid userObjectId) { timesheetViewModel = timesheetViewModel ?? throw new ArgumentNullException(nameof(timesheetViewModel)); var timesheet = new TimesheetEntity { TaskId = timesheetViewModel.TaskId, TaskTitle = timesheetViewModel.TaskTitle, TimesheetDate = timesheetDate, Hours = timesheetViewModel.Hours, Status = timesheetViewModel.Status, UserId = userObjectId, }; if (timesheetViewModel.Status == (int)TimesheetStatus.Submitted) { timesheet.SubmittedOn = DateTime.UtcNow; } else { timesheet.SubmittedOn = null; } return(timesheet); }
/// <summary> /// Maps timesheet view model details to timesheet entity model that to be updated in database. /// </summary> /// <param name="timesheetViewModel">The timesheet entity view model.</param> /// <param name="timesheetModel">The timesheet entity model.</param> public void MapForUpdateModel(TimesheetDetails timesheetViewModel, TimesheetEntity timesheetModel) { timesheetViewModel = timesheetViewModel ?? throw new ArgumentNullException(nameof(timesheetViewModel)); timesheetModel = timesheetModel ?? throw new ArgumentNullException(nameof(timesheetModel)); timesheetModel.Status = timesheetViewModel.Status; timesheetModel.Hours = timesheetViewModel.Hours; timesheetModel.LastModifiedOn = DateTime.UtcNow; }
/// <summary> /// Maps timesheet database entity to view model. /// </summary> /// <param name="timesheet">The timesheet details.</param> /// <returns>Returns timesheet view model.</returns> public TimesheetDTO MapForViewModel(TimesheetEntity timesheet) { timesheet = timesheet ?? throw new ArgumentNullException(nameof(timesheet), "Timesheet details should not be null"); return(new TimesheetDTO { Id = timesheet.Id, TaskTitle = timesheet.TaskTitle, TimesheetDate = timesheet.TimesheetDate.Date, Hours = timesheet.Hours, Status = timesheet.Status, }); }
/// <summary> /// Create groups of timesheets by date sequence. /// Ex. If timesheet dates are [1,2,4,6,7,8] then timesheets will be divided in 3 groups /// as [1,2],[4],[6,7,8]. /// </summary> /// <param name="projectwiseTimesheetsOrderedByDate">List of timesheets grouped by project.</param> /// <returns>List of timesheets grouped by date sequence.</returns> internal List <List <TimesheetEntity> > GetTimesheetsGroupedByDateSequence(IEnumerable <TimesheetEntity> projectwiseTimesheetsOrderedByDate) { var timesheetsGroupedByDateSequence = new List <List <TimesheetEntity> >(); if (!projectwiseTimesheetsOrderedByDate.Any()) { return(timesheetsGroupedByDateSequence); } var timesheetsSubList = new List <TimesheetEntity>(); TimesheetEntity lastTimesheet = new TimesheetEntity(); foreach (var timesheet in projectwiseTimesheetsOrderedByDate) { // If difference between last timesheet's date and current timesheet's date // is 1 day or its same date then add it to sub-list. if ((timesheet.TimesheetDate == lastTimesheet.TimesheetDate) || (timesheet.TimesheetDate.AddDays(-1) == lastTimesheet.TimesheetDate)) { timesheetsSubList.Add(timesheet); } else { // If difference between last timesheet's date and current timesheet's date // is more than 1 day then add sub-list to parent list and reset the sub-list to add new timesheet sequence. if (timesheetsSubList.Any()) { timesheetsGroupedByDateSequence.Add(timesheetsSubList); } timesheetsSubList = new List <TimesheetEntity> { timesheet, }; } lastTimesheet = timesheet; } // Add last sub-list to parent. timesheetsGroupedByDateSequence.Add(timesheetsSubList); return(timesheetsGroupedByDateSequence); }
private void UpdateNewTimesheetRecordAfterServerSync(int rowNo, TimesheetEntity timesheet) { // https://social.msdn.microsoft.com/Forums/vstudio/en-US/f89fe6b3-68c0-4a98-9522-953cc5befb34/how-to-make-a-excel-cell-readonly-by-c-code?forum=vsto Worksheet.Unprotect(); Globals.ThisAddIn.Application.Cells.Locked = false; Worksheet.Change -= new Microsoft.Office.Interop.Excel. DocEvents_ChangeEventHandler(changesRange_Change); ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.IdColumnIndex]).Value2 = timesheet.Id; #pragma warning disable S125 // Sections of code should not be commented out //((Excel.Range)sheet.Cells[timesheets.Count + 2, IdColumnIndex]).Interior.Color = Excel.XlRgbColor.rgbAliceBlue; #pragma warning restore S125 // Sections of code should not be commented out ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.DateColumnIndex]).Value2 = timesheet.Begin.Date.ToOADate(); if (timesheet.Project.HasValue) { var project = Globals.ThisAddIn.GetProjectById(timesheet.Project.Value); ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.CustomerColumnIndex]).Value2 = project.ParentTitle; ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.ProjectColumnIndex]).Value2 = project.Name; } if (timesheet.Activity.HasValue) { var activity = Globals.ThisAddIn.GetActivityById(timesheet.Activity.Value); ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.ActivityColumnIndex]).Value2 = activity.Name; } ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.DescColumnIndex]).Value2 = timesheet.Description; ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.BeginTimeIndex]).Value2 = timesheet.Begin.ToLocalTime().ToOADate(); if (timesheet.End.HasValue) { ((Range)Worksheet.Cells[rowNo, ExcelAddin.Constants.Sheet1.EndTimeIndex]).Value2 = timesheet.End.Value.ToLocalTime().ToOADate(); } Worksheet.Change += new Microsoft.Office.Interop.Excel. DocEvents_ChangeEventHandler(changesRange_Change); // https://social.msdn.microsoft.com/Forums/vstudio/en-US/f89fe6b3-68c0-4a98-9522-953cc5befb34/how-to-make-a-excel-cell-readonly-by-c-code?forum=vsto Globals.ThisAddIn.Application.Cells.Locked = false; Globals.ThisAddIn.Application.get_Range("A1", $"A{rowNo}").Locked = true; Worksheet.Protect(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); }
public void AddorUpdateTimehseet(string[] line) { int empid = Convert.ToInt32(line[0]); string date = line[3]; decimal hour = Convert.ToDecimal(line[4]); bool isleave = line[5] == "0"?false:true; bool isHalfday = line[6] == "0"?false:true; var time = sql.GetTimesheetUser(empid, date); if (time.Count > 0) { var _timeupd = new TimesheetEntity() { EmpId = empid, TimesheeetDate = Convert.ToDateTime(date), TimesheetHour = hour, IsHalfday = isHalfday, IsOff = isleave, ProjectId = 1, UserID = time[0].UserID, CreatedDate = DateTime.Now, Id = time[0].Id }; timeupd.Add(_timeupd); } else { var _timeAdd = new TimesheetEntity() { EmpId = empid, TimesheeetDate = DateTime.Parse(date), TimesheetHour = hour, IsHalfday = isHalfday, IsOff = isleave, ProjectId = 1, CreatedDate = DateTime.Now }; timeAdd.Add(_timeAdd); } }
/// <summary> /// Duplicates the efforts of source date timesheet to the target dates. /// </summary> /// <param name="sourceDate">The source date of which efforts needs to be duplicated.</param> /// <param name="targetDates">The target dates to which efforts needs to be duplicated.</param> /// <param name="clientLocalCurrentDate">The client's local current date.</param> /// <param name="userObjectId">The logged-in user object Id.</param> /// <returns>Returns duplicated timesheets.</returns> public async Task <List <TimesheetDTO> > DuplicateEffortsAsync(DateTime sourceDate, IEnumerable <DateTime> targetDates, DateTime clientLocalCurrentDate, Guid userObjectId) { // Get target dates those aren't frozen. targetDates = this.GetNotYetFrozenTimesheetDates(targetDates, clientLocalCurrentDate); var timesheets = await this.GetTimesheetsAsync(sourceDate, sourceDate, userObjectId); var sourceDateTimesheet = timesheets.FirstOrDefault(); var sourceDateProjectIds = sourceDateTimesheet.ProjectDetails.Select(project => project.Id); // Get timesheet details for target dates with source date project Ids. var targetDatesTimesheets = this.repositoryAccessors.TimesheetRepository.GetTimesheetsOfUser(targetDates, userObjectId, sourceDateProjectIds); var sourceDateFilledEfforts = this.GetTotalEffortsByDate(new List <UserTimesheet> { sourceDateTimesheet }); var duplicatedTimesheets = new List <TimesheetDTO>(); foreach (var targetDate in targetDates) { if (this.WillWeeklyEffortsExceedLimit(targetDate, sourceDateFilledEfforts, userObjectId)) { continue; } foreach (var project in sourceDateTimesheet.ProjectDetails) { // Do not copy efforts if: // 1. Target date is less than project start date // 2. OR target date is greater than project end date // 3. OR if timesheet wasn't filled for project of source date if (targetDate < project.StartDate || targetDate > project.EndDate || project.TimesheetDetails.IsNullOrEmpty()) { continue; } foreach (var timesheet in project.TimesheetDetails) { // Get timesheet to update from timesheet entity. var timesheetToUpdate = targetDatesTimesheets .Where(timesheetDetails => timesheetDetails.TimesheetDate.Equals(targetDate) && timesheetDetails.TaskId.Equals(timesheet.TaskId) && timesheetDetails.Task.ProjectId.Equals(project.Id)).FirstOrDefault(); // If timesheet details exists (user filled timesheet), then update it with updated details. if (timesheetToUpdate != null) { timesheetToUpdate.Hours = timesheet.Hours; timesheetToUpdate.Status = (int)TimesheetStatus.Saved; this.repositoryAccessors.TimesheetRepository.Update(timesheetToUpdate); duplicatedTimesheets.Add(this.timesheetMapper.MapForViewModel(timesheetToUpdate)); } else { // Create new timesheet in timesheet entity (as user didn't filled timesheet previously). var newTimesheetDetails = new TimesheetEntity { TimesheetDate = targetDate, TaskId = timesheet.TaskId, TaskTitle = timesheet.TaskTitle, Hours = timesheet.Hours, Status = (int)TimesheetStatus.Saved, UserId = userObjectId, }; this.repositoryAccessors.TimesheetRepository.Add(newTimesheetDetails); duplicatedTimesheets.Add(this.timesheetMapper.MapForViewModel(newTimesheetDetails)); } } } } var isEffortsDuplicated = await this.repositoryAccessors.SaveChangesAsync() > 0; if (isEffortsDuplicated) { return(duplicatedTimesheets); } this.logger.LogInformation("Failed to duplicate efforts."); return(null); }
/// <summary> /// Duplicates the efforts of source date timesheet to the target dates. /// </summary> /// <param name="sourceDate">The source date of which efforts needs to be duplicated.</param> /// <param name="targetDates">The target dates to which efforts needs to be duplicated.</param> /// <param name="clientLocalCurrentDate">The client's local current date.</param> /// <param name="userObjectId">The logged-in user object Id.</param> /// <returns>Return true if efforts duplicated successfully. Else returns false.</returns> public async Task <ResultResponse> DuplicateEffortsAsync(DateTime sourceDate, IEnumerable <DateTime> targetDates, DateTime clientLocalCurrentDate, Guid userObjectId) { var result = new ResultResponse { Response = Enumerable.Empty <TimesheetDTO>() }; // Validates whether client provided local date is valid. if (!this.IsClientCurrentDateValid(clientLocalCurrentDate, DateTime.UtcNow)) { this.logger.LogInformation("The timesheet can not be filled as provided current date is invalid."); result.StatusCode = HttpStatusCode.BadRequest; result.ErrorMessage = "The timesheet can not be filled as provided current date is invalid."; return(result); } // Get target dates those aren't frozen. var notYetFrozenTimesheetDates = this.GetNotYetFrozenTimesheetDates(targetDates, clientLocalCurrentDate); // If all target dates are frozen. if (notYetFrozenTimesheetDates.IsNullOrEmpty()) { this.logger.LogInformation("The timesheet can not be filled as the target dates are frozen."); result.StatusCode = HttpStatusCode.BadRequest; result.ErrorMessage = "The timesheet can not be filled as the target dates are frozen."; return(result); } targetDates = notYetFrozenTimesheetDates; var timesheets = await this.GetTimesheetsAsync(sourceDate, sourceDate, userObjectId); var sourceDateTimesheet = timesheets.FirstOrDefault(); if (sourceDateTimesheet == null || sourceDateTimesheet.ProjectDetails.IsNullOrEmpty()) { this.logger.LogInformation("The source date must have projects."); result.StatusCode = HttpStatusCode.BadRequest; result.ErrorMessage = "The source date must have projects."; return(result); } var sourceDateProjectIds = sourceDateTimesheet.ProjectDetails.Select(project => project.Id); // Get timesheet details for target dates with source date project Ids. var targetDatesTimesheets = this.repositoryAccessors.TimesheetRepository.GetTimesheetsOfUser(targetDates, userObjectId, sourceDateProjectIds); var sourceDateFilledEfforts = this.GetTotalEffortsByDate(new List <UserTimesheet> { sourceDateTimesheet }); var duplicatedTimesheets = new List <TimesheetDTO>(); foreach (var targetDate in targetDates) { if (this.WillWeeklyEffortsLimitExceed(targetDate, sourceDateFilledEfforts, userObjectId)) { continue; } foreach (var project in sourceDateTimesheet.ProjectDetails) { // Do not copy efforts if: // 1. Target date is less than project start date // 2. OR target date is greater than project end date // 3. OR if timesheet wasn't filled for project of source date if (targetDate < project.StartDate || targetDate > project.EndDate || project.TimesheetDetails.IsNullOrEmpty()) { continue; } foreach (var timesheet in project.TimesheetDetails) { // Get timesheet to update from timesheet entity. var timesheetToUpdate = targetDatesTimesheets .Where(timesheetDetails => timesheetDetails.TimesheetDate.Equals(targetDate) && timesheetDetails.TaskId.Equals(timesheet.TaskId) && timesheetDetails.Task.ProjectId.Equals(project.Id)).FirstOrDefault(); // If timesheet details exists (user filled timesheet), then update it with updated details. if (timesheetToUpdate != null) { timesheetToUpdate.Hours = timesheet.Hours; timesheetToUpdate.Status = (int)TimesheetStatus.Saved; this.repositoryAccessors.TimesheetRepository.Update(timesheetToUpdate); duplicatedTimesheets.Add(this.timesheetMapper.MapForViewModel(timesheetToUpdate)); } else { // Create new timesheet in timesheet entity (as user didn't filled timesheet previously). var newTimesheetDetails = new TimesheetEntity { TimesheetDate = targetDate, TaskId = timesheet.TaskId, TaskTitle = timesheet.TaskTitle, Hours = timesheet.Hours, Status = (int)TimesheetStatus.Saved, UserId = userObjectId, }; this.repositoryAccessors.TimesheetRepository.Add(newTimesheetDetails); duplicatedTimesheets.Add(this.timesheetMapper.MapForViewModel(newTimesheetDetails)); } } } } var isEffortsDuplicated = await this.repositoryAccessors.SaveChangesAsync() > 0; if (isEffortsDuplicated) { result.StatusCode = HttpStatusCode.OK; result.Response = duplicatedTimesheets; } else { this.logger.LogInformation("Failed to duplicate efforts."); result.StatusCode = HttpStatusCode.InternalServerError; result.ErrorMessage = "Failed to duplicate efforts."; } return(result); }