From 9da24c144ad1796c8a089f569a74e9b68a22104d Mon Sep 17 00:00:00 2001 From: misya Date: Fri, 16 May 2025 17:30:55 +0800 Subject: [PATCH] db conn --- Areas/MMS/Controllers/MarineController.cs | 84 +++++++++++++-------- Areas/MMS/Models/PDFGenerator/TarBallPDF.cs | 37 ++++----- DBContext/MMSSystemContext.cs | 39 ++++++++++ Models/MarineTarball.cs | 23 ++++++ 4 files changed, 135 insertions(+), 48 deletions(-) diff --git a/Areas/MMS/Controllers/MarineController.cs b/Areas/MMS/Controllers/MarineController.cs index 5e9a2dd..f0fb1ae 100644 --- a/Areas/MMS/Controllers/MarineController.cs +++ b/Areas/MMS/Controllers/MarineController.cs @@ -5,6 +5,9 @@ using System.IO; using System.Linq; using PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator; using QuestPDF.Fluent; +using System.Threading.Tasks; +using System.Threading; +using System.Collections.Generic; namespace PSTW_CentralSystem.Areas.MMS.Controllers { @@ -45,9 +48,10 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers } catch (Exception ex) { - Console.WriteLine($"Error: {ex.Message}"); - return StatusCode(500, "An error occurred while loading the data."); + // Show the real error in the browser (for debugging only) + return Content($"Error: {ex.Message}
{ex.StackTrace}", "text/html"); } + } [HttpGet] // Explicitly mark as a GET endpoint @@ -198,6 +202,12 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers return GeneratePdfResponse(id, true); } + public IActionResult DownloadPDF(int id) + { + return GeneratePdfResponse(id, true); + } + + public IActionResult ViewPDF(int id) { try @@ -244,6 +254,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers 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 { @@ -264,7 +276,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers marine.OptionalName2, marine.OptionalName3, marine.OptionalName4, - marine.FirstSampler + marine.FirstSampler, + user.FullName, + user.LevelID, + level.LevelName + }).FirstOrDefault(); if (tarballData == null) @@ -272,6 +288,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers // 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); var stationImages = new Dictionary(); @@ -283,17 +301,18 @@ 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 && - parts[1] == sampleDateString && - (f.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || - f.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) && - IsImageValid(f); + parts[0] == tarballData.StationID && // 1. StationID + parts[1] == sampleDateString && // 2. Date + parts[2].StartsWith(sampleTimePrefix); }) .ToList(); + Console.WriteLine($"Found {allImages.Count} images for {tarballData.StationID} on {sampleDateString} at {sampleTimePrefix}"); + // Define image priority order - var imageTypesInOrder = new List + var imageTypes = new List { "LEFTSIDECOASTALVIEW", "RIGHTSIDECOASTALVIEW", @@ -306,13 +325,16 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers }; // Match images to their types - foreach (var imageType in imageTypesInOrder) + foreach (var imagePath in allImages) { - var matchedImage = allImages.FirstOrDefault(f => - Path.GetFileNameWithoutExtension(f).ToUpper().Contains(imageType)); - if (matchedImage != null) + var fileName = Path.GetFileNameWithoutExtension(imagePath); + foreach (var type in imageTypes) { - stationImages[imageType] = matchedImage; + if (fileName.EndsWith(type, StringComparison.OrdinalIgnoreCase)) + { + stationImages[type] = imagePath; + break; + } } } } @@ -326,11 +348,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers "DRAWINGHORIZONTALLINES" }; - foreach (var mandatoryImage in mandatoryImages) + foreach (var mandatoryType in mandatoryImages) { - if (!stationImages.ContainsKey(mandatoryImage)) + if (!stationImages.ContainsKey(mandatoryType)) { - return StatusCode(400, $"Missing mandatory image: {mandatoryImage}"); + return StatusCode(400, $"Missing mandatory image for {tarballData.StationID} on {tarballData.DateSample:yyyy-MM-dd} at {tarballData.TimeSample}: {mandatoryType}"); } } @@ -349,19 +371,21 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers tarballData.IsSand, tarballData.IsNonSandy, tarballData.IsCoquina, - stationImages.ContainsKey("LEFTSIDECOASTALVIEW") ? stationImages["LEFTSIDECOASTALVIEW"] : null, - stationImages.ContainsKey("RIGHTSIDECOASTALVIEW") ? stationImages["RIGHTSIDECOASTALVIEW"] : null, - stationImages.ContainsKey("DRAWINGVERTICALLINES") ? stationImages["DRAWINGVERTICALLINES"] : null, - stationImages.ContainsKey("DRAWINGHORIZONTALLINES") ? stationImages["DRAWINGHORIZONTALLINES"] : null, - stationImages.ContainsKey("OPTIONAL01") ? stationImages["OPTIONAL01"] : null, - stationImages.ContainsKey("OPTIONAL02") ? stationImages["OPTIONAL02"] : null, - stationImages.ContainsKey("OPTIONAL03") ? stationImages["OPTIONAL03"] : null, - stationImages.ContainsKey("OPTIONAL04") ? stationImages["OPTIONAL04"] : null, + stationImages["LEFTSIDECOASTALVIEW"], + stationImages["RIGHTSIDECOASTALVIEW"], + stationImages["DRAWINGVERTICALLINES"], + stationImages["DRAWINGHORIZONTALLINES"], + stationImages.GetValueOrDefault("OPTIONAL01"), + stationImages.GetValueOrDefault("OPTIONAL02"), + stationImages.GetValueOrDefault("OPTIONAL03"), + stationImages.GetValueOrDefault("OPTIONAL04"), tarballData.OptionalName1, tarballData.OptionalName2, tarballData.OptionalName3, tarballData.OptionalName4, - tarballData.FirstSampler + tarballData.FirstSampler, + tarballData.FullName, + tarballData.LevelName ).GeneratePdf(); // 4. Return file @@ -371,13 +395,12 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers } catch (Exception ex) { - Console.WriteLine($"Error: {ex}"); - // Include inner exception if available - string errorMessage = ex.InnerException != null + var errorMessage = ex.InnerException != null ? $"{ex.Message} (Inner: {ex.InnerException.Message})" : ex.Message; - return StatusCode(500, $"PDF generation failed: {errorMessage}"); + return Content($"PDF generation failed: {errorMessage}
{ex.StackTrace}", "text/html"); } + finally { // Disconnect from the network path @@ -385,7 +408,6 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers } } - private bool IsImageValid(string imagePath) { try diff --git a/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs b/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs index 4c941f0..6997236 100644 --- a/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs +++ b/Areas/MMS/Models/PDFGenerator/TarBallPDF.cs @@ -3,6 +3,7 @@ using QuestPDF.Infrastructure; using QuestPDF.Helpers; using Google.Protobuf.WellKnownTypes; using PSTW_CentralSystem.Models; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator { @@ -12,7 +13,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator bool isCoquina, string photoPath1, string photoPath2, string photoPath3, string photoPath4, string photoPath5, string photoPath6, string photoPath7, string photoPath8, string optionalName1, string optionalName2, string optionalName3, string optionalName4, - string firstSampler + string firstSampler, string fullName, string levelName ) : IDocument { @@ -42,6 +43,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator private readonly string? _optionalName3 = optionalName3; private readonly string? _optionalName4 = optionalName4; private readonly string _firstSampler = firstSampler; + private readonly string _fullName = fullName; + private readonly string _levelName = levelName; private Image? LoadImage(string? imagePath) { @@ -81,14 +84,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator //will be included in each page page.Header().Row(row => { - row.RelativeItem(1).Element(CellStyle).Column(column => - { - column.Item() - .AlignMiddle() - .AlignCenter() - .Image("wwwroot/assets/images/pstw-logo.jpg") - .FitArea(); - }); + row.RelativeItem(1).Element(CellStyle) + .AlignMiddle() + .AlignCenter() + .Image("wwwroot/assets/images/pstw-logo.jpg") + .FitArea(); row.RelativeItem(1).Element(CellStyle) .AlignMiddle() @@ -338,7 +338,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator .Text(text => { text.Span("REPORTED BY: ").Bold().FontSize(12); - text.Span(_firstSampler).FontSize(10); + text.Span(_firstSampler).FontSize(12); }); table.Cell().Element(CellStyle).Text("Signature").FontSize(12); table.Cell().Element(CellStyle).Text(""); @@ -346,30 +346,33 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator table.Cell().Element(CellStyle).Text(""); table.Cell().Element(CellStyle).Text("Designation").FontSize(12); - table.Cell().ColumnSpan(3).Element(CellStyle).Text(""); + table.Cell().ColumnSpan(3).Element(CellStyle).Text(_levelName); table.Cell().RowSpan(2).Element(CellStyle) .Text(text => { text.Span("CHECKED BY: ").Bold().FontSize(12); - text.Span("***RIFAIE AZHARI").FontSize(10); + text.Span("RIFAIE AZHARI").FontSize(12); }); table.Cell().Element(CellStyle).Text("Signature").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); - table.Cell().ColumnSpan(3).Element(CellStyle).Text(""); + table.Cell().ColumnSpan(3).Element(CellStyle).Text("Executive").FontSize(12); - table.Cell().RowSpan(2).Element(CellStyle).Text("VERIFIED BY :").Bold().FontSize(12); + table.Cell().RowSpan(2).Element(CellStyle) + .Text(text => + { + text.Span("VERIFIED BY: ").Bold().FontSize(12); + text.Span("J SOMU").FontSize(12); + }); table.Cell().Element(CellStyle).Text("Signature").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); - table.Cell().ColumnSpan(3).Element(CellStyle).Text(""); + table.Cell().ColumnSpan(3).Element(CellStyle).Text("Technical Manager").FontSize(12); }); }); diff --git a/DBContext/MMSSystemContext.cs b/DBContext/MMSSystemContext.cs index 1310ea8..b512d52 100644 --- a/DBContext/MMSSystemContext.cs +++ b/DBContext/MMSSystemContext.cs @@ -14,6 +14,8 @@ namespace PSTW_CentralSystem.DBContext public DbSet MarineTarballs { get; set; } public DbSet MarineStations { get; set; } public DbSet States { get; set; } + public DbSet Users { get; set; } + public DbSet Levels { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -49,6 +51,14 @@ namespace PSTW_CentralSystem.DBContext .WithMany() .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 @@ -82,6 +92,35 @@ 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_user"); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id); // Primary key + entity.Property(e => e.Id).HasColumnName("id"); + entity.Property(e => e.UserID).HasColumnName("userID").HasMaxLength(20); + entity.Property(e => e.FullName).HasColumnName("fullname").HasMaxLength(50); + entity.Property(e => e.Username).HasColumnName("username").HasMaxLength(40); + entity.Property(e => e.Password).HasColumnName("pwd").HasMaxLength(100); + entity.Property(e => e.LevelID).HasColumnName("levelID").HasMaxLength(10); + entity.Property(e => e.DeptID).HasColumnName("departID").HasMaxLength(10); + + entity.HasOne(u => u.Level) + .WithMany() + .HasForeignKey(u => u.LevelID) + .HasPrincipalKey(c => c.LevelID); + }); + + modelBuilder.Entity().ToTable("tbl_level"); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id); // Primary key + entity.Property(e => e.Id).HasColumnName("id"); + entity.Property(e => e.LevelID).HasColumnName("levelID").HasMaxLength(10); + entity.Property(e => e.LevelName).HasColumnName("levelName").HasMaxLength(10); + }); } } } diff --git a/Models/MarineTarball.cs b/Models/MarineTarball.cs index 0aca079..fd55026 100644 --- a/Models/MarineTarball.cs +++ b/Models/MarineTarball.cs @@ -33,6 +33,8 @@ namespace PSTW_CentralSystem.Models [ForeignKey("StationID")] public required MarineStation MarineStation { get; set; } + [ForeignKey("FirstSampler")] + public required MarineStation User { get; set; } } public class MarineStation @@ -56,5 +58,26 @@ namespace PSTW_CentralSystem.Models public required string StateID { get; set; } // Maps to 'stateID' public required string StateName { get; set; } // Maps to 'stateName' } + + public class User + { + public int Id { get; set; } // Maps to 'id' + public required string UserID { get; set; } // Maps to 'userID' + public required string FullName { get; set; } // Maps to 'fullname' + public required string Username { get; set; } // Maps to 'username' + public required string Password { get; set; } // Maps to 'pwd' + public required string LevelID { get; set; } // Maps to 'levelID' + public required string DeptID { get; set; } // Maps to 'deptID' + + [ForeignKey("LevelID")] + public required Level Level { get; set; } // Maps to 'levelID' + } + + public class Level + { + public int Id { get; set; } // Maps to 'id' + public required string LevelID { get; set; } // Maps to 'levelID' + public required string LevelName { get; set; } // Maps to 'levelName' + } }