diff --git a/Areas/MMS/Controllers/MarineController.cs b/Areas/MMS/Controllers/MarineController.cs index f0fb1ae..2095ee5 100644 --- a/Areas/MMS/Controllers/MarineController.cs +++ b/Areas/MMS/Controllers/MarineController.cs @@ -8,9 +8,34 @@ using QuestPDF.Fluent; using System.Threading.Tasks; using System.Threading; using System.Collections.Generic; +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; namespace PSTW_CentralSystem.Areas.MMS.Controllers { + public class SimpleTarballDto + { + // From tbl_marine_tarball + public int Id { get; set; } + public string StationID { get; set; } + public string Longitude { get; set; } + public string Latitude { get; set; } + public DateTime DateSample { get; set; } + public TimeSpan TimeSample { get; set; } + public string ClassifyID { get; set; } + public string OptionalName1 { get; set; } + public string OptionalName2 { get; set; } + public string OptionalName3 { get; set; } + public string OptionalName4 { get; set; } + public string FirstSampler { get; set; } + + // From joined tables + public string LocationName { get; set; } // From tbl_marine_station + public string StateName { get; set; } // From tbl_state + public string FullName { get; set; } // From tbl_user + public string LevelName { get; set; } // From tbl_level + } + [Area("MMS")] public class MarineController : Controller { @@ -33,7 +58,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers { try { - var marineTarballs = _context.MarineTarballs + var marineTarballs = _context.MarineTarballs //error=========================================== .Where(t => t.StationID != "1") // To remove unusable data with invalid stationID .Select(t => new { @@ -197,14 +222,14 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers } } - public IActionResult GenerateReport(int id)//calls GeneratePdfResponse to generate a PDF for inline viewing + public async Task GenerateReport(int id)//calls GeneratePdfResponse to generate a PDF for inline viewing { - return GeneratePdfResponse(id, true); + return await GeneratePdfResponse(id, true); } - public IActionResult DownloadPDF(int id) + public async Task DownloadPDF(int id) { - return GeneratePdfResponse(id, true); + return await GeneratePdfResponse(id, true); } @@ -227,11 +252,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers } } - private IActionResult GeneratePdfResponse(int id, bool forceDownload) + private async Task GeneratePdfResponse(int id, bool forceDownload) { Console.WriteLine($"Requested ID in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {id}"); - // Add this temporary check at the start of GeneratePdfResponse + // Temporary network connection test try { Console.WriteLine("Testing network connection..."); @@ -248,49 +273,38 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers try { // Connect to the network path - _networkAccessService.ConnectToNetworkPath();//------------------ + _networkAccessService.ConnectToNetworkPath(); - // 1. Fetch core data from database - var tarballData = (from marine in _context.MarineTarballs - join station in _context.MarineStations on marine.StationID equals station.StationID - join state in _context.States on station.StateID equals state.StateID - join user in _context.Users on marine.FirstSampler equals user.FullName - join level in _context.Levels on user.LevelID equals level.LevelID - where marine.Id == id - select new - { - state.StateName, - marine.StationID, - station.LocationName, - marine.Longitude, - marine.Latitude, - marine.DateSample, - marine.TimeSample, - marine.ClassifyID, - TarBallYes = marine.ClassifyID != "NO", - TarBallNo = marine.ClassifyID == "NO", - IsSand = marine.ClassifyID == "SD", - IsNonSandy = marine.ClassifyID == "NS", - IsCoquina = marine.ClassifyID == "CO", - marine.OptionalName1, - marine.OptionalName2, - marine.OptionalName3, - marine.OptionalName4, - marine.FirstSampler, - user.FullName, - user.LevelID, - level.LevelName + // ===== 1. NEW SQL QUERY APPROACH ===== + var query = @" + SELECT + marine.*, station.LocationName, state.StateName,user.FullName,level.LevelName + FROM tbl_marine_tarball marine + JOIN tbl_marine_station station ON marine.StationID = station.StationID + JOIN tbl_state state ON station.StateID = state.StateID + JOIN tbl_user user ON marine.FirstSampler = user.FullName -- Corrected column name + JOIN tbl_level level ON user.LevelID = level.LevelID + WHERE marine.Id = @id"; - }).FirstOrDefault(); + var tarball = await _context.Database + .SqlQueryRaw(query, new SqlParameter("@id", id)) + .FirstOrDefaultAsync(); - if (tarballData == null) + if (tarball == null) return NotFound("Record not found"); - // 2. Get photos from station folder (with date matching) - var sampleDateString = tarballData.DateSample.ToString("yyyyMMdd"); - var sampleTimePrefix = ((int)tarballData.TimeSample.TotalHours).ToString("D2") + - tarballData.TimeSample.Minutes.ToString("D2"); - var stationFolder = Path.Combine(PhotoBasePath, tarballData.StationID); + //Prepare boolean values for PDF + bool tarBallYes = tarball.ClassifyID != "NO"; + bool tarBallNo = tarball.ClassifyID == "NO"; + bool isSand = tarball.ClassifyID == "SD"; + bool isNonSandy = tarball.ClassifyID == "NS"; + bool isCoquina = tarball.ClassifyID == "CO"; + + // ===== 2. Get Images from path ===== + var sampleDateString = tarball.DateSample.ToString("yyyyMMdd"); + var sampleTimePrefix = ((int)tarball.TimeSample.TotalHours).ToString("D2") + + tarball.TimeSample.Minutes.ToString("D2"); + var stationFolder = Path.Combine(PhotoBasePath, tarball.StationID); var stationImages = new Dictionary(); if (Directory.Exists(stationFolder)) @@ -300,18 +314,13 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers { var fileName = Path.GetFileNameWithoutExtension(f); var parts = fileName.Split('_'); - - //Match: StationID_Date_* return parts.Length >= 3 && - parts[0] == tarballData.StationID && // 1. StationID - parts[1] == sampleDateString && // 2. Date - parts[2].StartsWith(sampleTimePrefix); + parts[0] == tarball.StationID && + parts[1] == sampleDateString && + parts[2].StartsWith(sampleTimePrefix); }) .ToList(); - Console.WriteLine($"Found {allImages.Count} images for {tarballData.StationID} on {sampleDateString} at {sampleTimePrefix}"); - - // Define image priority order var imageTypes = new List { "LEFTSIDECOASTALVIEW", @@ -324,13 +333,12 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers "OPTIONAL04" }; - // Match images to their types foreach (var imagePath in allImages) { var fileName = Path.GetFileNameWithoutExtension(imagePath); - foreach (var type in imageTypes) + foreach(var type in imageTypes) { - if (fileName.EndsWith(type, StringComparison.OrdinalIgnoreCase)) + if(fileName.EndsWith(type,StringComparison.OrdinalIgnoreCase)) { stationImages[type] = imagePath; break; @@ -339,7 +347,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers } } - // Validate mandatory images + //Mandatory images var mandatoryImages = new List { "LEFTSIDECOASTALVIEW", @@ -348,29 +356,29 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers "DRAWINGHORIZONTALLINES" }; - foreach (var mandatoryType in mandatoryImages) + foreach(var mandatoryType in mandatoryImages) { - if (!stationImages.ContainsKey(mandatoryType)) + if(!stationImages.ContainsKey(mandatoryType)) { - return StatusCode(400, $"Missing mandatory image for {tarballData.StationID} on {tarballData.DateSample:yyyy-MM-dd} at {tarballData.TimeSample}: {mandatoryType}"); + return StatusCode(400, $"Missing mandatory image: {mandatoryType}"); } } - // 3. Generate PDF + // ===== 3. GENERATE PDF (ADAPTED FOR NEW DTO) ===== var pdf = new TarBallPDF( - tarballData.StateName, - tarballData.StationID, - tarballData.LocationName, - tarballData.Longitude, - tarballData.Latitude, - tarballData.DateSample, - tarballData.TimeSample, - tarballData.ClassifyID, - tarballData.TarBallYes, - tarballData.TarBallNo, - tarballData.IsSand, - tarballData.IsNonSandy, - tarballData.IsCoquina, + tarball.StateName, + tarball.StationID, + tarball.LocationName, + tarball.Longitude, + tarball.Latitude, + tarball.DateSample, + tarball.TimeSample, + tarball.ClassifyID, + tarBallYes, + tarBallNo, + isSand, + isNonSandy, + isCoquina, stationImages["LEFTSIDECOASTALVIEW"], stationImages["RIGHTSIDECOASTALVIEW"], stationImages["DRAWINGVERTICALLINES"], @@ -379,18 +387,17 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers stationImages.GetValueOrDefault("OPTIONAL02"), stationImages.GetValueOrDefault("OPTIONAL03"), stationImages.GetValueOrDefault("OPTIONAL04"), - tarballData.OptionalName1, - tarballData.OptionalName2, - tarballData.OptionalName3, - tarballData.OptionalName4, - tarballData.FirstSampler, - tarballData.FullName, - tarballData.LevelName + tarball.OptionalName1, + tarball.OptionalName2, + tarball.OptionalName3, + tarball.OptionalName4, + tarball.FirstSampler, + tarball.FullName, + tarball.LevelName ).GeneratePdf(); - // 4. Return file return forceDownload - ? File(pdf, "application/pdf", $"TbReport_{tarballData.StationID}_{tarballData.DateSample:yyyyMMdd}.pdf") + ? File(pdf, "application/pdf", $"TbReport_{tarball.StationID}_{tarball.DateSample:yyyyMMdd}.pdf") : File(pdf, "application/pdf"); } catch (Exception ex) @@ -400,14 +407,37 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers : ex.Message; return Content($"PDF generation failed: {errorMessage}
{ex.StackTrace}", "text/html"); } - finally { - // Disconnect from the network path _networkAccessService.DisconnectFromNetworkShare(); } } + // Add this class outside your controller (e.g., in a DTOs folder) + public class TarballPdfDto + { + public string StateName { get; set; } + public string StationID { get; set; } + public string LocationName { get; set; } + public string Longitude { get; set; } + public string Latitude { get; set; } + public DateTime DateSample { get; set; } + public TimeSpan TimeSample { get; set; } + public string ClassifyID { get; set; } + public int TarBallYes { get; set; } // SQL returns 1/0 for bits + public int TarBallNo { get; set; } + public int IsSand { get; set; } + public int IsNonSandy { get; set; } + public int IsCoquina { get; set; } + public string OptionalName1 { get; set; } + public string OptionalName2 { get; set; } + public string OptionalName3 { get; set; } + public string OptionalName4 { get; set; } + public string FirstSampler { get; set; } + public string FullName { get; set; } + public string LevelName { get; set; } + } + private bool IsImageValid(string imagePath) { try diff --git a/DBContext/MMSSystemContext.cs b/DBContext/MMSSystemContext.cs index b512d52..95abc40 100644 --- a/DBContext/MMSSystemContext.cs +++ b/DBContext/MMSSystemContext.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using PSTW_CentralSystem.Models; // Add this to use the MarineTarball class @@ -21,12 +22,11 @@ namespace PSTW_CentralSystem.DBContext { base.OnModelCreating(modelBuilder); - // Map MarineTarball to tbl_marine_tarball - modelBuilder.Entity().ToTable("tbl_marine_tarball"); - // Configure properties if needed modelBuilder.Entity(entity => { + entity.ToTable("tbl_marine_tarball"); + entity.HasKey(e => e.Id); // Primary key entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.ReportID).HasColumnName("reportID").HasMaxLength(50); @@ -52,20 +52,11 @@ namespace PSTW_CentralSystem.DBContext .HasForeignKey(m => m.StationID) .HasPrincipalKey(t => t.StationID); - //use SQL query - //======================================================== - entity.HasOne(a => a.User)//Each MarineTarball has ONE User - .WithMany()//Each User can be linked to MANY MarineTarballs - .HasForeignKey(a => a.FirstSampler)//Uses FirstSampler (name string) in MarineTarball as the connector to User - .HasPrincipalKey(b => b.FullName);//match FirstSampler with the FullName in the User table - //======================================================== }); - // Map TarballStation to tbl_tarball_station - modelBuilder.Entity().ToTable("tbl_marine_station"); - modelBuilder.Entity(entity => { + entity.ToTable("tbl_marine_station"); entity.HasKey(e => e.Id); // Primary key entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.StationID).HasColumnName("stationID").HasMaxLength(20); @@ -82,21 +73,18 @@ namespace PSTW_CentralSystem.DBContext .HasPrincipalKey(s => s.StateID); }); - // Map State to tbl_state - modelBuilder.Entity().ToTable("tbl_state"); - modelBuilder.Entity(entity => { + entity.ToTable("tbl_state"); entity.HasKey(e => e.Id); // Primary key entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.StateID).HasColumnName("stateID").HasMaxLength(20); entity.Property(e => e.StateName).HasColumnName("stateName").HasMaxLength(50); }); - modelBuilder.Entity().ToTable("tbl_user"); - modelBuilder.Entity(entity => { + entity.ToTable("tbl_user"); entity.HasKey(e => e.Id); // Primary key entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.UserID).HasColumnName("userID").HasMaxLength(20); @@ -109,7 +97,7 @@ namespace PSTW_CentralSystem.DBContext entity.HasOne(u => u.Level) .WithMany() .HasForeignKey(u => u.LevelID) - .HasPrincipalKey(c => c.LevelID); + .HasPrincipalKey(l => l.LevelID); }); modelBuilder.Entity().ToTable("tbl_level");