This commit is contained in:
misya 2025-05-16 17:30:55 +08:00
parent 6ee24de227
commit 9da24c144a
4 changed files with 135 additions and 48 deletions

View File

@ -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}<br/>{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<string, string>();
@ -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<string>
var imageTypes = new List<string>
{
"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}<br/>{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

View File

@ -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()
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);
});
});

View File

@ -14,6 +14,8 @@ namespace PSTW_CentralSystem.DBContext
public DbSet<MarineTarball> MarineTarballs { get; set; }
public DbSet<MarineStation> MarineStations { get; set; }
public DbSet<State> States { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Level> 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<User>().ToTable("tbl_user");
modelBuilder.Entity<User>(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<Level>().ToTable("tbl_level");
modelBuilder.Entity<Level>(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);
});
}
}
}

View File

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