367 lines
14 KiB
C#
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}"
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|