generate section survey finding (tick checkboxes). images need improving

This commit is contained in:
misya 2025-04-22 16:30:41 +08:00
parent c7b398374e
commit ba48e513df
4 changed files with 152 additions and 107 deletions

View File

@ -8,6 +8,7 @@ using System.Linq;
using QuestPDF.Fluent; using QuestPDF.Fluent;
using PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator; using PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator;
using System.Globalization; using System.Globalization;
using System.IO;
namespace PSTW_CentralSystem.Areas.MMS.Controllers namespace PSTW_CentralSystem.Areas.MMS.Controllers
{ {
@ -16,27 +17,26 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
public class MarineController(MMSSystemContext context) : Controller public class MarineController(MMSSystemContext context) : Controller
{ {
private readonly MMSSystemContext _context = context; private readonly MMSSystemContext _context = context;
private const string PhotoBasePath = @"\\192.168.12.42\images\marine\manual_tarball";
public IActionResult Index() 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() public IActionResult TarBallForm()
{ {
var marineTarballs = _context.MarineTarballs var marineTarballs = _context.MarineTarballs
.Where(t=>t.StationID != "1") //Exclude test data with station named "1" .Where(t => t.StationID != "1")
.Select(t => new .Select(t => new
{ {
t.Id, // Include Id property t.Id,
Date = t.DateSample.ToString("yyyy/MM/dd"), // Format DateSample as needed Date = t.DateSample.ToString("yyyy/MM/dd"),
Station = t.StationID Station = t.StationID
}) })
.ToList(); .ToList();
// For debugging // Debugging
Console.WriteLine("Fetched Data:");
foreach (var item in marineTarballs) foreach (var item in marineTarballs)
{ {
Console.WriteLine($"Date: {item.Date}, Station: {item.Station}"); Console.WriteLine($"Date: {item.Date}, Station: {item.Station}");
@ -45,65 +45,19 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
return View(marineTarballs); return View(marineTarballs);
} }
//what to do for generating report
public IActionResult GenerateReport(int id) public IActionResult GenerateReport(int id)
{ {
Console.WriteLine($"Requested ID in GenerateReport: {id}"); return GeneratePdfResponse(id, true);
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);
}
} }
public IActionResult ViewPDF(int id) 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 try
{ {
@ -121,7 +75,13 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
marine.Longitude, marine.Longitude,
marine.Latitude, marine.Latitude,
marine.DateSample, 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(); }).FirstOrDefault();
if (tarballData == null) if (tarballData == null)
@ -129,29 +89,69 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
return NotFound("The specified record was not found."); 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 pdfDocument = new TarBallPDF(
var document = new TarBallPDF(
tarballData.StateName, tarballData.StateName,
tarballData.StationID, tarballData.StationID,
tarballData.LocationName, tarballData.LocationName,
tarballData.Longitude, tarballData.Longitude,
tarballData.Latitude, tarballData.Latitude,
tarballData.DateSample, 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"); return File(pdf, "application/pdf");
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"Error in ViewPDF: {ex.Message}"); Console.WriteLine($"Error in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {ex.Message}");
return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while viewing the PDF. " + 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;
} }
} }
} }
} }

View File

@ -6,7 +6,11 @@ using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator 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 _stationId = stationID;
private readonly string _stateName = stateName; private readonly string _stateName = stateName;
@ -15,12 +19,31 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
private readonly string _latitude = latitude; private readonly string _latitude = latitude;
private readonly DateTime _dateSample = dateSample; private readonly DateTime _dateSample = dateSample;
private readonly TimeSpan _timeSample = timeSample; 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 // Metadata for the PDF document
public DocumentMetadata GetMetadata() => new() public DocumentMetadata GetMetadata() => new()
{ {
Title = "TarBall Sampling Form", Title = "TARBALL SAMPLING FORM",
Author = "PAKAR SCIENO TW Integrated Environmental Solutions", Author = "PAKAR SCIENO TW Integrated Environmental Solutions",
Subject = "Environmental Survey and Observations" Subject = "Environmental Survey and Observations"
}; };
@ -134,24 +157,41 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
column.Spacing(3); column.Spacing(3);
// Survey Findings // Survey Findings - ALWAYS shows all options
column.Item() column.Item()
.PaddingTop(10) .PaddingTop(10)
.PaddingBottom(10) .PaddingBottom(10)
.Text("SURVEY FINDING:") .Text("SURVEY FINDING:")
.Bold().FontSize(12); .Bold().FontSize(12);
// 1. Tar Ball YES/NO (always shown)
column.Item() column.Item()
.PaddingBottom(10) .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() column.Item()
.PaddingBottom(10) .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() column.Item()
.PaddingBottom(10) .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() column.Item()
.PaddingBottom(10) .PaddingBottom(10)
.Text("*tick wherever applicable"); .Text("*tick wherever applicable")
.Italic();
// Photos Section Title // Photos Section Title
column.Item() column.Item()
@ -161,7 +201,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
.Bold() .Bold()
.FontSize(14); .FontSize(14);
// Table for Photos // Photos Section
column.Item().Table(table => column.Item().Table(table =>
{ {
column.Spacing(0); column.Spacing(0);
@ -172,17 +212,37 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
columns.RelativeColumn(1); columns.RelativeColumn(1);
}); });
table.Cell().Element(CellStyle).Height(150); // Row 1: Photos
table.Cell().Element(CellStyle).Height(150); 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).Height(150)
table.Cell().Element(CellStyle).Text("Figure 2: Right Side Coastal View").FontSize(12).AlignLeft(); .Image(LoadImage(_photoPath2)); // Right Side View photo space
table.Cell().Element(CellStyle).Height(150); // Row 1: Captions
table.Cell().Element(CellStyle).Height(150); 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)
table.Cell().Element(CellStyle).Text("Figure 4: Drawing Horizontal Lines (Racking)").FontSize(12).AlignLeft(); .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 // Page Break
@ -217,6 +277,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
.PaddingTop(10) .PaddingTop(10)
.PaddingBottom(20) .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)") .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) .FontSize(10)
.AlignLeft(); .AlignLeft();

View File

@ -14,7 +14,6 @@ namespace PSTW_CentralSystem.DBContext
public DbSet<MarineTarball> MarineTarballs { get; set; } public DbSet<MarineTarball> MarineTarballs { get; set; }
public DbSet<MarineStation> MarineStations { get; set; } public DbSet<MarineStation> MarineStations { get; set; }
public DbSet<State> States { get; set; } public DbSet<State> States { get; set; }
public DbSet<MarineClassify> ClassifyID { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
@ -46,12 +45,6 @@ namespace PSTW_CentralSystem.DBContext
.WithMany() .WithMany()
.HasForeignKey(m => m.StationID) .HasForeignKey(m => m.StationID)
.HasPrincipalKey(t => t.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 // 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.StateID).HasColumnName("stateID").HasMaxLength(20);
entity.Property(e => e.StateName).HasColumnName("stateName").HasMaxLength(50); entity.Property(e => e.StateName).HasColumnName("stateName").HasMaxLength(50);
}); });
modelBuilder.Entity<MarineClassify>().ToTable("tbl_classify");
modelBuilder.Entity<MarineClassify>(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);
});
} }
} }
} }

View File

@ -18,11 +18,13 @@ namespace PSTW_CentralSystem.Models
public double GetLongitude { get; set; } // Maps to 'getLongitude' public double GetLongitude { get; set; } // Maps to 'getLongitude'
public DateTime Timestamp { get; set; } // Maps to 'timestamp' 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")] [ForeignKey("StationID")]
public required MarineStation MarineStation { get; set; } public required MarineStation MarineStation { get; set; }
[ForeignKey("ClassifyID")]
public required MarineClassify MarineClassify { get; set; }
} }
public class MarineStation public class MarineStation