using AutoMapper; using CPRNIMS.Domain.Contracts.Canvass; using CPRNIMS.Domain.Services; using CPRNIMS.Domain.Services.Canvass; using CPRNIMS.Infrastructure.Dto.Canvass; using CPRNIMS.Infrastructure.Dto.Canvass.Request; using CPRNIMS.Infrastructure.Dto.Canvass.Response; using CPRNIMS.Infrastructure.Helper; using CPRNIMS.Infrastructure.ViewModel.Canvass; using CPRNIMS.Infrastructure.ViewModel.Common; using Microsoft.AspNetCore.Mvc; using System.Text; namespace CPRNIMS.WebApi.Controllers.Canvass { [Security.AuthorizeRoles("CanvassMgmt")] public class CanvassMgmtController : Base.BaseController { private readonly SMTPHelper _smtpHelper; private readonly ICanvass _canvass; private readonly IConfiguration _config; private readonly SupplierSearchService _supplierSearchService; private readonly IMapper _mapper; public CanvassMgmtController(ErrorMessageService errorMessageService, IWebHostEnvironment webHostEnvironment, SMTPHelper sMTPHelper, IConfiguration configuration, ICanvass canvass, SupplierSearchService supplierSearchService, IMapper mapper) : base(errorMessageService, webHostEnvironment, configuration) { _canvass = canvass; _config = configuration; _smtpHelper = sMTPHelper; _supplierSearchService= supplierSearchService; _mapper = mapper; } #region Get [HttpPost("GetSupplierItemWOEmail")] public async Task GetSupplierItemWOEmail(CanvassDto viewModel) { return await ExecuteWithErrorHandling( () => _canvass.GetSupplierItemWOEmail(viewModel), nameof(GetSupplierItemWOEmail), false ); } [HttpPost("GetSupplierById")] public async Task GetSupplierById(CanvassDto viewModel) { return await ExecuteWithErrorHandling( () => _canvass.GetSupplierById(viewModel), nameof(GetSupplierById), false ); } [HttpPost("GetItemSupplierWOEmail")] public async Task GetItemSupplierWOEmail(CanvassDto viewModel) { return await ExecuteWithErrorHandling( () => _canvass.GetItemSupplierWOEmail(viewModel), nameof(GetItemSupplierWOEmail), false ); } [HttpPost("GetCanvassByPRNo")] public async Task GetCanvassByPRNo(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetCanvassByPRNo(itemCodeDto), nameof(GetCanvassByPRNo), false ); } [HttpPost("GetSupplierBid")] public async Task GetSupplierBid(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetSupplierBid(itemCodeDto), nameof(GetSupplierBid), false ); } [HttpPost("GetSupplierBidByItem")] public async Task GetSupplierBidByItem(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetSupplierBidByItem(itemCodeDto), nameof(GetSupplierBidByItem), false ); } [HttpPost("GetSupplierBidById")] public async Task GetSupplierBidById(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetSupplierBidById(itemCodeDto), nameof(GetSupplierBidById), false ); } [HttpPost("GetCanvassPerSupplier")] public async Task GetCanvassPerSupplier(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetCanvassPerSupplier(itemCodeDto), nameof(GetCanvassPerSupplier), false ); } [HttpPost("GetItemsForTagging")] public async Task GetItemsForTagging(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetItemsForTagging(itemCodeDto), nameof(GetItemsForTagging), false ); } [HttpPost("GetCanvassPerSupplierId")] public async Task GetCanvassPerSupplierId(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetCanvassPerSupplierId(itemCodeDto), nameof(GetCanvassPerSupplierId), false ); } [HttpPost("GetCanvassPerSupplierEmail")] public async Task GetCanvassPerSupplierEmail(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetCanvassPerSupplierEmail(itemCodeDto), nameof(GetCanvassPerSupplierEmail), false ); } [HttpPost("GetPRItemList")] public async Task GetPRItemList(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetPRItemList(itemCodeDto), nameof(GetPRItemList), false ); } [HttpPost("GetPRItem")] public async Task GetPRItem(CanvassDto itemCodeDto) { return await ExecuteWithErrorHandling( () => _canvass.GetPRItem(itemCodeDto), nameof(GetPRItem), false ); } [HttpPost("GetCanvassById")] public async Task GetCanvassById(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.GetCanvassById(CanvassDto), nameof(GetCanvassById), false ); } [HttpPost("GetCanvassWOResponse")] public async Task GetCanvassWOResponse(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.GetCanvassWOResponse(CanvassDto), nameof(GetCanvassWOResponse), false ); } [HttpPost("GetWOResponseBySuppId")] public async Task GetWOResponseBySuppId(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.GetWOResponseBySuppId(CanvassDto), nameof(GetWOResponseBySuppId), false ); } [HttpPost("GetForCanvassPerItem")] public async Task GetForCanvassPerItem(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.GetForCanvassPerItem(CanvassDto), nameof(GetForCanvassPerItem), false ); } [HttpPost("GetPRListByPRNo")] public async Task GetPRListByPRNo(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.GetPRListByPRNo(CanvassDto), nameof(GetPRListByPRNo), false ); } [HttpPost("GetMySuppliers")] public async Task GetMySuppliers(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.GetMySuppliers(CanvassDto), nameof(GetMySuppliers), false ); } [HttpPost("GetMyPRWOCanvass")] public async Task GetMyPRWOCanvass(CanvassDto itemDto) { return await ExecuteWithErrorHandling( () => _canvass.GetMyPRWOCanvass(itemDto), nameof(GetMyPRWOCanvass), false ); } [HttpPost("GetCanvassGroupByPRNo")] public async Task GetCanvassGroupByPRNo(CanvassDto itemDto) { return await ExecuteWithErrorHandling( () => _canvass.GetCanvassGroupByPRNo(itemDto), nameof(GetCanvassGroupByPRNo), false ); } [HttpPost("GetAlternativeOfferByPRDetailId")] public async Task GetAlternativeOfferByPRDetailId(CanvassDto itemDto) { return await ExecuteWithErrorHandling( () => _canvass.GetAlternativeOfferByPRDetailId(itemDto), nameof(GetAlternativeOfferByPRDetailId), false ); } #endregion #region Post Put [HttpPost("PostAllCanvass")] public async Task PostAllCanvass() { try { var baseTemplate = EMailTemplate("Content\\SMTPEmailContent", "SendToSupplier.cshtml"); // Get all canvass items var allCanvass = await _canvass.GetAllForCanvass(); // ✅ Group all items by supplier var groupedBySupplier = allCanvass .GroupBy(x => x.SupplierId) .ToList(); // Process each supplier group foreach (var supplierGroup in groupedBySupplier) { var firstItem = supplierGroup.First(); int canvassNo = await _canvass.GetCanvassNo(); // Insert all items for this supplier foreach (var rfqq in supplierGroup) { var canvass = new CanvassDto { PRDetailsId = rfqq.PRDetailsId, PRNo = rfqq.PRNo, ItemNo = rfqq.ItemNo, SupplierId = rfqq.SupplierId, UserId = rfqq.UserId, FullName = rfqq.FullName, CanvassNo = canvassNo + 1 }; await _canvass.PostPerSupplierToken(canvass); } // ✅ After inserting all items for this supplier, retrieve RFQ info var canvassInfo = new CanvassDto { SupplierId = firstItem.SupplierId, UserId = firstItem.UserId, FullName = firstItem.FullName, CanvassNo = canvassNo + 1 }; var rfq = await _canvass.GetRFQ(canvassInfo); if (rfq?.Any() == true) { // ✅ Prepare email body var message = new StringBuilder(baseTemplate); message.Replace("@ViewBag.FormLink", Convert.ToString(_configuration["WebEndPoint:SupplierForm"] + rfq[0].Token)); message.Replace("@ViewBag.Supplier", rfq[0].SupplierName); message.Replace("@ViewBag.Signature", firstItem.FullName); // ✅ Prepare email details var messageDetails = new EmailMessageDetailsVM { AttachPath = GetRelativePath(@"Content\Documents\Pdf\Offer_Submission_Procedure.pdf"), Recipient = rfq[0].EmailAddress, Message = message.ToString(), Subject = "CLMS - Request For Quotation #PRNo: " + rfq[0].AggrePRNo, CC = Convert.ToString(_configuration["Canvass:CC"]), SenderEmail = _config["SMTP:SenderEmail"], DisplayName = "lloydlabinc.com", NewPassword = _config["SMTP:Password"], OutGoingPort = 587, Server = _config["SMTP:Server"], UserName = _config["SMTP:UserName"], IsSuccess = false, IsCanvass = true }; await _smtpHelper.SendEmailAsync(messageDetails); // ✅ Post canvass record after successful send await _canvass.PostCanvass(canvassInfo); } } return Ok(new { message = "All canvass emails sent successfully." }); } catch (Exception ex) { var errorMessage = ex.InnerException?.ToString() ?? ex.Message.ToString(); await PostErrorMessage(errorMessage, "WebApi"); throw; } } [HttpPost("PostCanvassFollowUp")] public async Task PostCanvassFollowUp(CanvassDto itemDto) { try { var baseTemplate = EMailTemplate("Content\\SMTPEmailContent", "SendToSupplier.cshtml"); var canvassFolloUp = await _canvass.GetCanvassForFollowUp(itemDto); foreach (var canvassSupplierId in canvassFolloUp) { var message = new StringBuilder(baseTemplate); message.Replace("@ViewBag.FormLink", Convert.ToString(_config["WebEndPoint:SupplierForm"] + canvassSupplierId.FormLink)); message.Replace("@ViewBag.Supplier", Convert.ToString(canvassSupplierId.SupplierName)); message.Replace("@ViewBag.Signature", canvassSupplierId.Signature); var messageDetails = new EmailMessageDetailsVM { Recipient = canvassSupplierId.EmailAddress, Message = message.ToString(), Subject = canvassSupplierId.Subject, CC = canvassSupplierId.CC, SenderEmail = canvassSupplierId.SenderEmail, DisplayName = canvassSupplierId.DisplayName, NewPassword = canvassSupplierId.Password, OutGoingPort = 587, Server = canvassSupplierId.Server, UserName = canvassSupplierId.SenderEmail, IsSuccess = false }; messageDetails.IsCanvass = true; messageDetails.AttachPath = @"C:\webapi\Content\Documents\Pdf\Offer_Submission_Procedure.pdf"; if (await _smtpHelper.SendEmailAsync(messageDetails)) { await _canvass.PutSupplierCanvass(canvassSupplierId.CanvassSupplierId); } } return Ok(new { success = true, messCode = 1 }); } catch (Exception ex) { var errorMessage = ex.InnerException?.ToString() ?? ex.Message.ToString(); await PostErrorMessage(errorMessage, "WebApi"); throw; } } [HttpPost("PostPutSupplier")] public async Task PostPutSupplier(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.PostPutSupplier(CanvassDto), nameof(PostPutSupplier), true ); } [HttpPost("PostTaggingSupplier")] public async Task PostTaggingSupplier([FromBody] CanvassVM canvassVM) { var supplier = new SupplierResponse(); foreach (var items in canvassVM.SupplierList.SupplierId) { var index = canvassVM.SupplierList.SupplierId.IndexOf(items); var CanvassDto = new CanvassDto { SupplierId = canvassVM.SupplierList.SupplierId[index], ItemNo = canvassVM.ItemNo, IsActive = true, UserId = canvassVM.UserId, SupplierName = "N/A", EmailAddress = "N/A", Address = "N/A", ContactNo = "N/A", ContactPerson = "N/A", IsTagging = true }; supplier = await _canvass.PostTaggingSupplier(CanvassDto); } return Ok(supplier); } [HttpPost("PostPutItemTagging")] public async Task PostPutItemTagging([FromBody] CanvassVM canvassVM) { var supplier = new SupplierResponse(); foreach (var items in canvassVM.ItemList.ItemNo) { var index = canvassVM.ItemList.ItemNo.IndexOf(items); var CanvassDto = new CanvassDto { ItemNo = canvassVM.ItemList.ItemNo[index], SupplierId = canvassVM.SupplierId, IsActive = canvassVM.IsActive, UserId = canvassVM.UserId, }; supplier = await _canvass.PostPutItemTagging(CanvassDto); } return Ok(supplier); } [HttpPost("PostCanvass")] public async Task PostCanvass([FromBody] CanvassVM canvassVM) { var baseTemplate = EMailTemplate("Content\\SMTPEmailContent", "SendToSupplier.cshtml"); var CanvassDto = new CanvassDto(); int canvassNo = await _canvass.GetCanvassNo(); foreach (var itemCartId in canvassVM.CanvassList.PRDetailsId) { var index = canvassVM.CanvassList.PRDetailsId.IndexOf(itemCartId); CanvassDto = new CanvassDto { PRDetailsId = canvassVM.CanvassList.PRDetailsId[index], PRNo = canvassVM.CanvassList.PRNo[index], ItemNo = canvassVM.CanvassList.ItemNo[index], SupplierId = canvassVM.SupplierId, UserId = canvassVM.UserId, FullName = canvassVM.FullName, CanvassNo = canvassNo + 1, }; await _canvass.PostPerSupplierToken(CanvassDto); } var rfq = await _canvass.GetRFQ(CanvassDto); var message = new StringBuilder(baseTemplate); message.Replace("@ViewBag.FormLink", Convert.ToString(_configuration["WebEndPoint:SupplierForm"] + rfq[0].Token)); message.Replace("@ViewBag.Supplier", rfq[0].SupplierName); message.Replace("@ViewBag.Signature", CanvassDto.FullName); var messageDetails = new EmailMessageDetailsVM(); messageDetails.AttachPath = GetRelativePath(@"Content\Documents\Pdf\Offer_Submission_Procedure.pdf"); messageDetails.Recipient = rfq[0].EmailAddress; messageDetails.Message = message.ToString(); messageDetails.Subject = "CLMS - Request For Quotation #PRNo: " + rfq[0].AggrePRNo; messageDetails.CC = Convert.ToString(_configuration["Canvass:CC"]); messageDetails.SenderEmail = _config["SMTP:SenderEmail"]; messageDetails.DisplayName = "lloydlabinc.com"; messageDetails.NewPassword = _config["SMTP:Password"]; messageDetails.OutGoingPort = 587; messageDetails.Server = _config["SMTP:Server"]; messageDetails.UserName = _config["SMTP:UserName"]; messageDetails.IsSuccess = false; messageDetails.IsCanvass = true; await _smtpHelper.SendEmailAsync(messageDetails); var pR = await _canvass.PostCanvass(CanvassDto); return Ok(pR); } [HttpPost("PostSearchSupplierAndSend")] public async Task PostSearchSupplierAndSend(CancellationToken ct) { // #1 Get top 10 items without suppliers — must process all var response = await _canvass.GetForAISearchingTagging(); if (response == null || !response.Any()) return BadRequest("No items found."); var supplierResults = new List(); foreach (var item in response) { // #2 Search Tavily + Filter with Groq var suppliers = await _supplierSearchService .SearchAndFilterSuppliersAsync(item.ItemName, item.ItemDescription, item.IsInternational); if (!suppliers.Any()) { await _canvass.SearchingUpdate(item.PRDetailsId); continue; } // #3 & #4 Loop each found supplier foreach (var supplier in suppliers) { int canvassNo = await _canvass.GetCanvassNo(); var supplierRequest = _mapper.Map(supplier); supplierRequest.ItemNo = item.ItemNo; var result = await _canvass.PostSupplierAsync(supplierRequest, ct); if (result?.Value == null) continue; var canvassDto = new CanvassDto { PRDetailsId = item.PRDetailsId, PRNo = item.PRNo, ItemNo = item.ItemNo, SupplierId = result.Value.SupplierId, UserId = item.UserId, FullName = item.FullName, CanvassNo = ++canvassNo, }; await _canvass.PostPerSupplierToken(canvassDto); var rfq = await _canvass.GetRFQ(canvassDto); if (rfq == null || !rfq.Any()) continue; var supplierEmailRequest = new SupplierEmailRequest { AttachPath = GetRelativePath(@"Content\\Documents\\Pdf\\Offer_Submission_Procedure.pdf"), Recipient = "rmsoriano@lloydlab.com",//rfq[0].EmailAddress, // this will be implemented later Subject = $"CLMS - Request For Quotation #PRNo: {rfq[0].AggrePRNo}", CC = Convert.ToString(_configuration["Canvass:CC"] ?? ""), SenderEmail = _config["SMTP:SenderEmail"], DisplayName = "lloydlabinc.com", Password = _config["SMTP:Password"], OutGoingPort = 587, Server = _config["SMTP:Server"], UserName = _config["SMTP:UserName"], FormLink = Convert.ToString(_configuration["WebEndPoint:SupplierForm"] ?? ""), Token = rfq[0].Token, SupplierName = result.Value.SupplierName, Purchaser = item.FullName, IsSuccess = false, IsCanvass = true, }; await _canvass.SearchingUpdate(item.PRDetailsId); await _canvass.SendRFQ(supplierEmailRequest); supplierResults.Add(new { item = item.ItemName, supplier = supplier.SupplierName, email = supplier.EmailAddress, canvassNo = canvassDto.CanvassNo }); } } return Ok(new { totalProcessed = supplierResults.Count, suppliers = supplierResults }); } [HttpPost("PostSuggestedSupp")] public async Task PostSuggestedSupp(CanvassDto CanvassDto) { var pR = await _canvass.PostSuggestedSupp(CanvassDto); return Ok(pR); } [HttpPost("PostApprovedSupp")] public async Task PostApprovedSupp(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.PostApprovedSupp(CanvassDto), nameof(PostApprovedSupp), true ); } [HttpPost("PutSuppUnitPrice")] public async Task PutSuppUnitPrice(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.PutSuppUnitPrice(CanvassDto), nameof(PutSuppUnitPrice), true ); } [HttpPost("PutSuppBidDetails")] public async Task PutSuppBidDetails(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.PutSuppBidDetails(CanvassDto), nameof(PutSuppBidDetails), true ); } [HttpPost("PostPutMySupplier")] public async Task PostPutMySupplier(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.PostPutMySupplier(CanvassDto), nameof(PostPutMySupplier), true ); } [HttpPost("UnlockFormLink")] public async Task UnlockFormLink(CanvassDto CanvassDto) { return await ExecuteWithErrorHandling( () => _canvass.UnlockFormLink(CanvassDto), nameof(UnlockFormLink), true ); } #endregion } }