table link
This commit is contained in:
parent
9da24c144a
commit
00660345fc
@ -8,9 +8,34 @@ using QuestPDF.Fluent;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
||||||
{
|
{
|
||||||
|
public class SimpleTarballDto
|
||||||
|
{
|
||||||
|
// From tbl_marine_tarball
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string StationID { get; set; }
|
||||||
|
public string Longitude { get; set; }
|
||||||
|
public string Latitude { get; set; }
|
||||||
|
public DateTime DateSample { get; set; }
|
||||||
|
public TimeSpan TimeSample { get; set; }
|
||||||
|
public string ClassifyID { get; set; }
|
||||||
|
public string OptionalName1 { get; set; }
|
||||||
|
public string OptionalName2 { get; set; }
|
||||||
|
public string OptionalName3 { get; set; }
|
||||||
|
public string OptionalName4 { get; set; }
|
||||||
|
public string FirstSampler { get; set; }
|
||||||
|
|
||||||
|
// From joined tables
|
||||||
|
public string LocationName { get; set; } // From tbl_marine_station
|
||||||
|
public string StateName { get; set; } // From tbl_state
|
||||||
|
public string FullName { get; set; } // From tbl_user
|
||||||
|
public string LevelName { get; set; } // From tbl_level
|
||||||
|
}
|
||||||
|
|
||||||
[Area("MMS")]
|
[Area("MMS")]
|
||||||
public class MarineController : Controller
|
public class MarineController : Controller
|
||||||
{
|
{
|
||||||
@ -33,7 +58,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var marineTarballs = _context.MarineTarballs
|
var marineTarballs = _context.MarineTarballs //error===========================================
|
||||||
.Where(t => t.StationID != "1") // To remove unusable data with invalid stationID
|
.Where(t => t.StationID != "1") // To remove unusable data with invalid stationID
|
||||||
.Select(t => new
|
.Select(t => new
|
||||||
{
|
{
|
||||||
@ -197,14 +222,14 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult GenerateReport(int id)//calls GeneratePdfResponse to generate a PDF for inline viewing
|
public async Task<IActionResult> GenerateReport(int id)//calls GeneratePdfResponse to generate a PDF for inline viewing
|
||||||
{
|
{
|
||||||
return GeneratePdfResponse(id, true);
|
return await GeneratePdfResponse(id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult DownloadPDF(int id)
|
public async Task<IActionResult> DownloadPDF(int id)
|
||||||
{
|
{
|
||||||
return GeneratePdfResponse(id, true);
|
return await GeneratePdfResponse(id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -227,11 +252,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IActionResult GeneratePdfResponse(int id, bool forceDownload)
|
private async Task<IActionResult> GeneratePdfResponse(int id, bool forceDownload)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Requested ID in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {id}");
|
Console.WriteLine($"Requested ID in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {id}");
|
||||||
|
|
||||||
// Add this temporary check at the start of GeneratePdfResponse
|
// Temporary network connection test
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Console.WriteLine("Testing network connection...");
|
Console.WriteLine("Testing network connection...");
|
||||||
@ -248,49 +273,38 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Connect to the network path
|
// Connect to the network path
|
||||||
_networkAccessService.ConnectToNetworkPath();//------------------
|
_networkAccessService.ConnectToNetworkPath();
|
||||||
|
|
||||||
// 1. Fetch core data from database
|
// ===== 1. NEW SQL QUERY APPROACH =====
|
||||||
var tarballData = (from marine in _context.MarineTarballs
|
var query = @"
|
||||||
join station in _context.MarineStations on marine.StationID equals station.StationID
|
SELECT
|
||||||
join state in _context.States on station.StateID equals state.StateID
|
marine.*, station.LocationName, state.StateName,user.FullName,level.LevelName
|
||||||
join user in _context.Users on marine.FirstSampler equals user.FullName
|
FROM tbl_marine_tarball marine
|
||||||
join level in _context.Levels on user.LevelID equals level.LevelID
|
JOIN tbl_marine_station station ON marine.StationID = station.StationID
|
||||||
where marine.Id == id
|
JOIN tbl_state state ON station.StateID = state.StateID
|
||||||
select new
|
JOIN tbl_user user ON marine.FirstSampler = user.FullName -- Corrected column name
|
||||||
{
|
JOIN tbl_level level ON user.LevelID = level.LevelID
|
||||||
state.StateName,
|
WHERE marine.Id = @id";
|
||||||
marine.StationID,
|
|
||||||
station.LocationName,
|
|
||||||
marine.Longitude,
|
|
||||||
marine.Latitude,
|
|
||||||
marine.DateSample,
|
|
||||||
marine.TimeSample,
|
|
||||||
marine.ClassifyID,
|
|
||||||
TarBallYes = marine.ClassifyID != "NO",
|
|
||||||
TarBallNo = marine.ClassifyID == "NO",
|
|
||||||
IsSand = marine.ClassifyID == "SD",
|
|
||||||
IsNonSandy = marine.ClassifyID == "NS",
|
|
||||||
IsCoquina = marine.ClassifyID == "CO",
|
|
||||||
marine.OptionalName1,
|
|
||||||
marine.OptionalName2,
|
|
||||||
marine.OptionalName3,
|
|
||||||
marine.OptionalName4,
|
|
||||||
marine.FirstSampler,
|
|
||||||
user.FullName,
|
|
||||||
user.LevelID,
|
|
||||||
level.LevelName
|
|
||||||
|
|
||||||
}).FirstOrDefault();
|
var tarball = await _context.Database
|
||||||
|
.SqlQueryRaw<TarballPdfDto>(query, new SqlParameter("@id", id))
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
if (tarballData == null)
|
if (tarball == null)
|
||||||
return NotFound("Record not found");
|
return NotFound("Record not found");
|
||||||
|
|
||||||
// 2. Get photos from station folder (with date matching)
|
//Prepare boolean values for PDF
|
||||||
var sampleDateString = tarballData.DateSample.ToString("yyyyMMdd");
|
bool tarBallYes = tarball.ClassifyID != "NO";
|
||||||
var sampleTimePrefix = ((int)tarballData.TimeSample.TotalHours).ToString("D2") +
|
bool tarBallNo = tarball.ClassifyID == "NO";
|
||||||
tarballData.TimeSample.Minutes.ToString("D2");
|
bool isSand = tarball.ClassifyID == "SD";
|
||||||
var stationFolder = Path.Combine(PhotoBasePath, tarballData.StationID);
|
bool isNonSandy = tarball.ClassifyID == "NS";
|
||||||
|
bool isCoquina = tarball.ClassifyID == "CO";
|
||||||
|
|
||||||
|
// ===== 2. Get Images from path =====
|
||||||
|
var sampleDateString = tarball.DateSample.ToString("yyyyMMdd");
|
||||||
|
var sampleTimePrefix = ((int)tarball.TimeSample.TotalHours).ToString("D2") +
|
||||||
|
tarball.TimeSample.Minutes.ToString("D2");
|
||||||
|
var stationFolder = Path.Combine(PhotoBasePath, tarball.StationID);
|
||||||
var stationImages = new Dictionary<string, string>();
|
var stationImages = new Dictionary<string, string>();
|
||||||
|
|
||||||
if (Directory.Exists(stationFolder))
|
if (Directory.Exists(stationFolder))
|
||||||
@ -300,18 +314,13 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
{
|
{
|
||||||
var fileName = Path.GetFileNameWithoutExtension(f);
|
var fileName = Path.GetFileNameWithoutExtension(f);
|
||||||
var parts = fileName.Split('_');
|
var parts = fileName.Split('_');
|
||||||
|
|
||||||
//Match: StationID_Date_*
|
|
||||||
return parts.Length >= 3 &&
|
return parts.Length >= 3 &&
|
||||||
parts[0] == tarballData.StationID && // 1. StationID
|
parts[0] == tarball.StationID &&
|
||||||
parts[1] == sampleDateString && // 2. Date
|
parts[1] == sampleDateString &&
|
||||||
parts[2].StartsWith(sampleTimePrefix);
|
parts[2].StartsWith(sampleTimePrefix);
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
Console.WriteLine($"Found {allImages.Count} images for {tarballData.StationID} on {sampleDateString} at {sampleTimePrefix}");
|
|
||||||
|
|
||||||
// Define image priority order
|
|
||||||
var imageTypes = new List<string>
|
var imageTypes = new List<string>
|
||||||
{
|
{
|
||||||
"LEFTSIDECOASTALVIEW",
|
"LEFTSIDECOASTALVIEW",
|
||||||
@ -324,13 +333,12 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
"OPTIONAL04"
|
"OPTIONAL04"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Match images to their types
|
|
||||||
foreach (var imagePath in allImages)
|
foreach (var imagePath in allImages)
|
||||||
{
|
{
|
||||||
var fileName = Path.GetFileNameWithoutExtension(imagePath);
|
var fileName = Path.GetFileNameWithoutExtension(imagePath);
|
||||||
foreach (var type in imageTypes)
|
foreach(var type in imageTypes)
|
||||||
{
|
{
|
||||||
if (fileName.EndsWith(type, StringComparison.OrdinalIgnoreCase))
|
if(fileName.EndsWith(type,StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
stationImages[type] = imagePath;
|
stationImages[type] = imagePath;
|
||||||
break;
|
break;
|
||||||
@ -339,7 +347,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate mandatory images
|
//Mandatory images
|
||||||
var mandatoryImages = new List<string>
|
var mandatoryImages = new List<string>
|
||||||
{
|
{
|
||||||
"LEFTSIDECOASTALVIEW",
|
"LEFTSIDECOASTALVIEW",
|
||||||
@ -348,29 +356,29 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
"DRAWINGHORIZONTALLINES"
|
"DRAWINGHORIZONTALLINES"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var mandatoryType in mandatoryImages)
|
foreach(var mandatoryType in mandatoryImages)
|
||||||
{
|
{
|
||||||
if (!stationImages.ContainsKey(mandatoryType))
|
if(!stationImages.ContainsKey(mandatoryType))
|
||||||
{
|
{
|
||||||
return StatusCode(400, $"Missing mandatory image for {tarballData.StationID} on {tarballData.DateSample:yyyy-MM-dd} at {tarballData.TimeSample}: {mandatoryType}");
|
return StatusCode(400, $"Missing mandatory image: {mandatoryType}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Generate PDF
|
// ===== 3. GENERATE PDF (ADAPTED FOR NEW DTO) =====
|
||||||
var pdf = new TarBallPDF(
|
var pdf = new TarBallPDF(
|
||||||
tarballData.StateName,
|
tarball.StateName,
|
||||||
tarballData.StationID,
|
tarball.StationID,
|
||||||
tarballData.LocationName,
|
tarball.LocationName,
|
||||||
tarballData.Longitude,
|
tarball.Longitude,
|
||||||
tarballData.Latitude,
|
tarball.Latitude,
|
||||||
tarballData.DateSample,
|
tarball.DateSample,
|
||||||
tarballData.TimeSample,
|
tarball.TimeSample,
|
||||||
tarballData.ClassifyID,
|
tarball.ClassifyID,
|
||||||
tarballData.TarBallYes,
|
tarBallYes,
|
||||||
tarballData.TarBallNo,
|
tarBallNo,
|
||||||
tarballData.IsSand,
|
isSand,
|
||||||
tarballData.IsNonSandy,
|
isNonSandy,
|
||||||
tarballData.IsCoquina,
|
isCoquina,
|
||||||
stationImages["LEFTSIDECOASTALVIEW"],
|
stationImages["LEFTSIDECOASTALVIEW"],
|
||||||
stationImages["RIGHTSIDECOASTALVIEW"],
|
stationImages["RIGHTSIDECOASTALVIEW"],
|
||||||
stationImages["DRAWINGVERTICALLINES"],
|
stationImages["DRAWINGVERTICALLINES"],
|
||||||
@ -379,18 +387,17 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
stationImages.GetValueOrDefault("OPTIONAL02"),
|
stationImages.GetValueOrDefault("OPTIONAL02"),
|
||||||
stationImages.GetValueOrDefault("OPTIONAL03"),
|
stationImages.GetValueOrDefault("OPTIONAL03"),
|
||||||
stationImages.GetValueOrDefault("OPTIONAL04"),
|
stationImages.GetValueOrDefault("OPTIONAL04"),
|
||||||
tarballData.OptionalName1,
|
tarball.OptionalName1,
|
||||||
tarballData.OptionalName2,
|
tarball.OptionalName2,
|
||||||
tarballData.OptionalName3,
|
tarball.OptionalName3,
|
||||||
tarballData.OptionalName4,
|
tarball.OptionalName4,
|
||||||
tarballData.FirstSampler,
|
tarball.FirstSampler,
|
||||||
tarballData.FullName,
|
tarball.FullName,
|
||||||
tarballData.LevelName
|
tarball.LevelName
|
||||||
).GeneratePdf();
|
).GeneratePdf();
|
||||||
|
|
||||||
// 4. Return file
|
|
||||||
return forceDownload
|
return forceDownload
|
||||||
? File(pdf, "application/pdf", $"TbReport_{tarballData.StationID}_{tarballData.DateSample:yyyyMMdd}.pdf")
|
? File(pdf, "application/pdf", $"TbReport_{tarball.StationID}_{tarball.DateSample:yyyyMMdd}.pdf")
|
||||||
: File(pdf, "application/pdf");
|
: File(pdf, "application/pdf");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -400,14 +407,37 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
: ex.Message;
|
: ex.Message;
|
||||||
return Content($"PDF generation failed: {errorMessage}<br/>{ex.StackTrace}", "text/html");
|
return Content($"PDF generation failed: {errorMessage}<br/>{ex.StackTrace}", "text/html");
|
||||||
}
|
}
|
||||||
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Disconnect from the network path
|
|
||||||
_networkAccessService.DisconnectFromNetworkShare();
|
_networkAccessService.DisconnectFromNetworkShare();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add this class outside your controller (e.g., in a DTOs folder)
|
||||||
|
public class TarballPdfDto
|
||||||
|
{
|
||||||
|
public string StateName { get; set; }
|
||||||
|
public string StationID { get; set; }
|
||||||
|
public string LocationName { get; set; }
|
||||||
|
public string Longitude { get; set; }
|
||||||
|
public string Latitude { get; set; }
|
||||||
|
public DateTime DateSample { get; set; }
|
||||||
|
public TimeSpan TimeSample { get; set; }
|
||||||
|
public string ClassifyID { get; set; }
|
||||||
|
public int TarBallYes { get; set; } // SQL returns 1/0 for bits
|
||||||
|
public int TarBallNo { get; set; }
|
||||||
|
public int IsSand { get; set; }
|
||||||
|
public int IsNonSandy { get; set; }
|
||||||
|
public int IsCoquina { get; set; }
|
||||||
|
public string OptionalName1 { get; set; }
|
||||||
|
public string OptionalName2 { get; set; }
|
||||||
|
public string OptionalName3 { get; set; }
|
||||||
|
public string OptionalName4 { get; set; }
|
||||||
|
public string FirstSampler { get; set; }
|
||||||
|
public string FullName { get; set; }
|
||||||
|
public string LevelName { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsImageValid(string imagePath)
|
private bool IsImageValid(string imagePath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
using PSTW_CentralSystem.Models; // Add this to use the MarineTarball class
|
using PSTW_CentralSystem.Models; // Add this to use the MarineTarball class
|
||||||
|
|
||||||
@ -21,12 +22,11 @@ namespace PSTW_CentralSystem.DBContext
|
|||||||
{
|
{
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
|
|
||||||
// Map MarineTarball to tbl_marine_tarball
|
|
||||||
modelBuilder.Entity<MarineTarball>().ToTable("tbl_marine_tarball");
|
|
||||||
|
|
||||||
// Configure properties if needed
|
// Configure properties if needed
|
||||||
modelBuilder.Entity<MarineTarball>(entity =>
|
modelBuilder.Entity<MarineTarball>(entity =>
|
||||||
{
|
{
|
||||||
|
entity.ToTable("tbl_marine_tarball");
|
||||||
|
|
||||||
entity.HasKey(e => e.Id); // Primary key
|
entity.HasKey(e => e.Id); // Primary key
|
||||||
entity.Property(e => e.Id).HasColumnName("id");
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
entity.Property(e => e.ReportID).HasColumnName("reportID").HasMaxLength(50);
|
entity.Property(e => e.ReportID).HasColumnName("reportID").HasMaxLength(50);
|
||||||
@ -52,20 +52,11 @@ namespace PSTW_CentralSystem.DBContext
|
|||||||
.HasForeignKey(m => m.StationID)
|
.HasForeignKey(m => m.StationID)
|
||||||
.HasPrincipalKey(t => t.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
|
|
||||||
modelBuilder.Entity<MarineStation>().ToTable("tbl_marine_station");
|
|
||||||
|
|
||||||
modelBuilder.Entity<MarineStation>(entity =>
|
modelBuilder.Entity<MarineStation>(entity =>
|
||||||
{
|
{
|
||||||
|
entity.ToTable("tbl_marine_station");
|
||||||
entity.HasKey(e => e.Id); // Primary key
|
entity.HasKey(e => e.Id); // Primary key
|
||||||
entity.Property(e => e.Id).HasColumnName("id");
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
entity.Property(e => e.StationID).HasColumnName("stationID").HasMaxLength(20);
|
entity.Property(e => e.StationID).HasColumnName("stationID").HasMaxLength(20);
|
||||||
@ -82,21 +73,18 @@ namespace PSTW_CentralSystem.DBContext
|
|||||||
.HasPrincipalKey(s => s.StateID);
|
.HasPrincipalKey(s => s.StateID);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Map State to tbl_state
|
|
||||||
modelBuilder.Entity<State>().ToTable("tbl_state");
|
|
||||||
|
|
||||||
modelBuilder.Entity<State>(entity =>
|
modelBuilder.Entity<State>(entity =>
|
||||||
{
|
{
|
||||||
|
entity.ToTable("tbl_state");
|
||||||
entity.HasKey(e => e.Id); // Primary key
|
entity.HasKey(e => e.Id); // Primary key
|
||||||
entity.Property(e => e.Id).HasColumnName("id");
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
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<User>().ToTable("tbl_user");
|
|
||||||
|
|
||||||
modelBuilder.Entity<User>(entity =>
|
modelBuilder.Entity<User>(entity =>
|
||||||
{
|
{
|
||||||
|
entity.ToTable("tbl_user");
|
||||||
entity.HasKey(e => e.Id); // Primary key
|
entity.HasKey(e => e.Id); // Primary key
|
||||||
entity.Property(e => e.Id).HasColumnName("id");
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
entity.Property(e => e.UserID).HasColumnName("userID").HasMaxLength(20);
|
entity.Property(e => e.UserID).HasColumnName("userID").HasMaxLength(20);
|
||||||
@ -109,7 +97,7 @@ namespace PSTW_CentralSystem.DBContext
|
|||||||
entity.HasOne(u => u.Level)
|
entity.HasOne(u => u.Level)
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey(u => u.LevelID)
|
.HasForeignKey(u => u.LevelID)
|
||||||
.HasPrincipalKey(c => c.LevelID);
|
.HasPrincipalKey(l => l.LevelID);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<Level>().ToTable("tbl_level");
|
modelBuilder.Entity<Level>().ToTable("tbl_level");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user