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'
+ }
}