// The samples keep their state in small JSON files under STATE_DIR (default ./state). A real // connector keeps the same things in its own tables: the watermark, a staging table with a // unique key on (order id, version, line number), and the ERP's own documents. using System.Text.Json; namespace Slflo.Samples; public static class StateFiles { private static readonly string Dir = Environment.GetEnvironmentVariable("STATE_DIR") ?? "state"; public static T Load(string name) where T : new() { var path = Path.Combine(Dir, name); return File.Exists(path) ? JsonSerializer.Deserialize(File.ReadAllText(path)) ?? new T() : new T(); } public static void Save(string name, T value) { Directory.CreateDirectory(Dir); File.WriteAllText(Path.Combine(Dir, name), JsonSerializer.Serialize(value)); } } /// A stand-in for your ERP's books: sales orders by their customer reference, and journals. public sealed class FakeErp { public Dictionary SalesOrders { get; set; } = new(); // customer reference (the Slflo order id) -> SO number public Dictionary Journals { get; set; } = new(); // "kind:id:version" -> journal number // Numbers far from the Python stand-in's, since both answer the same sandbox company and // one ERP number can belong to one Slflo record only (409 EXTERNAL_REF_CONFLICT). private const int FirstNumber = 500_000; public static FakeErp Open() => StateFiles.Load("erp-cs.json"); public void Save() => StateFiles.Save("erp-cs.json", this); public static bool OnHold(string account) => (Environment.GetEnvironmentVariable("ERP_ON_HOLD") ?? "").Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).Contains(account); public string? FindSalesOrder(string customerReference) => SalesOrders.GetValueOrDefault(customerReference); public string CreateSalesOrder(string customerReference) { var number = $"SO-{SalesOrders.Count + 1 + FirstNumber:D7}"; SalesOrders[customerReference] = number; Save(); return number; } public string PostJournal(string kind, string id, long version) { var key = $"{kind}:{id}:{version}"; if (!Journals.TryGetValue(key, out var number)) { number = $"JRN-{Journals.Count + 1 + FirstNumber:D6}"; Journals[key] = number; Save(); } return number; } }