Fix formula export/import: embed fields as real JSON array, not escaped string
Previously FieldsJson was serialized as an escaped string in the export file, which was fragile and unreadable. Now parsed into a JsonElement and embedded as a proper JSON array under the key "fields". Import reads it back with GetRawText() to reconstruct the stored string. This prevents the null/empty fields bug caused by manually-edited or round-tripped files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3051,6 +3051,15 @@ public class CompanySettingsController : Controller
|
|||||||
var companyId = _tenantContext.GetCurrentCompanyId()!.Value;
|
var companyId = _tenantContext.GetCurrentCompanyId()!.Value;
|
||||||
var templates = await _unitOfWork.CustomItemTemplates.FindAsync(t => t.CompanyId == companyId);
|
var templates = await _unitOfWork.CustomItemTemplates.FindAsync(t => t.CompanyId == companyId);
|
||||||
|
|
||||||
|
// Parse FieldsJson into a real JsonElement so it is embedded as a proper JSON array
|
||||||
|
// in the export file rather than as an escaped string. This makes the file human-readable
|
||||||
|
// and avoids round-trip corruption when files are manually edited.
|
||||||
|
static System.Text.Json.JsonElement ParseFields(string? raw)
|
||||||
|
{
|
||||||
|
try { return System.Text.Json.JsonDocument.Parse(raw ?? "[]").RootElement.Clone(); }
|
||||||
|
catch { return System.Text.Json.JsonDocument.Parse("[]").RootElement.Clone(); }
|
||||||
|
}
|
||||||
|
|
||||||
var export = new
|
var export = new
|
||||||
{
|
{
|
||||||
exportedAt = DateTime.UtcNow,
|
exportedAt = DateTime.UtcNow,
|
||||||
@@ -3062,7 +3071,7 @@ public class CompanySettingsController : Controller
|
|||||||
t.Name,
|
t.Name,
|
||||||
t.Description,
|
t.Description,
|
||||||
t.OutputMode,
|
t.OutputMode,
|
||||||
t.FieldsJson,
|
Fields = ParseFields(t.FieldsJson),
|
||||||
t.Formula,
|
t.Formula,
|
||||||
t.DefaultRate,
|
t.DefaultRate,
|
||||||
t.RateLabel,
|
t.RateLabel,
|
||||||
@@ -3142,7 +3151,8 @@ public class CompanySettingsController : Controller
|
|||||||
Name = name,
|
Name = name,
|
||||||
Description = item.TryGetProperty("description", out var d) ? d.GetString() : null,
|
Description = item.TryGetProperty("description", out var d) ? d.GetString() : null,
|
||||||
OutputMode = item.TryGetProperty("outputMode", out var om) ? om.GetString() ?? "FixedRate" : "FixedRate",
|
OutputMode = item.TryGetProperty("outputMode", out var om) ? om.GetString() ?? "FixedRate" : "FixedRate",
|
||||||
FieldsJson = item.TryGetProperty("fieldsJson", out var fj) ? fj.GetString() ?? "[]" : "[]",
|
// "fields" is a real JSON array in the export; GetRawText() reconstructs the string
|
||||||
|
FieldsJson = item.TryGetProperty("fields", out var fj) ? fj.GetRawText() : "[]",
|
||||||
Formula = item.TryGetProperty("formula", out var f) ? f.GetString() ?? "" : "",
|
Formula = item.TryGetProperty("formula", out var f) ? f.GetString() ?? "" : "",
|
||||||
DefaultRate = item.TryGetProperty("defaultRate", out var dr) && dr.ValueKind == System.Text.Json.JsonValueKind.Number ? dr.GetDecimal() : null,
|
DefaultRate = item.TryGetProperty("defaultRate", out var dr) && dr.ValueKind == System.Text.Json.JsonValueKind.Number ? dr.GetDecimal() : null,
|
||||||
RateLabel = item.TryGetProperty("rateLabel", out var rl) ? rl.GetString() : null,
|
RateLabel = item.TryGetProperty("rateLabel", out var rl) ? rl.GetString() : null,
|
||||||
|
|||||||
Reference in New Issue
Block a user