Initial Enova365 sync service
This commit is contained in:
154
src/SmartB2B.Enova.Contracts/EnovaContracts.cs
Normal file
154
src/SmartB2B.Enova.Contracts/EnovaContracts.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
namespace SmartB2B.Enova.Contracts;
|
||||
|
||||
public enum OrderSaveMode
|
||||
{
|
||||
Buffer,
|
||||
Approved
|
||||
}
|
||||
|
||||
public sealed record EnovaConnectionOptions(
|
||||
string DatabaseName,
|
||||
string OperatorName,
|
||||
string Password);
|
||||
|
||||
public sealed record EnovaAdapterConfiguration(
|
||||
EnovaConnectionOptions Connection,
|
||||
string DocumentDefinition,
|
||||
string? DefaultWarehouseCode,
|
||||
OrderSaveMode SaveMode);
|
||||
|
||||
public sealed class OrderRequest
|
||||
{
|
||||
public string CustomerCode { get; init; } = string.Empty;
|
||||
|
||||
public string? CustomerReference { get; init; }
|
||||
|
||||
public string? Notes { get; init; }
|
||||
|
||||
public string DocumentDefinition { get; init; } = "ZO";
|
||||
|
||||
public string? WarehouseCode { get; init; }
|
||||
|
||||
public OrderSaveMode SaveMode { get; init; } = OrderSaveMode.Buffer;
|
||||
|
||||
public IReadOnlyList<OrderLineRequest> Items { get; init; } = [];
|
||||
}
|
||||
|
||||
public sealed class OrderLineRequest
|
||||
{
|
||||
public string ProductCode { get; init; } = string.Empty;
|
||||
|
||||
public decimal Quantity { get; init; }
|
||||
|
||||
public decimal UnitPrice { get; init; }
|
||||
|
||||
public decimal Discount { get; init; }
|
||||
}
|
||||
|
||||
public sealed record OrderResult(
|
||||
int Id,
|
||||
string Number,
|
||||
OrderSaveMode SaveMode,
|
||||
string CustomerCode,
|
||||
string WarehouseCode,
|
||||
string? CustomerReference,
|
||||
int LineCount,
|
||||
decimal Net,
|
||||
decimal Vat,
|
||||
decimal Gross,
|
||||
bool HasDiscount);
|
||||
|
||||
public sealed record EnovaAdapterInfo(
|
||||
string AdapterVersion,
|
||||
string SonetaBusinessVersion,
|
||||
string SonetaHandelVersion,
|
||||
string DatabaseName);
|
||||
|
||||
public interface IEnovaOrderAdapter
|
||||
{
|
||||
EnovaAdapterInfo Initialize(EnovaAdapterConfiguration configuration);
|
||||
|
||||
OrderResult CreateOrder(OrderRequest request);
|
||||
}
|
||||
|
||||
public sealed class EnovaOperationException : Exception
|
||||
{
|
||||
public EnovaOperationException(
|
||||
string errorUri,
|
||||
string message,
|
||||
IReadOnlyDictionary<string, object?>? details = null,
|
||||
Exception? innerException = null)
|
||||
: base(message, innerException)
|
||||
{
|
||||
ErrorUri = errorUri;
|
||||
Details = details ?? new Dictionary<string, object?>();
|
||||
}
|
||||
|
||||
public string ErrorUri { get; }
|
||||
|
||||
public IReadOnlyDictionary<string, object?> Details { get; }
|
||||
}
|
||||
|
||||
public static class OrderValidator
|
||||
{
|
||||
public static IReadOnlyList<string> Validate(OrderRequest? request)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
|
||||
if (request is null)
|
||||
{
|
||||
errors.Add("Brak danych zamówienia.");
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.CustomerCode))
|
||||
{
|
||||
errors.Add("Pole companyErpId jest wymagane.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.DocumentDefinition))
|
||||
{
|
||||
errors.Add("Definicja dokumentu jest wymagana.");
|
||||
}
|
||||
|
||||
if (request.Items is null || request.Items.Count == 0)
|
||||
{
|
||||
errors.Add("Zamówienie musi zawierać co najmniej jedną pozycję.");
|
||||
return errors;
|
||||
}
|
||||
|
||||
for (var index = 0; index < request.Items.Count; index++)
|
||||
{
|
||||
var line = request.Items[index];
|
||||
var prefix = $"lines[{index}]";
|
||||
|
||||
if (line is null)
|
||||
{
|
||||
errors.Add($"{prefix}: pozycja nie może być pusta.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(line.ProductCode))
|
||||
{
|
||||
errors.Add($"{prefix}.symbol jest wymagane.");
|
||||
}
|
||||
|
||||
if (line.Quantity <= 0)
|
||||
{
|
||||
errors.Add($"{prefix}.quantity musi być większe od zera.");
|
||||
}
|
||||
|
||||
if (line.UnitPrice < 0)
|
||||
{
|
||||
errors.Add($"{prefix}.price_netto nie może być ujemne.");
|
||||
}
|
||||
|
||||
if (line.Discount is < 0 or > 100)
|
||||
{
|
||||
errors.Add($"{prefix}.discount musi mieścić się w zakresie 0-100.");
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user