public async Task <ActionResult> Leave(LeaveApplicationViewModel applicationVM)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    double[] takenLeaves = new double[3];
                    foreach (var l in applicationVM.TimeRecords)
                    {
                        int index = (int)l.LeaveType - 1;
                        takenLeaves[index] += l.LeaveTime;
                    }

                    // Transfer attachments to ViewModel
                    if (applicationVM.Attachments.Count > 0)
                    {
                        List <LeaveAttachment> files = new List <LeaveAttachment>();
                        foreach (var file in applicationVM.Attachments)
                        {
                            if (file.ContentLength > 0)
                            {
                                var attachment = new LeaveAttachment
                                {
                                    FileName    = System.IO.Path.GetFileName(file.FileName),
                                    ContentType = file.ContentType
                                };
                                using (var reader = new System.IO.BinaryReader(file.InputStream))
                                {
                                    attachment.Content = reader.ReadBytes(file.ContentLength);
                                }
                                files.Add(attachment);
                            }
                        }
                        applicationVM.LeaveApplication.Attachments = files;
                    }

                    // Try to fetch Leaveapplication from DB if it exists
                    applicationVM.LeaveApplication.UserID = User.Identity.Name;
                    var application = (from a in contextDb.LeaveApplications
                                       where DbFunctions.TruncateTime(a.StartTime) == applicationVM.LeaveApplication.StartTime.Date &&
                                       DbFunctions.TruncateTime(a.EndTime) == applicationVM.LeaveApplication.EndTime.Date &&
                                       a.UserID == applicationVM.LeaveApplication.UserID
                                       select a).FirstOrDefault();

                    foreach (var r in applicationVM.TimeRecords)
                    {
                        // Configure time record if it's not a full day off
                        if (r.LeaveTime != 7.5)
                        {
                            r.SetAttendence(9, 17 - r.LeaveTime, 0.5);
                        }

                        // Sum up total leave time
                        applicationVM.LeaveApplication.TotalTime += r.LeaveTime;

                        // Try to fetch TimeRecord from DB if it exists
                        var timeRecord = (from a in contextDb.TimeRecords
                                          where DbFunctions.TruncateTime(a.RecordDate) == r.RecordDate.Date &&
                                          a.UserID == r.UserID
                                          select a).FirstOrDefault();

                        // Update TimeRecord if exists, Add if not
                        if (timeRecord == null)
                        {
                            contextDb.TimeRecords.Add(r);
                        }
                        else
                        {
                            int index = (int)timeRecord.LeaveType - 1;
                            takenLeaves[index]  -= timeRecord.LeaveTime;
                            timeRecord.LeaveTime = r.LeaveTime;
                            timeRecord.LeaveType = r.LeaveType;
                            contextDb.Entry(timeRecord).State = EntityState.Modified;
                        }
                        contextDb.SaveChanges();
                    }

                    // Update LeaveApplication if exists, add if not
                    if (application == null)
                    {
                        applicationVM.LeaveApplication.status = _status.submited;
                        contextDb.LeaveApplications.Add(applicationVM.LeaveApplication);
                    }
                    else
                    {
                        application.status    = _status.modified;
                        application.leaveType = applicationVM.LeaveApplication.leaveType;
                        application.ManagerID = applicationVM.LeaveApplication.ManagerID;
                        application.Comment   = applicationVM.LeaveApplication.Comment;
                        application.TotalTime = applicationVM.LeaveApplication.TotalTime;
                        contextDb.Entry(application).State = EntityState.Modified;
                    }
                    contextDb.SaveChanges();

                    // Update user leaves data in Db after submitting if it's leave application
                    if (applicationVM.LeaveApplication.leaveType != _leaveType.none)
                    {
                        for (int i = 1; i < 4; i++)
                        {
                            var LeaveBalance = contextDb.LeaveBalances.Find(User.Identity.Name, (_leaveType)i);
                            if (LeaveBalance == null)
                            {
                                LeaveBalance                      = new LeaveBalance();
                                LeaveBalance.LeaveType            = (_leaveType)i;
                                LeaveBalance.UserID               = User.Identity.Name;
                                LeaveBalance.AvailableLeaveHours -= takenLeaves[i - 1];
                                contextDb.LeaveBalances.Add(LeaveBalance);
                            }
                            else
                            {
                                LeaveBalance.AvailableLeaveHours   -= takenLeaves[i - 1];
                                contextDb.Entry(LeaveBalance).State = EntityState.Modified;
                            }
                            contextDb.SaveChanges();
                        }
                    }

                    // Send an email to manager
                    var applicationModel = (from a in contextDb.LeaveApplications
                                            where DbFunctions.TruncateTime(a.StartTime) == applicationVM.LeaveApplication.StartTime.Date &&
                                            DbFunctions.TruncateTime(a.EndTime) == applicationVM.LeaveApplication.EndTime.Date &&
                                            a.UserID == applicationVM.LeaveApplication.UserID
                                            select a).FirstOrDefault();

                    if (applicationModel != null)
                    {
                        Task.Run(() => EmailSetting.SendEmail(applicationModel.ManagerID, string.Empty, "LeaveApplication", applicationModel.id.ToString()));
                    }
                }
            }
            catch (RetryLimitExceededException /* dex */)
            {
                //Log the error (uncomment dex variable name and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                Debug.WriteLine(e.StackTrace);
            }
            return(RedirectToAction("Index"));
        }
示例#2
0
        public async Task <ActionResult> Leave(LeaveApplicationViewModel applicationVM)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    // Initialise variables
                    double[] appliedLeaveTimes = new double[3];
                    string   originalBalances  = String.Empty;

                    // Record Submitted Time
                    applicationVM.LeaveApplication.SubmittedTime = DateTime.Now;

                    // Calculate applied leave times and group by leavetype
                    foreach (var l in applicationVM.TimeRecords)
                    {
                        // Compassionate pay will take Sick leave balance
                        if (l.LeaveType == _leaveType.compassionatePay)
                        {
                            appliedLeaveTimes[(int)_leaveType.sick] += l.LeaveTime;
                        }
                        // Subtract balance for Sick Leave, Flexi Leave, and Annual Leave
                        else if ((int)l.LeaveType < 3)
                        {
                            appliedLeaveTimes[(int)l.LeaveType] += l.LeaveTime;
                        }
                        // Flexi hours will increase Flexi leave balance
                        else if (l.LeaveType == _leaveType.flexiHours)
                        {
                            appliedLeaveTimes[(int)_leaveType.flexi] -= l.LeaveTime;
                        }
                    }

                    // Update TimeRecords in Db
                    foreach (var r in applicationVM.TimeRecords)
                    {
                        // Configure attendance of a TimeRecord
                        if (r.LeaveType == _leaveType.flexiHours ||
                            r.LeaveType == _leaveType.additionalHours)
                        {
                            if (r.LeaveTime < 14.5)
                            {
                                r.SetAttendence(9, 9.5 + r.LeaveTime, 0.5);
                            }
                            else
                            {
                                r.SetAttendence(12 - r.LeaveTime / 2.0, 12 + r.LeaveTime / 2.0, 0);
                            }
                        }
                        else
                        {
                            if (r.LeaveTime <= 7.6)
                            {
                                r.SetAttendence(9, 17 - r.LeaveTime, 0.5);
                            }
                        }

                        // Sum up total leave time
                        applicationVM.LeaveApplication.TotalLeaveTime += r.LeaveTime;

                        // Try to fetch TimeRecord from Db if it exists
                        var timeRecord = (from a in contextDb.TimeRecords
                                          where DbFunctions.TruncateTime(a.RecordDate) == r.RecordDate.Date &&
                                          a.UserID == r.UserID
                                          select a).FirstOrDefault();

                        // Update TimeRecord if exists, add if not
                        if (timeRecord == null)
                        {
                            contextDb.TimeRecords.Add(r);
                        }
                        else
                        {
                            // Record the difference of applied leave time and the balance in Db
                            if (timeRecord.LeaveType != null)
                            {
                                // Compassionate pay will take Sick leaves balance
                                if (timeRecord.LeaveType == _leaveType.compassionatePay)
                                {
                                    appliedLeaveTimes[(int)_leaveType.sick] -= timeRecord.LeaveTime;
                                }
                                // Flexi hours will increase Flexi leave balance
                                else if (timeRecord.LeaveType == _leaveType.flexiHours)
                                {
                                    appliedLeaveTimes[(int)_leaveType.flexi] += timeRecord.LeaveTime;
                                }
                                // Subtract balance for Sick Leave, Flexi Leave, and Annual Leave
                                else if ((int)timeRecord.LeaveType < 3)
                                {
                                    appliedLeaveTimes[(int)timeRecord.LeaveType] -= timeRecord.LeaveTime;
                                }
                            }

                            timeRecord.LeaveTime = r.LeaveTime;
                            timeRecord.LeaveType = r.LeaveType;
                            contextDb.Entry(timeRecord).State = EntityState.Modified;
                        }
                    }

                    // Transfer attachments to ViewModel
                    if (applicationVM.Attachments.Count != 0)
                    {
                        List <LeaveAttachment> files = new List <LeaveAttachment>();
                        foreach (var file in applicationVM.Attachments)
                        {
                            if (file != null && file.ContentLength > 0)
                            {
                                var attachment = new LeaveAttachment
                                {
                                    FileName    = System.IO.Path.GetFileName(file.FileName),
                                    ContentType = file.ContentType
                                };
                                using (var reader = new System.IO.BinaryReader(file.InputStream))
                                {
                                    attachment.Content = reader.ReadBytes(file.ContentLength);
                                }
                                files.Add(attachment);
                            }
                        }
                        applicationVM.LeaveApplication.Attachments = files;
                    }

                    // Update user leaves balance in Db after submitting
                    for (int i = 0; i < 3; i++)
                    {
                        var LeaveBalance = contextDb.LeaveBalances.Find(User.Identity.Name, (_leaveType)i);
                        if (LeaveBalance == null)
                        {
                            originalBalances += "0.00";
                            LeaveBalance      = new LeaveBalance()
                            {
                                LeaveType           = (_leaveType)i,
                                UserID              = User.Identity.Name,
                                AvailableLeaveHours = 0
                            };
                            contextDb.LeaveBalances.Add(LeaveBalance);
                        }
                        else
                        {
                            originalBalances += string.Format("{0:0.00}", LeaveBalance.AvailableLeaveHours);
                            LeaveBalance.AvailableLeaveHours   -= appliedLeaveTimes[i];
                            contextDb.Entry(LeaveBalance).State = EntityState.Modified;
                        }
                        if (i != 2)
                        {
                            originalBalances += "/";
                        }
                        //contextDb.SaveChanges();
                    }

                    // Try to fetch Leaveapplication from DB if it exists
                    applicationVM.LeaveApplication.UserID = User.Identity.Name;
                    var application = (from a in contextDb.LeaveApplications
                                       where DbFunctions.TruncateTime(a.StartTime) == applicationVM.LeaveApplication.StartTime.Date &&
                                       DbFunctions.TruncateTime(a.EndTime) == applicationVM.LeaveApplication.EndTime.Date &&
                                       a.UserID == applicationVM.LeaveApplication.UserID
                                       select a).FirstOrDefault();

                    // Update LeaveApplication if exists, add if not
                    if (application == null)
                    {
                        applicationVM.LeaveApplication.status           = _status.submited;
                        applicationVM.LeaveApplication.UserName         = contextDb.ADUsers.Find(User.Identity.Name).UserName;
                        applicationVM.LeaveApplication.OriginalBalances = originalBalances;
                        contextDb.LeaveApplications.Add(applicationVM.LeaveApplication);
                    }
                    else
                    {
                        application.status                 = _status.modified;
                        application.leaveType              = applicationVM.LeaveApplication.leaveType;
                        application.ManagerIDs             = applicationVM.LeaveApplication.ManagerIDs;
                        application.Comment                = applicationVM.LeaveApplication.Comment;
                        application.ApprovedBy             = null;
                        application.ApprovedTime           = null;
                        application.TotalLeaveTime         = applicationVM.LeaveApplication.TotalLeaveTime;
                        contextDb.Entry(application).State = EntityState.Modified;
                    }
                    contextDb.SaveChanges();

                    // Send an email to manager
                    var applicationModel = (from a in contextDb.LeaveApplications
                                            where DbFunctions.TruncateTime(a.StartTime) == applicationVM.LeaveApplication.StartTime.Date &&
                                            DbFunctions.TruncateTime(a.EndTime) == applicationVM.LeaveApplication.EndTime.Date &&
                                            a.UserID == applicationVM.LeaveApplication.UserID
                                            select a).FirstOrDefault();

                    if (applicationModel != null)
                    {
                        foreach (var mangerId in applicationModel._managerIDs)
                        {
                            await Task.Run(() => EmailSetting.SendEmail(mangerId, string.Empty, "LeaveApplication", applicationModel.id.ToString()));
                        }
                    }

                    return(RedirectToAction("PostRequest", new { status = postRequestStatus.success }));
                }
                //TempData["ErrorModel"] = ModelState.Values;
                return(RedirectToAction("PostRequest", new { status = postRequestStatus.fail }));
            }
            catch (RetryLimitExceededException /* dex */)
            {
                //Log the error (uncomment dex variable name and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
            }
            catch (Exception e)
            {
                throw e;
            }
            return(RedirectToAction("PostRequest", new { status = postRequestStatus.fail }));
        }