eSPJ/Services/DetailPenjemputanJGCService.cs

222 lines
9.6 KiB
C#

using eSPJ.Models;
namespace eSPJ.Services
{
public class DetailPenjemputanJGCService
{
private readonly IDetailPenjemputanStore _store;
private readonly IWebHostEnvironment _env;
private readonly ILogger<DetailPenjemputanJGCService> _logger;
public DetailPenjemputanJGCService(
IWebHostEnvironment env,
IDetailPenjemputanStore store,
ILogger<DetailPenjemputanJGCService> logger)
{
_env = env;
_store = store;
_logger = logger;
}
private static string SanitizePathSegment(string? value, string fallback = "jgc")
{
var safe = string.Concat((value ?? string.Empty).Trim().Select(c =>
char.IsLetterOrDigit(c) || c == '-' || c == '_'
? c
: '-'));
while (safe.Contains("--"))
{
safe = safe.Replace("--", "-");
}
safe = safe.Trim('-');
return string.IsNullOrWhiteSpace(safe) ? fallback : safe;
}
public async Task<DetailPenjemputanResponse> SubmitPenjemputanAsync(DetailPenjemputanRequest request)
{
try
{
if (string.IsNullOrEmpty(request.TpsName))
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Nama TPS harus diisi"
};
}
if (string.IsNullOrEmpty(request.NamaPetugas))
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Nama petugas harus diisi"
};
}
var existingRecord = await GetRecordDetailAsync(request.NomorSpj, request.SpjDetailId, request.LokasiAngkutId, request.TpsName);
var now = DateTime.Now;
var datePart = now.ToString("yyyy-MM-dd");
var spjFolder = SanitizePathSegment(request.NomorSpj, "spj-jgc");
var tpsFolder = SanitizePathSegment(request.TpsName, "tps-jgc");
var uploadPath = Path.Combine(_env.ContentRootPath, "uploads", "penjemputan", datePart, spjFolder, tpsFolder);
var uploadBaseUrl = $"/uploads/penjemputan/{datePart}/{spjFolder}/{tpsFolder}";
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
var tpsData = existingRecord != null
? CloneRecord(existingRecord)
: new TpsData();
tpsData.NomorSpj = request.NomorSpj;
tpsData.LokasiAngkutId = request.LokasiAngkutId;
tpsData.SpjDetailId = request.SpjDetailId;
tpsData.Name = request.TpsName;
tpsData.Latitude = request.Latitude;
tpsData.Longitude = request.Longitude;
tpsData.AlamatJalan = request.AlamatJalan;
tpsData.WaktuKedatangan = request.WaktuKedatangan;
tpsData.NamaPetugas = request.NamaPetugas;
tpsData.IsSubmit = true;
tpsData.SubmittedAt ??= DateTime.Now;
tpsData.UpdatedAt = DateTime.Now;
if (request.FotoKedatangan != null && request.FotoKedatangan.Any())
{
tpsData.FotoKedatangan = new List<string>();
foreach (var file in request.FotoKedatangan)
{
var fileName = $"kedatangan_{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
var filePath = Path.Combine(uploadPath, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
tpsData.FotoKedatangan.Add($"{uploadBaseUrl}/{fileName}");
}
tpsData.FotoKedatanganUploaded = tpsData.FotoKedatangan.Count > 0;
}
else if (existingRecord?.FotoKedatangan?.Any() == true)
{
tpsData.FotoKedatangan = new List<string>(existingRecord.FotoKedatangan);
tpsData.FotoKedatanganUploaded = existingRecord.FotoKedatanganUploaded || tpsData.FotoKedatangan.Count > 0;
}
else
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Foto kedatangan harus diupload"
};
}
if (request.FotoPetugas != null && request.FotoPetugas.Any())
{
tpsData.FotoPetugas = new List<string>();
foreach (var file in request.FotoPetugas)
{
var fileName = $"petugas_{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
var filePath = Path.Combine(uploadPath, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
tpsData.FotoPetugas.Add($"{uploadBaseUrl}/{fileName}");
}
tpsData.FotoPetugasUploaded = tpsData.FotoPetugas.Count > 0;
}
else if (existingRecord?.FotoPetugas?.Any() == true)
{
tpsData.FotoPetugas = new List<string>(existingRecord.FotoPetugas);
tpsData.FotoPetugasUploaded = existingRecord.FotoPetugasUploaded || tpsData.FotoPetugas.Count > 0;
}
else
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Foto petugas harus diupload"
};
}
await _store.SaveSubmittedAsync(tpsData);
return new DetailPenjemputanResponse
{
Success = true,
Message = "Data penjemputan berhasil disimpan",
Data = tpsData
};
}
catch (Exception ex)
{
_logger.LogError(ex, "Error submitting penjemputan data");
return new DetailPenjemputanResponse
{
Success = false,
Message = $"Terjadi kesalahan: {ex.Message}"
};
}
}
public async Task<TpsData?> GetRecordDetailAsync(string nomorSpj, string? spjDetailId = null, string? lokasiAngkutId = null, string? namaTps = null)
{
var normalizedNomorSpj = (nomorSpj ?? string.Empty).Trim();
var normalizedSpjDetailId = (spjDetailId ?? string.Empty).Trim();
var normalizedLokasiAngkutId = (lokasiAngkutId ?? string.Empty).Trim();
var normalizedNamaTps = (namaTps ?? string.Empty).Trim();
var allData = await _store.GetByNomorSpjAsync(normalizedNomorSpj);
return allData
.OrderByDescending(item => item.UpdatedAt)
.FirstOrDefault(item =>
(string.IsNullOrWhiteSpace(normalizedSpjDetailId) || string.Equals((item.SpjDetailId ?? string.Empty).Trim(), normalizedSpjDetailId, StringComparison.OrdinalIgnoreCase)) &&
(string.IsNullOrWhiteSpace(normalizedLokasiAngkutId) || string.Equals((item.LokasiAngkutId ?? string.Empty).Trim(), normalizedLokasiAngkutId, StringComparison.OrdinalIgnoreCase)) &&
(string.IsNullOrWhiteSpace(normalizedNamaTps) || string.Equals((item.Name ?? string.Empty).Trim(), normalizedNamaTps, StringComparison.OrdinalIgnoreCase)));
}
public async Task<RecordSaveResponse> SaveRecordJGCAsync(RecordSaveRequest request)
{
try
{
await _store.SaveRecordAsync(request);
return new RecordSaveResponse { Success = true, Message = "Data tersimpan." };
}
catch (Exception ex)
{
_logger.LogError(ex, "Error saving JGC penjemputan record");
return new RecordSaveResponse { Success = false, Message = $"Gagal menyimpan data: {ex.Message}" };
}
}
private static TpsData CloneRecord(TpsData source)
{
return new TpsData
{
NomorSpj = source.NomorSpj,
LokasiAngkutId = source.LokasiAngkutId,
SpjDetailId = source.SpjDetailId,
Name = source.Name,
Index = source.Index,
Latitude = source.Latitude,
Longitude = source.Longitude,
AlamatJalan = source.AlamatJalan,
WaktuKedatangan = source.WaktuKedatangan,
FotoKedatangan = new List<string>(source.FotoKedatangan ?? new List<string>()),
FotoKedatanganUploaded = source.FotoKedatanganUploaded,
FotoPetugas = new List<string>(source.FotoPetugas ?? new List<string>()),
FotoPetugasUploaded = source.FotoPetugasUploaded,
NamaPetugas = source.NamaPetugas,
IsSubmit = source.IsSubmit,
UpdatedAt = source.UpdatedAt,
SubmittedAt = source.SubmittedAt,
};
}
}
}