diff --git a/devdocs/todo.txt b/devdocs/todo.txt
index 21f020a6..3b863a5e 100644
--- a/devdocs/todo.txt
+++ b/devdocs/todo.txt
@@ -1,10 +1,8 @@
PRIORITY - ALWAYS Lowest level stuff first
=-=-=-=-
-
----
+
todo: API REFACTORING (note: workordercontroller / biz should be following all these rules so it's the template if need reference)
-todo: consider renaming ConcurrencyToken to a shorter string?
todo: all api route parameters, post object sb "newObject", put="putObject"
IN BIZ TOO
todo: all api routes, re-arrange code in controller in this order POST (and postlike such as duplicate), GET, PUT, DELETE for consistency and logicality
diff --git a/server/AyaNova/Controllers/WidgetController.cs b/server/AyaNova/Controllers/WidgetController.cs
index 9575d211..8292f46e 100644
--- a/server/AyaNova/Controllers/WidgetController.cs
+++ b/server/AyaNova/Controllers/WidgetController.cs
@@ -46,6 +46,37 @@ namespace AyaNova.Api.Controllers
serverState = apiServerState;
}
+ ///
+ /// Create widget
+ ///
+ ///
+ /// From route path
+ ///
+ [HttpPost]
+ public async Task PostWidget([FromBody] Widget newObject, ApiVersion apiVersion)
+ {
+ if (!serverState.IsOpen)
+ return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
+
+ //Instantiate the business object handler
+ WidgetBiz biz = WidgetBiz.GetBiz(ct, HttpContext);
+
+ //If a user has change roles
+ if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType))
+ return StatusCode(403, new ApiNotAuthorizedResponse());
+
+ if (!ModelState.IsValid)
+ return BadRequest(new ApiErrorResponse(ModelState));
+
+ //Create and validate
+ Widget o = await biz.CreateAsync(newObject);
+ if (o == null)
+ return BadRequest(new ApiErrorResponse(biz.Errors));
+ else
+ return CreatedAtAction(nameof(WidgetController.GetWidget), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
+
+
+ }
///
/// Get full widget object
@@ -121,37 +152,7 @@ namespace AyaNova.Api.Controllers
}
- ///
- /// Post widget
- ///
- ///
- /// From route path
- ///
- [HttpPost]
- public async Task PostWidget([FromBody] Widget inObj, ApiVersion apiVersion)
- {
- if (!serverState.IsOpen)
- return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
- //Instantiate the business object handler
- WidgetBiz biz = WidgetBiz.GetBiz(ct, HttpContext);
-
- //If a user has change roles
- if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType))
- return StatusCode(403, new ApiNotAuthorizedResponse());
-
- if (!ModelState.IsValid)
- return BadRequest(new ApiErrorResponse(ModelState));
-
- //Create and validate
- Widget o = await biz.CreateAsync(inObj);
- if (o == null)
- return BadRequest(new ApiErrorResponse(biz.Errors));
- else
- return CreatedAtAction(nameof(WidgetController.GetWidget), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
-
-
- }
///
/// Duplicate widget
@@ -229,7 +230,7 @@ namespace AyaNova.Api.Controllers
public ActionResult GetException()
{
//log.LogInformation("Widget::getexception-> Test exception and log from controller test");
- if (!serverState.IsOpen)
+ if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
throw new System.NotSupportedException("Test exception from widget controller");
}
@@ -241,7 +242,7 @@ namespace AyaNova.Api.Controllers
[HttpGet("altexception")]
public ActionResult GetAltException()
{
- if (!serverState.IsOpen)
+ if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
throw new System.ArgumentException("Test exception (ALT) from widget controller");
}
diff --git a/server/AyaNova/biz/ContractBiz.cs b/server/AyaNova/biz/ContractBiz.cs
index 1bbf6210..152ab12f 100644
--- a/server/AyaNova/biz/ContractBiz.cs
+++ b/server/AyaNova/biz/ContractBiz.cs
@@ -38,37 +38,21 @@ namespace AyaNova.Biz
return await ct.Contract.AnyAsync(e => e.Id == id);
}
- ////////////////////////////////////////////////////////////////////////////////////////////////
- /// GET
- ///
- ///
-
- internal async Task GetAsync(long fetchId, bool logTheGetEvent = true)
- {
- //This is simple so nothing more here, but often will be copying to a different output object or some other ops
- var ret = await ct.Contract.SingleOrDefaultAsync(m => m.Id == fetchId);
- if (logTheGetEvent && ret != null)
- {
- //Log
- await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
- }
- return ret;
- }
////////////////////////////////////////////////////////////////////////////////////////////////
//CREATE
//Called from route and also seeder
- internal async Task CreateAsync(Contract inObj)
+ internal async Task CreateAsync(Contract newObject)
{
- await ValidateAsync(inObj, null);
+ await ValidateAsync(newObject, null);
if (HasErrors)
return null;
else
{
//do stuff with Contract
- Contract outObj = inObj;
+ Contract outObj = newObject;
outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
@@ -124,6 +108,24 @@ namespace AyaNova.Biz
}
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ /// GET
+ ///
+ ///
+
+ internal async Task GetAsync(long fetchId, bool logTheGetEvent = true)
+ {
+ //This is simple so nothing more here, but often will be copying to a different output object or some other ops
+ var ret = await ct.Contract.SingleOrDefaultAsync(m => m.Id == fetchId);
+ if (logTheGetEvent && ret != null)
+ {
+ //Log
+ await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
+ }
+ return ret;
+ }
+
+
////////////////////////////////////////////////////////////////////////////////////////////////
//UPDATE
//
diff --git a/server/AyaNova/biz/CustomerBiz.cs b/server/AyaNova/biz/CustomerBiz.cs
index 50f1e83a..b7261873 100644
--- a/server/AyaNova/biz/CustomerBiz.cs
+++ b/server/AyaNova/biz/CustomerBiz.cs
@@ -38,6 +38,66 @@ namespace AyaNova.Biz
return await ct.Customer.AnyAsync(e => e.Id == id);
}
+
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ //CREATE
+ //
+ internal async Task CreateAsync(Customer newObject)
+ {
+ await ValidateAsync(newObject, null);
+ if (HasErrors)
+ return null;
+ else
+ {
+ newObject.Tags = TagUtil.NormalizeTags(newObject.Tags);
+ newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
+ await ct.Customer.AddAsync(newObject);
+ await ct.SaveChangesAsync();
+ await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
+ await SearchIndexAsync(newObject, true);
+ await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
+ return newObject;
+ }
+ }
+
+
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ //DUPLICATE
+ //
+
+ internal async Task DuplicateAsync(long id)
+ {
+ Customer dbObject = await GetAsync(id, false);
+ if (dbObject == null)
+ {
+ AddError(ApiErrorCode.NOT_FOUND, "id");
+ return null;
+ }
+ Customer newObject = new Customer();
+ CopyObject.Copy(dbObject, newObject, "Wiki");
+ string newUniqueName = string.Empty;
+ bool NotUnique = true;
+ long l = 1;
+ do
+ {
+ newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255);
+ NotUnique = await ct.Customer.AnyAsync(m => m.Name == newUniqueName);
+ } while (NotUnique);
+ newObject.Name = newUniqueName;
+ newObject.Id = 0;
+ newObject.Concurrency = 0;
+ await ct.Customer.AddAsync(newObject);
+ await ct.SaveChangesAsync();
+ await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
+ await SearchIndexAsync(newObject, true);
+ await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
+ return newObject;
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////
/// GET
///
@@ -55,75 +115,6 @@ namespace AyaNova.Biz
return ret;
}
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //CREATE
-
- //Called from route and also seeder
- internal async Task CreateAsync(Customer inObj)
- {
- await ValidateAsync(inObj, null);
- if (HasErrors)
- return null;
- else
- {
- //do stuff with Customer
- Customer outObj = inObj;
-
- outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
- outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
- //Save to db
- await ct.Customer.AddAsync(outObj);
- await ct.SaveChangesAsync();
- //Handle child and associated items:
- await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
- await SearchIndexAsync(outObj, true);
- await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
-
- return outObj;
- }
- }
-
-
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //DUPLICATE
- //
-
- internal async Task DuplicateAsync(Customer dbObj)
- {
-
- Customer outObj = new Customer();
- CopyObject.Copy(dbObj, outObj, "Wiki");
- // outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255);
- //generate unique name
- string newUniqueName = string.Empty;
- bool NotUnique = true;
- long l = 1;
- do
- {
- newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObj.Name, l++, 255);
- NotUnique = await ct.Customer.AnyAsync(m => m.Name == newUniqueName);
- } while (NotUnique);
-
- outObj.Name = newUniqueName;
-
-
- outObj.Id = 0;
- outObj.Concurrency = 0;
-
- await ct.Customer.AddAsync(outObj);
- await ct.SaveChangesAsync();
-
- //Handle child and associated items:
- await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
- await SearchIndexAsync(outObj, true);
- await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
- return outObj;
-
- }
-
////////////////////////////////////////////////////////////////////////////////////////////////
//UPDATE
//
@@ -159,7 +150,7 @@ namespace AyaNova.Biz
return true;
}
-
+
private async Task SearchIndexAsync(Customer obj, bool isNew)
{
//SEARCH INDEXING