eSPJ/Services/DetailPenjemputanService.cs

367 lines
14 KiB
C#

using System.Text.Json;
using eSPJ.Models;
namespace eSPJ.Services
{
public class DetailPenjemputanService
{
private readonly string _dataFilePath;
private readonly IWebHostEnvironment _env;
private readonly ILogger<DetailPenjemputanService> _logger;
public DetailPenjemputanService(
IWebHostEnvironment env,
ILogger<DetailPenjemputanService> logger)
{
_env = env;
_logger = logger;
_dataFilePath = Path.Combine(_env.ContentRootPath, "Data", "detail-penjemputan.json");
}
public async Task<List<TpsData>> GetAllTpsDataAsync()
{
try
{
if (!File.Exists(_dataFilePath))
{
return new List<TpsData>();
}
var json = await File.ReadAllTextAsync(_dataFilePath);
var data = JsonSerializer.Deserialize<List<TpsData>>(json);
return data ?? new List<TpsData>();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error reading TPS data from JSON");
return new List<TpsData>();
}
}
public async Task<bool> SaveTpsDataAsync(List<TpsData> data)
{
try
{
var directory = Path.GetDirectoryName(_dataFilePath);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
var options = new JsonSerializerOptions
{
WriteIndented = true
};
var json = JsonSerializer.Serialize(data, options);
await File.WriteAllTextAsync(_dataFilePath, json);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error saving TPS data to JSON");
return false;
}
}
public async Task<DetailPenjemputanResponse> SubmitPenjemputanAsync(DetailPenjemputanRequest request)
{
try
{
// Validate request
if (string.IsNullOrEmpty(request.TpsName))
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Nama TPS harus diisi"
};
}
if (request.FotoKedatangan == null || !request.FotoKedatangan.Any())
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Foto kedatangan harus diupload"
};
}
if (request.FotoTimbangan == null || !request.FotoTimbangan.Any())
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Foto timbangan harus diupload"
};
}
if (request.FotoPetugas == null || !request.FotoPetugas.Any())
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Foto petugas harus diupload"
};
}
if (string.IsNullOrEmpty(request.NamaPetugas))
{
return new DetailPenjemputanResponse
{
Success = false,
Message = "Nama petugas harus diisi"
};
}
var uploadPath = Path.Combine(_env.ContentRootPath, "uploads", "penjemputan", DateTime.Now.ToString("yyyy-MM-dd"));
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
var tpsData = new TpsData
{
Name = request.TpsName,
Latitude = request.Latitude,
Longitude = request.Longitude,
AlamatJalan = request.AlamatJalan,
WaktuKedatangan = request.WaktuKedatangan,
TotalTimbangan = request.TotalTimbangan,
TotalOrganik = request.TotalOrganik,
TotalAnorganik = request.TotalAnorganik,
TotalResidu = request.TotalResidu,
NamaPetugas = request.NamaPetugas,
Submitted = true,
FotoKedatanganUploaded = true,
FotoPetugasUploaded = true
};
// Save foto kedatangan
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}");
}
// Save foto timbangan
if (request.BeratTimbangan != null && request.JenisSampahList != null)
{
for (int i = 0; i < request.FotoTimbangan.Count; i++)
{
var file = request.FotoTimbangan[i];
var fileName = $"timbangan_{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
var filePath = Path.Combine(uploadPath, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var jenisSampah = JenisSampah.Residu;
if (i < request.JenisSampahList.Count && Enum.TryParse<JenisSampah>(request.JenisSampahList[i], out var parsed))
{
jenisSampah = parsed;
}
tpsData.Timbangan.Add(new TimbanganItem
{
FotoFileName = $"{uploadBaseUrl}/{fileName}",
Berat = new List<decimal> { (i < request.BeratTimbangan.Count ? request.BeratTimbangan[i] : 0) },
LokasiAngkut = new List<string>(),
JenisSampah = new List<JenisSampah> { jenisSampah },
IsUploaded = true,
WaktuUpload = DateTime.Now
});
}
}
// Save foto petugas
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}");
}
var allData = await GetAllTpsDataAsync();
allData.Add(tpsData);
await SaveTpsDataAsync(allData);
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}"
};
}
}
private string GetDraftFilePath(string prefix, string sessionKey)
{
var dir = Path.Combine(_env.ContentRootPath, "Data", "drafts");
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
var safe = string.Concat(sessionKey.Where(c => char.IsLetterOrDigit(c) || c == '-' || c == '_'));
if (string.IsNullOrEmpty(safe)) safe = "default";
return Path.Combine(dir, $"draft-{prefix}-{safe}.json");
}
private Task<DraftSaveResponse> SaveDraftAsync(string prefix, DraftSaveRequest request)
{
return SaveDraftInternalAsync(prefix, request);
}
private async Task<DraftSaveResponse> SaveDraftInternalAsync(string prefix, DraftSaveRequest request)
{
try
{
var filePath = GetDraftFilePath(prefix, request.SessionKey);
var draft = new DraftPenjemputanNonTps
{
SessionKey = request.SessionKey,
LokasiAngkutId = request.LokasiAngkutId,
SpjDetailId = request.SpjDetailId,
Latitude = request.Latitude,
Longitude = request.Longitude,
AlamatJalan = request.AlamatJalan,
WaktuKedatangan = request.WaktuKedatangan,
FotoKedatanganFileNames = request.FotoKedatanganFileNames,
FotoKedatanganUploaded = request.FotoKedatanganUploaded,
Timbangan = request.Timbangan,
TotalOrganik = request.TotalOrganik,
TotalAnorganik = request.TotalAnorganik,
TotalResidu = request.TotalResidu,
TotalTimbangan = request.TotalTimbangan,
FotoPetugasFileNames = request.FotoPetugasFileNames,
FotoPetugasUploaded = request.FotoPetugasUploaded,
NamaPetugas = request.NamaPetugas,
UpdatedAt = DateTime.Now
};
var options = new JsonSerializerOptions { WriteIndented = true };
var json = JsonSerializer.Serialize(draft, options);
await File.WriteAllTextAsync(filePath, json);
return new DraftSaveResponse { Success = true, Message = "Draft tersimpan.", DraftKey = request.DraftKey, SessionKey = request.SessionKey };
}
catch (Exception ex)
{
_logger.LogError(ex, "Error saving {Prefix} draft", prefix);
return new DraftSaveResponse { Success = false, Message = $"Gagal menyimpan draft: {ex.Message}" };
}
}
public async Task<DraftSaveResponse> SaveDraftNonTpsAsync(DraftSaveRequest request)
{
return await SaveDraftAsync("non-tps", request);
}
public async Task<DraftSaveResponse> SaveDraftTpsAsync(DraftSaveRequest request)
{
return await SaveDraftAsync("tps", request);
}
public async Task<DraftLoadResponse> LoadDraftNonTpsAsync(string sessionKey)
{
return await LoadDraftAsync("non-tps", sessionKey);
}
public async Task<DraftLoadResponse> LoadDraftTpsAsync(string sessionKey)
{
return await LoadDraftAsync("tps", sessionKey);
}
private async Task<DraftLoadResponse> LoadDraftAsync(string prefix, string sessionKey)
{
try
{
var filePath = GetDraftFilePath(prefix, sessionKey);
if (!File.Exists(filePath))
return new DraftLoadResponse { Success = true, HasDraft = false, Message = "Tidak ada draft." };
var json = await File.ReadAllTextAsync(filePath);
var draft = JsonSerializer.Deserialize<DraftPenjemputanNonTps>(json,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (draft == null)
return new DraftLoadResponse { Success = true, HasDraft = false, Message = "Draft kosong." };
return new DraftLoadResponse { Success = true, HasDraft = true, Draft = draft };
}
catch (Exception ex)
{
_logger.LogError(ex, "Error loading {Prefix} draft", prefix);
return new DraftLoadResponse { Success = false, HasDraft = false, Message = $"Gagal memuat draft: {ex.Message}" };
}
}
public async Task<bool> DeleteDraftNonTpsAsync(string sessionKey)
{
return await DeleteDraftAsync("non-tps", sessionKey);
}
public async Task<bool> DeleteDraftTpsAsync(string sessionKey)
{
return await DeleteDraftAsync("tps", sessionKey);
}
private async Task<bool> DeleteDraftAsync(string prefix, string sessionKey)
{
try
{
var filePath = GetDraftFilePath(prefix, sessionKey);
if (File.Exists(filePath)) File.Delete(filePath);
await Task.CompletedTask;
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting {Prefix} draft", prefix);
return false;
}
}
public async Task<OcrTimbanganResponse> ProcessOcrTimbanganAsync(IFormFile foto)
{
try
{
await Task.Delay(500);
return new OcrTimbanganResponse
{
Success = true,
Weight = "54.50",
Raw = "54.50 kg",
Message = "OCR processed successfully (mock)"
};
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing OCR timbangan");
return new OcrTimbanganResponse
{
Success = false,
Message = $"Terjadi kesalahan: {ex.Message}"
};
}
}
}
}