diff --git a/Areas/MMS/Controllers/MarineController.cs b/Areas/MMS/Controllers/MarineController.cs index 7000cbe..7fa199c 100644 --- a/Areas/MMS/Controllers/MarineController.cs +++ b/Areas/MMS/Controllers/MarineController.cs @@ -8,6 +8,7 @@ using System.Linq; using QuestPDF.Fluent; using PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator; using System.Globalization; +using System.IO; namespace PSTW_CentralSystem.Areas.MMS.Controllers { @@ -16,27 +17,26 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers public class MarineController(MMSSystemContext context) : Controller { private readonly MMSSystemContext _context = context; + private const string PhotoBasePath = @"\\192.168.12.42\images\marine\manual_tarball"; public IActionResult Index() { - return View(); // This will look for Index.cshtml in Areas/MMS/Views/Marine + return View(); } - //what to require from database into front-end (here is logic for calling, etc.) public IActionResult TarBallForm() { var marineTarballs = _context.MarineTarballs - .Where(t=>t.StationID != "1") //Exclude test data with station named "1" + .Where(t => t.StationID != "1") .Select(t => new { - t.Id, // Include Id property - Date = t.DateSample.ToString("yyyy/MM/dd"), // Format DateSample as needed + t.Id, + Date = t.DateSample.ToString("yyyy/MM/dd"), Station = t.StationID }) .ToList(); - // For debugging - Console.WriteLine("Fetched Data:"); + // Debugging foreach (var item in marineTarballs) { Console.WriteLine($"Date: {item.Date}, Station: {item.Station}"); @@ -45,65 +45,19 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers return View(marineTarballs); } - //what to do for generating report public IActionResult GenerateReport(int id) { - Console.WriteLine($"Requested ID in GenerateReport: {id}"); - - try - { - 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 - where marine.Id == id - select new - { - state.StateName, - marine.StationID, - station.LocationName, - marine.Longitude, - marine.Latitude, - marine.DateSample, - marine.TimeSample - - }).FirstOrDefault(); - - if (tarballData == null) - { - return NotFound("The specified record was not found."); - } - - Console.WriteLine($"DateSample: {tarballData.DateSample}, TimeSample: {tarballData.TimeSample}"); - - var pdfDocument = new TarBallPDF( - tarballData.StateName, - tarballData.StationID, - tarballData.LocationName, - tarballData.Longitude, - tarballData.Latitude, - tarballData.DateSample, // Pass DateSample directly (raw value) - tarballData.TimeSample // Pass TimeSample directly (raw value) - ); - var pdf = pdfDocument.GeneratePdf(); - Console.WriteLine("PDF generation completed."); - - var formattedDate = tarballData.DateSample.ToString("yyyyMMdd"); - var fileName = $"TbReport_{tarballData.StationID}_{formattedDate}.pdf"; - - return File(pdf, "application/pdf", fileName); - } - catch (Exception ex) - { - Console.WriteLine($"Error in GenerateReport: {ex.Message}"); - return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while generating the PDF. Generate PDF error. " + ex.Message); - } + return GeneratePdfResponse(id, true); } public IActionResult ViewPDF(int id) { - Console.WriteLine($"Requested ID in ViewReport: {id}"); + return GeneratePdfResponse(id, false); + } + + private IActionResult GeneratePdfResponse(int id, bool forceDownload) + { + Console.WriteLine($"Requested ID in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {id}"); try { @@ -121,7 +75,13 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers marine.Longitude, marine.Latitude, marine.DateSample, - marine.TimeSample + marine.TimeSample, + marine.ClassifyID, + TarBallYes = marine.ClassifyID != "NO", + TarBallNo = marine.ClassifyID == "NO", + IsSand = marine.ClassifyID == "SD", + IsNonSandy = marine.ClassifyID == "NS", + IsCoquina = marine.ClassifyID == "CO" }).FirstOrDefault(); if (tarballData == null) @@ -129,29 +89,69 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers return NotFound("The specified record was not found."); } - Console.WriteLine($"DateSample: {tarballData.DateSample}, TimeSample: {tarballData.TimeSample}"); + // Generate photo paths + var photoBaseName = $"{tarballData.StationID}_{tarballData.DateSample:yyyyMMdd}"; + var photoPath1 = GetValidPhotoPath(photoBaseName + "_1.jpg"); + var photoPath2 = GetValidPhotoPath(photoBaseName + "_2.jpg"); + var photoPath3 = GetValidPhotoPath(photoBaseName + "_3.jpg"); + var photoPath4 = GetValidPhotoPath(photoBaseName + "_4.jpg"); - // Generate the PDF - Make sure parameter order matches the constructor - var document = new TarBallPDF( + var pdfDocument = new TarBallPDF( tarballData.StateName, tarballData.StationID, tarballData.LocationName, tarballData.Longitude, tarballData.Latitude, tarballData.DateSample, - tarballData.TimeSample + tarballData.TimeSample, + tarballData.ClassifyID, + tarballData.TarBallYes, + tarballData.TarBallNo, + tarballData.IsSand, + tarballData.IsNonSandy, + tarballData.IsCoquina, + photoPath1, + photoPath2, + photoPath3, + photoPath4 ); - var pdf = document.GeneratePdf(); + var pdf = pdfDocument.GeneratePdf(); + Console.WriteLine("PDF generation completed."); + + if (forceDownload) + { + var fileName = $"TbReport_{tarballData.StationID}_{tarballData.DateSample:yyyyMMdd}.pdf"; + return File(pdf, "application/pdf", fileName); + } - // Return the file without forcing download return File(pdf, "application/pdf"); } catch (Exception ex) { - Console.WriteLine($"Error in ViewPDF: {ex.Message}"); - return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while viewing the PDF. " + ex.Message); + Console.WriteLine($"Error in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {ex.Message}"); + return StatusCode(StatusCodes.Status500InternalServerError, + $"An error occurred while {(forceDownload ? "generating" : "viewing")} the PDF. {ex.Message}"); + } + } + + private string GetValidPhotoPath(string photoName) + { + var fullPath = Path.Combine(PhotoBasePath, photoName); + return System.IO.File.Exists(fullPath) ? fullPath : null; + } + + private string? FindPhoto(string folderPath, string searchPattern) + { + try + { + var files = Directory.GetFiles(folderPath, searchPattern); + return files.Length > 0 ? files[0] : null; + } + catch + { + return null; } } } -} +} \ No newline at end of file diff --git a/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs b/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs index 767a2de..3d8f3ec 100644 --- a/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs +++ b/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs @@ -6,7 +6,11 @@ using PSTW_CentralSystem.Models; namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator { - public class TarBallPDF(string stationID, string stateName, string locationName, string longitude, string latitude, DateTime dateSample, TimeSpan timeSample) : IDocument + public class TarBallPDF(string stationID, string stateName, string locationName, + string longitude, string latitude, DateTime dateSample, TimeSpan timeSample, + string classifyID, bool tarBallYes, bool tarBallNo, bool isSand, bool isNonSandy, + bool isCoquina, string photoPath1, string photoPath2, string photoPath3, string photoPath4) + : IDocument { private readonly string _stationId = stationID; private readonly string _stateName = stateName; @@ -15,12 +19,31 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator private readonly string _latitude = latitude; private readonly DateTime _dateSample = dateSample; private readonly TimeSpan _timeSample = timeSample; + private readonly string _classifyID = classifyID; + private readonly bool _tarBallYes = tarBallYes; + private readonly bool _tarBallNo = tarBallNo; + private readonly bool _isSand = isSand; + private readonly bool _isNonSandy = isNonSandy; + private readonly bool _isCoquina = isCoquina; + private readonly string _photoPath1 = photoPath1; + private readonly string _photoPath2 = photoPath2; + private readonly string _photoPath3 = photoPath3; + private readonly string _photoPath4 = photoPath4; + //INSERT LOADIMAGE() HERE + private static Image? LoadImage(string path) + { + if (!string.IsNullOrEmpty(path) && File.Exists(path)) + { + return Image.FromFile(path); // Load image if the file exists + } + return Image.FromFile("default-placeholder.jpg"); // Return null if the file is missing + } // Metadata for the PDF document public DocumentMetadata GetMetadata() => new() { - Title = "TarBall Sampling Form", + Title = "TARBALL SAMPLING FORM", Author = "PAKAR SCIENO TW Integrated Environmental Solutions", Subject = "Environmental Survey and Observations" }; @@ -134,24 +157,41 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator column.Spacing(3); - // Survey Findings + // Survey Findings - ALWAYS shows all options column.Item() .PaddingTop(10) .PaddingBottom(10) .Text("SURVEY FINDING:") .Bold().FontSize(12); + + // 1. Tar Ball YES/NO (always shown) column.Item() .PaddingBottom(10) - .Text("Tar Ball: [☐] YES [☐] NO").FontSize(10); + .Text(text => + { + text.Span("Tar Ball: ").Style(TextStyle.Default.FontSize(10)); + text.Span(_classifyID == "NO" ? "☐ YES ☑ NO" : "☑ YES ☐ NO").Style(TextStyle.Default.FontSize(10)); + }); + + // 2. Classification (always shown) column.Item() .PaddingBottom(10) - .Text("If YES, Tar Ball falls under the classification of:").FontSize(10); + .Text("If YES, Tar Ball falls under the Classification of:") + .FontSize(10); + column.Item() .PaddingBottom(10) - .Text("[☐] Sand [☐] Non-sandy [☐] Coquina").FontSize(10); + .Text(text => + { + text.Span(_classifyID == "SD" ? "☑ Sand " : "☐ Sand ").Style(TextStyle.Default.FontSize(10)); + text.Span(_classifyID == "NS" ? "☑ Non-sandy " : "☐ Non-sandy ").Style(TextStyle.Default.FontSize(10)); + text.Span(_classifyID == "CO" ? "☑ Coquina" : "☐ Coquina").Style(TextStyle.Default.FontSize(10)); + }); + column.Item() .PaddingBottom(10) - .Text("*tick wherever applicable"); + .Text("*tick wherever applicable") + .Italic(); // Photos Section Title column.Item() @@ -161,7 +201,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator .Bold() .FontSize(14); - // Table for Photos + // Photos Section column.Item().Table(table => { column.Spacing(0); @@ -172,17 +212,37 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator columns.RelativeColumn(1); }); - table.Cell().Element(CellStyle).Height(150); - table.Cell().Element(CellStyle).Height(150); + // Row 1: Photos + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath1)); // Left Side View photo space - table.Cell().Element(CellStyle).Text("Figure 1: Left Side Coastal View").FontSize(12).AlignLeft(); - table.Cell().Element(CellStyle).Text("Figure 2: Right Side Coastal View").FontSize(12).AlignLeft(); + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath2)); // Right Side View photo space - table.Cell().Element(CellStyle).Height(150); - table.Cell().Element(CellStyle).Height(150); + // Row 1: Captions + table.Cell().Element(CellStyle) + .Text("Figure 1: Left Side Coastal View") + .FontSize(12).AlignLeft(); - table.Cell().Element(CellStyle).Text("Figure 3: Drawing Vertical Lines").FontSize(12).AlignLeft(); - table.Cell().Element(CellStyle).Text("Figure 4: Drawing Horizontal Lines (Racking)").FontSize(12).AlignLeft(); + table.Cell().Element(CellStyle) + .Text("Figure 2: Right Side Coastal View") + .FontSize(12).AlignLeft(); + + // Row 2: Photos + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath3)); // Vertical Lines photo space + + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath4)); // Horizontal Lines photo space + + // Row 2: Captions + table.Cell().Element(CellStyle) + .Text("Figure 3: Drawing Vertical Lines") + .FontSize(12).AlignLeft(); + + table.Cell().Element(CellStyle) + .Text("Figure 4: Drawing Horizontal Lines (Racking)") + .FontSize(12).AlignLeft(); }); // Page Break @@ -217,6 +277,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator .PaddingTop(10) .PaddingBottom(20) .Text("* If there are any event observe at the current station it is compulsory to add optional photo with description (figure 5 to figure 8)") + .Bold() .FontSize(10) .AlignLeft(); diff --git a/DBContext/MMSSystemContext.cs b/DBContext/MMSSystemContext.cs index a2e6256..b92ae7e 100644 --- a/DBContext/MMSSystemContext.cs +++ b/DBContext/MMSSystemContext.cs @@ -14,7 +14,6 @@ namespace PSTW_CentralSystem.DBContext public DbSet MarineTarballs { get; set; } public DbSet MarineStations { get; set; } public DbSet States { get; set; } - public DbSet ClassifyID { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -46,12 +45,6 @@ namespace PSTW_CentralSystem.DBContext .WithMany() .HasForeignKey(m => m.StationID) .HasPrincipalKey(t => t.StationID); - - //Configure relationship with TarballStation - entity.HasOne(m => m.MarineClassify) - .WithMany() - .HasForeignKey(m => m.ClassifyID) - .HasPrincipalKey(t => t.ClassifyID); }); // Map TarballStation to tbl_tarball_station @@ -85,17 +78,6 @@ namespace PSTW_CentralSystem.DBContext entity.Property(e => e.StateID).HasColumnName("stateID").HasMaxLength(20); entity.Property(e => e.StateName).HasColumnName("stateName").HasMaxLength(50); }); - - modelBuilder.Entity().ToTable("tbl_classify"); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.Id); // Primary key - entity.Property(e => e.Id).HasColumnName("id"); - entity.Property(e => e.ClassifyID).HasColumnName("classifyID").HasMaxLength(2); - entity.Property(e => e.ClassifyName).HasColumnName("classifyName").HasMaxLength(50); - }); - } } } diff --git a/Models/MarineTarball.cs b/Models/MarineTarball.cs index 404ed9f..b81c69d 100644 --- a/Models/MarineTarball.cs +++ b/Models/MarineTarball.cs @@ -18,11 +18,13 @@ namespace PSTW_CentralSystem.Models public double GetLongitude { get; set; } // Maps to 'getLongitude' public DateTime Timestamp { get; set; } // Maps to 'timestamp' + public string PhotoPath1 { get; set; } // Left Side Coastal View + public string PhotoPath2 { get; set; } // Right Side Coastal View + public string PhotoPath3 { get; set; } // Vertical Lines + public string PhotoPath4 { get; set; } // Horizontal Lines + [ForeignKey("StationID")] public required MarineStation MarineStation { get; set; } - - [ForeignKey("ClassifyID")] - public required MarineClassify MarineClassify { get; set; } } public class MarineStation