using CPRNIMS.Domain.Contracts.PR; using CPRNIMS.Infrastructure.Database; using CPRNIMS.Infrastructure.Dto.PR; using CPRNIMS.Infrastructure.Entities.Common; using CPRNIMS.Infrastructure.Entities.Purchasing; using CPRNIMS.Infrastructure.Entities.SMTP; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using static CPRNIMS.Domain.Services.OutputParamMessage; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json.Linq; using CPRNIMS.Infrastructure.Models.Common; namespace CPRNIMS.Domain.Services.PR { public class PRequest : IPRequest { private readonly NonInventoryDbContext _dbContext; public PRequest(NonInventoryDbContext dbContext) { _dbContext = dbContext; } #region Get public async Task> GetAllPR(PRDto PRDto) { var allItems = await _dbContext.PRLists .FromSqlRaw($"EXEC GetAllPR @UserId,@IsArchived", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@IsArchived", PRDto.IsArchived)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetApproverNameByPRNo(PRDto PRDto) { var result = await _dbContext.Approved .Where(a => a.PRNo == PRDto.PRNo && (a.ApproverId == 1 || a.ApproverId == 2)) .GroupBy(a => a.PRNo) .Select(g => new PRDto { AttestedBy = g.Where(x => x.ApproverId == 1 && x.ApprovedBy != null) .Select(x => x.ApprovedBy) .FirstOrDefault(), ApprovedBy = g.Where(x => x.ApproverId == 2 && x.ApprovedBy != null) .Select(x => x.ApprovedBy) .FirstOrDefault() }) .ToListAsync(); if (result.Any() && (result[0].AttestedBy != null || result[0].ApprovedBy != null)) { return result; } return new List(); } public async Task> GetApproverName(PRDto PRDto) { var result = await _dbContext.Approved .Where(a => a.PRDetailsId == PRDto.PRDetailsId && (a.ApproverId == 1 || a.ApproverId == 2)) .GroupBy(a => a.PRDetailsId) .Select(g => new PRDto { AttestedBy = g.Where(x => x.ApproverId == 1).Select(x => x.ApprovedBy).FirstOrDefault(), ApprovedBy = g.Where(x => x.ApproverId == 2).Select(x => x.ApprovedBy).FirstOrDefault() }) .ToListAsync(); return result ?? new List(); } public async Task> GetPRByRRId(PRDto PRDto) { var allItems = await _dbContext.ForRRs .FromSqlRaw($"EXEC GetPRByRRId @RRId = '{PRDto.RRId}',@UserId = '{PRDto.UserId}'") .ToListAsync(); return allItems ?? new List(); } public async Task> GetForReceiving(PRDto PRDto) { var allItems = await _dbContext.ForReceivings .FromSqlRaw($"EXEC GetForReceiving @UserId,@IsDenied", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@IsDenied", PRDto.IsDenied)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetRRDetailByPO(PRDto PRDto) { var allItems = await _dbContext.ReceivingDetails .FromSqlRaw($"EXEC GetRRDetailByPO @PONo,@POTypeId,@UserId", new SqlParameter("@PONo", PRDto.PONo), new SqlParameter("@POTypeId", PRDto.POTypeId), new SqlParameter("@UserId", PRDto.UserId)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetItemDetailForReceiving(PRDto PRDto) { var allItems = await _dbContext.ForReceivings .FromSqlRaw("EXEC GetItemDetailForReceiving @UserId,@ItemNo", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@ItemNo", PRDto.ItemNo)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetMyPR(PRDto PRDto) { var allItems = await _dbContext.ItemApprovals .FromSqlRaw($"EXEC GetMyPR @UserId,@PRDetailsId", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PRDetailsId", PRDto.PRDetailsId)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetNotifUserKey(PRDto PRDto) { var allItems = await _dbContext.NotifUserKeys .FromSqlRaw($"EXEC GetNotifUserKey @UserId,@Status,@PRDetailsId,@PRNo", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@Status", PRDto.Status), new SqlParameter("@PRDetailsId", PRDto.PRDetailsId), new SqlParameter("@PRNo", PRDto.PRNo)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetPRDetailByPRNo(PRDto PRDto) { var allItems = await _dbContext.PRItemLists .FromSqlRaw($"EXEC GetPRDetailByPRNo @UserId, @PRNo", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PRNo", PRDto.PRNo)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetPRStatusById(PRDto PRDto) { var allItems = await _dbContext.PRTrackings .FromSqlRaw("EXEC GetPRStatusById @UserId,@PRDetailId", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PRDetailId", PRDto.PRDetailsId)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetDashBoard(PRDto PRDto) { var allItems = await _dbContext.Dashboards .FromSqlRaw($"EXEC GetDashBoard @UserId", new SqlParameter("@UserId", PRDto.UserId)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetPRListByPRNo(PRDto PRDto) { var allItems = await _dbContext.PRItemList .FromSqlRaw("EXEC GetPRListByPRNo @PRNo,@UserId", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PRNo", PRDto.PRNo)) .ToListAsync(); return new List(); } public async Task> GetDetailedPRTracking(PRDto PRDto) { var allItems = await _dbContext.DetailedPRTrackings .FromSqlRaw("EXEC GetDetailedPRTracking @UserId", new SqlParameter("@UserId", PRDto.UserId)).ToListAsync(); return allItems ?? new List(); } public async Task> GetSupplierAlternativeOffer(PRDto PRDto) { var rfq = await _dbContext.AlternativeOffers .FromSqlRaw("EXEC GetSupplierAlternativeOffer @UserId", new SqlParameter("@UserId", PRDto.UserId)).ToListAsync(); return rfq ?? new List(); } public async Task> GetSupplierAlterOfferDetails(PRDto PRDto) { var rfq = await _dbContext.AlternativeOfferDetails .FromSqlRaw("EXEC GetAlternativeOfferDetails @UserId,@CanvassDetailId", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@CanvassDetailId", PRDto.CanvassDetailId)).ToListAsync(); return rfq ?? new List(); } #endregion #region Post Put public async Task PostPRApproveReject(PRDto PRDto) { try { await _dbContext.Database .ExecuteSqlRawAsync("EXEC PostPRApproveReject @UserId, @ItemNo, @Status, @PRDetailsId, @Remarks", new SqlParameter("@ItemNo", PRDto.ItemNo != null ? PRDto.ItemNo : 0L), new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@Status", PRDto.Status), new SqlParameter("@PRDetailsId", PRDto.PRDetailsId), new SqlParameter("@Remarks", PRDto.Remarks ?? "N/A")); return new PRDetails(); } catch (SqlException ex) { ex.ToString(); throw; } } public async Task PutItemDetail(PRDto PRDto) { try { await _dbContext.Database .ExecuteSqlRawAsync($"EXEC PutPRItemDetail @UserId, @ItemLocalId, @UOMId, @ItemColorId," + $"@Qty,@ItemCategoryId,@PRDetailsId,@Remarks,@ItemName,@ItemDescription", new SqlParameter("@PRDetailsId", PRDto.PRDetailsId != null ? PRDto.PRDetailsId : 0L), new SqlParameter("@ItemLocalId", PRDto.ItemLocalId), new SqlParameter("@UOMId", PRDto.UOMId), new SqlParameter("@ItemColorId", PRDto.ItemColorId), new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@Qty", PRDto.Qty), new SqlParameter("@ItemCategoryId", PRDto.ItemCategoryId), new SqlParameter("@Remarks", PRDto.Remarks), new SqlParameter("@ItemName", PRDto.ItemName), new SqlParameter("@ItemDescription", PRDto.ItemDescription)); return new PRDetails(); } catch (SqlException ex) { ex.ToString(); throw; } } public async Task PostPutDeniedItem(PRDto PRDto) { try { await _dbContext.Database .ExecuteSqlRawAsync("EXEC PostPutDeniedItem @UserId,@PRDetailsId,@Remarks", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PRDetailsId", PRDto.PRDetailsId), new SqlParameter("@Remarks", PRDto.Remarks ?? "N/A")); return new PRDetails(); } catch (SqlException ex) { ex.ToString(); throw; } } public async Task PostPutReceiving(PRDto PRDto) { try { await _dbContext.Database .ExecuteSqlRawAsync($"EXEC PostPutReceiving @UserId, @PONo, @POTypeId, @EmailAddress, @DRNo, @DocTypeId, @QuantityReceived,@RRNo,@PRDetailsId,@Remarks,@ReceivedDate,@IsCompleted", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PONo", PRDto.PONo), new SqlParameter("@POTypeId", PRDto.POTypeId), new SqlParameter("@EmailAddress", PRDto.EmailAddress), new SqlParameter("@DRNo", PRDto.DRNo), new SqlParameter("@DocTypeId", PRDto.DocTypeId), new SqlParameter("@QuantityReceived", PRDto.QuantityReceived), new SqlParameter("@RRNo", PRDto.RRNo), new SqlParameter("@PRDetailsId", PRDto.PRDetailsId), new SqlParameter("@Remarks", PRDto.Remarks ?? "N/A"), new SqlParameter("@ReceivedDate", PRDto.ReceivedDate), new SqlParameter("@IsCompleted", PRDto.IsCompleted)); return new PRDetails(); } catch (SqlException ex) { ex.ToString(); throw; } } public async Task PutPOClose(PRDto PRDto) { await _dbContext.Database .ExecuteSqlRawAsync("EXEC PutPOClose @UserId, @PONo, @POTypeId, @EmailAddress,@PRDetailsId,@DocTypeId,@PRNo,@Remarks", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PONo", PRDto.PONo), new SqlParameter("@POTypeId", PRDto.POTypeId), new SqlParameter("@EmailAddress", PRDto.EmailAddress), new SqlParameter("@DocTypeId", PRDto.DocTypeId), new SqlParameter("@PRDetailsId", PRDto.PRDetailsId), new SqlParameter("@PRNo", PRDto.PRNo), new SqlParameter("@Remarks", PRDto.Remarks ?? "N/A")); return new PRDetails(); } public async Task PutSupplierAlterOffer(PRDto pRDto) { await _dbContext.Database .ExecuteSqlRawAsync("EXEC PutSupplierAlterOffer @UserId,@AlternativeOfferId,@CanvassDetailId", new SqlParameter("@UserId", pRDto.UserId), new SqlParameter("@AlternativeOfferId", pRDto.AlternativeOfferId), new SqlParameter("@CanvassDetailId", pRDto.CanvassDetailId)); return new AlternativeOfferDetails(); } public async Task> GetNotificationById(PRDto PRDto) { var allItems = await _dbContext.NotificationByIds .FromSqlRaw("EXEC GetNotificationById @UserId,@PRDetailsId,@AppsModuleId", new SqlParameter("@UserId", PRDto.UserId), new SqlParameter("@PRDetailsId", PRDto.PRDetailsId), new SqlParameter("@AppsModuleId", PRDto.AppsModuleId)) .ToListAsync(); return allItems ?? new List(); } public async Task> GetProjectCodes(PRDto pRDto) { return await _dbContext.ProjectCodes.ToListAsync(); } public async Task PRItemRemoval(PRDto prDto) { var (messCode, message) = CreateOutputParams(); await _dbContext.Database.ExecuteSqlRawAsync( "EXEC PRItemRemoval @UserId,@PRDetailsId,@Remarks,@MessCode OUTPUT,@Message OUTPUT", new SqlParameter("@UserId", prDto.UserId), new SqlParameter("@PRDetailsId", prDto.PRDetailsId), new SqlParameter("@Remarks", prDto.Remarks ?? (object)DBNull.Value), messCode, message ); var response = new MessageResponse { Message = message.Value?.ToString(), MessageCode = Convert.ToByte(messCode.Value) }; return response; } public async Task PostPutProjectCode(PRDto prDto) { if (prDto == null) throw new ArgumentNullException(nameof(prDto)); var existing = await _dbContext.ProjectCodes .FirstOrDefaultAsync(p => p.ProjectCodeId == prDto.ProjectCodeId); if (existing == null) { var project = new ProjectCodes { ProjectCode = prDto.ProjectCode, ProjectName = prDto.ProjectName, DeliveryAddress = prDto.DeliveryAddress, MaxDays = prDto.MaxDays, IsActive = prDto.IsActive }; await _dbContext.ProjectCodes.AddAsync(project); } else { if (await IsUsingAsync(prDto.ProjectCodeId)) { return new ResponseObject() { message = "Cannot update this project code because it is already being used in a Purchase Order (PO).", messCode = 0, success = false, }; } else { existing.ProjectCode = prDto.ProjectCode; existing.ProjectName = prDto.ProjectName; existing.DeliveryAddress = prDto.DeliveryAddress; existing.MaxDays = prDto.MaxDays; existing.IsActive = prDto.IsActive; } } await _dbContext.SaveChangesAsync(); return new ResponseObject() { message = "Project code detail successfully updated", messCode = 1, success = true }; } private async Task IsUsingAsync(int projectCodeId) { try { return await (from pr in _dbContext.PRs join pod in _dbContext.PODetails on pr.PRNo equals pod.PRNo where pr.ProjectCodeId == projectCodeId && !pod.IsRemoved && pr.IsActive select pr).AnyAsync(); } catch (Exception ex) { ex.ToString(); throw; } } #endregion } }