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