case 4693 - form field lists published only when fully built

FormFieldReferenceList and FormFieldKeys built their static lists lazily
and published them before filling them, so requests arriving during the
first build after a restart saw a half-filled list ("is not valid").
Both are now built in a local and published when complete (volatile).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 20:28:11 -07:00
parent d8be701bcd
commit eb1deff2ba
3 changed files with 51 additions and 44 deletions

View File

@@ -14,8 +14,9 @@ namespace AyaNova.Biz
public static class FormFieldOptionalCustomizableReference
{
private static Dictionary<string, List<FormField>> _formFields;
private static List<string> _formFieldKeys = null;
//case 4693: volatile, and published only once it is fully built (see FormFieldReferenceList)
private static volatile Dictionary<string, List<FormField>> _formFields;
private static volatile List<string> _formFieldKeys = null;
public static List<string> FormFieldKeys
{
@@ -23,23 +24,25 @@ namespace AyaNova.Biz
{
if (_formFieldKeys == null)
{
_formFieldKeys = new List<string>();
//case 4693: built in a local and published when complete, as FormFieldReferenceList
var formFieldKeys = new List<string>();
var values = Enum.GetValues(typeof(AyaType));
foreach (AyaType t in values)
{
if (t.HasAttribute(typeof(CoreBizObjectAttribute)))
{
_formFieldKeys.Add(t.ToString());
formFieldKeys.Add(t.ToString());
}
}
//No type / not corebiz form keys:
_formFieldKeys.Add("Contact");
formFieldKeys.Add("Contact");
//_formFieldKeys.Add(AyaType.ServiceBank.ToString());
_formFieldKeys.Add(AyaType.QuoteStatus.ToString());
_formFieldKeys.Add(AyaType.WorkOrderStatus.ToString());
_formFieldKeys.Add(AyaType.WorkOrderItemStatus.ToString());
_formFieldKeys.Add(AyaType.WorkOrderItemPriority.ToString());
_formFieldKeys.Add(AyaType.UnitMeterReading.ToString());
formFieldKeys.Add(AyaType.QuoteStatus.ToString());
formFieldKeys.Add(AyaType.WorkOrderStatus.ToString());
formFieldKeys.Add(AyaType.WorkOrderItemStatus.ToString());
formFieldKeys.Add(AyaType.WorkOrderItemPriority.ToString());
formFieldKeys.Add(AyaType.UnitMeterReading.ToString());
_formFieldKeys = formFieldKeys;
}
return _formFieldKeys;
}
@@ -54,9 +57,11 @@ namespace AyaNova.Biz
public static List<FormField> FormFieldReferenceList(string key)
{
//Initialize the static list here on first retrieval
//case 4693: built in a local and published when complete: requests arriving during the build after a
//restart saw a half-filled list ("is not valid"); two building at once is harmless, the result is the same
if (_formFields == null)
{
_formFields = new Dictionary<string, List<FormField>>();
var formFields = new Dictionary<string, List<FormField>>();
/* ***************************** WARNING: Be careful here, if a standard field is hideable and also it's DB SCHEMA is set to NON NULLABLE then the CLIENT end needs to set a default
***************************** Otherwise the hidden field can't be set and the object can't be saved EVER
*/
@@ -86,7 +91,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "UserCustom14", FieldKey = "UserCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "UserCustom15", FieldKey = "UserCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "UserCustom16", FieldKey = "UserCustom16", IsCustomField = true });
_formFields.Add(AyaType.User.ToString(), l);
formFields.Add(AyaType.User.ToString(), l);
}
#endregion
@@ -115,7 +120,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "UserCustom14", FieldKey = "UserCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "UserCustom15", FieldKey = "UserCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "UserCustom16", FieldKey = "UserCustom16", IsCustomField = true });
_formFields.Add("Contact", l);
formFields.Add("Contact", l);
}
#endregion
@@ -171,7 +176,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "CustomerCustom14", FieldKey = "CustomerCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "CustomerCustom15", FieldKey = "CustomerCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "CustomerCustom16", FieldKey = "CustomerCustom16", IsCustomField = true });
_formFields.Add(AyaType.Customer.ToString(), l);
formFields.Add(AyaType.Customer.ToString(), l);
}
#endregion
@@ -222,7 +227,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "HeadOfficeCustom14", FieldKey = "HeadOfficeCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "HeadOfficeCustom15", FieldKey = "HeadOfficeCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "HeadOfficeCustom16", FieldKey = "HeadOfficeCustom16", IsCustomField = true });
_formFields.Add(AyaType.HeadOffice.ToString(), l);
formFields.Add(AyaType.HeadOffice.ToString(), l);
}
#endregion
@@ -251,7 +256,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "ContractCustom14", FieldKey = "ContractCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "ContractCustom15", FieldKey = "ContractCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "ContractCustom16", FieldKey = "ContractCustom16", IsCustomField = true });
_formFields.Add(AyaType.Contract.ToString(), l);
formFields.Add(AyaType.Contract.ToString(), l);
}
#endregion
@@ -295,7 +300,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "LoanUnitCustom14", FieldKey = "LoanUnitCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "LoanUnitCustom15", FieldKey = "LoanUnitCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "LoanUnitCustom16", FieldKey = "LoanUnitCustom16", IsCustomField = true });
_formFields.Add(AyaType.LoanUnit.ToString(), l);
formFields.Add(AyaType.LoanUnit.ToString(), l);
}
#endregion
@@ -323,7 +328,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "MemoCustom14", FieldKey = "MemoCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "MemoCustom15", FieldKey = "MemoCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "MemoCustom16", FieldKey = "MemoCustom16", IsCustomField = true });
_formFields.Add(AyaType.Memo.ToString(), l);
formFields.Add(AyaType.Memo.ToString(), l);
}
#endregion
@@ -351,7 +356,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "ReminderCustom14", FieldKey = "ReminderCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "ReminderCustom15", FieldKey = "ReminderCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "ReminderCustom16", FieldKey = "ReminderCustom16", IsCustomField = true });
_formFields.Add(AyaType.Reminder.ToString(), l);
formFields.Add(AyaType.Reminder.ToString(), l);
}
#endregion
@@ -377,7 +382,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "ReviewCustom14", FieldKey = "ReviewCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "ReviewCustom15", FieldKey = "ReviewCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "ReviewCustom16", FieldKey = "ReviewCustom16", IsCustomField = true });
_formFields.Add(AyaType.Review.ToString(), l);
formFields.Add(AyaType.Review.ToString(), l);
}
#endregion
@@ -415,7 +420,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "PartCustom14", FieldKey = "PartCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "PartCustom15", FieldKey = "PartCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "PartCustom16", FieldKey = "PartCustom16", IsCustomField = true });
_formFields.Add(AyaType.Part.ToString(), l);
formFields.Add(AyaType.Part.ToString(), l);
}
#endregion
@@ -445,7 +450,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "PartWarehouseCustom14", FieldKey = "PartWarehouseCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "PartWarehouseCustom15", FieldKey = "PartWarehouseCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "PartWarehouseCustom16", FieldKey = "PartWarehouseCustom16", IsCustomField = true });
_formFields.Add(AyaType.PartWarehouse.ToString(), l);
formFields.Add(AyaType.PartWarehouse.ToString(), l);
}
#endregion
@@ -474,7 +479,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "PartAssemblyCustom14", FieldKey = "PartAssemblyCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "PartAssemblyCustom15", FieldKey = "PartAssemblyCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "PartAssemblyCustom16", FieldKey = "PartAssemblyCustom16", IsCustomField = true });
_formFields.Add(AyaType.PartAssembly.ToString(), l);
formFields.Add(AyaType.PartAssembly.ToString(), l);
}
#endregion
@@ -507,7 +512,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "ProjectCustom14", FieldKey = "ProjectCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "ProjectCustom15", FieldKey = "ProjectCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "ProjectCustom16", FieldKey = "ProjectCustom16", IsCustomField = true });
_formFields.Add(AyaType.Project.ToString(), l);
formFields.Add(AyaType.Project.ToString(), l);
}
#endregion
@@ -555,7 +560,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "PurchaseOrderCustom14", FieldKey = "PurchaseOrderCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "PurchaseOrderCustom15", FieldKey = "PurchaseOrderCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "PurchaseOrderCustom16", FieldKey = "PurchaseOrderCustom16", IsCustomField = true });
_formFields.Add(AyaType.PurchaseOrder.ToString(), l);
formFields.Add(AyaType.PurchaseOrder.ToString(), l);
}
#endregion
@@ -588,7 +593,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "ServiceRateCustom14", FieldKey = "ServiceRateCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "ServiceRateCustom15", FieldKey = "ServiceRateCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "ServiceRateCustom16", FieldKey = "ServiceRateCustom16", IsCustomField = true });
_formFields.Add(AyaType.ServiceRate.ToString(), l);
formFields.Add(AyaType.ServiceRate.ToString(), l);
}
#endregion
@@ -619,7 +624,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "TravelRateCustom14", FieldKey = "TravelRateCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "TravelRateCustom15", FieldKey = "TravelRateCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "TravelRateCustom16", FieldKey = "TravelRateCustom16", IsCustomField = true });
_formFields.Add(AyaType.TravelRate.ToString(), l);
formFields.Add(AyaType.TravelRate.ToString(), l);
}
#endregion
@@ -631,7 +636,7 @@ namespace AyaNova.Biz
// l.Add(new FormField { TKey = "TaskGroupNotes", FieldKey = "Notes" });
// _formFields.Add(AyaType.TaskGroup.ToString(), l);
// formFields.Add(AyaType.TaskGroup.ToString(), l);
// }
// #endregion
@@ -661,7 +666,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "TaxCodeCustom14", FieldKey = "TaxCodeCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "TaxCodeCustom15", FieldKey = "TaxCodeCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "TaxCodeCustom16", FieldKey = "TaxCodeCustom16", IsCustomField = true });
_formFields.Add(AyaType.TaxCode.ToString(), l);
formFields.Add(AyaType.TaxCode.ToString(), l);
}
#endregion
@@ -671,7 +676,7 @@ namespace AyaNova.Biz
// l.Add(new FormField { TKey = "ServiceBankCurrency", FieldKey = "Currency" });
// l.Add(new FormField { TKey = "ServiceBankHours", FieldKey = "Hours" });
// l.Add(new FormField { TKey = "ServiceBankIncidents", FieldKey = "Incidents" });
// _formFields.Add(AyaType.ServiceBank.ToString(), l);
// formFields.Add(AyaType.ServiceBank.ToString(), l);
// }
// #endregion
@@ -727,7 +732,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "UnitCustom14", FieldKey = "UnitCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "UnitCustom15", FieldKey = "UnitCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "UnitCustom16", FieldKey = "UnitCustom16", IsCustomField = true });
_formFields.Add(AyaType.Unit.ToString(), l);
formFields.Add(AyaType.Unit.ToString(), l);
}
#endregion
@@ -765,7 +770,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "UnitModelCustom14", FieldKey = "UnitModelCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "UnitModelCustom15", FieldKey = "UnitModelCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "UnitModelCustom16", FieldKey = "UnitModelCustom16", IsCustomField = true });
_formFields.Add(AyaType.UnitModel.ToString(), l);
formFields.Add(AyaType.UnitModel.ToString(), l);
}
#endregion
@@ -816,7 +821,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "VendorCustom14", FieldKey = "VendorCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "VendorCustom15", FieldKey = "VendorCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "VendorCustom16", FieldKey = "VendorCustom16", IsCustomField = true });
_formFields.Add(AyaType.Vendor.ToString(), l);
formFields.Add(AyaType.Vendor.ToString(), l);
}
#endregion
@@ -1052,7 +1057,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "LineTotal", FieldKey = "OutsideServiceLineTotalViz", TKeySection = "WorkOrderItemOutsideService", Requireable = false });
_formFields.Add(AyaType.WorkOrder.ToString(), l);
formFields.Add(AyaType.WorkOrder.ToString(), l);
}
#endregion
@@ -1278,7 +1283,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "TaxBAmt", FieldKey = "OutsideServiceTaxBViz", TKeySection = "WorkOrderItemOutsideService", Requireable = false });
l.Add(new FormField { TKey = "LineTotal", FieldKey = "OutsideServiceLineTotalViz", TKeySection = "WorkOrderItemOutsideService", Requireable = false });
_formFields.Add(AyaType.Quote.ToString(), l);
formFields.Add(AyaType.Quote.ToString(), l);
}
#endregion quote
@@ -1287,7 +1292,7 @@ namespace AyaNova.Biz
{
List<FormField> l = new List<FormField>();
l.Add(new FormField { TKey = "StatusNotes", FieldKey = "StatusNotes" });
_formFields.Add(AyaType.QuoteStatus.ToString(), l);
formFields.Add(AyaType.QuoteStatus.ToString(), l);
}
#endregion
@@ -1295,7 +1300,7 @@ namespace AyaNova.Biz
{
List<FormField> l = new List<FormField>();
l.Add(new FormField { TKey = "StatusNotes", FieldKey = "StatusNotes" });
_formFields.Add(AyaType.WorkOrderStatus.ToString(), l);
formFields.Add(AyaType.WorkOrderStatus.ToString(), l);
}
#endregion
@@ -1303,21 +1308,21 @@ namespace AyaNova.Biz
{
List<FormField> l = new List<FormField>();
l.Add(new FormField { TKey = "WorkOrderItemStatusNotes", FieldKey = "WorkOrderItemStatusNotes" });
_formFields.Add(AyaType.WorkOrderItemStatus.ToString(), l);
formFields.Add(AyaType.WorkOrderItemStatus.ToString(), l);
}
#endregion
#region WorkOrderItemPriority
{
List<FormField> l = new List<FormField>();
_formFields.Add(AyaType.WorkOrderItemPriority.ToString(), l);
formFields.Add(AyaType.WorkOrderItemPriority.ToString(), l);
}
#endregion
#region UnitmeterReading
{
List<FormField> l = new List<FormField>();
_formFields.Add(AyaType.UnitMeterReading.ToString(), l);
formFields.Add(AyaType.UnitMeterReading.ToString(), l);
}
#endregion
@@ -1545,7 +1550,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "TaxBAmt", FieldKey = "OutsideServiceTaxBViz", TKeySection = "WorkOrderItemOutsideService", Requireable = false });
l.Add(new FormField { TKey = "LineTotal", FieldKey = "OutsideServiceLineTotalViz", TKeySection = "WorkOrderItemOutsideService", Requireable = false });
_formFields.Add(AyaType.PM.ToString(), l);
formFields.Add(AyaType.PM.ToString(), l);
}
#endregion quote
@@ -1583,12 +1588,13 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "CustomerServiceRequestCustom14", FieldKey = "CustomerServiceRequestCustom14", IsCustomField = true });
l.Add(new FormField { TKey = "CustomerServiceRequestCustom15", FieldKey = "CustomerServiceRequestCustom15", IsCustomField = true });
l.Add(new FormField { TKey = "CustomerServiceRequestCustom16", FieldKey = "CustomerServiceRequestCustom16", IsCustomField = true });
_formFields.Add(AyaType.CustomerServiceRequest.ToString(), l);
formFields.Add(AyaType.CustomerServiceRequest.ToString(), l);
}
#endregion
//******************************************************
_formFields = formFields;
}
if (!_formFields.ContainsKey(key))