public static async Task <DataWithVersion <DefinitionsForClient> > LoadDefinitionsForClient(ApplicationRepository repo) { var(version, lookupDefs, agentDefs, resourceDefs, reportDefs) = await repo.Definitions__Load(); var result = new DefinitionsForClient { Lookups = lookupDefs.ToDictionary(def => def.Id, def => MapLookupDefinition(def)), Agents = agentDefs.ToDictionary(def => def.Id, def => MapAgentDefinition(def)), Resources = resourceDefs.ToDictionary(def => def.Id, def => MapResourceDefinition(def)), Reports = reportDefs.ToDictionary(def => def.Id, def => MapReportDefinition(def)), // TODO: Load these from the database as well Documents = new Dictionary <string, DocumentDefinitionForClient> { ["manual-journal-vouchers"] = new DocumentDefinitionForClient { Prefix = "JV", TitlePlural = "Manual Journal Vouchers", TitlePlural2 = "قيود تسوية يدوية", TitlePlural3 = "手动日记帐凭单", TitleSingular = "Manual Journal Voucher", TitleSingular2 = "قيد تسوية يدوي", TitleSingular3 = "手动日记帐凭证", MainMenuIcon = "exchange-alt", MainMenuSection = "Financials", MainMenuSortKey = 50m, // TODO: implement mock } }, Lines = new Dictionary <string, LineTypeForClient> { //["bla"] = new LineDefinitionForClient //{ // // TODO: implement mock //} }, }; return(new DataWithVersion <DefinitionsForClient> { Data = result, Version = version.ToString() }); }
/// <summary> /// Validates the control options JSON, returning any errors as localized messages. /// </summary> public static IEnumerable <string> ValidateControlOptions(string control, string controlOptions, IStringLocalizer localizer, SettingsForClient settings, DefinitionsForClient defs) { var errors = new List <string>(); if (string.IsNullOrWhiteSpace(controlOptions)) { return(errors); // Nothing to validate } try { switch (control) { case "text": case "date": case "datetime": case "boolean": case null: break; case "serial": { var options = JsonSerializer.Deserialize <SerialControlOptions>(controlOptions, _serializerOptions); if ((options.codeWidth ?? 4) < 0) { string label = localizer["ControlOptions_codeWidth"]; errors.Add(localizer[ErrorMessages.Error_0MustBeGreaterOrEqualZero, label]); } const int max = 9; // More than that won't fit in INT datatype if ((options.codeWidth ?? 4) > max) { string label = localizer["ControlOptions_codeWidth"]; errors.Add($"Field {label} cannot be larger than {max}."); } } break; case "choice": { var options = JsonSerializer.Deserialize <ChoiceControlOptions>(controlOptions, _serializerOptions); if (options.choices != null) { if (options.choices.Any(e => string.IsNullOrWhiteSpace(e.value))) { errors.Add(localizer[ErrorMessages.Error_Field0IsRequired, localizer["ControlOptions_value"]]); } if (options.choices.Any(e => string.IsNullOrWhiteSpace(e.name))) { string label = localizer["Name"]; if (settings.SecondaryLanguageId != null || settings.TernaryLanguageId != null) { label += $" ({settings.PrimaryLanguageSymbol})"; } errors.Add(localizer[ErrorMessages.Error_Field0IsRequired, label]); } } } break; case "number": { var options = JsonSerializer.Deserialize <NumberControlOptions>(controlOptions, _serializerOptions); if ((options.minDecimalPlaces ?? 0) < 0) { string label = localizer["ControlOptions_minDecimalPlaces"]; errors.Add(localizer[ErrorMessages.Error_0MustBeGreaterOrEqualZero, label]); } if ((options.maxDecimalPlaces ?? 0) < 0) { string label = localizer["ControlOptions_maxDecimalPlaces"]; errors.Add(localizer[ErrorMessages.Error_0MustBeGreaterOrEqualZero, label]); } if ((options.minDecimalPlaces ?? 0) > (options.maxDecimalPlaces ?? 4)) { string minLabel = localizer["ControlOptions_minDecimalPlaces"]; string maxLabel = localizer["ControlOptions_maxDecimalPlaces"]; errors.Add($"Field {minLabel} cannot be larger {maxLabel}."); } } break; case "percent": { var options = JsonSerializer.Deserialize <PercentControlOptions>(controlOptions, _serializerOptions); if ((options.minDecimalPlaces ?? 0) < 0) { string label = localizer["ControlOptions_minDecimalPlaces"]; errors.Add(localizer[ErrorMessages.Error_0MustBeGreaterOrEqualZero, label]); } if ((options.maxDecimalPlaces ?? 0) < 0) { string label = localizer["ControlOptions_maxDecimalPlaces"]; errors.Add(localizer[ErrorMessages.Error_0MustBeGreaterOrEqualZero, label]); } if ((options.minDecimalPlaces ?? 0) > (options.maxDecimalPlaces ?? 4)) { string minLabel = localizer["ControlOptions_minDecimalPlaces"]; string maxLabel = localizer["ControlOptions_maxDecimalPlaces"]; errors.Add($"Field {minLabel} cannot be larger {maxLabel}."); } } break; default: { const string invalidDefError = "Invalid definition."; var options = JsonSerializer.Deserialize <NavigationControlOptions>(controlOptions, _serializerOptions); if (options.definitionId != null) { var definitionId = options.definitionId.Value; switch (control) { case nameof(Document): if (!defs.Documents.ContainsKey(definitionId)) { errors.Add(invalidDefError); } break; case nameof(Agent): if (!defs.Agents.ContainsKey(definitionId)) { errors.Add(invalidDefError); } break; case nameof(Resource): if (!defs.Resources.ContainsKey(definitionId)) { errors.Add(invalidDefError); } break; case nameof(Lookup): if (!defs.Lookups.ContainsKey(definitionId)) { errors.Add(invalidDefError); } break; } } } break; } } catch (Exception ex) { errors.Add($"Error parsing {nameof(controlOptions)}: {ex.Message}"); } return(errors); }