Files
BimAI/BimAI.Infrastructure/Sync/InvoiceSyncService.cs
2025-11-27 23:52:32 +01:00

138 lines
6.1 KiB
C#

using System.Text.Json;
using System.Web;
using BimAI.Domain.Entities;
using BimAI.Infrastructure.Data;
using Microsoft.Extensions.Configuration;
namespace BimAI.Infrastructure.Sync;
public class InvoiceSyncService(HttpClient httpClient, BimAIDbContext db, IConfiguration configuration)
{
private string DecodeHtmlEntities(string text)
{
if (string.IsNullOrEmpty(text))
return text;
return HttpUtility.HtmlDecode(text);
}
public async Task RunAsync()
{
var apiKey = configuration["E5_CRM:ApiKey"];
var syncState = db.SyncStates.FirstOrDefault(x => x.Entity == "Invoice") ?? new SyncState { Entity = "Invoice", LastSynced = 0 };
var url = $"https://crm.twinpol.com/REST/index.php?key={apiKey}&action=bimai.export.ecommerce&since=0";
var response = await httpClient.GetStringAsync(url);
var jsonDoc = JsonSerializer.Deserialize<JsonElement>(response);
if (!jsonDoc.TryGetProperty("data", out var dataElement))
{
Console.WriteLine("[SYNC] No 'data' property in response");
return;
}
var invoices = dataElement.EnumerateArray();
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
foreach (var invoiceJson in invoices)
{
try
{
var e5Id = invoiceJson.GetProperty("e5Id").GetString() ?? "";
var documentNo = DecodeHtmlEntities(invoiceJson.GetProperty("documentNo").GetString() ?? "");
var type = DecodeHtmlEntities(invoiceJson.GetProperty("type").GetString() ?? "");
var registerDateStr = invoiceJson.GetProperty("registerDate").GetString() ?? "";
var sellDateStr = invoiceJson.GetProperty("sellDate").GetString() ?? "";
var clientName = DecodeHtmlEntities(invoiceJson.GetProperty("clientName").GetString() ?? "");
var clientId = DecodeHtmlEntities(invoiceJson.GetProperty("clientId").GetString() ?? "");
var clientNip = DecodeHtmlEntities(invoiceJson.GetProperty("clientNip").GetString() ?? "");
var clientAddress = DecodeHtmlEntities(invoiceJson.GetProperty("clientAddress").GetString() ?? "");
var currency = invoiceJson.GetProperty("currency").GetString() ?? "PLN";
var totalNettoStr = invoiceJson.GetProperty("totalNetto").GetString() ?? "0";
var totalBruttoStr = invoiceJson.GetProperty("totalBrutto").GetString() ?? "0";
var totalVatStr = invoiceJson.GetProperty("totalVat").GetString() ?? "0";
var source = invoiceJson.GetProperty("source").GetString() ?? "";
if (!DateTime.TryParse(registerDateStr, out var registerDate))
{
Console.WriteLine($"[SYNC] Invalid registerDate for invoice {documentNo}: {registerDateStr}");
continue;
}
if (!DateTime.TryParse(sellDateStr, out var sellDate))
{
Console.WriteLine($"[SYNC] Invalid sellDate for invoice {documentNo}: {sellDateStr}");
continue;
}
if (!decimal.TryParse(totalNettoStr, out var totalNetto))
totalNetto = 0;
if (!decimal.TryParse(totalBruttoStr, out var totalBrutto))
totalBrutto = 0;
if (!decimal.TryParse(totalVatStr, out var totalVat))
totalVat = 0;
var existing = db.Invoices.FirstOrDefault(x => x.DocumentNo == documentNo && x.Source == source);
if (existing == null)
{
var invoice = new Invoice
{
DocumentNo = documentNo,
Type = type,
RegisterDate = registerDate,
SellDate = sellDate,
ClientName = clientName,
ClientId = string.IsNullOrWhiteSpace(clientId) ? null : clientId,
ClientNip = string.IsNullOrWhiteSpace(clientNip) ? null : clientNip,
ClientAddress = string.IsNullOrWhiteSpace(clientAddress) ? null : clientAddress,
Currency = currency,
TotalNetto = totalNetto,
TotalBrutto = totalBrutto,
TotalVat = totalVat,
Source = source,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
db.Invoices.Add(invoice);
Console.WriteLine($"[SYNC] Added invoice: {documentNo} from {source}");
}
else
{
existing.Type = type;
existing.RegisterDate = registerDate;
existing.SellDate = sellDate;
existing.ClientName = clientName;
existing.ClientId = string.IsNullOrWhiteSpace(clientId) ? null : clientId;
existing.ClientNip = string.IsNullOrWhiteSpace(clientNip) ? null : clientNip;
existing.ClientAddress = string.IsNullOrWhiteSpace(clientAddress) ? null : clientAddress;
existing.Currency = currency;
existing.TotalNetto = totalNetto;
existing.TotalBrutto = totalBrutto;
existing.TotalVat = totalVat;
existing.UpdatedAt = DateTime.UtcNow;
Console.WriteLine($"[SYNC] Updated invoice: {documentNo} from {source}");
}
}
catch (Exception ex)
{
Console.WriteLine($"[SYNC] Error processing invoice: {ex.Message}");
}
}
syncState.LastSynced = now;
if (db.SyncStates.FirstOrDefault(x => x.Entity == "Invoice") == null)
{
db.SyncStates.Add(syncState);
}
else
{
db.SyncStates.Update(syncState);
}
await db.SaveChangesAsync();
Console.WriteLine("[SYNC] Invoice sync completed");
}
}