diff --git a/docs/8.0/ayanova/docs/ay-customize.md b/docs/8.0/ayanova/docs/ay-customize.md
index 90832ed9..0caa3fff 100644
--- a/docs/8.0/ayanova/docs/ay-customize.md
+++ b/docs/8.0/ayanova/docs/ay-customize.md
@@ -49,7 +49,7 @@ To enforce a rule that a field **must** have data entered into it, put a checkma
Some fields by their nature can't be set to required and will not display a Required checkbox:
-- many fields are already required internally by AyaNova such as a Customer Name field
+- many fields are already required internally by AyaNova such as a Customer Name and many numeric / currency fields which are not optional
- some control types such as checkboxes don't support the concept of no entry due to having only two states
- logistics reasons apply to other controls such as signature controls on work orders which logically can't be signed until the work is completed
diff --git a/server/AyaNova/Controllers/FormCustomController.cs b/server/AyaNova/Controllers/FormCustomController.cs
index 701ab8db..8e7e351f 100644
--- a/server/AyaNova/Controllers/FormCustomController.cs
+++ b/server/AyaNova/Controllers/FormCustomController.cs
@@ -142,10 +142,10 @@ namespace AyaNova.Api.Controllers
/// Update FormCustom
///
///
- ///
+ ///
///
[HttpPut("{formkey}")]
- public async Task PutFormCustom([FromRoute] string formkey, [FromBody] FormCustom inObj)
+ public async Task PutFormCustom([FromRoute] string formkey, [FromBody] FormCustom updatedObject)
{
if (!serverState.IsOpen && UserIdFromContext.Id(HttpContext.Items) != 1)//bypass for superuser to fix fundamental problems
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
@@ -156,26 +156,36 @@ namespace AyaNova.Api.Controllers
//Instantiate the business object handler
FormCustomBiz biz = FormCustomBiz.GetBiz(ct, HttpContext);
- var o = await biz.GetAsync(formkey);
- if (o == null)
- return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
+ // var o = await biz.GetAsync(formkey);
+ // if (o == null)
+ // return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType))
return StatusCode(403, new ApiNotAuthorizedResponse());
- try
+ var o = await biz.PutAsync(updatedObject);
+ if (o == null)
{
- if (!await biz.PutAsync(o, inObj))
+ if (biz.Errors.Exists(z => z.Code == ApiErrorCode.CONCURRENCY_CONFLICT))
+ return StatusCode(409, new ApiErrorResponse(biz.Errors));
+ else
return BadRequest(new ApiErrorResponse(biz.Errors));
}
- catch (DbUpdateConcurrencyException)
- {
- if (!await biz.ExistsAsync(formkey))
- return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
- else
- return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT));
- }
- return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency }));
+ return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency })); ;
+
+ // try
+ // {
+ // if (!await biz.PutAsync(o, inObj))
+ // return BadRequest(new ApiErrorResponse(biz.Errors));
+ // }
+ // catch (DbUpdateConcurrencyException)
+ // {
+ // if (!await biz.ExistsAsync(formkey))
+ // return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
+ // else
+ // return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT));
+ // }
+ // return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency }));
}
diff --git a/server/AyaNova/biz/FormCustomBiz.cs b/server/AyaNova/biz/FormCustomBiz.cs
index 09c0772f..1d146163 100644
--- a/server/AyaNova/biz/FormCustomBiz.cs
+++ b/server/AyaNova/biz/FormCustomBiz.cs
@@ -111,35 +111,67 @@ namespace AyaNova.Biz
-
////////////////////////////////////////////////////////////////////////////////////////////////
//UPDATE
//
//put
- internal async Task PutAsync(FormCustom dbObject, FormCustom inObj)
+ internal async Task PutAsync(FormCustom putObject)
{
- //todo: replace with new put methodology
- //Replace the db object with the PUT object
- CopyObject.Copy(inObj, dbObject, "Id");
- //Set "original" value of concurrency token to input token
- //this will allow EF to check it out
- ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency;
-
- await ValidateAsync(dbObject, false);
+ var dbObject = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == putObject.FormKey);
+ if (dbObject == null)
+ {
+ AddError(ApiErrorCode.NOT_FOUND, "formKey");
+ return null;
+ }
+ if (dbObject.Concurrency != putObject.Concurrency)
+ {
+ AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
+ return null;
+ }
+ dbObject.Template = JsonUtil.CompactJson(putObject.Template);
+ putObject.Id=dbObject.Id;//weird workaround needed because ID is not sent with the putobject for...reasons 🤷?
+ await ValidateAsync(putObject, false);
if (HasErrors)
- return false;
-
- dbObject.Template = JsonUtil.CompactJson(dbObject.Template);
- await ct.SaveChangesAsync();
-
+ return null;
+ ct.Replace(dbObject, putObject);
+ try
+ {
+ await ct.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!await ExistsAsync(putObject.FormKey))
+ AddError(ApiErrorCode.NOT_FOUND);
+ else
+ AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
+ return null;
+ }
//Log modification and save context
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
+ return putObject;
+ // //todo: replace with new put methodology
+
+ // //Replace the db object with the PUT object
+ // CopyObject.Copy(putObject, dbObject, "Id");
+ // //Set "original" value of concurrency token to input token
+ // //this will allow EF to check it out
+ // ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
+
+ // await ValidateAsync(dbObject, false);
+ // if (HasErrors)
+ // return false;
+
+ // dbObject.Template = JsonUtil.CompactJson(dbObject.Template);
+ // await ct.SaveChangesAsync();
+
+ // //Log modification and save context
+ // await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
- return true;
+ // return true;
}
diff --git a/server/AyaNova/biz/FormFieldReference.cs b/server/AyaNova/biz/FormFieldReference.cs
index e8358b9e..9fb2cc3b 100644
--- a/server/AyaNova/biz/FormFieldReference.cs
+++ b/server/AyaNova/biz/FormFieldReference.cs
@@ -1013,7 +1013,8 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "TaxBAmt", FieldKey = "ExpenseTaxBViz", TKeySection = "WorkOrderItemExpense", Requireable = false });
l.Add(new FormField { TKey = "LineTotal", FieldKey = "ExpenseLineTotalViz", TKeySection = "WorkOrderItemExpense", Requireable = false });
- //WORKORDER ITEM LOAN
+ //WORKORDER ITEM LOAN WorkOrderItemLoanRate ?
+ l.Add(new FormField { TKey = "WorkOrderItemLoanRate", TKeySection = "WorkOrderItemLoan", ModelProperty = "Rate", Requireable = false });
l.Add(new FormField { TKey = "WorkOrderItemLoanNotes", TKeySection = "WorkOrderItemLoan", ModelProperty = "Notes" });
l.Add(new FormField { TKey = "WorkOrderItemLoanOutDate", TKeySection = "WorkOrderItemLoan", ModelProperty = "OutDate" });
l.Add(new FormField { TKey = "WorkOrderItemLoanDueDate", TKeySection = "WorkOrderItemLoan", ModelProperty = "DueDate" });
@@ -1023,7 +1024,7 @@ namespace AyaNova.Biz
l.Add(new FormField { TKey = "ListPrice", FieldKey = "LoanListPrice", TKeySection = "WorkOrderItemLoan", Requireable = false });
l.Add(new FormField { TKey = "Price", FieldKey = "LoanPriceViz", TKeySection = "WorkOrderItemLoan", Requireable = false });
l.Add(new FormField { TKey = "PriceOverride", FieldKey = "LoanPriceOverride", TKeySection = "WorkOrderItemLoan", ModelProperty = "PriceOverride" });
- l.Add(new FormField { TKey = "UnitOfMeasure", FieldKey = "LoanUnitOfMeasureViz", TKeySection = "WorkOrderItemLoan", Requireable = false });
+ //l.Add(new FormField { TKey = "UnitOfMeasure", FieldKey = "LoanUnitOfMeasureViz", TKeySection = "WorkOrderItemLoan", Requireable = false });
l.Add(new FormField { TKey = "NetPrice", FieldKey = "LoanNetViz", TKeySection = "WorkOrderItemLoan", Requireable = false });
l.Add(new FormField { TKey = "TaxAAmt", FieldKey = "LoanTaxAViz", TKeySection = "WorkOrderItemLoan", Requireable = false });
l.Add(new FormField { TKey = "TaxBAmt", FieldKey = "LoanTaxBViz", TKeySection = "WorkOrderItemLoan", Requireable = false });