/// <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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
            }
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
        /// <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);
        }