コード例 #1
0
        /// <summary>
        /// This is option 2
        /// </summary>
        /// <param name="pettyCashRequestDto"></param>
        /// <param name="empCurAvailBal"></param>
        private async Task DepartmentCashRequest(PettyCashRequestDTO pettyCashRequestDto, decimal empCurAvailBal)
        {
            #region
            int     empid          = pettyCashRequestDto.EmployeeId;
            decimal empReqAmount   = pettyCashRequestDto.PettyClaimAmount;
            int     empApprGroupId = _context.Employees.Find(empid).ApprovalGroupId;

            //### 1. Employee Eligible for Cash Claim enter a record and reduce the available amount for next claim

            var curPettyCashBal = _context.EmpCurrentPettyCashBalances.Where(x => x.EmployeeId == empid).FirstOrDefault();
            curPettyCashBal.Id         = curPettyCashBal.Id;
            curPettyCashBal.CurBalance = empCurAvailBal - empReqAmount;
            curPettyCashBal.EmployeeId = empid;
            _context.Update(curPettyCashBal);
            await _context.SaveChangesAsync();

            #endregion


            #region
            //##### 2. Adding entry to PettyCashRequest table for record

            var pcrq = new PettyCashRequest()
            {
                EmployeeId       = empid,
                PettyClaimAmount = empReqAmount,
                CashReqDate      = DateTime.Now,
                ProjectId        = pettyCashRequestDto.ProjectId,
                SubProjectId     = pettyCashRequestDto.SubProjectId,
                WorkTaskId       = pettyCashRequestDto.WorkTaskId
            };
            _context.PettyCashRequests.Add(pcrq);
            await _context.SaveChangesAsync();

            #endregion

            #region
            //##### 3. Adding a entry in DisbursementsAndClaimsMaster table for records


            _context.DisbursementsAndClaimsMasters.Add(new DisbursementsAndClaimsMaster()
            {
                EmployeeId            = empid,
                PettyCashRequestId    = pcrq.Id,
                ExpenseReimburseReqId = null,
                AdvanceOrReimburseId  = (int)ClaimType.CashAdvance,
                ProjectId             = pettyCashRequestDto.ProjectId,
                SubProjectId          = pettyCashRequestDto.SubProjectId,
                WorkTaskId            = pettyCashRequestDto.WorkTaskId,
                RecordDate            = DateTime.Now,
                Amount           = empReqAmount,
                CostCentreId     = _context.Departments.Find(_context.Employees.Find(empid).DepartmentId).CostCentreId,
                ApprovalStatusId = (int)ApprovalStatus.Pending
            });
            await _context.SaveChangesAsync();

            #endregion

            #region

            //##### 4. ClaimsApprovalTracker to be updated for all the allowed Approvers

            var getEmpClaimApproversAllLevels = _context.ApprovalRoleMaps.Where(a => a.ApprovalGroupId == empApprGroupId).ToList().OrderBy(a => a.ApprovalLevel);

            foreach (ApprovalRoleMap ApprMap in getEmpClaimApproversAllLevels)
            {
                int role_id  = ApprMap.RoleId;
                var approver = _context.Employees.Where(e => e.RoleId == role_id).FirstOrDefault();

                _context.ClaimApprovalStatusTrackers.Add(new ClaimApprovalStatusTracker
                {
                    EmployeeId           = pettyCashRequestDto.EmployeeId,
                    PettyCashRequestId   = pettyCashRequestDto.Id,
                    DepartmentId         = approver.DepartmentId,
                    ProjectId            = null,
                    RoleId               = approver.RoleId,
                    ReqDate              = DateTime.Now,
                    FinalApprovedDate    = null,
                    ApprovalStatusTypeId = (int)ApprovalStatus.Pending //1-Pending, 2-Approved, 3-Rejected
                });


                await _context.SaveChangesAsync();

                #endregion
                //##### 5. Send email to the Approver
                //####################################

                var      approverMailAddress = approver.Email;
                string   subject             = "Pettycash Request Approval " + pettyCashRequestDto.Id.ToString();
                Employee emp = await _context.Employees.FindAsync(pettyCashRequestDto.EmployeeId);

                var    pettycashreq = _context.PettyCashRequests.Find(pettyCashRequestDto.Id);
                string content      = "Petty Cash Approval sought by " + emp.FirstName + "/nCash Request for the amount of " + pettycashreq.PettyClaimAmount + "/ntowards " + pettycashreq.PettyClaimRequestDesc;
                var    messagemail  = new Message(new string[] { approverMailAddress }, subject, content);

                await _emailSender.SendEmailAsync(messagemail);
            }
        }
コード例 #2
0
        public async Task <IActionResult> PutExpenseReimburseStatusTracker(List <ExpenseReimburseStatusTrackerDTO> ListExpenseReimburseStatusTrackerDto)
        {
            if (ListExpenseReimburseStatusTrackerDto.Count == 0)
            {
                return(Conflict(new RespStatus {
                    Status = "Failure", Message = "No Request to Approve!"
                }));
            }


            bool isNextApproverAvailable = true;
            bool bRejectMessage          = false;

            foreach (ExpenseReimburseStatusTrackerDTO expenseReimburseStatusTrackerDto in ListExpenseReimburseStatusTrackerDto)
            {
                var expenseReimburseStatusTracker = await _context.ExpenseReimburseStatusTrackers.FindAsync(expenseReimburseStatusTrackerDto.Id);

                //if same status continue to next loop, otherwise process
                if (expenseReimburseStatusTracker.ApprovalStatusTypeId == expenseReimburseStatusTrackerDto.ApprovalStatusTypeId)
                {
                    continue;
                }

                if (expenseReimburseStatusTrackerDto.ApprovalStatusTypeId == (int)EApprovalStatus.Rejected)
                {
                    bRejectMessage = true;
                }
                expenseReimburseStatusTracker.Id         = expenseReimburseStatusTrackerDto.Id;
                expenseReimburseStatusTracker.EmployeeId = expenseReimburseStatusTrackerDto.EmployeeId;
                expenseReimburseStatusTracker.ExpenseReimburseRequestId = expenseReimburseStatusTrackerDto.ExpenseReimburseRequestId;
                expenseReimburseStatusTracker.DepartmentId         = expenseReimburseStatusTrackerDto.DepartmentId;
                expenseReimburseStatusTracker.ProjectId            = expenseReimburseStatusTrackerDto.ProjectId;
                expenseReimburseStatusTracker.JobRoleId            = expenseReimburseStatusTrackerDto.JobRoleId;
                expenseReimburseStatusTracker.ApprovalLevelId      = expenseReimburseStatusTrackerDto.ApprovalLevelId;
                expenseReimburseStatusTracker.ExpReimReqDate       = expenseReimburseStatusTrackerDto.ExpReimReqDate;
                expenseReimburseStatusTracker.ApprovedDate         = expenseReimburseStatusTrackerDto.ApprovedDate;
                expenseReimburseStatusTracker.ApprovalStatusTypeId = expenseReimburseStatusTrackerDto.ApprovalStatusTypeId;
                expenseReimburseStatusTracker.Comments             = bRejectMessage ? expenseReimburseStatusTrackerDto.Comments : "Approved";



                ExpenseReimburseStatusTracker claimitem;
                //Department based Expense Reimburse approval/rejection
                if (expenseReimburseStatusTrackerDto.DepartmentId != null)
                {
                    int empApprGroupId = _context.Employees.Find(expenseReimburseStatusTracker.EmployeeId).ApprovalGroupId;

                    //Check if the record is already approved
                    //if it is not approved then trigger next approver level email & Change the status to approved
                    if (expenseReimburseStatusTrackerDto.ApprovalStatusTypeId == (int)EApprovalStatus.Approved)
                    {
                        //Get the next approval level (get its ID)
                        //int qExpReimRequestId = expenseReimburseStatusTrackerDto.ExpenseReimburseRequestId ?? 0;
                        int qExpReimRequestId = expenseReimburseStatusTrackerDto.ExpenseReimburseRequestId;

                        isNextApproverAvailable = true;

                        int CurClaimApprovalLevel  = _context.ApprovalLevels.Find(expenseReimburseStatusTrackerDto.ApprovalLevelId).Level;
                        int nextClaimApprovalLevel = CurClaimApprovalLevel + 1;
                        int qApprovalLevelId;
                        int apprGroupId = _context.ExpenseReimburseStatusTrackers.Find(expenseReimburseStatusTrackerDto.Id).ApprovalGroupId;

                        if (_context.ApprovalRoleMaps.Where(a => a.ApprovalGroupId == apprGroupId && a.ApprovalLevelId == nextClaimApprovalLevel).FirstOrDefault() != null)
                        {
                            qApprovalLevelId = _context.ApprovalLevels.Where(x => x.Level == nextClaimApprovalLevel).FirstOrDefault().Id;
                        }
                        else
                        {
                            qApprovalLevelId        = _context.ApprovalLevels.Where(x => x.Level == CurClaimApprovalLevel).FirstOrDefault().Id;
                            isNextApproverAvailable = false;
                        }

                        int qApprovalStatusTypeId = isNextApproverAvailable ? (int)EApprovalStatus.Initiating : (int)EApprovalStatus.Pending;

                        //update the next level approver Track request to PENDING (from Initiating)
                        //if claimitem is not null change the status
                        if (isNextApproverAvailable)
                        {
                            claimitem = _context.ExpenseReimburseStatusTrackers.Where(c => c.ExpenseReimburseRequestId == qExpReimRequestId &&
                                                                                      c.ApprovalStatusTypeId == qApprovalStatusTypeId &&
                                                                                      c.ApprovalGroupId == empApprGroupId &&
                                                                                      c.ApprovalLevelId == qApprovalLevelId).FirstOrDefault();

                            if (claimitem != null)
                            {
                                claimitem.ApprovalStatusTypeId = (int)EApprovalStatus.Pending;
                            }
                        }
                        else
                        {
                            //final approver hence update PettyCashRequest
                            claimitem = _context.ExpenseReimburseStatusTrackers.Where(c => c.ExpenseReimburseRequestId == qExpReimRequestId &&
                                                                                      c.ApprovalStatusTypeId == qApprovalStatusTypeId &&
                                                                                      c.ApprovalGroupId == empApprGroupId &&
                                                                                      c.ApprovalLevelId == qApprovalLevelId).FirstOrDefault();
                            //claimitem.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                            claimitem.ApprovedDate = DateTime.Now;


                            //final Approver hence updating ExpenseReimburseRequest table
                            var expenseReimburseRequest = _context.ExpenseReimburseRequests.Find(qExpReimRequestId);
                            expenseReimburseRequest.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                            expenseReimburseRequest.ApprovedDate         = DateTime.Now;
                            expenseReimburseRequest.Comments             = bRejectMessage ? expenseReimburseStatusTrackerDto.Comments : "Approved";
                            _context.Update(expenseReimburseRequest);


                            //DisbursementAndClaimsMaster update the record to Approved (ApprovalStatusId
                            int disbAndClaimItemId = _context.DisbursementsAndClaimsMasters.Where(d => d.ExpenseReimburseReqId == claimitem.ExpenseReimburseRequestId).FirstOrDefault().Id;
                            var disbAndClaimItem   = await _context.DisbursementsAndClaimsMasters.FindAsync(disbAndClaimItemId);

                            /// #############################
                            //   Crediting back to the wallet
                            /// #############################
                            double expenseReimAmt = expenseReimburseRequest.TotalClaimAmount;
                            double RoleLimitAmt   = _context.JobRoles.Find(_context.Employees.Find(expenseReimburseRequest.EmployeeId).RoleId).MaxPettyCashAllowed;
                            EmpCurrentPettyCashBalance empCurrentPettyCashBalance = _context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == expenseReimburseRequest.EmployeeId).FirstOrDefault();
                            double empCurPettyBal = empCurrentPettyCashBalance.CurBalance;

                            //logic goes here

                            if (expenseReimAmt + empCurPettyBal >= RoleLimitAmt) // claiming amount is greater than replishable amount
                            {
                                disbAndClaimItem.AmountToWallet = RoleLimitAmt - empCurPettyBal;
                                disbAndClaimItem.AmountToCredit = expenseReimAmt - (RoleLimitAmt - empCurPettyBal);
                            }
                            else
                            {
                                //fully credit to Wallet - Zero amount to bank amount
                                disbAndClaimItem.AmountToWallet = expenseReimAmt;
                                disbAndClaimItem.AmountToCredit = 0;
                            }


                            disbAndClaimItem.ApprovalStatusId = (int)EApprovalStatus.Approved;
                            _context.Update(disbAndClaimItem);


                            //Final Approveer hence update the EmpCurrentPettyCashBalance table for the employee to reflect the credit
                            empCurrentPettyCashBalance.CurBalance = empCurPettyBal + disbAndClaimItem.AmountToWallet ?? 0;
                            empCurrentPettyCashBalance.UpdatedOn  = DateTime.Now;
                            _context.EmpCurrentPettyCashBalances.Update(empCurrentPettyCashBalance);

                            ///
                        }

                        //Save to database
                        if (claimitem != null)
                        {
                            _context.Update(claimitem);
                        }
                        ;
                        await _context.SaveChangesAsync();

                        int reqApprGroupId = _context.Employees.Find(expenseReimburseStatusTrackerDto.EmployeeId).ApprovalGroupId;
                        var getEmpClaimApproversAllLevels = _context.ApprovalRoleMaps.Include(a => a.ApprovalLevel).Where(a => a.ApprovalGroupId == reqApprGroupId).OrderBy(o => o.ApprovalLevel.Level).ToList();

                        foreach (var ApprMap in getEmpClaimApproversAllLevels)
                        {
                            //only next level (level + 1) approver is considered here
                            if (ApprMap.ApprovalLevelId == expenseReimburseStatusTracker.ApprovalLevelId + 1)
                            {
                                int role_id  = ApprMap.RoleId;
                                var approver = _context.Employees.Where(e => e.RoleId == role_id && e.ApprovalGroupId == reqApprGroupId).FirstOrDefault();

                                //##### 4. Send email to the Approver
                                //####################################



                                var      approverMailAddress = approver.Email;
                                var      expReimReqt         = _context.ExpenseReimburseRequests.Find(expenseReimburseStatusTracker.ExpenseReimburseRequestId);
                                string   subject             = expReimReqt.ExpenseReportTitle + " - #" + expenseReimburseStatusTracker.ExpenseReimburseRequest.Id.ToString();
                                Employee emp         = _context.Employees.Find(expenseReimburseStatusTracker.EmployeeId);
                                string   content     = "Expense Reimbursement request Approval sought by " + emp.FirstName + "<br/>for the amount of " + expReimReqt.TotalClaimAmount + "<br/>towards " + expReimReqt.ExpenseReportTitle;
                                var      messagemail = new Message(new string[] { approverMailAddress }, subject, content);

                                await _emailSender.SendEmailAsync(messagemail);

                                break;
                            }
                        }
                    }

                    //if nothing else then just update the approval status
                    expenseReimburseStatusTracker.ApprovalStatusTypeId = expenseReimburseStatusTrackerDto.ApprovalStatusTypeId;

                    //If no expenseReimburseStatusTrackers are in pending for the Expense request then update the ExpenseReimburse request table

                    int pendingApprovals = _context.ExpenseReimburseStatusTrackers
                                           .Where(t => t.ExpenseReimburseRequestId == expenseReimburseStatusTrackerDto.ExpenseReimburseRequestId &&
                                                  t.ApprovalStatusTypeId == (int)EApprovalStatus.Pending).Count();

                    if (pendingApprovals == 0)
                    {
                        var expReimbReq = _context.ExpenseReimburseRequests.Where(p => p.Id == expenseReimburseStatusTrackerDto.ExpenseReimburseRequestId).FirstOrDefault();
                        expReimbReq.ApprovalStatusTypeId = expenseReimburseStatusTrackerDto.ApprovalStatusTypeId;
                        expReimbReq.ApprovedDate         = DateTime.Now;
                        expReimbReq.Comments             = bRejectMessage ? expenseReimburseStatusTrackerDto.Comments : "Approved";
                        _context.ExpenseReimburseRequests.Update(expReimbReq);
                        await _context.SaveChangesAsync();
                    }



                    //update the Expense Reimburse request table to reflect the rejection
                    if (bRejectMessage)
                    {
                        var expReimbReq = _context.ExpenseReimburseRequests.Where(p => p.Id == expenseReimburseStatusTrackerDto.ExpenseReimburseRequestId).FirstOrDefault();
                        expReimbReq.ApprovalStatusTypeId = expenseReimburseStatusTrackerDto.ApprovalStatusTypeId;
                        expReimbReq.ApprovedDate         = DateTime.Now;
                        expReimbReq.Comments             = expenseReimburseStatusTrackerDto.Comments;
                        _context.ExpenseReimburseRequests.Update(expReimbReq);
                        await _context.SaveChangesAsync();
                    }
                }


                //project based Expense Reimburse approval/rejection
                //only one approver (Project manager)
                else
                {
                    //final approver hence update Expense Reimburse request claim
                    claimitem = _context.ExpenseReimburseStatusTrackers.Where(c => c.ExpenseReimburseRequestId == expenseReimburseStatusTracker.ExpenseReimburseRequestId &&
                                                                              c.ApprovalStatusTypeId == (int)EApprovalStatus.Pending).FirstOrDefault();
                    expenseReimburseStatusTracker.ApprovalStatusTypeId = expenseReimburseStatusTrackerDto.ApprovalStatusTypeId;
                    //DisbursementAndClaimsMaster update the record to Approved (ApprovalStatusId
                    int disbAndClaimItemId = _context.DisbursementsAndClaimsMasters.Where(d => d.ExpenseReimburseReqId == claimitem.ExpenseReimburseRequestId).FirstOrDefault().Id;
                    var disbAndClaimItem   = await _context.DisbursementsAndClaimsMasters.FindAsync(disbAndClaimItemId);

                    /// #############################
                    //   Crediting back to the wallet
                    /// #############################
                    double expenseReimAmt = claimitem.TotalClaimAmount;
                    double RoleLimitAmt   = _context.JobRoles.Find(_context.Employees.Find(claimitem.EmployeeId).RoleId).MaxPettyCashAllowed;
                    EmpCurrentPettyCashBalance empCurrentPettyCashBalance = _context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == claimitem.EmployeeId).FirstOrDefault();
                    double empCurPettyBal = empCurrentPettyCashBalance.CurBalance;

                    //logic goes here

                    if (expenseReimAmt + empCurPettyBal >= RoleLimitAmt) // claiming amount is greater than replishable amount
                    {
                        disbAndClaimItem.AmountToWallet = RoleLimitAmt - empCurPettyBal;
                        disbAndClaimItem.AmountToCredit = expenseReimAmt - (RoleLimitAmt - empCurPettyBal);
                    }
                    else
                    {
                        //fully credit to Wallet - Zero amount to bank amount
                        disbAndClaimItem.AmountToWallet = expenseReimAmt;
                        disbAndClaimItem.AmountToCredit = 0;
                    }


                    disbAndClaimItem.ApprovalStatusId = bRejectMessage ? (int)EApprovalStatus.Rejected : (int)EApprovalStatus.Approved;
                    _context.Update(disbAndClaimItem);


                    //Final Approveer hence update the EmpCurrentPettyCashBalance table for the employee to reflect the credit
                    empCurrentPettyCashBalance.CurBalance = empCurPettyBal + disbAndClaimItem.AmountToWallet ?? 0;
                    _context.EmpCurrentPettyCashBalances.Update(empCurrentPettyCashBalance);

                    /////
                    ///


                    //Update ExpenseReimburseRequests table to update the record to Approved as the final approver has approved it.
                    int expenseReimReqId = _context.ExpenseReimburseRequests.Where(d => d.Id == claimitem.ExpenseReimburseRequestId).FirstOrDefault().Id;
                    var expenseReimReq   = await _context.ExpenseReimburseRequests.FindAsync(expenseReimReqId);

                    expenseReimReq.ApprovalStatusTypeId = bRejectMessage ? (int)EApprovalStatus.Rejected : (int)EApprovalStatus.Approved;
                    expenseReimReq.Comments             = bRejectMessage? expenseReimburseStatusTrackerDto.Comments: "Approved";
                    expenseReimReq.ApprovedDate         = DateTime.Now;
                    _context.Update(expenseReimReq);
                }

                _context.ExpenseReimburseStatusTrackers.Update(expenseReimburseStatusTracker);
            }

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                throw;
            }


            RespStatus respStatus = new();

            if (bRejectMessage)
            {
                respStatus.Status  = "Success";
                respStatus.Message = "Expense-Reimburse Request(s) Rejected!";
            }
            else
            {
                respStatus.Status  = "Success";
                respStatus.Message = "Expense-Reimburse Request(s) Approved!";
            }

            return(Ok(respStatus));
        }
コード例 #3
0
        /// <summary>
        /// This is the option 1 : : PROJECT BASED CASH ADVANCE REQUEST
        /// </summary>
        /// <param name="pettyCashRequestDto"></param>
        /// <param name="empCurAvailBal"></param>
        private async Task <IActionResult> ProjectCashRequest(PettyCashRequestDTO pettyCashRequestDto, Double empCurAvailBal)
        {
            //### 1. If Employee Eligible for Cash Claim enter a record and reduce the available amount for next claim
            #region
            int costCenter = _context.Projects.Find(pettyCashRequestDto.ProjectId).CostCenterId;

            int projManagerid = _context.Projects.Find(pettyCashRequestDto.ProjectId).ProjectManagerId;

            var approver = _context.Employees.Find(projManagerid);
            ////
            int    empid        = pettyCashRequestDto.EmployeeId;
            Double empReqAmount = pettyCashRequestDto.PettyClaimAmount;
            //int empApprGroupId = _context.Employees.Find(empid).ApprovalGroupId;
            double maxCashAllowedForRole = (_context.JobRoles.Find(_context.Employees.Find(pettyCashRequestDto.EmployeeId).RoleId).MaxPettyCashAllowed);

            if (pettyCashRequestDto.PettyClaimAmount > maxCashAllowedForRole)
            {
                return(Conflict(new RespStatus {
                    Status = "Failure", Message = "Advance Amount is not eligibile"
                }));
            }

            var curPettyCashBal = _context.EmpCurrentPettyCashBalances.Where(x => x.EmployeeId == empid).FirstOrDefault();
            curPettyCashBal.Id         = curPettyCashBal.Id;
            curPettyCashBal.CurBalance = empCurAvailBal - empReqAmount <= maxCashAllowedForRole ? empCurAvailBal - empReqAmount : maxCashAllowedForRole;
            curPettyCashBal.EmployeeId = empid;
            curPettyCashBal.UpdatedOn  = DateTime.Now;
            _context.Update(curPettyCashBal);
            await _context.SaveChangesAsync();

            #endregion

            //##### 2. Adding entry to PettyCashRequest table for record
            #region
            var pcrq = new PettyCashRequest()
            {
                EmployeeId            = empid,
                PettyClaimAmount      = empReqAmount,
                CashReqDate           = DateTime.Now,
                DepartmentId          = null,
                ProjectId             = pettyCashRequestDto.ProjectId,
                SubProjectId          = pettyCashRequestDto.SubProjectId,
                WorkTaskId            = pettyCashRequestDto.WorkTaskId,
                PettyClaimRequestDesc = pettyCashRequestDto.PettyClaimRequestDesc,
                CurrencyTypeId        = pettyCashRequestDto.CurrencyTypeId,
                ApprovalStatusTypeId  = (int)EApprovalStatus.Pending,
                Comments = "Cash Advance Request in Process!"
            };
            _context.PettyCashRequests.Add(pcrq);
            await _context.SaveChangesAsync();

            pettyCashRequestDto.Id = pcrq.Id;
            #endregion

            //##### 3. Add an entry to ClaimApproval Status tracker
            //get costcenterID based on project
            #region

            ///////////////////////////// Check if self Approved Request /////////////////////////////
            int  maxApprLevel          = _context.ApprovalRoleMaps.Max(a => a.ApprovalLevelId);
            int  empApprLevel          = _context.ApprovalRoleMaps.Where(a => a.RoleId == _context.Employees.Find(empid).RoleId).FirstOrDefault().Id;
            bool isSelfApprovedRequest = false;
            //if highest approver is requesting Petty cash request himself
            if (maxApprLevel == empApprLevel || projManagerid == empid)
            {
                isSelfApprovedRequest = true;
            }
            //////////////////////////////////////////////////////////////////////////////////////////
            if (isSelfApprovedRequest)
            {
                ClaimApprovalStatusTracker claimAppStatusTrack = new()
                {
                    EmployeeId         = pettyCashRequestDto.EmployeeId,
                    PettyCashRequestId = pettyCashRequestDto.Id,
                    DepartmentId       = null,
                    ProjManagerId      = projManagerid,
                    ProjectId          = pettyCashRequestDto.ProjectId,
                    SubProjectId       = pettyCashRequestDto.SubProjectId,
                    WorkTaskId         = pettyCashRequestDto.WorkTaskId,
                    RoleId             = approver.RoleId,
                    // get the next ProjectManager approval.
                    ApprovalGroupId      = _context.Employees.Find(pettyCashRequestDto.EmployeeId).ApprovalGroupId,
                    ApprovalLevelId      = 2, //empApprLevel or 2 default approval level is 2 for Project based request
                    ReqDate              = DateTime.Now,
                    FinalApprovedDate    = DateTime.Now,
                    ApprovalStatusTypeId = (int)EApprovalStatus.Approved, //1-Initiating, 2-Pending, 3-InReview, 4-Approved, 5-Rejected
                    Comments             = "Self Approved Request!"
                };


                _context.ClaimApprovalStatusTrackers.Add(claimAppStatusTrack);
                pcrq.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                _context.PettyCashRequests.Update(pcrq);
                await _context.SaveChangesAsync();
            }
            else
            {
                ClaimApprovalStatusTracker claimAppStatusTrack = new()
                {
                    EmployeeId         = pettyCashRequestDto.EmployeeId,
                    PettyCashRequestId = pettyCashRequestDto.Id,
                    DepartmentId       = null,
                    ProjManagerId      = projManagerid,
                    ProjectId          = pettyCashRequestDto.ProjectId,
                    SubProjectId       = pettyCashRequestDto.SubProjectId,
                    WorkTaskId         = pettyCashRequestDto.WorkTaskId,
                    RoleId             = approver.RoleId,
                    // get the next ProjectManager approval.
                    ApprovalGroupId      = _context.Employees.Find(pettyCashRequestDto.EmployeeId).ApprovalGroupId,
                    ApprovalLevelId      = 2, // default approval level is 2 for Project based request
                    ReqDate              = DateTime.Now,
                    FinalApprovedDate    = null,
                    ApprovalStatusTypeId = (int)EApprovalStatus.Pending, //1-Initiating, 2-Pending, 3-InReview, 4-Approved, 5-Rejected
                    Comments             = "Awaiting Approver Action"
                };


                _context.ClaimApprovalStatusTrackers.Add(claimAppStatusTrack);
                await _context.SaveChangesAsync();

                #endregion


                //##### 4. Send email to the user
                //####################################
                #region
                var      approverMailAddress = approver.Email;
                string   subject             = "Pettycash Request Approval " + pettyCashRequestDto.Id.ToString();
                Employee emp = await _context.Employees.FindAsync(pettyCashRequestDto.EmployeeId);

                var    pettycashreq = _context.PettyCashRequests.Find(pettyCashRequestDto.Id);
                string content      = "Petty Cash Approval sought by " + emp.FirstName + "/nCash Request for the amount of " + pettycashreq.PettyClaimAmount + "/ntowards " + pettycashreq.PettyClaimRequestDesc;
                var    messagemail  = new Message(new string[] { approverMailAddress }, subject, content);

                await _emailSender.SendEmailAsync(messagemail);

                #endregion
            }



            //##### 5. Adding a entry in DisbursementsAndClaimsMaster table for records
            #region

            DisbursementsAndClaimsMaster disbursementsAndClaimsMaster = new();

            disbursementsAndClaimsMaster.EmployeeId            = pettyCashRequestDto.EmployeeId;
            disbursementsAndClaimsMaster.PettyCashRequestId    = pettyCashRequestDto.Id;
            disbursementsAndClaimsMaster.ExpenseReimburseReqId = null;
            disbursementsAndClaimsMaster.RequestTypeId         = (int)ERequestType.CashAdvance;
            disbursementsAndClaimsMaster.DepartmentId          = null;
            disbursementsAndClaimsMaster.ProjectId             = pettyCashRequestDto.ProjectId;
            disbursementsAndClaimsMaster.SubProjectId          = pettyCashRequestDto.SubProjectId;
            disbursementsAndClaimsMaster.WorkTaskId            = pettyCashRequestDto.WorkTaskId;
            disbursementsAndClaimsMaster.RecordDate            = DateTime.Now;
            disbursementsAndClaimsMaster.CurrencyTypeId        = pettyCashRequestDto.CurrencyTypeId;
            disbursementsAndClaimsMaster.ClaimAmount           = pettyCashRequestDto.PettyClaimAmount;
            disbursementsAndClaimsMaster.AmountToWallet        = 0;
            disbursementsAndClaimsMaster.AmountToCredit        = 0;
            disbursementsAndClaimsMaster.CostCenterId          = _context.Projects.Find(pettyCashRequestDto.ProjectId).CostCenterId;
            disbursementsAndClaimsMaster.ApprovalStatusId      = (int)EApprovalStatus.Pending; //1-Initiating, 2-Pending, 3-InReview, 4-Approved, 5-Rejected

            _context.DisbursementsAndClaimsMasters.Add(disbursementsAndClaimsMaster);
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                string error = ex.Message;
            }
            #endregion

            return(Ok(new RespStatus {
                Status = "Success", Message = "Advance Request Created!"
            }));
        }
コード例 #4
0
        public async Task <IActionResult> PutTravelApprovalStatusTracker(List <TravelApprovalStatusTrackerDTO> ListTravelApprovalStatusTrackerDTO)
        {
            if (ListTravelApprovalStatusTrackerDTO.Count == 0)
            {
                return(Conflict(new RespStatus {
                    Status = "Failure", Message = "No Request to Approve!"
                }));
            }

            bool isNextApproverAvailable = true;
            bool bRejectMessage          = false;

            foreach (TravelApprovalStatusTrackerDTO travelApprovalStatusTrackerDTO in ListTravelApprovalStatusTrackerDTO)
            {
                var travelApprovalStatusTracker = await _context.TravelApprovalStatusTrackers.FindAsync(travelApprovalStatusTrackerDTO.Id);

                //if same status continue to next loop, otherwise process
                if (travelApprovalStatusTracker.ApprovalStatusTypeId == travelApprovalStatusTrackerDTO.ApprovalStatusTypeId)
                {
                    continue;
                }
                if (travelApprovalStatusTrackerDTO.ApprovalStatusTypeId == (int)EApprovalStatus.Rejected)
                {
                    bRejectMessage = true;
                }
                travelApprovalStatusTracker.Id         = travelApprovalStatusTrackerDTO.Id;
                travelApprovalStatusTracker.EmployeeId = travelApprovalStatusTrackerDTO.EmployeeId;

                travelApprovalStatusTracker.TravelApprovalRequestId = travelApprovalStatusTrackerDTO.TravelApprovalRequestId ?? 0;

                travelApprovalStatusTracker.DepartmentId      = travelApprovalStatusTrackerDTO.DepartmentId;
                travelApprovalStatusTracker.ProjectId         = travelApprovalStatusTrackerDTO.ProjectId;
                travelApprovalStatusTracker.RoleId            = travelApprovalStatusTrackerDTO.RoleId;
                travelApprovalStatusTracker.ApprovalLevelId   = travelApprovalStatusTrackerDTO.ApprovalLevelId;
                travelApprovalStatusTracker.ReqDate           = travelApprovalStatusTrackerDTO.ReqDate;
                travelApprovalStatusTracker.FinalApprovedDate = DateTime.Now;
                travelApprovalStatusTracker.Comments          = bRejectMessage ? travelApprovalStatusTrackerDTO.Comments : "Approved";

                TravelApprovalStatusTracker travelItem;

                //department based request
                if (travelApprovalStatusTrackerDTO.DepartmentId != null)
                {
                    int empApprGroupId = _context.Employees.Find(travelApprovalStatusTrackerDTO.EmployeeId).ApprovalGroupId;

                    //Check if the record is already approved
                    //if it is not approved then trigger next approver level email & Change the status to approved
                    if (travelApprovalStatusTrackerDTO.ApprovalStatusTypeId == (int)EApprovalStatus.Approved)
                    {
                        //Get the next approval level (get its ID)
                        int qTravelApprovalRequestId = travelApprovalStatusTrackerDTO.TravelApprovalRequestId ?? 0;
                        int CurTravelApprovalLevel   = _context.ApprovalLevels.Find(travelApprovalStatusTrackerDTO.ApprovalLevelId).Level;


                        //int MaxApprLevelForApprGroupId =  _context.ApprovalRoleMaps.Where(a => a.ApprovalGroupId == travelApprovalStatusTracker.ApprovalGroupId).Select(s => s.ApprovalLevel).Max(x => x.Level);

                        // if(CurTravelApprovalLevel == MaxApprLevelForApprGroupId)
                        // {
                        //     isNextApproverAvailable = false;
                        // }



                        int nextClaimApprovalLevel = CurTravelApprovalLevel + 1;
                        int qApprovalLevelId;
                        int apprGroupId = _context.TravelApprovalStatusTrackers.Find(travelApprovalStatusTrackerDTO.Id).ApprovalGroupId;

                        if (_context.ApprovalRoleMaps.Where(a => a.ApprovalGroupId == apprGroupId && a.ApprovalLevelId == nextClaimApprovalLevel).FirstOrDefault() != null)
                        {
                            qApprovalLevelId = _context.ApprovalLevels.Where(x => x.Level == nextClaimApprovalLevel).FirstOrDefault().Id;
                        }
                        else
                        {
                            qApprovalLevelId        = _context.ApprovalLevels.Where(x => x.Level == CurTravelApprovalLevel).FirstOrDefault().Id;
                            isNextApproverAvailable = false;
                        }

                        int qApprovalStatusTypeId = isNextApproverAvailable ? (int)EApprovalStatus.Initiating : (int)EApprovalStatus.Pending;

                        //update the next level approver Track request to PENDING (from Initiating)
                        //if claimitem is not null change the status
                        if (isNextApproverAvailable)
                        {
                            travelItem = _context.TravelApprovalStatusTrackers
                                         .Where(c =>
                                                c.TravelApprovalRequestId == qTravelApprovalRequestId &&
                                                c.ApprovalStatusTypeId == qApprovalStatusTypeId &&
                                                c.ApprovalGroupId == empApprGroupId &&
                                                c.ApprovalLevelId == qApprovalLevelId).FirstOrDefault();
                            if (travelItem != null)
                            {
                                travelItem.ApprovalStatusTypeId = (int)EApprovalStatus.Pending;
                            }
                        }
                        else
                        {
                            //final approver hence update TravelApprovalRequest
                            travelItem = _context.TravelApprovalStatusTrackers.Where(c => c.TravelApprovalRequestId == qTravelApprovalRequestId &&
                                                                                     c.ApprovalStatusTypeId == qApprovalStatusTypeId &&
                                                                                     c.ApprovalGroupId == empApprGroupId &&
                                                                                     c.ApprovalLevelId == qApprovalLevelId).FirstOrDefault();
                            //travelItem.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                            travelItem.FinalApprovedDate = DateTime.Now;

                            //final Approver hence updating TravelApprovalRequest
                            var travelApprovalRequest = _context.TravelApprovalRequests.Find(qTravelApprovalRequestId);
                            travelApprovalRequest.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                            travelApprovalRequest.Comments             = bRejectMessage ? travelApprovalStatusTrackerDTO.Comments : "Approved";
                            travelApprovalRequest.ApprovedDate         = DateTime.Now;
                            _context.Update(travelApprovalRequest);
                        }

                        if (travelItem != null)
                        {
                            _context.Update(travelItem);
                        }
                        ;
                        await _context.SaveChangesAsync();

                        int reqApprGroupId = _context.Employees.Find(travelApprovalStatusTrackerDTO.EmployeeId).ApprovalGroupId;

                        //Save to database
                        var getEmpClaimApproversAllLevels = _context.ApprovalRoleMaps.Include(a => a.ApprovalLevel).Where(a => a.ApprovalGroupId == empApprGroupId).OrderBy(o => o.ApprovalLevel.Level).ToList();

                        foreach (var ApprMap in getEmpClaimApproversAllLevels)
                        {
                            //only next level (level + 1) approver is considered here
                            if (ApprMap.ApprovalLevelId == travelApprovalStatusTracker.ApprovalLevelId + 1)
                            {
                                int role_id  = ApprMap.RoleId;
                                var approver = _context.Employees.Where(e => e.RoleId == role_id && e.ApprovalGroupId == reqApprGroupId).FirstOrDefault();

                                //##### 4. Send email to the Approver
                                //####################################
                                var      approverMailAddress = approver.Email;
                                string   subject             = "Travel Approval Request " + travelApprovalStatusTracker.TravelApprovalRequestId.ToString();
                                Employee emp = await _context.Employees.FindAsync(travelApprovalStatusTracker.EmployeeId);

                                var    travelApprReq = _context.TravelApprovalRequests.Find(travelApprovalStatusTracker.TravelApprovalRequestId);
                                string content       = "Travel Request Approval sought by " + emp.FirstName + "<br/>for the purpose of " + travelApprReq.TravelPurpose;
                                var    messagemail   = new Message(new string[] { approverMailAddress }, subject, content);


                                await _emailSender.SendEmailAsync(messagemail);

                                break;
                            }
                        }
                    }

                    //if nothing else then just update the approval status
                    travelApprovalStatusTracker.ApprovalStatusTypeId = travelApprovalStatusTrackerDTO.ApprovalStatusTypeId;

                    //If no travelApprovalStatusTrackers are in pending for the travel request then update the TravelRequest table

                    int pendingApprovals = _context.TravelApprovalStatusTrackers
                                           .Where(t => t.TravelApprovalRequestId == travelApprovalStatusTrackerDTO.TravelApprovalRequestId &&
                                                  t.ApprovalStatusTypeId == (int)EApprovalStatus.Pending).Count();

                    if (pendingApprovals == 0)
                    {
                        var trvlApprReq = _context.TravelApprovalRequests.Where(p => p.Id == travelApprovalStatusTrackerDTO.TravelApprovalRequestId).FirstOrDefault();
                        trvlApprReq.ApprovalStatusTypeId = travelApprovalStatusTrackerDTO.ApprovalStatusTypeId;
                        trvlApprReq.ApprovedDate         = DateTime.Now;
                        trvlApprReq.Comments             = travelApprovalStatusTrackerDTO.Comments;
                        _context.TravelApprovalRequests.Update(trvlApprReq);
                        await _context.SaveChangesAsync();
                    }

                    //update the Travel request table to reflect the rejection
                    if (bRejectMessage)
                    {
                        var trvlApprReq = _context.TravelApprovalRequests.Where(p => p.Id == travelApprovalStatusTrackerDTO.TravelApprovalRequestId).FirstOrDefault();
                        trvlApprReq.ApprovalStatusTypeId = travelApprovalStatusTrackerDTO.ApprovalStatusTypeId;
                        trvlApprReq.ApprovedDate         = DateTime.Now;
                        trvlApprReq.Comments             = travelApprovalStatusTrackerDTO.Comments;
                        _context.TravelApprovalRequests.Update(trvlApprReq);
                        await _context.SaveChangesAsync();
                    }
                }
                else //if the approver is the final approver
                {
                    //final approver hence update TravelApprovalRequest
                    travelItem = _context.TravelApprovalStatusTrackers.Where(c => c.TravelApprovalRequestId == travelApprovalStatusTracker.TravelApprovalRequestId &&
                                                                             c.ApprovalStatusTypeId == (int)EApprovalStatus.Pending).FirstOrDefault();
                    travelApprovalStatusTracker.ApprovalStatusTypeId = travelApprovalStatusTrackerDTO.ApprovalStatusTypeId;
                    //Update the TravelApprovalRequst table -> update the record to Approved (ApprovalStatusId

                    int travelApprovalrequestId = _context.TravelApprovalRequests.Where(d => d.Id == travelItem.TravelApprovalRequestId).FirstOrDefault().Id;
                    var travelApprovalrequest   = await _context.TravelApprovalRequests.FindAsync(travelApprovalrequestId);

                    travelApprovalrequest.ApprovalStatusTypeId = bRejectMessage ? (int)EApprovalStatus.Rejected : (int)EApprovalStatus.Approved;
                    travelApprovalrequest.ApprovedDate         = DateTime.Now;
                    travelApprovalrequest.Comments             = bRejectMessage ? travelApprovalStatusTrackerDTO.Comments : "Approved";
                    _context.Update(travelApprovalrequest);
                }

                _context.TravelApprovalStatusTrackers.Update(travelApprovalStatusTracker);
            }


            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                throw;
            }

            RespStatus respStatus = new();

            if (bRejectMessage)
            {
                respStatus.Status  = "Success";
                respStatus.Message = "Travel Approval Request(s) Rejected!";
            }
            else
            {
                respStatus.Status  = "Success";
                respStatus.Message = "Travel Approval Request(s) Approved!";
            }

            return(Ok(respStatus));
        }
コード例 #5
0
        public async Task <IActionResult> PutClaimApprovalStatusTracker(List <ClaimApprovalStatusTrackerDTO> ListClaimApprovalStatusTrackerDto)
        {
            if (ListClaimApprovalStatusTrackerDto.Count == 0)
            {
                return(Conflict(new RespStatus {
                    Status = "Failure", Message = "No Request to Approve!"
                }));
            }


            bool isNextApproverAvailable = true;
            bool bRejectMessage          = false;

            foreach (ClaimApprovalStatusTrackerDTO claimApprovalStatusTrackerDto in ListClaimApprovalStatusTrackerDto)
            {
                var claimApprovalStatusTracker = await _context.ClaimApprovalStatusTrackers.FindAsync(claimApprovalStatusTrackerDto.Id);

                //if same status continue to next loop, otherwise process
                if (claimApprovalStatusTracker.ApprovalStatusTypeId == claimApprovalStatusTrackerDto.ApprovalStatusTypeId)
                {
                    continue;
                }

                if (claimApprovalStatusTrackerDto.ApprovalStatusTypeId == (int)EApprovalStatus.Rejected)
                {
                    bRejectMessage = true;
                }
                //claimApprovalStatusTracker.Id = claimApprovalStatusTrackerDto.Id;
                //claimApprovalStatusTracker.EmployeeId = claimApprovalStatusTrackerDto.EmployeeId;
                //claimApprovalStatusTracker.PettyCashRequestId = claimApprovalStatusTrackerDto.PettyCashRequestId;
                //claimApprovalStatusTracker.DepartmentId = claimApprovalStatusTrackerDto.DepartmentId;
                //claimApprovalStatusTracker.ProjectId = claimApprovalStatusTrackerDto.ProjectId;
                //claimApprovalStatusTracker.RoleId = claimApprovalStatusTrackerDto.RoleId;
                //claimApprovalStatusTracker.ApprovalLevelId = claimApprovalStatusTrackerDto.ApprovalLevelId;
                //claimApprovalStatusTracker.ReqDate = claimApprovalStatusTrackerDto.ReqDate;
                claimApprovalStatusTracker.FinalApprovedDate = DateTime.Now;
                claimApprovalStatusTracker.Comments          = bRejectMessage ? claimApprovalStatusTrackerDto.Comments : "Approved";

                ClaimApprovalStatusTracker claimitem;
                //department based petty cash request
                if (claimApprovalStatusTrackerDto.DepartmentId != null)
                {
                    int empApprGroupId = _context.Employees.Find(claimApprovalStatusTracker.EmployeeId).ApprovalGroupId;

                    //Check if the record is already approved
                    //if it is not approved then trigger next approver level email & Change the status to approved
                    if (claimApprovalStatusTrackerDto.ApprovalStatusTypeId == (int)EApprovalStatus.Approved)
                    {
                        //Get the next approval level (get its ID)
                        int qPettyCashRequestId = claimApprovalStatusTrackerDto.PettyCashRequestId ?? 0;

                        isNextApproverAvailable = true;

                        int CurClaimApprovalLevel  = _context.ApprovalLevels.Find(claimApprovalStatusTrackerDto.ApprovalLevelId).Level;
                        int nextClaimApprovalLevel = CurClaimApprovalLevel + 1;
                        int qApprovalLevelId;

                        int apprGroupId = _context.ClaimApprovalStatusTrackers.Find(claimApprovalStatusTrackerDto.Id).ApprovalGroupId;

                        if (_context.ApprovalRoleMaps.Where(a => a.ApprovalGroupId == apprGroupId && a.ApprovalLevelId == nextClaimApprovalLevel).FirstOrDefault() != null)
                        {
                            qApprovalLevelId = _context.ApprovalLevels.Where(x => x.Level == nextClaimApprovalLevel).FirstOrDefault().Id;
                        }
                        else
                        {
                            qApprovalLevelId        = _context.ApprovalLevels.Where(x => x.Level == CurClaimApprovalLevel).FirstOrDefault().Id;
                            isNextApproverAvailable = false;
                        }

                        int qApprovalStatusTypeId = isNextApproverAvailable ? (int)EApprovalStatus.Initiating : (int)EApprovalStatus.Pending;

                        //update the next level approver Track request to PENDING (from Initiating)
                        //if claimitem is not null change the status
                        if (isNextApproverAvailable)
                        {
                            claimitem = _context.ClaimApprovalStatusTrackers.Where(c => c.PettyCashRequestId == qPettyCashRequestId &&
                                                                                   c.ApprovalStatusTypeId == qApprovalStatusTypeId &&
                                                                                   c.ApprovalGroupId == empApprGroupId &&
                                                                                   c.ApprovalLevelId == qApprovalLevelId).FirstOrDefault();

                            if (claimitem != null)
                            {
                                claimitem.ApprovalStatusTypeId = (int)EApprovalStatus.Pending;
                            }
                        }
                        else
                        {
                            //final approver hence update PettyCashRequest
                            claimitem = _context.ClaimApprovalStatusTrackers.Where(c => c.PettyCashRequestId == qPettyCashRequestId &&
                                                                                   c.ApprovalStatusTypeId == qApprovalStatusTypeId &&
                                                                                   c.ApprovalGroupId == empApprGroupId &&
                                                                                   c.ApprovalLevelId == qApprovalLevelId).FirstOrDefault();
                            //claimitem.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                            claimitem.FinalApprovedDate = DateTime.Now;


                            //final Approver hence updating ExpenseReimburseRequest table
                            var pettyCashRequest = _context.PettyCashRequests.Find(qPettyCashRequestId);
                            pettyCashRequest.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                            pettyCashRequest.ApprovedDate         = DateTime.Now;
                            pettyCashRequest.Comments             = bRejectMessage ? claimApprovalStatusTrackerDto.Comments : "Approved";
                            _context.Update(pettyCashRequest);


                            //DisbursementAndClaimsMaster update the record to Approved (ApprovalStatusId
                            int disbAndClaimItemId = _context.DisbursementsAndClaimsMasters.Where(d => d.PettyCashRequestId == claimitem.PettyCashRequestId).FirstOrDefault().Id;
                            var disbAndClaimItem   = await _context.DisbursementsAndClaimsMasters.FindAsync(disbAndClaimItemId);

                            disbAndClaimItem.ApprovalStatusId = (int)EApprovalStatus.Approved;
                            _context.Update(disbAndClaimItem);
                        }

                        //Save to database
                        if (claimitem != null)
                        {
                            _context.Update(claimitem);
                        }
                        ;
                        await _context.SaveChangesAsync();

                        int reqApprGroupId = _context.Employees.Find(claimApprovalStatusTrackerDto.EmployeeId).ApprovalGroupId;
                        var getEmpClaimApproversAllLevels = _context.ApprovalRoleMaps.Include(a => a.ApprovalLevel).Where(a => a.ApprovalGroupId == reqApprGroupId).OrderBy(o => o.ApprovalLevel.Level).ToList();

                        foreach (var ApprMap in getEmpClaimApproversAllLevels)
                        {
                            //only next level (level + 1) approver is considered here
                            if (ApprMap.ApprovalLevelId == claimApprovalStatusTracker.ApprovalLevelId + 1)
                            {
                                int role_id  = ApprMap.RoleId;
                                var approver = _context.Employees.Where(e => e.RoleId == role_id && e.ApprovalGroupId == reqApprGroupId).FirstOrDefault();

                                //##### 4. Send email to the Approver
                                //####################################
                                var      approverMailAddress = approver.Email;
                                string   subject             = "Pettycash Request Approval " + claimApprovalStatusTracker.PettyCashRequestId.ToString();
                                Employee emp = await _context.Employees.FindAsync(claimApprovalStatusTracker.EmployeeId);

                                var    pettycashreq = _context.PettyCashRequests.Find(claimApprovalStatusTracker.PettyCashRequestId);
                                string content      = "Petty Cash Approval sought by " + emp.FirstName + "<br/>Cash Request for the amount of " + pettycashreq.PettyClaimAmount + "<br/>towards " + pettycashreq.PettyClaimRequestDesc;
                                var    messagemail  = new Message(new string[] { approverMailAddress }, subject, content);

                                await _emailSender.SendEmailAsync(messagemail);

                                break;
                            }
                        }
                    }

                    //if nothing else then just update the approval status
                    claimApprovalStatusTracker.ApprovalStatusTypeId = claimApprovalStatusTrackerDto.ApprovalStatusTypeId;


                    int pendingApprovals = _context.ClaimApprovalStatusTrackers
                                           .Where(t => t.PettyCashRequestId == claimApprovalStatusTrackerDto.PettyCashRequestId &&
                                                  t.ApprovalStatusTypeId == (int)EApprovalStatus.Pending).Count();

                    if (pendingApprovals == 0)
                    {
                        var pettyCashReq = _context.PettyCashRequests.Where(p => p.Id == claimApprovalStatusTrackerDto.PettyCashRequestId).FirstOrDefault();
                        pettyCashReq.ApprovalStatusTypeId = claimApprovalStatusTrackerDto.ApprovalStatusTypeId;
                        pettyCashReq.ApprovedDate         = DateTime.Now;
                        pettyCashReq.Comments             = bRejectMessage ? claimApprovalStatusTrackerDto.Comments : "Approved";
                        _context.PettyCashRequests.Update(pettyCashReq);
                        await _context.SaveChangesAsync();
                    }



                    //update the pettycash request table to reflect the rejection
                    if (bRejectMessage)
                    {
                        var pettyCashReq = _context.PettyCashRequests.Where(p => p.Id == claimApprovalStatusTrackerDto.PettyCashRequestId).FirstOrDefault();
                        pettyCashReq.ApprovalStatusTypeId = claimApprovalStatusTrackerDto.ApprovalStatusTypeId;
                        pettyCashReq.ApprovedDate         = DateTime.Now;
                        pettyCashReq.Comments             = bRejectMessage ? claimApprovalStatusTrackerDto.Comments : "Approved";
                        _context.PettyCashRequests.Update(pettyCashReq);

                        //update the EmpPettyCashBalance to credit back the deducted amount
                        var empPettyCashBal = _context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == pettyCashReq.EmployeeId).FirstOrDefault();
                        empPettyCashBal.CurBalance = empPettyCashBal.CurBalance + pettyCashReq.PettyClaimAmount;
                        empPettyCashBal.UpdatedOn  = DateTime.Now;
                        _context.EmpCurrentPettyCashBalances.Update(empPettyCashBal);


                        var disbursementsAndClaimsMaster = _context.DisbursementsAndClaimsMasters.Where(d => d.PettyCashRequestId == pettyCashReq.Id).FirstOrDefault();
                        disbursementsAndClaimsMaster.ApprovalStatusId = (int)EApprovalStatus.Rejected;
                        disbursementsAndClaimsMaster.ClaimAmount      = 0;
                        disbursementsAndClaimsMaster.AmountToWallet   = 0;
                        disbursementsAndClaimsMaster.AmountToCredit   = 0;
                        _context.DisbursementsAndClaimsMasters.Update(disbursementsAndClaimsMaster);
                        await _context.SaveChangesAsync();
                    }
                }

                //Project based petty cash request
                else
                {
                    //final approver hence update PettyCashRequest
                    claimitem = _context.ClaimApprovalStatusTrackers.Where(c => c.PettyCashRequestId == claimApprovalStatusTracker.PettyCashRequestId &&
                                                                           c.ApprovalStatusTypeId == (int)EApprovalStatus.Pending).FirstOrDefault();
                    claimApprovalStatusTracker.ApprovalStatusTypeId = claimApprovalStatusTrackerDto.ApprovalStatusTypeId;
                    //DisbursementAndClaimsMaster update the record to Approved (ApprovalStatusId
                    int disbAndClaimItemId = _context.DisbursementsAndClaimsMasters.Where(d => d.PettyCashRequestId == claimitem.PettyCashRequestId).FirstOrDefault().Id;
                    var disbAndClaimItem   = await _context.DisbursementsAndClaimsMasters.FindAsync(disbAndClaimItemId);

                    disbAndClaimItem.ApprovalStatusId = bRejectMessage ? (int)EApprovalStatus.Rejected : (int)EApprovalStatus.Approved;
                    disbAndClaimItem.ClaimAmount      = 0;
                    disbAndClaimItem.AmountToWallet   = 0;
                    disbAndClaimItem.AmountToCredit   = 0;
                    _context.DisbursementsAndClaimsMasters.Update(disbAndClaimItem);
                    _context.Update(disbAndClaimItem);

                    //Update Pettycashrequest table to update the record to Approved as the final approver has approved it.
                    int pettyCashReqId = _context.PettyCashRequests.Where(d => d.Id == claimitem.PettyCashRequestId).FirstOrDefault().Id;
                    var pettyCashReq   = await _context.PettyCashRequests.FindAsync(pettyCashReqId);

                    //update the EmpPettyCashBalance to credit back the deducted amount
                    if (bRejectMessage)
                    {
                        var empPettyCashBal = _context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == pettyCashReq.EmployeeId).FirstOrDefault();
                        empPettyCashBal.CurBalance = empPettyCashBal.CurBalance + pettyCashReq.PettyClaimAmount;
                        empPettyCashBal.UpdatedOn  = DateTime.Now;
                        _context.EmpCurrentPettyCashBalances.Update(empPettyCashBal);
                    }

                    pettyCashReq.ApprovalStatusTypeId = bRejectMessage ? (int)EApprovalStatus.Rejected : (int)EApprovalStatus.Approved;
                    pettyCashReq.ApprovedDate         = DateTime.Now;
                    pettyCashReq.Comments             = bRejectMessage ? claimApprovalStatusTrackerDto.Comments : "Approved";
                    _context.Update(pettyCashReq);
                }

                _context.ClaimApprovalStatusTrackers.Update(claimApprovalStatusTracker);
            }

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                throw;
            }

            RespStatus respStatus = new();

            if (bRejectMessage)
            {
                respStatus.Status  = "Success";
                respStatus.Message = "Cash Advance(s) Rejected!";
            }
            else
            {
                respStatus.Status  = "Success";
                respStatus.Message = "Cash Advance(s) Approved!";
            }

            return(Ok(respStatus));
        }
コード例 #6
0
        /// <summary>
        /// Department based Expreimburse request
        /// </summary>
        /// <param name="expenseReimburseRequestDto"></param>
        /// <returns></returns>

        private async Task <IActionResult> DepartmentBasedExpReimRequest(ExpenseReimburseRequestDTO expenseReimburseRequestDto)
        {
            #region
            int      reqEmpid       = expenseReimburseRequestDto.EmployeeId;
            Employee reqEmp         = _context.Employees.Find(reqEmpid);
            int      reqApprGroupId = reqEmp.ApprovalGroupId;
            int      reqRoleId      = reqEmp.RoleId;

            var approRolMapsList = _context.ApprovalRoleMaps.Include("ApprovalLevel").Where(a => a.ApprovalGroupId == reqApprGroupId).ToList();
            int maxApprLevel     = approRolMapsList.Select(x => x.ApprovalLevel).Max(a => a.Level);
            int reqApprLevel     = _context.ApprovalRoleMaps.Include("ApprovalLevel").Where(a => a.ApprovalGroupId == reqApprGroupId && a.RoleId == reqRoleId).Select(x => x.ApprovalLevel).FirstOrDefault().Level;


            bool isSelfApprovedRequest = false;
            ////

            ExpenseReimburseRequest expenseReimburseRequest = new();
            double dblTotalClaimAmount = 0;

            expenseReimburseRequest.ExpenseReportTitle   = expenseReimburseRequestDto.ExpenseReportTitle;
            expenseReimburseRequest.EmployeeId           = expenseReimburseRequestDto.EmployeeId;
            expenseReimburseRequest.CurrencyTypeId       = expenseReimburseRequestDto.CurrencyTypeId;
            expenseReimburseRequest.TotalClaimAmount     = dblTotalClaimAmount; //Currently Zero but added as per the request
            expenseReimburseRequest.ExpReimReqDate       = DateTime.Now;
            expenseReimburseRequest.DepartmentId         = _context.Employees.Find(expenseReimburseRequestDto.EmployeeId).DepartmentId;
            expenseReimburseRequest.ProjectId            = null;
            expenseReimburseRequest.SubProjectId         = null;
            expenseReimburseRequest.WorkTaskId           = null;
            expenseReimburseRequest.ApprovalStatusTypeId = (int)EApprovalStatus.Pending;
            //expenseReimburseRequest.ApprovedDate = expenseReimburseRequestDto.ApprovedDate;
            expenseReimburseRequest.Comments = "Expense Reimburse Request in Process!";

            _context.ExpenseReimburseRequests.Add(expenseReimburseRequest); //  <= this generated the Id
            await _context.SaveChangesAsync();

            //
            foreach (ExpenseSubClaimDTO expenseSubClaimDto in expenseReimburseRequestDto.ExpenseSubClaims)
            {
                ExpenseSubClaim expenseSubClaim = new();

                //get expensereimburserequestId from the saved record and then use here for sub-claims
                expenseSubClaim.ExpenseReimburseRequestId = expenseReimburseRequest.Id;
                expenseSubClaim.ExpenseTypeId             = expenseSubClaimDto.ExpenseTypeId;
                expenseSubClaim.ExpenseReimbClaimAmount   = expenseSubClaimDto.ExpenseReimbClaimAmount;
                expenseSubClaim.DocumentIDs = expenseSubClaimDto.DocumentIDs;
                expenseSubClaim.InvoiceNo   = expenseSubClaimDto.InvoiceNo;
                expenseSubClaim.InvoiceDate = expenseSubClaimDto.InvoiceDate;
                expenseSubClaim.Tax         = expenseSubClaimDto.Tax;
                expenseSubClaim.TaxAmount   = expenseSubClaimDto.TaxAmount;
                expenseSubClaim.Vendor      = expenseSubClaimDto.Vendor;
                expenseSubClaim.Location    = expenseSubClaimDto.Location;
                expenseSubClaim.Description = expenseSubClaimDto.Description;

                _context.ExpenseSubClaims.Add(expenseSubClaim);
                await _context.SaveChangesAsync();

                dblTotalClaimAmount = dblTotalClaimAmount + expenseSubClaimDto.TaxAmount + expenseSubClaimDto.ExpenseReimbClaimAmount;
            }

            ExpenseReimburseRequest exp = _context.ExpenseReimburseRequests.Find(expenseReimburseRequest.Id);

            exp.TotalClaimAmount = dblTotalClaimAmount;
            _context.ExpenseReimburseRequests.Update(exp);
            await _context.SaveChangesAsync();



            ///////////////////////////// Check if self Approved Request /////////////////////////////

            //if highest approver is requesting Petty cash request himself
            if (maxApprLevel == reqApprLevel)
            {
                isSelfApprovedRequest = true;
            }
            //////////////////////////////////////////////////////////////////////////////////////////
            //var test = _context.ApprovalRoleMaps.Include(a => a.ApprovalLevel).ToList().OrderBy(o => o.ApprovalLevel.Level);
            int reqApprovGroupId = _context.Employees.Find(reqEmpid).ApprovalGroupId;
            var getEmpClaimApproversAllLevels = _context.ApprovalRoleMaps.Include(a => a.ApprovalLevel).Where(a => a.ApprovalGroupId == reqApprovGroupId).OrderBy(o => o.ApprovalLevel.Level).ToList();

            var  ReqEmpRoleId          = _context.Employees.Where(e => e.Id == reqEmpid).FirstOrDefault().RoleId;
            var  ReqEmpHisOwnApprLevel = _context.ApprovalRoleMaps.Where(a => a.RoleId == ReqEmpRoleId);
            bool isFirstApprover       = true;

            if (isSelfApprovedRequest)
            {
                ExpenseReimburseStatusTracker expenseReimburseStatusTracker = new()
                {
                    EmployeeId = expenseReimburseRequestDto.EmployeeId,
                    ExpenseReimburseRequestId = expenseReimburseRequest.Id,
                    CurrencyTypeId            = expenseReimburseRequestDto.CurrencyTypeId,
                    TotalClaimAmount          = dblTotalClaimAmount,
                    ExpReimReqDate            = DateTime.Now,
                    DepartmentId         = _context.Employees.Find(expenseReimburseRequestDto.EmployeeId).DepartmentId,
                    ProjectId            = null, //Approver Project Id
                    JobRoleId            = _context.Employees.Find(expenseReimburseRequestDto.EmployeeId).RoleId,
                    ApprovalGroupId      = reqApprGroupId,
                    ApprovalLevelId      = reqApprLevel,
                    ApprovedDate         = null,
                    ApprovalStatusTypeId = (int)EApprovalStatus.Approved, //1-Pending, 2-Approved, 3-Rejected
                    Comments             = "Self Approved Request"
                };
                _context.ExpenseReimburseStatusTrackers.Add(expenseReimburseStatusTracker);
                expenseReimburseRequest.ApprovalStatusTypeId = (int)EApprovalStatus.Approved;
                _context.ExpenseReimburseRequests.Update(expenseReimburseRequest);
                await _context.SaveChangesAsync();
            }
            else
            {
                foreach (ApprovalRoleMap ApprMap in getEmpClaimApproversAllLevels)
                {
                    int role_id  = ApprMap.RoleId;
                    var approver = _context.Employees.Where(e => e.RoleId == role_id && e.ApprovalGroupId == reqApprGroupId).FirstOrDefault();
                    if (approver == null)
                    {
                        continue;
                    }
                    int approverLevelid = _context.ApprovalRoleMaps.Where(x => x.RoleId == approver.RoleId && x.ApprovalGroupId == reqApprGroupId).FirstOrDefault().ApprovalLevelId;
                    int approverLevel   = _context.ApprovalLevels.Find(approverLevelid).Level;

                    if (reqApprLevel >= approverLevel)
                    {
                        continue;
                    }


                    ExpenseReimburseStatusTracker expenseReimburseStatusTracker = new()
                    {
                        EmployeeId = expenseReimburseRequestDto.EmployeeId,
                        ExpenseReimburseRequestId = expenseReimburseRequest.Id,
                        CurrencyTypeId            = expenseReimburseRequestDto.CurrencyTypeId,
                        TotalClaimAmount          = dblTotalClaimAmount,
                        ExpReimReqDate            = DateTime.Now,
                        DepartmentId         = _context.Employees.Find(expenseReimburseRequestDto.EmployeeId).DepartmentId,
                        ProjectId            = null, //Approver Project Id
                        JobRoleId            = approver.RoleId,
                        ApprovalGroupId      = reqApprGroupId,
                        ApprovalLevelId      = ApprMap.ApprovalLevelId,
                        ApprovedDate         = null,
                        ApprovalStatusTypeId = isFirstApprover ? (int)EApprovalStatus.Pending : (int)EApprovalStatus.Initiating,
                        Comments             = "Awaiting Approver Action"
                    };
                    _context.ExpenseReimburseStatusTrackers.Add(expenseReimburseStatusTracker);
                    await _context.SaveChangesAsync();

                    //##### 5. Send email to the Approver
                    //####################################

                    if (isFirstApprover)
                    {
                        var      approverMailAddress = approver.Email;
                        string   subject             = expenseReimburseRequest.ExpenseReportTitle + " - #" + expenseReimburseRequest.Id.ToString();
                        Employee emp         = _context.Employees.Find(expenseReimburseRequestDto.EmployeeId);
                        string   content     = "Expense Reimbursement request Approval sought by " + emp.FirstName + "<br/>for the amount of " + expenseReimburseRequest.TotalClaimAmount + "<br/>towards " + expenseReimburseRequest.ExpenseReportTitle;
                        var      messagemail = new Message(new string[] { approverMailAddress }, subject, content);

                        await _emailSender.SendEmailAsync(messagemail);
                    }
                    isFirstApprover = false;

                    //repeat for each approver
                }
            }

            //##### 5. Adding a entry in DisbursementsAndClaimsMaster table for records
            #region

            DisbursementsAndClaimsMaster disbursementsAndClaimsMaster = new();
            disbursementsAndClaimsMaster.EmployeeId              = expenseReimburseRequestDto.EmployeeId;
            disbursementsAndClaimsMaster.ExpenseReimburseReqId   = expenseReimburseRequest.Id;
            disbursementsAndClaimsMaster.RequestTypeId           = (int)ERequestType.ExpenseReim;
            disbursementsAndClaimsMaster.DepartmentId            = _context.Employees.Find(expenseReimburseRequestDto.EmployeeId).DepartmentId;
            disbursementsAndClaimsMaster.ProjectId               = expenseReimburseRequestDto.ProjectId;
            disbursementsAndClaimsMaster.SubProjectId            = expenseReimburseRequestDto.SubProjectId;
            disbursementsAndClaimsMaster.WorkTaskId              = expenseReimburseRequestDto.WorkTaskId;
            disbursementsAndClaimsMaster.RecordDate              = DateTime.Now;
            disbursementsAndClaimsMaster.CurrencyTypeId          = expenseReimburseRequestDto.CurrencyTypeId;
            disbursementsAndClaimsMaster.ClaimAmount             = dblTotalClaimAmount;
            disbursementsAndClaimsMaster.CostCenterId            = _context.Departments.Find(_context.Employees.Find(expenseReimburseRequestDto.EmployeeId).DepartmentId).CostCenterId;
            disbursementsAndClaimsMaster.ApprovalStatusId        = (int)EApprovalStatus.Pending; //1-Initiating; 2-Pending; 3-InReview; 4-Approved; 5-Rejected
            disbursementsAndClaimsMaster.IsSettledAmountCredited = false;
            //save at the end of the code. not here!
            #endregion


            /// #############################
            //   Crediting back to the wallet (for self approvedRequest Only)
            /// #############################
            ///
            if (isSelfApprovedRequest)
            {
                double expenseReimAmt = expenseReimburseRequest.TotalClaimAmount;
                double RoleLimitAmt   = _context.JobRoles.Find(_context.Employees.Find(expenseReimburseRequest.EmployeeId).RoleId).MaxPettyCashAllowed;
                EmpCurrentPettyCashBalance empCurrentPettyCashBalance = _context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == expenseReimburseRequest.EmployeeId).FirstOrDefault();
                double empCurPettyBal = empCurrentPettyCashBalance.CurBalance;

                //logic goes here

                if (expenseReimAmt + empCurPettyBal >= RoleLimitAmt) // claiming amount is greater than replishable amount
                {
                    disbursementsAndClaimsMaster.AmountToWallet = RoleLimitAmt - empCurPettyBal;
                    disbursementsAndClaimsMaster.AmountToCredit = expenseReimAmt - (RoleLimitAmt - empCurPettyBal);
                }
                else
                {
                    //fully credit to Wallet - Zero amount to bank amount
                    disbursementsAndClaimsMaster.AmountToWallet = expenseReimAmt;
                    disbursementsAndClaimsMaster.AmountToCredit = 0;
                }


                disbursementsAndClaimsMaster.ApprovalStatusId = (int)EApprovalStatus.Approved;
                _context.Update(disbursementsAndClaimsMaster);


                //Final Approveer hence update the EmpCurrentPettyCashBalance table for the employee to reflect the credit
                empCurrentPettyCashBalance.CurBalance = empCurPettyBal + disbursementsAndClaimsMaster.AmountToWallet ?? 0;
                empCurrentPettyCashBalance.UpdatedOn  = DateTime.Now;
                _context.EmpCurrentPettyCashBalances.Update(empCurrentPettyCashBalance);

                await _context.DisbursementsAndClaimsMasters.AddAsync(disbursementsAndClaimsMaster);

                await _context.SaveChangesAsync();

                return(Ok(new RespStatus {
                    Status = "Success", Message = "Self approved Expense Claim Submitted Successfully!"
                }));
            }
            ///

            await _context.DisbursementsAndClaimsMasters.AddAsync(disbursementsAndClaimsMaster);

            await _context.SaveChangesAsync();

            return(Ok(new RespStatus {
                Status = "Success", Message = "Expense Claim Submitted Successfully!"
            }));
        }