From e220868d72f36a5466b3b0ed953cf28270da5576 Mon Sep 17 00:00:00 2001 From: misya Date: Thu, 24 Apr 2025 15:41:53 +0800 Subject: [PATCH] generate images within pdf following naming format, stationID_date_... --- Areas/MMS/Controllers/MarineController.cs | 93 ++++++++++++++++++--- Areas/MMS/Models/PDFGenerator/TarBallPDF.cs | 43 ++++++---- Models/MarineTarball.cs | 11 +-- 3 files changed, 112 insertions(+), 35 deletions(-) diff --git a/Areas/MMS/Controllers/MarineController.cs b/Areas/MMS/Controllers/MarineController.cs index 009517d..56070f1 100644 --- a/Areas/MMS/Controllers/MarineController.cs +++ b/Areas/MMS/Controllers/MarineController.cs @@ -27,7 +27,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers public IActionResult TarBallForm() { var marineTarballs = _context.MarineTarballs - .Where(t => t.StationID != "1") + .Where(t => t.StationID != "1")//remove unusable data (to be modified later to delete) .Select(t => new { t.Id, @@ -86,20 +86,71 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers if (tarballData == null) return NotFound("Record not found"); - // 2. Get photos from station folder + // 2. Get photos from station folder (with date matching) + var sampleDateString = tarballData.DateSample.ToString("yyyyMMdd"); var stationFolder = Path.Combine(PhotoBasePath, tarballData.StationID); var stationImages = new List(); if (Directory.Exists(stationFolder)) { - stationImages = Directory.GetFiles(stationFolder) - .Where(f => f.EndsWith(".jpg") || f.EndsWith(".png")) - .OrderBy(f => f) // Alphabetical order - .Take(4) // Only need 4 photos max - .ToList(); + var allImages = Directory.GetFiles(stationFolder) + .Where(f => { + var fileName = Path.GetFileNameWithoutExtension(f); + var parts = fileName.Split('_'); + + return parts.Length >= 3 && + parts[0] == tarballData.StationID && + parts[1] == sampleDateString && + (f.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || + f.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) && + IsImageValid(f); + }) + .ToList(); + + // Define image priority order + var imageTypesInOrder = new List + { + "LEFTSIDECOASTALVIEW", + "RIGHTSIDECOASTALVIEW", + "DRAWINGVERTICALLINES", + "DRAWINGHORIZONTALLINES", + "OPTIONAL01", + "OPTIONAL02", + "OPTIONAL03", + "OPTIONAL04" + }; + + // Sort logic (same as before) + bool hasValidFormat = allImages.Any(f => + imageTypesInOrder.Any(t => Path.GetFileNameWithoutExtension(f).ToUpper().Contains(t))); + + if (hasValidFormat) + { + stationImages = allImages + .OrderBy(f => { + var fileName = Path.GetFileNameWithoutExtension(f).ToUpper(); + var typeIndex = imageTypesInOrder.FindIndex(t => fileName.Contains(t)); + return typeIndex >= 0 ? typeIndex : int.MaxValue; + }) + .ThenBy(f => f) + .Take(8) + .ToList(); + } + else + { + stationImages = allImages + .OrderBy(f => f) + .Take(8) + .ToList(); + Console.WriteLine($"WARNING: No images matched keywords. Sorted alphabetically."); + } } - Console.WriteLine($"Found {stationImages.Count} images for {tarballData.StationID}"); + // Validate minimum images + if (stationImages.Count < 4) + { + return StatusCode(400, $"Minimum 4 images required for {tarballData.DateSample:yyyy/MM/dd}. Found: {stationImages.Count}"); + } // 3. Generate PDF var pdf = new TarBallPDF( @@ -119,7 +170,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers stationImages.Count > 0 ? stationImages[0] : null, stationImages.Count > 1 ? stationImages[1] : null, stationImages.Count > 2 ? stationImages[2] : null, - stationImages.Count > 3 ? stationImages[3] : null + stationImages.Count > 3 ? stationImages[3] : null, + stationImages.Count > 4 ? stationImages[4] : null, + stationImages.Count > 5 ? stationImages[5] : null, + stationImages.Count > 6 ? stationImages[6] : null, + stationImages.Count > 7 ? stationImages[7] : null ).GeneratePdf(); // 4. Return file @@ -141,7 +196,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers if (!Directory.Exists(folderPath)) { Console.WriteLine($"Folder not found: {folderPath}"); - return new List(); // Return empty list + return []; // Return empty list } // Get ALL .jpg/.png files (no date sorting) @@ -153,10 +208,24 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers catch (Exception ex) { Console.WriteLine($"Error fetching photos: {ex.Message}"); - return new List(); // Return empty list on error + return []; // Return empty list on error } } - + private bool IsImageValid(string imagePath) + { + try + { + using (var image = System.Drawing.Image.FromFile(imagePath)) + return true; + } + catch + { + Console.WriteLine($"Invalid image skipped: {imagePath}"); + return false; + } + } } + + } \ No newline at end of file diff --git a/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs b/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs index 94c80c6..0fbcf1d 100644 --- a/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs +++ b/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs @@ -9,7 +9,9 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator 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) + bool isCoquina, string photoPath1, string photoPath2, string photoPath3, string photoPath4, + string photoPath5, string photoPath6, string photoPath7, string photoPath8 + ) : IDocument { private readonly string _stationId = stationID; @@ -29,6 +31,10 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator private readonly string? _photoPath2 = photoPath2; private readonly string? _photoPath3 = photoPath3; private readonly string? _photoPath4 = photoPath4; + private readonly string? _photoPath5 = photoPath5; + private readonly string? _photoPath6 = photoPath6; + private readonly string? _photoPath7 = photoPath7; + private readonly string? _photoPath8 = photoPath8; //INSERT LOADIMAGE() HERE private Image? LoadImage(string? imagePath) @@ -180,7 +186,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator .Text(text => { text.Span("Tar Ball: ").Style(TextStyle.Default.FontSize(10)); - text.Span(_classifyID == "NO" ? "☐ YES ☑ NO" : "☑ YES ☐ NO").Style(TextStyle.Default.FontSize(10)); + text.Span(_classifyID == "NO" ? " ☐ YES ☑ NO" : " ☑ YES ☐ NO").Style(TextStyle.Default.FontSize(10)); }); // 2. Classification (always shown) @@ -194,7 +200,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator .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 == "NS" ? " ☑ Non-sandy " : " ☐ Non-sandy ").Style(TextStyle.Default.FontSize(10)); text.Span(_classifyID == "CO" ? "☑ Coquina" : "☐ Coquina").Style(TextStyle.Default.FontSize(10)); }); @@ -267,7 +273,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator // Additional Photos Section column.Item().Table(table => { - column.Spacing(0); + column.Spacing(3); table.ColumnsDefinition(columns => { @@ -275,14 +281,22 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator columns.RelativeColumn(1); }); - table.Cell().Element(CellStyle).Height(150); - table.Cell().Element(CellStyle).Height(150); + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath5) ?? null) // Just pass null if no image + .FitArea(); + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath6) ?? null) // Just pass null if no image + .FitArea(); table.Cell().Element(CellStyle).Text("Figure 5:").FontSize(12).AlignLeft(); table.Cell().Element(CellStyle).Text("Figure 6:").FontSize(12).AlignLeft(); - table.Cell().Element(CellStyle).Height(150); - table.Cell().Element(CellStyle).Height(150); + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath7) ?? null) // Just pass null if no image + .FitArea(); + table.Cell().Element(CellStyle).Height(150) + .Image(LoadImage(_photoPath8) ?? null) // Just pass null if no image + .FitArea(); table.Cell().Element(CellStyle).Text("Figure 7:").FontSize(12).AlignLeft(); table.Cell().Element(CellStyle).Text("Figure 8:").FontSize(12).AlignLeft(); @@ -302,6 +316,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator { table.ColumnsDefinition(columns => { + //the overall layout of the authorization section columns.RelativeColumn(2); columns.RelativeColumn(1); columns.RelativeColumn(2); @@ -320,8 +335,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator table.Cell().RowSpan(2).Element(CellStyle).Text("CHECKED BY :").Bold().FontSize(12); table.Cell().Element(CellStyle).Text("Signature").FontSize(12); - table.Cell().Element(CellStyle).Text(""); - table.Cell().Element(CellStyle).Text("Date").FontSize(12); + table.Cell().ColumnSpan(2).Element(CellStyle).Text(""); + //table.Cell().Element(CellStyle).Text("Date").FontSize(12); table.Cell().Element(CellStyle).Text(""); table.Cell().Element(CellStyle).Text("Designation").FontSize(12); @@ -329,8 +344,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator table.Cell().RowSpan(2).Element(CellStyle).Text("VERIFIED BY :").Bold().FontSize(12); table.Cell().Element(CellStyle).Text("Signature").FontSize(12); - table.Cell().Element(CellStyle).Text(""); - table.Cell().Element(CellStyle).Text("Date").FontSize(12); + table.Cell().ColumnSpan(2).Element(CellStyle).Text(""); + //table.Cell().Element(CellStyle).Text("Date").FontSize(12); table.Cell().Element(CellStyle).Text(""); table.Cell().Element(CellStyle).Text("Designation").FontSize(12); @@ -341,10 +356,6 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator // Footer Section page.Footer().AlignCenter().Text(text => { - text.Span("Page "); - text.CurrentPageNumber(); - text.Span(" of "); - text.TotalPages(); }); static IContainer CellStyle(IContainer container) => container.Border(0.5f).Padding(5); diff --git a/Models/MarineTarball.cs b/Models/MarineTarball.cs index 87b9c07..bb77c0e 100644 --- a/Models/MarineTarball.cs +++ b/Models/MarineTarball.cs @@ -22,6 +22,10 @@ namespace PSTW_CentralSystem.Models public required string PhotoPath2 { get; set; } // Right Side Coastal View public required string PhotoPath3 { get; set; } // Vertical Lines public required string PhotoPath4 { get; set; } // Horizontal Lines + public required string PhotoPath5 { get; set; } // optional + public required string PhotoPath6 { get; set; } // optional + public required string PhotoPath7 { get; set; } // optional + public required string PhotoPath8 { get; set; } // optional [ForeignKey("StationID")] public required MarineStation MarineStation { get; set; } @@ -48,12 +52,5 @@ namespace PSTW_CentralSystem.Models public required string StateID { get; set; } // Maps to 'stateID' public required string StateName { get; set; } // Maps to 'stateName' } - - public class MarineClassify - { - public int Id { get; set; } // Maps to 'id' - public required string ClassifyID{ get; set; } // Maps to classification ID - public required string ClassifyName { get; set; } // Maps to classification name - } }