public async Task <ActionResult <PettyCashRequest> > PostPettyCashRequest(PettyCashRequestDTO pettyCashRequestDto) { /*!!========================================= * Check Eligibility for Cash Disbursement * .==========================================*/ Double empCurAvailBal = GetEmpCurrentAvailablePettyCashBalance(pettyCashRequestDto); if (pettyCashRequestDto.PettyClaimAmount <= empCurAvailBal && pettyCashRequestDto.PettyClaimAmount > 0) { await Task.Run(() => ProcessPettyCashRequestClaim(pettyCashRequestDto, empCurAvailBal)); return(Created("PostPettyCashRequest", new RespStatus() { Status = "Success", Message = "Cash Advance Request Created" })); } else { return(Conflict(new RespStatus() { Status = "Failure", Message = "Invalid Cash Request Amount Or Limit Exceeded" })); } }
//NO HTTPACTION HERE. Void method just to add data to database table private async Task ProcessPettyCashRequestClaim(PettyCashRequestDTO pettyCashRequestDto, decimal empCurAvailBal) { if (pettyCashRequestDto.ProjectId == null) { //Goes to Option 1 (Project) await Task.Run(() => ProjectCashRequest(pettyCashRequestDto, empCurAvailBal)); } else { //Goes to Option 2 (Department) await Task.Run(() => DepartmentCashRequest(pettyCashRequestDto, empCurAvailBal)); } }
private Double GetEmpCurrentAvailablePettyCashBalance(PettyCashRequestDTO pettyCashRequest) { var empCurPettyBalance = _context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == pettyCashRequest.EmployeeId).FirstOrDefault(); if (empCurPettyBalance != null) { return(empCurPettyBalance.CurBalance); } AddEmpCurrentPettyCashBalanceForEmployee(pettyCashRequest.EmployeeId); return(0); }
/// <summary> /// This is the option 1 /// </summary> /// <param name="pettyCashRequestDto"></param> /// <param name="empCurAvailBal"></param> private async Task ProjectCashRequest(PettyCashRequestDTO pettyCashRequestDto, decimal empCurAvailBal) { //get costcentID based on project int costCentre = _context.Projects.Find(pettyCashRequestDto.ProjectId).CostCentreId; int projManagerid = _context.ProjectManagements.Find(pettyCashRequestDto.ProjectId).EmployeeId; var approver = _context.Employees.Find(projManagerid); _context.ClaimApprovalStatusTrackers.Add(new ClaimApprovalStatusTracker { EmployeeId = pettyCashRequestDto.EmployeeId, PettyCashRequestId = pettyCashRequestDto.Id, DepartmentId = null, ProjectId = pettyCashRequestDto.ProjectId.Value, RoleId = approver.RoleId, ReqDate = DateTime.Now, FinalApprovedDate = null, ApprovalStatusTypeId = (int)ApprovalStatus.Pending //1-Pending, 2-Approved, 3-Rejected }); await _context.SaveChangesAsync(); //##### 5. Send email to the user //## //## //## SEND EMAIL HERE /// //## //#################################### 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 <ActionResult <PettyCashRequest> > PostPettyCashRequest(PettyCashRequestDTO pettyCashRequestDto) { /*!!========================================= * Check Eligibility for Cash Disbursement * .==========================================*/ decimal empCurAvailBal = getEmpCurrentAvailablePettyCashBalance(pettyCashRequestDto); if (pettyCashRequestDto.PettyClaimAmount <= empCurAvailBal && pettyCashRequestDto.PettyClaimAmount >= 0) { await Task.Run(() => ProcessPettyCashRequestClaim(pettyCashRequestDto, empCurAvailBal)); return(Ok(pettyCashRequestDto)); } else { return(Ok("{ Employee cannot draw more than the Allocated Limit}")); } }
public async Task <IActionResult> PutPettyCashRequest(int id, PettyCashRequestDTO pettyCashRequestDto) { if (id != pettyCashRequestDto.Id) { return(BadRequest()); } var pettyCashRequest = await _context.PettyCashRequests.FindAsync(id); pettyCashRequest.Id = pettyCashRequestDto.Id; pettyCashRequest.Id = pettyCashRequestDto.Id; pettyCashRequest.EmployeeId = pettyCashRequestDto.EmployeeId; pettyCashRequest.PettyClaimAmount = pettyCashRequestDto.PettyClaimAmount; pettyCashRequest.PettyClaimRequestDesc = pettyCashRequestDto.PettyClaimRequestDesc; pettyCashRequest.CashReqDate = pettyCashRequestDto.CashReqDate; pettyCashRequest.ProjectId = pettyCashRequestDto.ProjectId; pettyCashRequest.SubProjectId = pettyCashRequestDto.SubProjectId; pettyCashRequest.WorkTaskId = pettyCashRequestDto.WorkTaskId; _context.PettyCashRequests.Update(pettyCashRequest); //_context.Entry(pettyCashRequest).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!PettyCashRequestExists(id)) { return(NotFound()); } else { throw; } } return(NoContent()); }
public async Task <ActionResult <PettyCashRequestDTO> > GetPettyCashRequest(int id) { PettyCashRequestDTO pettyCashRequestDTO = new PettyCashRequestDTO(); var pettyCashRequest = await _context.PettyCashRequests.FindAsync(id); if (pettyCashRequest == null) { return(NotFound()); } pettyCashRequestDTO.Id = pettyCashRequest.Id; pettyCashRequestDTO.EmployeeId = pettyCashRequest.EmployeeId; pettyCashRequestDTO.PettyClaimAmount = pettyCashRequest.PettyClaimAmount; pettyCashRequestDTO.PettyClaimRequestDesc = pettyCashRequest.PettyClaimRequestDesc; pettyCashRequestDTO.CashReqDate = pettyCashRequest.CashReqDate; pettyCashRequestDTO.ProjectId = pettyCashRequest.ProjectId; pettyCashRequestDTO.SubProjectId = pettyCashRequest.SubProjectId; pettyCashRequestDTO.WorkTaskId = pettyCashRequest.WorkTaskId; return(pettyCashRequestDTO); }
private decimal getEmpCurrentAvailablePettyCashBalance(PettyCashRequestDTO pettyCashRequest) { //If Employee has no previous record of requesting the Cash so add a new record with full balance to amount to "EmpCurrentPettyCashBalance" //<<<----------- decimal empPettyCashAmounteligible = _context.JobRoles.Find(_context.Employees.Find(pettyCashRequest.EmployeeId).RoleId).MaxPettyCashAllowed; //Check if employee cash balance is availabel in the EmpCurrentPettyCashBalance table, if NOT then ADD if (!_context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == pettyCashRequest.EmployeeId).Any()) { _context.EmpCurrentPettyCashBalances.Add(new EmpCurrentPettyCashBalance() { EmployeeId = pettyCashRequest.EmployeeId, CurBalance = empPettyCashAmounteligible }); _context.SaveChangesAsync(); return(empPettyCashAmounteligible); } return(_context.EmpCurrentPettyCashBalances.Find(pettyCashRequest.EmployeeId).CurBalance); }
public async Task <ActionResult <IEnumerable <PettyCashRequestDTO> > > GetPettyCashRequests() { List <PettyCashRequestDTO> ListPettyCashRequestDTO = new List <PettyCashRequestDTO>(); var pettyCashRequests = await _context.PettyCashRequests.ToListAsync(); foreach (PettyCashRequest pettyCashRequest in pettyCashRequests) { PettyCashRequestDTO pettyCashRequestsDTO = new PettyCashRequestDTO(); pettyCashRequestsDTO.Id = pettyCashRequest.Id; pettyCashRequestsDTO.EmployeeId = pettyCashRequest.EmployeeId; pettyCashRequestsDTO.PettyClaimAmount = pettyCashRequest.PettyClaimAmount; pettyCashRequestsDTO.PettyClaimRequestDesc = pettyCashRequest.PettyClaimRequestDesc; pettyCashRequestsDTO.CashReqDate = pettyCashRequest.CashReqDate; pettyCashRequestsDTO.ProjectId = pettyCashRequest.ProjectId; pettyCashRequestsDTO.SubProjectId = pettyCashRequest.SubProjectId; pettyCashRequestsDTO.WorkTaskId = pettyCashRequest.WorkTaskId; ListPettyCashRequestDTO.Add(pettyCashRequestsDTO); } return(ListPettyCashRequestDTO); }
/// <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); } }
/// <summary> /// This is option 2 : DEPARTMENT BASED CASH ADVANCE REQUEST /// </summary> /// <param name="pettyCashRequestDto"></param> /// <param name="empCurAvailBal"></param> private async Task DepartmentCashRequest(PettyCashRequestDTO pettyCashRequestDto, Double empCurAvailBal) { //### 1. If Employee Eligible for Cash Claim enter a record and reduce the available amount for next claim #region int reqEmpid = pettyCashRequestDto.EmployeeId; Employee reqEmp = _context.Employees.Find(reqEmpid); int reqApprGroupId = reqEmp.ApprovalGroupId; int reqRoleId = reqEmp.RoleId; int maxApprLevel = _context.ApprovalRoleMaps.Include("ApprovalLevel").Where(a => a.ApprovalGroupId == reqApprGroupId).ToList().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; Double empReqAmount = pettyCashRequestDto.PettyClaimAmount; var curPettyCashBal = _context.EmpCurrentPettyCashBalances.Where(x => x.EmployeeId == reqEmpid).FirstOrDefault(); if (_context.JobRoles.Find(_context.Employees.Find(pettyCashRequestDto.EmployeeId).RoleId).MaxPettyCashAllowed >= empCurAvailBal - empReqAmount) { curPettyCashBal.CurBalance = empCurAvailBal - empReqAmount; } curPettyCashBal.EmployeeId = reqEmpid; 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 = reqEmpid, PettyClaimAmount = empReqAmount, CashReqDate = DateTime.Now, PettyClaimRequestDesc = pettyCashRequestDto.PettyClaimRequestDesc, ProjectId = pettyCashRequestDto.ProjectId, SubProjectId = pettyCashRequestDto.SubProjectId, WorkTaskId = pettyCashRequestDto.WorkTaskId, DepartmentId = _context.Employees.Find(reqEmpid).DepartmentId, CurrencyTypeId = pettyCashRequestDto.CurrencyTypeId, ApprovalStatusTypeId = (int)EApprovalStatus.Pending, Comments = "Cash Advance Request in Process!" }; _context.PettyCashRequests.Add(pcrq); await _context.SaveChangesAsync(); //get the saved record Id pettyCashRequestDto.Id = pcrq.Id; #endregion //##### STEP 3. ClaimsApprovalTracker to be updated for all the allowed Approvers ///////////////////////////// Check if self Approved Request ///////////////////////////// //if highest approver is requesting Petty cash request himself if (maxApprLevel == reqApprLevel) { isSelfApprovedRequest = true; } ////////////////////////////////////////////////////////////////////////////////////////// var getEmpClaimApproversAllLevels = _context.ApprovalRoleMaps .Include(a => a.ApprovalLevel) .Where(a => a.ApprovalGroupId == reqApprGroupId) .OrderBy(o => o.ApprovalLevel.Level).ToList(); bool isFirstApprover = true; if (isSelfApprovedRequest) { ClaimApprovalStatusTracker claimAppStatusTrack = new() { EmployeeId = pettyCashRequestDto.EmployeeId, PettyCashRequestId = pettyCashRequestDto.Id, DepartmentId = _context.Employees.Find(pettyCashRequestDto.EmployeeId).DepartmentId, ProjectId = null, SubProjectId = null, WorkTaskId = null, RoleId = _context.Employees.Find(pettyCashRequestDto.EmployeeId).RoleId, ApprovalGroupId = reqApprGroupId, ApprovalLevelId = reqApprLevel, ReqDate = DateTime.Now, FinalApprovedDate = DateTime.Now, ApprovalStatusTypeId = (int)EApprovalStatus.Approved, Comments = "Self Approved Request!" //1-Initiating, 2-Pending, 3-InReview, 4-Approved, 5-Rejected }; _context.ClaimApprovalStatusTrackers.Add(claimAppStatusTrack); pcrq.ApprovalStatusTypeId = (int)EApprovalStatus.Approved; _context.PettyCashRequests.Update(pcrq); 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; } ClaimApprovalStatusTracker claimAppStatusTrack = new() { EmployeeId = pettyCashRequestDto.EmployeeId, PettyCashRequestId = pettyCashRequestDto.Id, DepartmentId = approver.DepartmentId, ProjectId = null, SubProjectId = null, WorkTaskId = null, RoleId = approver.RoleId, ApprovalGroupId = reqApprGroupId, ApprovalLevelId = ApprMap.ApprovalLevelId, ReqDate = DateTime.Now, FinalApprovedDate = null, ApprovalStatusTypeId = isFirstApprover ? (int)EApprovalStatus.Pending : (int)EApprovalStatus.Initiating, Comments = "Awaiting Approver Action" //1-Initiating, 2-Pending, 3-InReview, 4-Approved, 5-Rejected }; _context.ClaimApprovalStatusTrackers.Add(claimAppStatusTrack); await _context.SaveChangesAsync(); if (isFirstApprover) { //##### 4. 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 + "@<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); } //first approver will be added as Pending, other approvers will be with In Approval Queue isFirstApprover = false; } } //##### STEP 5. Adding a SINGLE entry in DisbursementsAndClaimsMaster table for records #region DisbursementsAndClaimsMaster disbursementsAndClaimsMaster = new(); disbursementsAndClaimsMaster.EmployeeId = reqEmpid; disbursementsAndClaimsMaster.PettyCashRequestId = pcrq.Id; disbursementsAndClaimsMaster.ExpenseReimburseReqId = null; disbursementsAndClaimsMaster.RequestTypeId = (int)ERequestType.CashAdvance; disbursementsAndClaimsMaster.DepartmentId = _context.Employees.Find(reqEmpid).DepartmentId; disbursementsAndClaimsMaster.ProjectId = null; disbursementsAndClaimsMaster.SubProjectId = null; disbursementsAndClaimsMaster.WorkTaskId = null; disbursementsAndClaimsMaster.RecordDate = DateTime.Now; disbursementsAndClaimsMaster.CurrencyTypeId = pettyCashRequestDto.CurrencyTypeId; disbursementsAndClaimsMaster.ClaimAmount = empReqAmount; disbursementsAndClaimsMaster.CostCenterId = _context.Departments.Find(_context.Employees.Find(reqEmpid).DepartmentId).CostCenterId; disbursementsAndClaimsMaster.ApprovalStatusId = isSelfApprovedRequest ? (int)EApprovalStatus.Approved : (int)EApprovalStatus.Pending; _context.DisbursementsAndClaimsMasters.Add(disbursementsAndClaimsMaster); try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { throw; } #endregion }
/// <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> PutPettyCashRequest(int id, PettyCashRequestDTO pettyCashRequestDto) { if (id != pettyCashRequestDto.Id) { return(Conflict(new RespStatus { Status = "Failure", Message = "Id is invalid" })); } var pettyCashRequest = await _context.PettyCashRequests.FindAsync(id); pettyCashRequestDto.EmployeeId = pettyCashRequest.EmployeeId; Double empCurAvailBal = GetEmpCurrentAvailablePettyCashBalance(pettyCashRequestDto); if (!(pettyCashRequestDto.PettyClaimAmount <= empCurAvailBal && pettyCashRequestDto.PettyClaimAmount > 0)) { return(Conflict(new RespStatus() { Status = "Failure", Message = "Invalid Cash Request Amount Or Limit Exceeded" })); } int ApprovedCount = _context.ExpenseReimburseStatusTrackers.Where(e => e.ExpenseReimburseRequestId == pettyCashRequest.Id && e.ApprovalStatusTypeId == (int)EApprovalStatus.Approved).Count(); if (ApprovedCount != 0) { return(Conflict(new RespStatus { Status = "Failure", Message = "PettyCash Requests cant be Edited after Approval!" })); } //if Pettycash request is modified then trigger changes to other tables if (pettyCashRequest.PettyClaimAmount != pettyCashRequestDto.PettyClaimAmount) { //update the EmpPettyCashBalance to credit back the deducted amount EmpCurrentPettyCashBalance empPettyCashBal = _context.EmpCurrentPettyCashBalances.Where(e => e.EmployeeId == pettyCashRequest.EmployeeId).FirstOrDefault(); double oldBal = empPettyCashBal.CurBalance; double prevAmt = pettyCashRequest.PettyClaimAmount; double NewAmt = pettyCashRequestDto.PettyClaimAmount; pettyCashRequest.PettyClaimAmount = pettyCashRequestDto.PettyClaimAmount; pettyCashRequest.PettyClaimRequestDesc = pettyCashRequestDto.PettyClaimRequestDesc; //check employee allowed limit to Cash Advance, if limit exceeded return with an conflict message. double maxAllowed = _context.JobRoles.Find(_context.Employees.Find(pettyCashRequest.EmployeeId).RoleId).MaxPettyCashAllowed; if (maxAllowed >= oldBal + prevAmt - NewAmt && oldBal + prevAmt - NewAmt > 0) { empPettyCashBal.CurBalance = oldBal + prevAmt - NewAmt; empPettyCashBal.UpdatedOn = DateTime.Now; _context.EmpCurrentPettyCashBalances.Update(empPettyCashBal); } else { return(Conflict(new RespStatus() { Status = "Failure", Message = "Invalid Cash Request Amount Or Limit Exceeded" })); } } //// /// pettyCashRequest.PettyClaimAmount = pettyCashRequestDto.PettyClaimAmount; pettyCashRequest.PettyClaimRequestDesc = pettyCashRequestDto.PettyClaimRequestDesc; pettyCashRequest.CashReqDate = DateTime.Now; _context.PettyCashRequests.Update(pettyCashRequest); //Step -2 change the claim approval status tracker records var claims = await _context.ClaimApprovalStatusTrackers.Where(c => c.PettyCashRequestId == pettyCashRequestDto.Id).ToListAsync(); bool IsFirstEmail = true; int? newDeptId = pettyCashRequest.DepartmentId; int? newProjId = pettyCashRequestDto.ProjectId; int? newSubProjId = pettyCashRequestDto.SubProjectId; int? newWorkTaskId = pettyCashRequestDto.WorkTaskId; foreach (ClaimApprovalStatusTracker claim in claims) { claim.DepartmentId = newDeptId; claim.ProjectId = newProjId; claim.SubProjectId = newSubProjId; claim.WorkTaskId = newWorkTaskId; claim.ReqDate = pettyCashRequest.CashReqDate; claim.FinalApprovedDate = null; //claim.ApprovalStatusTypeId = claim.ApprovalLevelId == 1 ? (int)EApprovalStatus.Pending : (int)EApprovalStatus.Initiating; claim.Comments = "Modified Request"; _context.ClaimApprovalStatusTrackers.Update(claim); if (IsFirstEmail) { //#################################### var approver = _context.Employees.Where(e => e.RoleId == claim.RoleId && e.ApprovalGroupId == claim.ApprovalGroupId).FirstOrDefault(); var approverMailAddress = approver.Email; string subject = "(Modified) Pettycash Request Approval " + pettyCashRequestDto.Id.ToString(); Employee emp = await _context.Employees.FindAsync(pettyCashRequest.EmployeeId); var pettycashreq = _context.PettyCashRequests.Find(pettyCashRequestDto.Id); string content = "(Modified) 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); IsFirstEmail = false; } } //_context.Entry(pettyCashRequest).State = EntityState.Modified; //Step-3 change the Disbursements and Claims Master record var disburseMasterRecord = _context.DisbursementsAndClaimsMasters.Where(d => d.PettyCashRequestId == pettyCashRequestDto.Id).FirstOrDefault(); disburseMasterRecord.DepartmentId = newDeptId; disburseMasterRecord.ProjectId = newProjId; disburseMasterRecord.SubProjectId = newSubProjId; disburseMasterRecord.WorkTaskId = newWorkTaskId; disburseMasterRecord.RecordDate = DateTime.Now; disburseMasterRecord.ClaimAmount = pettyCashRequestDto.PettyClaimAmount; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { throw; } return(Ok(new RespStatus { Status = "Success", Message = "Request Updated!" })); }