De-Templatization for ALL THE THINGS!!
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -54,7 +54,7 @@
|
|||||||
"AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles",
|
"AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles",
|
||||||
"AYANOVA_FOLDER_TEMPORARY_SERVER_FILES": "c:\\temp\\RavenTestData\\tempfiles",
|
"AYANOVA_FOLDER_TEMPORARY_SERVER_FILES": "c:\\temp\\RavenTestData\\tempfiles",
|
||||||
"AYANOVA_SERVER_TEST_MODE": "true",
|
"AYANOVA_SERVER_TEST_MODE": "true",
|
||||||
"AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "false",
|
"AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small",
|
||||||
"AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-7",
|
"AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-7",
|
||||||
"AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_13\\bin\\"
|
"AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_13\\bin\\"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -233,4 +233,4 @@ https://en.wikipedia.org/wiki/Non-functional_requirement
|
|||||||
|
|
||||||
|
|
||||||
## ASCII ART
|
## ASCII ART
|
||||||
//http://www.patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=work-order
|
//http://www.patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=quote
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using AyaNova.Models;
|
|
||||||
using AyaNova.Api.ControllerHelpers;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AyaNova.Api.Controllers
|
|
||||||
{
|
|
||||||
[ApiController]
|
|
||||||
[ApiVersion("8.0")]
|
|
||||||
[Route("api/v{version:apiVersion}/pm-template")]
|
|
||||||
[Produces("application/json")]
|
|
||||||
[Authorize]
|
|
||||||
public class PMTemplateController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly AyContext ct;
|
|
||||||
private readonly ILogger<PMTemplateController> log;
|
|
||||||
private readonly ApiServerState serverState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbcontext"></param>
|
|
||||||
/// <param name="logger"></param>
|
|
||||||
/// <param name="apiServerState"></param>
|
|
||||||
public PMTemplateController(AyContext dbcontext, ILogger<PMTemplateController> logger, ApiServerState apiServerState)
|
|
||||||
{
|
|
||||||
ct = dbcontext;
|
|
||||||
log = logger;
|
|
||||||
serverState = apiServerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create PMTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="newObject"></param>
|
|
||||||
/// <param name="apiVersion">From route path</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPost]
|
|
||||||
public async Task<IActionResult> PostPMTemplate([FromBody] PMTemplate newObject, ApiVersion apiVersion)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
PMTemplateBiz biz = PMTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
PMTemplate o = await biz.CreateAsync(newObject);
|
|
||||||
if (o == null)
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
else
|
|
||||||
return CreatedAtAction(nameof(PMTemplateController.GetPMTemplate), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
// /// <summary>
|
|
||||||
// /// Duplicate PMTemplate
|
|
||||||
// /// (Wiki and Attachments are not duplicated)
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="id">Source object id</param>
|
|
||||||
// /// <param name="apiVersion">From route path</param>
|
|
||||||
// /// <returns>PMTemplate</returns>
|
|
||||||
// [HttpPost("duplicate/{id}")]
|
|
||||||
// public async Task<IActionResult> DuplicatePMTemplate([FromRoute] long id, ApiVersion apiVersion)
|
|
||||||
// {
|
|
||||||
// if (!serverState.IsOpen)
|
|
||||||
// return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
// PMTemplateBiz biz = PMTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
// if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType))
|
|
||||||
// return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
// if (!ModelState.IsValid)
|
|
||||||
// return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
// PMTemplate o = await biz.DuplicateAsync(id);
|
|
||||||
// if (o == null)
|
|
||||||
// return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
// else
|
|
||||||
// return CreatedAtAction(nameof(PMTemplateController.GetPMTemplate), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get PMTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns>PMTemplate</returns>
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public async Task<IActionResult> GetPMTemplate([FromRoute] long id)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
PMTemplateBiz biz = PMTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
if (!Authorized.HasReadFullRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
var o = await biz.GetAsync(id);
|
|
||||||
if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
return Ok(ApiOkResponse.Response(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update PMTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="updatedObject"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPut]
|
|
||||||
public async Task<IActionResult> PutPMTemplate([FromBody] PMTemplate updatedObject)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
PMTemplateBiz biz = PMTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
var o = await biz.PutAsync(updatedObject);//In future may need to return entire object, for now just concurrency token
|
|
||||||
if (o == null)
|
|
||||||
{
|
|
||||||
if (biz.Errors.Exists(z => z.Code == ApiErrorCode.CONCURRENCY_CONFLICT))
|
|
||||||
return StatusCode(409, new ApiErrorResponse(biz.Errors));
|
|
||||||
else
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
}
|
|
||||||
return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency }));;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delete PMTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns>NoContent</returns>
|
|
||||||
[HttpDelete("{id}")]
|
|
||||||
public async Task<IActionResult> DeletePMTemplate([FromRoute] long id)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
PMTemplateBiz biz = PMTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
if (!await biz.DeleteAsync(id))
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
return NoContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------
|
|
||||||
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
}//eons
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using AyaNova.Models;
|
|
||||||
using AyaNova.Api.ControllerHelpers;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AyaNova.Api.Controllers
|
|
||||||
{
|
|
||||||
|
|
||||||
[ApiController]
|
|
||||||
[ApiVersion("8.0")]
|
|
||||||
[Route("api/v{version:apiVersion}/quote-template")]
|
|
||||||
[Produces("application/json")]
|
|
||||||
[Authorize]
|
|
||||||
public class QuoteTemplateController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly AyContext ct;
|
|
||||||
private readonly ILogger<QuoteTemplateController> log;
|
|
||||||
private readonly ApiServerState serverState;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbcontext"></param>
|
|
||||||
/// <param name="logger"></param>
|
|
||||||
/// <param name="apiServerState"></param>
|
|
||||||
public QuoteTemplateController(AyContext dbcontext, ILogger<QuoteTemplateController> logger, ApiServerState apiServerState)
|
|
||||||
{
|
|
||||||
ct = dbcontext;
|
|
||||||
log = logger;
|
|
||||||
serverState = apiServerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get full QuoteTemplate object
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns>A single QuoteTemplate</returns>
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public async Task<IActionResult> GetQuoteTemplate([FromRoute] long id)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
QuoteTemplateBiz biz = QuoteTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
|
|
||||||
//NOTE: This is the first check and often the only check but in some cases with some objects this will also need to check biz object rules
|
|
||||||
if (!Authorized.HasReadFullRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
|
|
||||||
var o = await biz.GetAsync(id);
|
|
||||||
if (o == null)
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
// NOTE: HERE would be the second check of biz rules before returning the object
|
|
||||||
// in cases where there is also a business rule to affect retrieval on top of basic rights
|
|
||||||
|
|
||||||
return Ok(ApiOkResponse.Response(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update QuoteTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <param name="inObj"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPut("{id}")]
|
|
||||||
public async Task<IActionResult> PutQuoteTemplate([FromRoute] long id, [FromBody] QuoteTemplate inObj)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
QuoteTemplateBiz biz = QuoteTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
|
|
||||||
var o = await biz.GetAsync(id, false);
|
|
||||||
if (o == null)
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!await biz.PutAsync(o, inObj))
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
}
|
|
||||||
catch (DbUpdateConcurrencyException)
|
|
||||||
{
|
|
||||||
if (!await biz.ExistsAsync(id))
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
else
|
|
||||||
return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT));
|
|
||||||
}
|
|
||||||
return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency }));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create QuoteTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="inObj"></param>
|
|
||||||
/// <param name="apiVersion">From route path</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPost]
|
|
||||||
public async Task<IActionResult> PostQuoteTemplate([FromBody] QuoteTemplate inObj, ApiVersion apiVersion)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
QuoteTemplateBiz biz = QuoteTemplateBiz.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
|
|
||||||
QuoteTemplate o = await biz.CreateAsync(inObj);
|
|
||||||
if (o == null)
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
else
|
|
||||||
return CreatedAtAction(nameof(QuoteTemplateController.GetQuoteTemplate), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// /// <summary>
|
|
||||||
// /// Duplicate QuoteTemplate
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="id">Create a duplicate of this items id</param>
|
|
||||||
// /// <param name="apiVersion">From route path</param>
|
|
||||||
// /// <returns></returns>
|
|
||||||
// [HttpPost("duplicate/{id}")]
|
|
||||||
// public async Task<IActionResult> DuplicateQuoteTemplate([FromRoute] long id, ApiVersion apiVersion)
|
|
||||||
// {
|
|
||||||
// if (!serverState.IsOpen)
|
|
||||||
// return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
// //Instantiate the business object handler
|
|
||||||
// QuoteTemplateBiz biz = QuoteTemplateBiz.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));
|
|
||||||
|
|
||||||
// var oSrc = await biz.GetAsync(id, false);
|
|
||||||
// if (oSrc == null)
|
|
||||||
// return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
// //Create and validate
|
|
||||||
// QuoteTemplate o = await biz.DuplicateAsync(oSrc);
|
|
||||||
// if (o == null)
|
|
||||||
// return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
// else
|
|
||||||
// return CreatedAtAction(nameof(QuoteTemplateController.GetQuoteTemplate), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delete QuoteTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns>Ok</returns>
|
|
||||||
[HttpDelete("{id}")]
|
|
||||||
public async Task<IActionResult> DeleteQuoteTemplate([FromRoute] long id)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
QuoteTemplateBiz biz = QuoteTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
|
|
||||||
var o = await biz.GetAsync(id, false);
|
|
||||||
if (o == null)
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
|
|
||||||
if (!await biz.DeleteAsync(o))
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
|
|
||||||
return NoContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------
|
|
||||||
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
}//eons
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using AyaNova.Models;
|
|
||||||
using AyaNova.Api.ControllerHelpers;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AyaNova.Api.Controllers
|
|
||||||
{
|
|
||||||
|
|
||||||
[ApiController]
|
|
||||||
[ApiVersion("8.0")]
|
|
||||||
[Route("api/v{version:apiVersion}/workorder-template")]
|
|
||||||
[Produces("application/json")]
|
|
||||||
[Authorize]
|
|
||||||
public class WorkOrderTemplateController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly AyContext ct;
|
|
||||||
private readonly ILogger<WorkOrderTemplateController> log;
|
|
||||||
private readonly ApiServerState serverState;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbcontext"></param>
|
|
||||||
/// <param name="logger"></param>
|
|
||||||
/// <param name="apiServerState"></param>
|
|
||||||
public WorkOrderTemplateController(AyContext dbcontext, ILogger<WorkOrderTemplateController> logger, ApiServerState apiServerState)
|
|
||||||
{
|
|
||||||
ct = dbcontext;
|
|
||||||
log = logger;
|
|
||||||
serverState = apiServerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get full WorkOrderTemplate object
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns>A single WorkOrderTemplate</returns>
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public async Task<IActionResult> GetWorkOrderTemplate([FromRoute] long id)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
WorkOrderTemplateBiz biz = WorkOrderTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
|
|
||||||
//NOTE: This is the first check and often the only check but in some cases with some objects this will also need to check biz object rules
|
|
||||||
if (!Authorized.HasReadFullRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
|
|
||||||
var o = await biz.GetAsync(id);
|
|
||||||
if (o == null)
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
// NOTE: HERE would be the second check of biz rules before returning the object
|
|
||||||
// in cases where there is also a business rule to affect retrieval on top of basic rights
|
|
||||||
|
|
||||||
return Ok(ApiOkResponse.Response(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update WorkOrderTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <param name="inObj"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPut("{id}")]
|
|
||||||
public async Task<IActionResult> PutWorkOrderTemplate([FromRoute] long id, [FromBody] WorkOrderTemplate inObj)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
WorkOrderTemplateBiz biz = WorkOrderTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
|
|
||||||
var o = await biz.GetAsync(id, false);
|
|
||||||
if (o == null)
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!await biz.PutAsync(o, inObj))
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
}
|
|
||||||
catch (DbUpdateConcurrencyException)
|
|
||||||
{
|
|
||||||
if (!await biz.ExistsAsync(id))
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
else
|
|
||||||
return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT));
|
|
||||||
}
|
|
||||||
return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency }));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create WorkOrderTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="inObj"></param>
|
|
||||||
/// <param name="apiVersion">From route path</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPost]
|
|
||||||
public async Task<IActionResult> PostWorkOrderTemplate([FromBody] WorkOrderTemplate inObj, ApiVersion apiVersion)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
WorkOrderTemplateBiz biz = WorkOrderTemplateBiz.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
|
|
||||||
WorkOrderTemplate o = await biz.CreateAsync(inObj);
|
|
||||||
if (o == null)
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
else
|
|
||||||
return CreatedAtAction(nameof(WorkOrderTemplateController.GetWorkOrderTemplate), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// /// <summary>
|
|
||||||
// /// Duplicate WorkOrderTemplate
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="id">Create a duplicate of this items id</param>
|
|
||||||
// /// <param name="apiVersion">From route path</param>
|
|
||||||
// /// <returns></returns>
|
|
||||||
// [HttpPost("duplicate/{id}")]
|
|
||||||
// public async Task<IActionResult> DuplicateWorkOrderTemplate([FromRoute] long id, ApiVersion apiVersion)
|
|
||||||
// {
|
|
||||||
// if (!serverState.IsOpen)
|
|
||||||
// return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
// //Instantiate the business object handler
|
|
||||||
// WorkOrderTemplateBiz biz = WorkOrderTemplateBiz.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));
|
|
||||||
|
|
||||||
// var oSrc = await biz.GetAsync(id, false);
|
|
||||||
// if (oSrc == null)
|
|
||||||
// return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
// //Create and validate
|
|
||||||
// WorkOrderTemplate o = await biz.DuplicateAsync(oSrc);
|
|
||||||
// if (o == null)
|
|
||||||
// return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
// else
|
|
||||||
// return CreatedAtAction(nameof(WorkOrderTemplateController.GetWorkOrderTemplate), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delete WorkOrderTemplate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns>Ok</returns>
|
|
||||||
[HttpDelete("{id}")]
|
|
||||||
public async Task<IActionResult> DeleteWorkOrderTemplate([FromRoute] long id)
|
|
||||||
{
|
|
||||||
if (!serverState.IsOpen)
|
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
|
||||||
|
|
||||||
//Instantiate the business object handler
|
|
||||||
WorkOrderTemplateBiz biz = WorkOrderTemplateBiz.GetBiz(ct, HttpContext);
|
|
||||||
|
|
||||||
var o = await biz.GetAsync(id, false);
|
|
||||||
if (o == null)
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
|
||||||
|
|
||||||
if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType))
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
|
||||||
|
|
||||||
if (!await biz.DeleteAsync(o))
|
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
|
||||||
|
|
||||||
return NoContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------
|
|
||||||
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
}//eons
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
namespace AyaNova.PickList
|
|
||||||
{
|
|
||||||
internal class WorkOrderTemplatePickList : AyaPickList
|
|
||||||
{
|
|
||||||
public WorkOrderTemplatePickList()
|
|
||||||
{
|
|
||||||
|
|
||||||
DefaultListAType = AyaType.WorkOrderTemplate;
|
|
||||||
SQLFrom = "from aworkordertemplate";
|
|
||||||
AllowedRoles = BizRoles.GetRoleSet(DefaultListAType).Select;
|
|
||||||
dynamic dTemplate = new JArray();
|
|
||||||
|
|
||||||
dynamic cm = new JObject();
|
|
||||||
cm.fld = "name";
|
|
||||||
dTemplate.Add(cm);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
base.DefaultTemplate = dTemplate.ToString(Newtonsoft.Json.Formatting.None);
|
|
||||||
|
|
||||||
//NOTE: Due to the join, all the sql id and name fields that can conflict with the joined table need to be specified completely
|
|
||||||
ColumnDefinitions = new List<AyaPickListFieldDefinition>();
|
|
||||||
ColumnDefinitions.Add(new AyaPickListFieldDefinition
|
|
||||||
{
|
|
||||||
TKey = "Active",
|
|
||||||
FieldKey = "active",
|
|
||||||
ColumnDataType = UiFieldDataType.Bool,
|
|
||||||
SqlValueColumnName = "aworkordertemplate.active",
|
|
||||||
IsActiveColumn = true
|
|
||||||
});
|
|
||||||
ColumnDefinitions.Add(new AyaPickListFieldDefinition
|
|
||||||
{
|
|
||||||
TKey = "Name",
|
|
||||||
FieldKey = "name",
|
|
||||||
ColumnDataType = UiFieldDataType.Text,
|
|
||||||
SqlIdColumnName = "aworkordertemplate.id",
|
|
||||||
SqlValueColumnName = "aworkordertemplate.name",
|
|
||||||
IsRowId = true
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}//eoc
|
|
||||||
}//eons
|
|
||||||
@@ -54,9 +54,9 @@ namespace AyaNova.Biz
|
|||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
PMItem = 22,
|
PMItem = 22,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
PMTemplate = 23,
|
unused23 = 23,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
PMTemplateItem = 24,
|
unused24 = 24,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
Project = 25,
|
Project = 25,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
@@ -66,9 +66,9 @@ namespace AyaNova.Biz
|
|||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
QuoteItem = 28,
|
QuoteItem = 28,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
QuoteTemplate = 29,
|
unused29 = 29,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
QuoteTemplateItem = 30,
|
unused30 = 30,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
Unit = 31,
|
Unit = 31,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
@@ -100,9 +100,9 @@ namespace AyaNova.Biz
|
|||||||
WorkOrderItemUnit = 44,
|
WorkOrderItemUnit = 44,
|
||||||
//---
|
//---
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
WorkOrderTemplate = 45,
|
unused45 = 45,
|
||||||
[CoreBizObject]
|
[CoreBizObject]
|
||||||
WorkOrderTemplateItem = 46,
|
unused46 = 46,
|
||||||
GlobalOps = 47,//really only used for rights, not an object type of any kind
|
GlobalOps = 47,//really only used for rights, not an object type of any kind
|
||||||
BizMetrics = 48,//deprecate? Not used for anything as of nov 2020
|
BizMetrics = 48,//deprecate? Not used for anything as of nov 2020
|
||||||
Backup = 49,
|
Backup = 49,
|
||||||
|
|||||||
@@ -56,10 +56,7 @@ namespace AyaNova.Biz
|
|||||||
return await ct.PM.AnyAsync(z => z.Id == id);
|
return await ct.PM.AnyAsync(z => z.Id == id);
|
||||||
case AyaType.PMItem:
|
case AyaType.PMItem:
|
||||||
return await ct.PMItem.AnyAsync(z => z.Id == id);
|
return await ct.PMItem.AnyAsync(z => z.Id == id);
|
||||||
case AyaType.PMTemplate:
|
|
||||||
return await ct.PMTemplate.AnyAsync(z => z.Id == id);
|
|
||||||
case AyaType.PMTemplateItem:
|
|
||||||
return await ct.PMTemplateItem.AnyAsync(z => z.Id == id);
|
|
||||||
case AyaType.Project:
|
case AyaType.Project:
|
||||||
return await ct.Project.AnyAsync(z => z.Id == id);
|
return await ct.Project.AnyAsync(z => z.Id == id);
|
||||||
case AyaType.PurchaseOrder:
|
case AyaType.PurchaseOrder:
|
||||||
@@ -68,10 +65,7 @@ namespace AyaNova.Biz
|
|||||||
return await ct.Quote.AnyAsync(z => z.Id == id);
|
return await ct.Quote.AnyAsync(z => z.Id == id);
|
||||||
case AyaType.QuoteItem:
|
case AyaType.QuoteItem:
|
||||||
return await ct.QuoteItem.AnyAsync(z => z.Id == id);
|
return await ct.QuoteItem.AnyAsync(z => z.Id == id);
|
||||||
case AyaType.QuoteTemplate:
|
|
||||||
return await ct.QuoteTemplate.AnyAsync(z => z.Id == id);
|
|
||||||
case AyaType.QuoteTemplateItem:
|
|
||||||
return await ct.QuoteTemplateItem.AnyAsync(z => z.Id == id);
|
|
||||||
case AyaType.Unit:
|
case AyaType.Unit:
|
||||||
return await ct.Unit.AnyAsync(z => z.Id == id);
|
return await ct.Unit.AnyAsync(z => z.Id == id);
|
||||||
case AyaType.UnitModel:
|
case AyaType.UnitModel:
|
||||||
@@ -104,10 +98,7 @@ namespace AyaNova.Biz
|
|||||||
case AyaType.WorkOrderItemOutsideService:
|
case AyaType.WorkOrderItemOutsideService:
|
||||||
return await ct.WorkOrderItemOutsideService.AnyAsync(z => z.Id == id);
|
return await ct.WorkOrderItemOutsideService.AnyAsync(z => z.Id == id);
|
||||||
//---
|
//---
|
||||||
case AyaType.WorkOrderTemplate:
|
|
||||||
return await ct.WorkOrderTemplate.AnyAsync(z => z.Id == id);
|
|
||||||
case AyaType.WorkOrderTemplateItem:
|
|
||||||
return await ct.WorkOrderTemplateItem.AnyAsync(z => z.Id == id);
|
|
||||||
case AyaType.Report:
|
case AyaType.Report:
|
||||||
return await ct.Report.AnyAsync(z => z.Id == id);
|
return await ct.Report.AnyAsync(z => z.Id == id);
|
||||||
case AyaType.Reminder:
|
case AyaType.Reminder:
|
||||||
|
|||||||
@@ -64,9 +64,7 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
case AyaType.PM:
|
case AyaType.PM:
|
||||||
return new PMBiz(ct, userId, translationId, roles);
|
return new PMBiz(ct, userId, translationId, roles);
|
||||||
case AyaType.PMTemplate:
|
|
||||||
return new PMTemplateBiz(ct, userId, translationId, roles);
|
|
||||||
|
|
||||||
case AyaType.Project:
|
case AyaType.Project:
|
||||||
return new ProjectBiz(ct, userId, translationId, roles);
|
return new ProjectBiz(ct, userId, translationId, roles);
|
||||||
case AyaType.PurchaseOrder:
|
case AyaType.PurchaseOrder:
|
||||||
@@ -74,9 +72,7 @@ namespace AyaNova.Biz
|
|||||||
case AyaType.Quote:
|
case AyaType.Quote:
|
||||||
return new QuoteBiz(ct, userId, translationId, roles);
|
return new QuoteBiz(ct, userId, translationId, roles);
|
||||||
|
|
||||||
case AyaType.QuoteTemplate:
|
|
||||||
return new QuoteTemplateBiz(ct, userId, translationId, roles);
|
|
||||||
|
|
||||||
case AyaType.Unit:
|
case AyaType.Unit:
|
||||||
return new UnitBiz(ct, userId, translationId, roles);
|
return new UnitBiz(ct, userId, translationId, roles);
|
||||||
case AyaType.UnitModel:
|
case AyaType.UnitModel:
|
||||||
@@ -98,9 +94,7 @@ namespace AyaNova.Biz
|
|||||||
case AyaType.WorkOrderItemOutsideService:
|
case AyaType.WorkOrderItemOutsideService:
|
||||||
return new WorkOrderBiz(ct, userId, translationId, roles, UserType.NotService);//default to not service for now arbitrarily on the principle of least access
|
return new WorkOrderBiz(ct, userId, translationId, roles, UserType.NotService);//default to not service for now arbitrarily on the principle of least access
|
||||||
//---
|
//---
|
||||||
case AyaType.WorkOrderTemplate:
|
|
||||||
return new WorkOrderTemplateBiz(ct, userId, translationId, roles);
|
|
||||||
|
|
||||||
case AyaType.Reminder:
|
case AyaType.Reminder:
|
||||||
return new ReminderBiz(ct, userId, translationId, roles);
|
return new ReminderBiz(ct, userId, translationId, roles);
|
||||||
case AyaType.Review:
|
case AyaType.Review:
|
||||||
|
|||||||
@@ -269,25 +269,7 @@ namespace AyaNova.Biz
|
|||||||
Select = AuthorizationRoles.All
|
Select = AuthorizationRoles.All
|
||||||
});
|
});
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//PMTemplate
|
|
||||||
//
|
|
||||||
roles.Add(AyaType.PMTemplate, new BizRoleSet()
|
|
||||||
{
|
|
||||||
Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales | AuthorizationRoles.Tech | AuthorizationRoles.Accounting,
|
|
||||||
ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted,
|
|
||||||
Select = AuthorizationRoles.All
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//PMTemplateItem
|
|
||||||
//
|
|
||||||
roles.Add(AyaType.PMTemplateItem, new BizRoleSet()
|
|
||||||
{
|
|
||||||
Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales | AuthorizationRoles.Tech | AuthorizationRoles.Accounting,
|
|
||||||
ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted,
|
|
||||||
Select = AuthorizationRoles.All
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//Project
|
//Project
|
||||||
@@ -400,26 +382,7 @@ namespace AyaNova.Biz
|
|||||||
Select = AuthorizationRoles.All
|
Select = AuthorizationRoles.All
|
||||||
});
|
});
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//QuoteTemplate
|
|
||||||
//
|
|
||||||
roles.Add(AyaType.QuoteTemplate, new BizRoleSet()
|
|
||||||
{
|
|
||||||
Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales | AuthorizationRoles.Tech | AuthorizationRoles.Accounting,
|
|
||||||
ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted,
|
|
||||||
Select = AuthorizationRoles.All
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//QuoteTemplateItem
|
|
||||||
//
|
|
||||||
roles.Add(AyaType.QuoteTemplateItem, new BizRoleSet()
|
|
||||||
{
|
|
||||||
Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales | AuthorizationRoles.Tech | AuthorizationRoles.Accounting,
|
|
||||||
ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted,
|
|
||||||
Select = AuthorizationRoles.All
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//Unit
|
//Unit
|
||||||
//
|
//
|
||||||
@@ -597,28 +560,6 @@ namespace AyaNova.Biz
|
|||||||
//---
|
//---
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//WorkOrderTemplate
|
|
||||||
//
|
|
||||||
roles.Add(AyaType.WorkOrderTemplate, new BizRoleSet()
|
|
||||||
{
|
|
||||||
Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales | AuthorizationRoles.Tech | AuthorizationRoles.Accounting,
|
|
||||||
ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted,
|
|
||||||
Select = AuthorizationRoles.All
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//WorkOrderTemplateItem
|
|
||||||
//
|
|
||||||
roles.Add(AyaType.WorkOrderTemplateItem, new BizRoleSet()
|
|
||||||
{
|
|
||||||
Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales | AuthorizationRoles.Tech | AuthorizationRoles.Accounting,
|
|
||||||
ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted,
|
|
||||||
Select = AuthorizationRoles.All
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//GLOBAL BIZ SETTINGS
|
//GLOBAL BIZ SETTINGS
|
||||||
|
|||||||
@@ -1,309 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using AyaNova.Util;
|
|
||||||
using AyaNova.Api.ControllerHelpers;
|
|
||||||
using AyaNova.Models;
|
|
||||||
|
|
||||||
namespace AyaNova.Biz
|
|
||||||
{
|
|
||||||
internal class PMTemplateBiz : BizObject, ISearchAbleObject, INotifiableObject
|
|
||||||
{
|
|
||||||
internal PMTemplateBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
|
|
||||||
{
|
|
||||||
ct = dbcontext;
|
|
||||||
UserId = currentUserId;
|
|
||||||
UserTranslationId = userTranslationId;
|
|
||||||
CurrentUserRoles = UserRoles;
|
|
||||||
BizType = AyaType.PMTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static PMTemplateBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null)
|
|
||||||
{
|
|
||||||
if (httpContext != null)
|
|
||||||
return new PMTemplateBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items));
|
|
||||||
else
|
|
||||||
return new PMTemplateBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//EXISTS
|
|
||||||
internal async Task<bool> ExistsAsync(long id)
|
|
||||||
{
|
|
||||||
return await ct.PMTemplate.AnyAsync(z => z.Id == id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//CREATE
|
|
||||||
//
|
|
||||||
internal async Task<PMTemplate> CreateAsync(PMTemplate newObject)
|
|
||||||
{
|
|
||||||
await ValidateAsync(newObject, null);
|
|
||||||
if (HasErrors)
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
|
|
||||||
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
|
||||||
await ct.PMTemplate.AddAsync(newObject);
|
|
||||||
await ct.SaveChangesAsync();
|
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
|
||||||
await SearchIndexAsync(newObject, true);
|
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Created, newObject);
|
|
||||||
return newObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// //DUPLICATE
|
|
||||||
// //
|
|
||||||
// internal async Task<PMTemplate> DuplicateAsync(long id)
|
|
||||||
// {
|
|
||||||
// PMTemplate dbObject = await GetAsync(id, false);
|
|
||||||
// if (dbObject == null)
|
|
||||||
// {
|
|
||||||
// AddError(ApiErrorCode.NOT_FOUND, "id");
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// PMTemplate newObject = new PMTemplate();
|
|
||||||
// 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.PMTemplate.AnyAsync(z => z.Name == newUniqueName);
|
|
||||||
// } while (NotUnique);
|
|
||||||
// newObject.Name = newUniqueName;
|
|
||||||
// newObject.Id = 0;
|
|
||||||
// newObject.Concurrency = 0;
|
|
||||||
// await ct.PMTemplate.AddAsync(newObject);
|
|
||||||
// await ct.SaveChangesAsync();
|
|
||||||
// await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
|
||||||
// await SearchIndexAsync(newObject, true);
|
|
||||||
// await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
|
||||||
// await HandlePotentialNotificationEvent(AyaEvent.Created, newObject);
|
|
||||||
// return newObject;
|
|
||||||
// }
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//GET
|
|
||||||
//
|
|
||||||
internal async Task<PMTemplate> GetAsync(long id, bool logTheGetEvent = true)
|
|
||||||
{
|
|
||||||
var ret = await ct.PMTemplate.SingleOrDefaultAsync(z => z.Id == id);
|
|
||||||
if (logTheGetEvent && ret != null)
|
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, BizType, AyaEvent.Retrieved), ct);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE PARTASSEMBLYBIZ / some of WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//UPDATE
|
|
||||||
//
|
|
||||||
internal async Task<PMTemplate> PutAsync(PMTemplate putObject)
|
|
||||||
{
|
|
||||||
PMTemplate dbObject = await ct.PMTemplate.SingleOrDefaultAsync(z => z.Id == putObject.Id);
|
|
||||||
if (dbObject == null)
|
|
||||||
{
|
|
||||||
AddError(ApiErrorCode.NOT_FOUND, "id");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
PMTemplate SnapshotOfOriginalDBObj = new PMTemplate();
|
|
||||||
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj);
|
|
||||||
CopyObject.Copy(putObject, dbObject, "Id");
|
|
||||||
dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags);
|
|
||||||
dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields);
|
|
||||||
ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
|
|
||||||
await ValidateAsync(dbObject, SnapshotOfOriginalDBObj);
|
|
||||||
if (HasErrors) return null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await ct.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
catch (DbUpdateConcurrencyException)
|
|
||||||
{
|
|
||||||
if (!await ExistsAsync(putObject.Id))
|
|
||||||
AddError(ApiErrorCode.NOT_FOUND);
|
|
||||||
else
|
|
||||||
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
|
|
||||||
await SearchIndexAsync(dbObject, false);
|
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags);
|
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj);
|
|
||||||
return dbObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//DELETE
|
|
||||||
//
|
|
||||||
internal async Task<bool> DeleteAsync(long id)
|
|
||||||
{
|
|
||||||
using (var transaction = await ct.Database.BeginTransactionAsync())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
PMTemplate dbObject = await ct.PMTemplate.SingleOrDefaultAsync(z => z.Id == id);
|
|
||||||
if (dbObject == null)
|
|
||||||
{
|
|
||||||
AddError(ApiErrorCode.NOT_FOUND);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ValidateCanDelete(dbObject);
|
|
||||||
if (HasErrors)
|
|
||||||
return false;
|
|
||||||
if (HasErrors)
|
|
||||||
return false;
|
|
||||||
ct.PMTemplate.Remove(dbObject);
|
|
||||||
await ct.SaveChangesAsync();
|
|
||||||
|
|
||||||
//Log event
|
|
||||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct);
|
|
||||||
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
|
||||||
await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags);
|
|
||||||
await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct);
|
|
||||||
await transaction.CommitAsync();
|
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
//Just re-throw for now, let exception handler deal, but in future may want to deal with this more here
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//SEARCH
|
|
||||||
//
|
|
||||||
private async Task SearchIndexAsync(PMTemplate obj, bool isNew)
|
|
||||||
{
|
|
||||||
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType);
|
|
||||||
DigestSearchText(obj, SearchParams);
|
|
||||||
if (isNew)
|
|
||||||
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
|
|
||||||
else
|
|
||||||
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Search.SearchIndexProcessObjectParameters> GetSearchResultSummary(long id)
|
|
||||||
{
|
|
||||||
var obj = await ct.PMTemplate.SingleOrDefaultAsync(z => z.Id == id);
|
|
||||||
var SearchParams = new Search.SearchIndexProcessObjectParameters();
|
|
||||||
DigestSearchText(obj, SearchParams);
|
|
||||||
return SearchParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DigestSearchText(PMTemplate obj, Search.SearchIndexProcessObjectParameters searchParams)
|
|
||||||
{
|
|
||||||
if (obj != null)
|
|
||||||
searchParams.AddText(obj.Notes)
|
|
||||||
.AddText(obj.Name)
|
|
||||||
.AddText(obj.Wiki)
|
|
||||||
.AddText(obj.Tags)
|
|
||||||
.AddCustomFields(obj.CustomFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//VALIDATION
|
|
||||||
//
|
|
||||||
|
|
||||||
private async Task ValidateAsync(PMTemplate proposedObj, PMTemplate currentObj)
|
|
||||||
{
|
|
||||||
|
|
||||||
bool isNew = currentObj == null;
|
|
||||||
|
|
||||||
//Name required
|
|
||||||
if (string.IsNullOrWhiteSpace(proposedObj.Name))
|
|
||||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name");
|
|
||||||
|
|
||||||
|
|
||||||
//If name is otherwise OK, check that name is unique
|
|
||||||
if (!PropertyHasErrors("Name"))
|
|
||||||
{
|
|
||||||
//Use Any command is efficient way to check existance, it doesn't return the record, just a true or false
|
|
||||||
if (await ct.PMTemplate.AnyAsync(z => z.Name == proposedObj.Name && z.Id != proposedObj.Id))
|
|
||||||
{
|
|
||||||
AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Any form customizations to validate?
|
|
||||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.PMTemplate.ToString());
|
|
||||||
if (FormCustomization != null)
|
|
||||||
{
|
|
||||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
|
||||||
|
|
||||||
//validate users choices for required non custom fields
|
|
||||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
|
||||||
|
|
||||||
//validate custom fields
|
|
||||||
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ValidateCanDelete(PMTemplate inObj)
|
|
||||||
{
|
|
||||||
//whatever needs to be check to delete this object
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// NOTIFICATION PROCESSING
|
|
||||||
//
|
|
||||||
public async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null)
|
|
||||||
{
|
|
||||||
ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger<PMTemplateBiz>();
|
|
||||||
if (ServerBootConfig.SEEDING) return;
|
|
||||||
log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{this.BizType}, AyaEvent:{ayaEvent}]");
|
|
||||||
|
|
||||||
bool isNew = currentObj == null;
|
|
||||||
|
|
||||||
|
|
||||||
//STANDARD EVENTS FOR ALL OBJECTS
|
|
||||||
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);
|
|
||||||
|
|
||||||
//SPECIFIC EVENTS FOR THIS OBJECT
|
|
||||||
|
|
||||||
}//end of process notifications
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
|
|
||||||
@@ -1,307 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
using AyaNova.Util;
|
|
||||||
using AyaNova.Api.ControllerHelpers;
|
|
||||||
using AyaNova.Models;
|
|
||||||
|
|
||||||
namespace AyaNova.Biz
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class QuoteTemplateBiz : BizObject, ISearchAbleObject
|
|
||||||
{
|
|
||||||
|
|
||||||
internal QuoteTemplateBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
|
|
||||||
{
|
|
||||||
ct = dbcontext;
|
|
||||||
UserId = currentUserId;
|
|
||||||
UserTranslationId = userTranslationId;
|
|
||||||
CurrentUserRoles = UserRoles;
|
|
||||||
BizType = AyaType.QuoteTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static QuoteTemplateBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (httpContext != null)
|
|
||||||
return new QuoteTemplateBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items));
|
|
||||||
else//when called internally for internal ops there will be no context so need to set default values for that
|
|
||||||
return new QuoteTemplateBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//EXISTS
|
|
||||||
internal async Task<bool> ExistsAsync(long id)
|
|
||||||
{
|
|
||||||
return await ct.QuoteTemplate.AnyAsync(z => z.Id == id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// GET
|
|
||||||
///
|
|
||||||
///
|
|
||||||
|
|
||||||
internal async Task<QuoteTemplate> 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.QuoteTemplate.SingleOrDefaultAsync(z => z.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<QuoteTemplate> CreateAsync(QuoteTemplate inObj)
|
|
||||||
{
|
|
||||||
await ValidateAsync(inObj, null);
|
|
||||||
if (HasErrors)
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//do stuff with QuoteTemplate
|
|
||||||
QuoteTemplate outObj = inObj;
|
|
||||||
|
|
||||||
outObj.Tags = TagBiz.NormalizeTags(outObj.Tags);
|
|
||||||
outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
|
|
||||||
//Save to db
|
|
||||||
await ct.QuoteTemplate.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 TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
|
|
||||||
|
|
||||||
return outObj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// //DUPLICATE
|
|
||||||
// //
|
|
||||||
|
|
||||||
// internal async Task<QuoteTemplate> DuplicateAsync(QuoteTemplate dbObject)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// QuoteTemplate outObj = new QuoteTemplate();
|
|
||||||
// CopyObject.Copy(dbObject, 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(dbObject.Name, l++, 255);
|
|
||||||
// NotUnique = await ct.QuoteTemplate.AnyAsync(z => z.Name == newUniqueName);
|
|
||||||
// } while (NotUnique);
|
|
||||||
|
|
||||||
// outObj.Name = newUniqueName;
|
|
||||||
|
|
||||||
|
|
||||||
// outObj.Id = 0;
|
|
||||||
// outObj.Concurrency = 0;
|
|
||||||
|
|
||||||
// await ct.QuoteTemplate.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 TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
|
|
||||||
// return outObj;
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE PARTASSEMBLYBIZ / some of WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//UPDATE
|
|
||||||
//
|
|
||||||
|
|
||||||
//put
|
|
||||||
internal async Task<bool> PutAsync(QuoteTemplate dbObject, QuoteTemplate inObj)
|
|
||||||
{
|
|
||||||
|
|
||||||
//make a snapshot of the original for validation but update the original to preserve workflow
|
|
||||||
QuoteTemplate SnapshotOfOriginalDBObj = new QuoteTemplate();
|
|
||||||
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj);
|
|
||||||
|
|
||||||
//Replace the db object with the PUT object
|
|
||||||
CopyObject.Copy(inObj, dbObject, "Id");
|
|
||||||
|
|
||||||
dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags);
|
|
||||||
dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields);
|
|
||||||
|
|
||||||
//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, SnapshotOfOriginalDBObj);
|
|
||||||
if (HasErrors)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//Log event and save context
|
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
|
|
||||||
await SearchIndexAsync(dbObject, false);
|
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//SEARCH
|
|
||||||
//
|
|
||||||
private async Task SearchIndexAsync(QuoteTemplate obj, bool isNew)
|
|
||||||
{
|
|
||||||
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType);
|
|
||||||
DigestSearchText(obj, SearchParams);
|
|
||||||
if (isNew)
|
|
||||||
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
|
|
||||||
else
|
|
||||||
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Search.SearchIndexProcessObjectParameters> GetSearchResultSummary(long id)
|
|
||||||
{
|
|
||||||
var obj = await ct.QuoteTemplate.SingleOrDefaultAsync(z => z.Id == id);
|
|
||||||
var SearchParams = new Search.SearchIndexProcessObjectParameters();
|
|
||||||
DigestSearchText(obj, SearchParams);
|
|
||||||
return SearchParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DigestSearchText(QuoteTemplate obj, Search.SearchIndexProcessObjectParameters searchParams)
|
|
||||||
{
|
|
||||||
if (obj != null)
|
|
||||||
searchParams.AddText(obj.Notes)
|
|
||||||
.AddText(obj.Name)
|
|
||||||
.AddText(obj.Wiki)
|
|
||||||
.AddText(obj.Tags)
|
|
||||||
.AddCustomFields(obj.CustomFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//DELETE
|
|
||||||
//
|
|
||||||
internal async Task<bool> DeleteAsync(QuoteTemplate dbObject)
|
|
||||||
{
|
|
||||||
//Determine if the object can be deleted, do the deletion tentatively
|
|
||||||
//Probably also in here deal with tags and associated search text etc
|
|
||||||
|
|
||||||
//NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObject);
|
|
||||||
if (HasErrors)
|
|
||||||
return false;
|
|
||||||
ct.QuoteTemplate.Remove(dbObject);
|
|
||||||
await ct.SaveChangesAsync();
|
|
||||||
|
|
||||||
//Log event
|
|
||||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct);
|
|
||||||
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
|
||||||
await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags);
|
|
||||||
await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//VALIDATION
|
|
||||||
//
|
|
||||||
|
|
||||||
//Can save or update?
|
|
||||||
private async Task ValidateAsync(QuoteTemplate proposedObj, QuoteTemplate currentObj)
|
|
||||||
{
|
|
||||||
|
|
||||||
//run validation and biz rules
|
|
||||||
bool isNew = currentObj == null;
|
|
||||||
|
|
||||||
//Name required
|
|
||||||
if (string.IsNullOrWhiteSpace(proposedObj.Name))
|
|
||||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//If name is otherwise OK, check that name is unique
|
|
||||||
if (!PropertyHasErrors("Name"))
|
|
||||||
{
|
|
||||||
//Use Any command is efficient way to check existance, it doesn't return the record, just a true or false
|
|
||||||
if (await ct.QuoteTemplate.AnyAsync(z => z.Name == proposedObj.Name && z.Id != proposedObj.Id))
|
|
||||||
{
|
|
||||||
AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Any form customizations to validate?
|
|
||||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.QuoteTemplate.ToString());
|
|
||||||
if (FormCustomization != null)
|
|
||||||
{
|
|
||||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
|
||||||
|
|
||||||
//validate users choices for required non custom fields
|
|
||||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
|
||||||
|
|
||||||
//validate custom fields
|
|
||||||
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Can delete?
|
|
||||||
// private void ValidateCanDelete(QuoteTemplate inObj)
|
|
||||||
// {
|
|
||||||
// //whatever needs to be check to delete this object
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//JOB / OPERATIONS
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
//Other job handlers here...
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
|
|
||||||
@@ -1,322 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
using AyaNova.Util;
|
|
||||||
using AyaNova.Api.ControllerHelpers;
|
|
||||||
using AyaNova.Models;
|
|
||||||
|
|
||||||
namespace AyaNova.Biz
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class WorkOrderTemplateBiz : BizObject, ISearchAbleObject, INotifiableObject
|
|
||||||
{
|
|
||||||
|
|
||||||
internal WorkOrderTemplateBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
|
|
||||||
{
|
|
||||||
ct = dbcontext;
|
|
||||||
UserId = currentUserId;
|
|
||||||
UserTranslationId = userTranslationId;
|
|
||||||
CurrentUserRoles = UserRoles;
|
|
||||||
BizType = AyaType.WorkOrderTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static WorkOrderTemplateBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (httpContext != null)
|
|
||||||
return new WorkOrderTemplateBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items));
|
|
||||||
else//when called internally for internal ops there will be no context so need to set default values for that
|
|
||||||
return new WorkOrderTemplateBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//EXISTS
|
|
||||||
internal async Task<bool> ExistsAsync(long id)
|
|
||||||
{
|
|
||||||
return await ct.WorkOrderTemplate.AnyAsync(z => z.Id == id);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// GET
|
|
||||||
///
|
|
||||||
///
|
|
||||||
|
|
||||||
internal async Task<WorkOrderTemplate> 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.WorkOrderTemplate.SingleOrDefaultAsync(z => z.Id == fetchId);
|
|
||||||
if (logTheGetEvent && ret != null)
|
|
||||||
{
|
|
||||||
//Log
|
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//CREATE
|
|
||||||
|
|
||||||
//Called from route and also seeder
|
|
||||||
internal async Task<WorkOrderTemplate> CreateAsync(WorkOrderTemplate newObject)
|
|
||||||
{
|
|
||||||
await ValidateAsync(newObject, null);
|
|
||||||
if (HasErrors)
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//do stuff with WorkOrderTemplate
|
|
||||||
WorkOrderTemplate outObj = newObject;
|
|
||||||
|
|
||||||
outObj.Tags = TagBiz.NormalizeTags(outObj.Tags);
|
|
||||||
outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
|
|
||||||
//Save to db
|
|
||||||
await ct.WorkOrderTemplate.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 TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
|
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Created, newObject);
|
|
||||||
|
|
||||||
return outObj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// //DUPLICATE
|
|
||||||
// //
|
|
||||||
|
|
||||||
// internal async Task<WorkOrderTemplate> DuplicateAsync(WorkOrderTemplate dbObject)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// WorkOrderTemplate newObject = new WorkOrderTemplate();
|
|
||||||
// CopyObject.Copy(dbObject, newObject, "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(dbObject.Name, l++, 255);
|
|
||||||
// NotUnique = await ct.WorkOrderTemplate.AnyAsync(z => z.Name == newUniqueName);
|
|
||||||
// } while (NotUnique);
|
|
||||||
|
|
||||||
// newObject.Name = newUniqueName;
|
|
||||||
|
|
||||||
|
|
||||||
// newObject.Id = 0;
|
|
||||||
// newObject.Concurrency = 0;
|
|
||||||
|
|
||||||
// await ct.WorkOrderTemplate.AddAsync(newObject);
|
|
||||||
// await ct.SaveChangesAsync();
|
|
||||||
|
|
||||||
// //Handle child and associated items:
|
|
||||||
// await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
|
||||||
// await SearchIndexAsync(newObject, true);
|
|
||||||
// await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
|
||||||
// await HandlePotentialNotificationEvent(AyaEvent.Created, newObject);
|
|
||||||
// return newObject;
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE PARTASSEMBLYBIZ / some of WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//UPDATE
|
|
||||||
//
|
|
||||||
|
|
||||||
//put
|
|
||||||
internal async Task<bool> PutAsync(WorkOrderTemplate dbObject, WorkOrderTemplate inObj)
|
|
||||||
{
|
|
||||||
|
|
||||||
//make a snapshot of the original for validation but update the original to preserve workflow
|
|
||||||
WorkOrderTemplate SnapshotOfOriginalDBObj = new WorkOrderTemplate();
|
|
||||||
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj);
|
|
||||||
|
|
||||||
//Replace the db object with the PUT object
|
|
||||||
CopyObject.Copy(inObj, dbObject, "Id");
|
|
||||||
|
|
||||||
dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags);
|
|
||||||
dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields);
|
|
||||||
|
|
||||||
//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, SnapshotOfOriginalDBObj);
|
|
||||||
if (HasErrors)
|
|
||||||
return false;
|
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
|
|
||||||
await SearchIndexAsync(dbObject, false);
|
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags);
|
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//SEARCH
|
|
||||||
//
|
|
||||||
private async Task SearchIndexAsync(WorkOrderTemplate obj, bool isNew)
|
|
||||||
{
|
|
||||||
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType);
|
|
||||||
DigestSearchText(obj, SearchParams);
|
|
||||||
if (isNew)
|
|
||||||
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
|
|
||||||
else
|
|
||||||
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Search.SearchIndexProcessObjectParameters> GetSearchResultSummary(long id)
|
|
||||||
{
|
|
||||||
var obj = await ct.WorkOrderTemplate.SingleOrDefaultAsync(z => z.Id == id);
|
|
||||||
var SearchParams = new Search.SearchIndexProcessObjectParameters();
|
|
||||||
DigestSearchText(obj, SearchParams);
|
|
||||||
return SearchParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DigestSearchText(WorkOrderTemplate obj, Search.SearchIndexProcessObjectParameters searchParams)
|
|
||||||
{
|
|
||||||
if (obj != null)
|
|
||||||
searchParams.AddText(obj.Notes)
|
|
||||||
.AddText(obj.Name)
|
|
||||||
.AddText(obj.Wiki)
|
|
||||||
.AddText(obj.Tags)
|
|
||||||
.AddCustomFields(obj.CustomFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
// WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED
|
|
||||||
//###################################################################################################################################################
|
|
||||||
//###################################################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//DELETE
|
|
||||||
//
|
|
||||||
internal async Task<bool> DeleteAsync(WorkOrderTemplate dbObject)
|
|
||||||
{
|
|
||||||
//Determine if the object can be deleted, do the deletion tentatively
|
|
||||||
//Probably also in here deal with tags and associated search text etc
|
|
||||||
|
|
||||||
//NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObject);
|
|
||||||
if (HasErrors)
|
|
||||||
return false;
|
|
||||||
ct.WorkOrderTemplate.Remove(dbObject);
|
|
||||||
await ct.SaveChangesAsync();
|
|
||||||
|
|
||||||
//Log event
|
|
||||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct);
|
|
||||||
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
|
||||||
await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags);
|
|
||||||
await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct);
|
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//VALIDATION
|
|
||||||
//
|
|
||||||
|
|
||||||
//Can save or update?
|
|
||||||
private async Task ValidateAsync(WorkOrderTemplate proposedObj, WorkOrderTemplate currentObj)
|
|
||||||
{
|
|
||||||
|
|
||||||
//run validation and biz rules
|
|
||||||
bool isNew = currentObj == null;
|
|
||||||
|
|
||||||
//Name required
|
|
||||||
if (string.IsNullOrWhiteSpace(proposedObj.Name))
|
|
||||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name");
|
|
||||||
|
|
||||||
//If name is otherwise OK, check that name is unique
|
|
||||||
if (!PropertyHasErrors("Name"))
|
|
||||||
{
|
|
||||||
//Use Any command is efficient way to check existance, it doesn't return the record, just a true or false
|
|
||||||
if (await ct.WorkOrderTemplate.AnyAsync(z => z.Name == proposedObj.Name && z.Id != proposedObj.Id))
|
|
||||||
{
|
|
||||||
AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Any form customizations to validate?
|
|
||||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderTemplate.ToString());
|
|
||||||
if (FormCustomization != null)
|
|
||||||
{
|
|
||||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
|
||||||
|
|
||||||
//validate users choices for required non custom fields
|
|
||||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
|
||||||
|
|
||||||
//validate custom fields
|
|
||||||
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Can delete?
|
|
||||||
// private void ValidateCanDelete(WorkOrderTemplate inObj)
|
|
||||||
// {
|
|
||||||
// //whatever needs to be check to delete this object
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// NOTIFICATION PROCESSING
|
|
||||||
//
|
|
||||||
public async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null)
|
|
||||||
{
|
|
||||||
ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger<WorkOrderTemplateBiz>();
|
|
||||||
if (ServerBootConfig.SEEDING) return;
|
|
||||||
log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{this.BizType}, AyaEvent:{ayaEvent}]");
|
|
||||||
|
|
||||||
bool isNew = currentObj == null;
|
|
||||||
|
|
||||||
|
|
||||||
//STANDARD EVENTS FOR ALL OBJECTS
|
|
||||||
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);
|
|
||||||
|
|
||||||
//SPECIFIC EVENTS FOR THIS OBJECT
|
|
||||||
|
|
||||||
}//end of process notifications
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
|
|
||||||
@@ -54,15 +54,12 @@ namespace AyaNova.Models
|
|||||||
public virtual DbSet<PartAssemblyItem> PartAssemblyItem { get; set; }
|
public virtual DbSet<PartAssemblyItem> PartAssemblyItem { get; set; }
|
||||||
public virtual DbSet<PM> PM { get; set; }
|
public virtual DbSet<PM> PM { get; set; }
|
||||||
public virtual DbSet<PMItem> PMItem { get; set; }
|
public virtual DbSet<PMItem> PMItem { get; set; }
|
||||||
public virtual DbSet<PMTemplate> PMTemplate { get; set; }
|
|
||||||
public virtual DbSet<PMTemplateItem> PMTemplateItem { get; set; }
|
|
||||||
public virtual DbSet<Project> Project { get; set; }
|
public virtual DbSet<Project> Project { get; set; }
|
||||||
public virtual DbSet<PurchaseOrder> PurchaseOrder { get; set; }
|
public virtual DbSet<PurchaseOrder> PurchaseOrder { get; set; }
|
||||||
public virtual DbSet<PurchaseOrderItem> PurchaseOrderItem { get; set; }
|
public virtual DbSet<PurchaseOrderItem> PurchaseOrderItem { get; set; }
|
||||||
public virtual DbSet<Quote> Quote { get; set; }
|
|
||||||
public virtual DbSet<QuoteItem> QuoteItem { get; set; }
|
|
||||||
public virtual DbSet<QuoteTemplate> QuoteTemplate { get; set; }
|
|
||||||
public virtual DbSet<QuoteTemplateItem> QuoteTemplateItem { get; set; }
|
|
||||||
public virtual DbSet<Unit> Unit { get; set; }
|
public virtual DbSet<Unit> Unit { get; set; }
|
||||||
public virtual DbSet<UnitModel> UnitModel { get; set; }
|
public virtual DbSet<UnitModel> UnitModel { get; set; }
|
||||||
public virtual DbSet<Vendor> Vendor { get; set; }
|
public virtual DbSet<Vendor> Vendor { get; set; }
|
||||||
@@ -92,9 +89,25 @@ namespace AyaNova.Models
|
|||||||
public virtual DbSet<WorkOrderItemPriority> WorkOrderItemPriority { get; set; }
|
public virtual DbSet<WorkOrderItemPriority> WorkOrderItemPriority { get; set; }
|
||||||
public virtual DbSet<WorkOrderItemStatus> WorkOrderItemStatus { get; set; }
|
public virtual DbSet<WorkOrderItemStatus> WorkOrderItemStatus { get; set; }
|
||||||
|
|
||||||
//WorkOrderTemplate
|
//Quote
|
||||||
public virtual DbSet<WorkOrderTemplate> WorkOrderTemplate { get; set; }
|
public virtual DbSet<Quote> Quote { get; set; }
|
||||||
public virtual DbSet<WorkOrderTemplateItem> WorkOrderTemplateItem { get; set; }
|
public virtual DbSet<QuoteItem> QuoteItem { get; set; }
|
||||||
|
public virtual DbSet<QuoteState> QuoteState { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemExpense> QuoteItemExpense { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemLabor> QuoteItemLabor { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemLoan> QuoteItemLoan { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemPart> QuoteItemPart { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemScheduledUser> QuoteItemScheduledUser { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemTask> QuoteItemTask { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemTravel> QuoteItemTravel { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemUnit> QuoteItemUnit { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemOutsideService> QuoteItemOutsideService { get; set; }
|
||||||
|
public virtual DbSet<QuoteStatus> QuoteStatus { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemPriority> QuoteItemPriority { get; set; }
|
||||||
|
public virtual DbSet<QuoteItemStatus> QuoteItemStatus { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public virtual DbSet<Logo> Logo { get; set; }
|
public virtual DbSet<Logo> Logo { get; set; }
|
||||||
public virtual DbSet<Report> Report { get; set; }
|
public virtual DbSet<Report> Report { get; set; }
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace AyaNova.Models
|
|
||||||
{
|
|
||||||
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
|
|
||||||
//otherwise the server will call it an invalid record if the field isn't sent from client
|
|
||||||
|
|
||||||
public class PMTemplate : ICoreBizObjectModel
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public uint Concurrency { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Active { get; set; }
|
|
||||||
public string Notes { get; set; }
|
|
||||||
public string Wiki { get; set; }
|
|
||||||
public string CustomFields { get; set; }
|
|
||||||
public List<string> Tags { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public PMTemplate()
|
|
||||||
{
|
|
||||||
Tags = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
|
||||||
public AyaType AyaType { get => AyaType.PMTemplate; }
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace AyaNova.Models
|
|
||||||
{
|
|
||||||
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
|
|
||||||
//otherwise the server will call it an invalid record if the field isn't sent from client
|
|
||||||
|
|
||||||
public class PMTemplateItem : ICoreBizObjectModel
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public uint Concurrency { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Active { get; set; }
|
|
||||||
public string Notes { get; set; }
|
|
||||||
public string Wiki { get; set; }
|
|
||||||
public string CustomFields { get; set; }
|
|
||||||
public List<string> Tags { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public PMTemplateItem()
|
|
||||||
{
|
|
||||||
Tags = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
|
||||||
public AyaType AyaType { get => AyaType.PMTemplateItem; }
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
@@ -6,9 +7,7 @@ using AyaNova.Biz;
|
|||||||
|
|
||||||
namespace AyaNova.Models
|
namespace AyaNova.Models
|
||||||
{
|
{
|
||||||
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
|
|
||||||
//otherwise the server will call it an invalid record if the field isn't sent from client
|
|
||||||
|
|
||||||
public class Quote : ICoreBizObjectModel
|
public class Quote : ICoreBizObjectModel
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
@@ -16,37 +15,148 @@ namespace AyaNova.Models
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public long Serial { get; set; }
|
public long Serial { get; set; }
|
||||||
public bool Active { get; set; }
|
|
||||||
public string Notes { get; set; }
|
public string Notes { get; set; }//WAS "SUMMARY"
|
||||||
public string Wiki { get; set; }
|
public string Wiki { get; set; }
|
||||||
public string CustomFields { get; set; }
|
public string CustomFields { get; set; }
|
||||||
public List<string> Tags { get; set; }
|
public List<string> Tags { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public long CustomerId { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public string CustomerViz { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public string CustomerTechNotesViz { get; set; }
|
||||||
|
|
||||||
|
public long? ProjectId { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public string ProjectViz { get; set; }
|
||||||
|
public string InternalReferenceNumber { get; set; }
|
||||||
|
public string CustomerReferenceNumber { get; set; }
|
||||||
|
public string CustomerContactName { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
|
||||||
|
public DateTime? ServiceDate { get; set; }
|
||||||
|
public DateTime? CompleteByDate { get; set; }
|
||||||
|
public TimeSpan DurationToCompleted { get; set; } = TimeSpan.Zero;
|
||||||
|
public string InvoiceNumber { get; set; }
|
||||||
|
public string CustomerSignature { get; set; }
|
||||||
|
public string CustomerSignatureName { get; set; }
|
||||||
|
public DateTime? CustomerSignatureCaptured { get; set; }
|
||||||
|
public string TechSignature { get; set; }
|
||||||
|
public string TechSignatureName { get; set; }
|
||||||
|
public DateTime? TechSignatureCaptured { get; set; }
|
||||||
|
public bool Onsite { get; set; }
|
||||||
|
public long? ContractId { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public string ContractViz { get; set; }
|
||||||
|
|
||||||
|
//redundant field to speed up list queries
|
||||||
|
//(added after status system already coded)
|
||||||
|
public long? LastStatusId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
//workaround for notification
|
//POSTAL ADDRESS / "BILLING ADDRESS"
|
||||||
|
public string PostAddress { get; set; }
|
||||||
|
public string PostCity { get; set; }
|
||||||
|
public string PostRegion { get; set; }
|
||||||
|
public string PostCountry { get; set; }
|
||||||
|
public string PostCode { get; set; }
|
||||||
|
|
||||||
|
//PHYSICAL ADDRESS / "SERVICE ADDRESS"
|
||||||
|
public string Address { get; set; }
|
||||||
|
public string City { get; set; }
|
||||||
|
public string Region { get; set; }
|
||||||
|
public string Country { get; set; }
|
||||||
|
public decimal? Latitude { get; set; }
|
||||||
|
public decimal? Longitude { get; set; }
|
||||||
|
|
||||||
|
public List<WorkOrderItem> Items { get; set; } = new List<WorkOrderItem>();
|
||||||
|
public List<WorkOrderState> States { get; set; } = new List<WorkOrderState>();
|
||||||
|
|
||||||
|
|
||||||
|
//UTILITY FIELDS
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsLockedAtServer { get; set; } = false;//signal to client that it came from the server in a locked state
|
||||||
|
[NotMapped]
|
||||||
|
public string AlertViz { get; set; } = null;
|
||||||
|
[NotMapped]
|
||||||
|
public string FromQuoteViz { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public string FromPMViz { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public string FromCSRViz { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsCompleteRecord { get; set; } = true;//indicates if some items were removed due to user role / type restrictions (i.e. woitems they are not scheduled on)
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public bool UserIsRestrictedType { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool UserIsTechRestricted { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool UserIsSubContractorFull { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool UserIsSubContractorRestricted { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool UserCanViewPartCosts { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool UserCanViewLaborOrTravelRateCosts { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool UserCanViewLoanerCosts { get; set; }
|
||||||
|
|
||||||
|
[NotMapped, JsonIgnore]
|
||||||
|
public AyaType AyaType { get => AyaType.WorkOrder; }
|
||||||
|
|
||||||
|
//workaround for notification
|
||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
todo: Consider adding latitude / longitude to wo, quote, pm objects
|
|
||||||
can copy over from the unit or customer or set themselves
|
|
||||||
and can always hide
|
|
||||||
means wo could be scheduled for ad-hoc locations and serviced that way, i.e. a truck parked on the side of the highway etc
|
|
||||||
*/
|
|
||||||
//dependents
|
|
||||||
public List<QuoteItem> QuoteItems { get; set; }
|
|
||||||
|
|
||||||
public Quote()
|
|
||||||
{
|
|
||||||
Tags = new List<string>();
|
|
||||||
QuoteItems = new List<QuoteItem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
|
||||||
public AyaType AyaType { get => AyaType.Quote; }
|
|
||||||
|
|
||||||
}//eoc
|
}//eoc
|
||||||
|
|
||||||
}//eons
|
}//eons
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
QUOTE FIELDS
|
||||||
|
CREATE TABLE [dbo].[AWORKORDERQUOTE](
|
||||||
|
[AID] [uniqueidentifier] NOT NULL,
|
||||||
|
[AWORKORDERID] [uniqueidentifier] NOT NULL,
|
||||||
|
[ACREATOR] [uniqueidentifier] NOT NULL,
|
||||||
|
[AMODIFIER] [uniqueidentifier] NOT NULL,
|
||||||
|
[ACREATED] [datetime] NOT NULL,
|
||||||
|
[AMODIFIED] [datetime] NOT NULL,
|
||||||
|
[AQUOTENUMBER] [int] IDENTITY(1,1) NOT NULL,
|
||||||
|
[AQUOTESTATUSTYPE] [smallint] NULL,
|
||||||
|
[APREPAREDBYID] [uniqueidentifier] NULL,
|
||||||
|
[AQUOTEREQUESTDATE] [datetime] NULL,
|
||||||
|
[AINTRODUCTION] [nvarchar](255) NULL,
|
||||||
|
[AVALIDUNTILDATE] [datetime] NULL,
|
||||||
|
[ADATESUBMITTED] [datetime] NULL,
|
||||||
|
[ADATEAPPROVED] [datetime] NULL,
|
||||||
|
PRIMARY KEY NONCLUSTERED
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QUOTE DOESN'T NEED THESE FIELDS
|
||||||
|
|
||||||
|
CREATE TABLE [dbo].[AWORKORDERSERVICE](
|
||||||
|
[AID] [uniqueidentifier] NOT NULL,
|
||||||
|
[AWORKORDERID] [uniqueidentifier] NOT NULL,
|
||||||
|
[ACREATOR] [uniqueidentifier] NOT NULL,
|
||||||
|
[AMODIFIER] [uniqueidentifier] NOT NULL,
|
||||||
|
[ACREATED] [datetime] NOT NULL,
|
||||||
|
[AMODIFIED] [datetime] NOT NULL,
|
||||||
|
[AWORKORDERSTATUSID] [uniqueidentifier] NULL,//## Replaced by workorderstate collection
|
||||||
|
[ASERVICEDATE] [datetime] NULL,
|
||||||
|
[AINVOICENUMBER] [nvarchar](255) NULL,
|
||||||
|
[ASERVICENUMBER] [int] IDENTITY(1,1) NOT NULL,//## replaced by Serial field
|
||||||
|
[AQUOTEWORKORDERID] [uniqueidentifier] NULL,
|
||||||
|
[ACLIENTREQUESTID] [uniqueidentifier] NULL,//# now FromCSRId
|
||||||
|
[APREVENTIVEMAINTENANCEID] [uniqueidentifier] NULL,
|
||||||
|
[ACLOSEBYDATE] [datetime] NULL,//## Now CompleteByDate
|
||||||
|
[ASIGNATURE] [ntext] NULL,//# now customersignature (more sig types coming)
|
||||||
|
[ASIGNED] [datetime] NULL,//# now CustomerSignatureCaptured
|
||||||
|
*/
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace AyaNova.Models
|
|
||||||
{
|
|
||||||
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
|
|
||||||
//otherwise the server will call it an invalid record if the field isn't sent from client
|
|
||||||
|
|
||||||
public class QuoteTemplate : ICoreBizObjectModel
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public uint Concurrency { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Active { get; set; }
|
|
||||||
public string Notes { get; set; }
|
|
||||||
public string Wiki { get; set; }
|
|
||||||
public string CustomFields { get; set; }
|
|
||||||
public List<string> Tags { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public QuoteTemplate()
|
|
||||||
{
|
|
||||||
Tags = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
|
||||||
public AyaType AyaType { get => AyaType.QuoteTemplate; }
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace AyaNova.Models
|
|
||||||
{
|
|
||||||
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
|
|
||||||
//otherwise the server will call it an invalid record if the field isn't sent from client
|
|
||||||
|
|
||||||
public class QuoteTemplateItem : ICoreBizObjectModel
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public uint Concurrency { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Active { get; set; }
|
|
||||||
public string Notes { get; set; }
|
|
||||||
public string Wiki { get; set; }
|
|
||||||
public string CustomFields { get; set; }
|
|
||||||
public List<string> Tags { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public QuoteTemplateItem()
|
|
||||||
{
|
|
||||||
Tags = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
|
||||||
public AyaType AyaType { get => AyaType.QuoteTemplateItem; }
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace AyaNova.Models
|
|
||||||
{
|
|
||||||
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
|
|
||||||
//otherwise the server will call it an invalid record if the field isn't sent from client
|
|
||||||
|
|
||||||
public class WorkOrderTemplate : ICoreBizObjectModel
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public uint Concurrency { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Active { get; set; }
|
|
||||||
public string Notes { get; set; }
|
|
||||||
public string Wiki { get; set; }
|
|
||||||
public string CustomFields { get; set; }
|
|
||||||
public List<string> Tags { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public WorkOrderTemplate()
|
|
||||||
{
|
|
||||||
Tags = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
|
||||||
public AyaType AyaType { get => AyaType.WorkOrderTemplate; }
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AyaNova.Biz;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace AyaNova.Models
|
|
||||||
{
|
|
||||||
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
|
|
||||||
//otherwise the server will call it an invalid record if the field isn't sent from client
|
|
||||||
|
|
||||||
public class WorkOrderTemplateItem : ICoreBizObjectModel
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public uint Concurrency { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
public bool Active { get; set; }
|
|
||||||
public string Notes { get; set; }
|
|
||||||
public string Wiki { get; set; }
|
|
||||||
public string CustomFields { get; set; }
|
|
||||||
public List<string> Tags { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public WorkOrderTemplateItem()
|
|
||||||
{
|
|
||||||
Tags = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
|
||||||
public AyaType AyaType { get => AyaType.WorkOrderTemplateItem; }
|
|
||||||
|
|
||||||
}//eoc
|
|
||||||
|
|
||||||
}//eons
|
|
||||||
@@ -896,30 +896,28 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
|||||||
|
|
||||||
//----------
|
//----------
|
||||||
|
|
||||||
//WORKORDERTEMPLATE
|
|
||||||
await ExecQueryAsync("CREATE TABLE aworkordertemplate (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
|
||||||
await ExecQueryAsync("ALTER TABLE acustomer ADD column defaultservicetemplateid BIGINT NULL REFERENCES aworkordertemplate");
|
|
||||||
|
|
||||||
//WORKORDERTEMPLATEITEM
|
/*
|
||||||
await ExecQueryAsync("CREATE TABLE aworkordertemplateitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
██████╗ ██╗ ██╗ ██████╗ ████████╗███████╗
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
██╔═══██╗██║ ██║██╔═══██╗╚══██╔══╝██╔════╝
|
||||||
|
██║ ██║██║ ██║██║ ██║ ██║ █████╗
|
||||||
|
██║▄▄ ██║██║ ██║██║ ██║ ██║ ██╔══╝
|
||||||
|
╚██████╔╝╚██████╔╝╚██████╔╝ ██║ ███████╗
|
||||||
|
╚══▀▀═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
||||||
|
*/
|
||||||
|
|
||||||
//QUOTE
|
|
||||||
await ExecQueryAsync("CREATE TABLE aquote (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, serial BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, active BOOL NOT NULL, "
|
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
|
||||||
|
|
||||||
//QUOTEITEM
|
|
||||||
await ExecQueryAsync("CREATE TABLE aquoteitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, quoteid BIGINT NOT NULL REFERENCES aquote (id), name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
|
||||||
|
|
||||||
//QUOTETEMPLATE
|
// //QUOTE
|
||||||
await ExecQueryAsync("CREATE TABLE aquotetemplate (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
// await ExecQueryAsync("CREATE TABLE aquote (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, serial BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, active BOOL NOT NULL, "
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
// + "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
||||||
|
|
||||||
|
// //QUOTEITEM
|
||||||
|
// await ExecQueryAsync("CREATE TABLE aquoteitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, quoteid BIGINT NOT NULL REFERENCES aquote (id), name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
||||||
|
// + "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
||||||
|
|
||||||
|
|
||||||
//QUOTETEMPLATEITEM
|
|
||||||
await ExecQueryAsync("CREATE TABLE aquotetemplateitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
|
||||||
|
|
||||||
//PM
|
//PM
|
||||||
await ExecQueryAsync("CREATE TABLE apm (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, serial BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, active BOOL NOT NULL, "
|
await ExecQueryAsync("CREATE TABLE apm (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, serial BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, active BOOL NOT NULL, "
|
||||||
@@ -928,15 +926,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
|||||||
//PMITEM
|
//PMITEM
|
||||||
await ExecQueryAsync("CREATE TABLE apmitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, pmid BIGINT NOT NULL REFERENCES apm (id), name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
await ExecQueryAsync("CREATE TABLE apmitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, pmid BIGINT NOT NULL REFERENCES apm (id), name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
||||||
|
|
||||||
//PMTEMPLATE
|
|
||||||
await ExecQueryAsync("CREATE TABLE apmtemplate (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
|
||||||
|
|
||||||
//PMTEMPLATEITEM
|
|
||||||
await ExecQueryAsync("CREATE TABLE apmtemplateitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, "
|
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY )");
|
|
||||||
|
|
||||||
//CUSTOMERSERVICEREQUEST
|
//CUSTOMERSERVICEREQUEST
|
||||||
await ExecQueryAsync("CREATE TABLE acustomerservicerequest (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL, "
|
await ExecQueryAsync("CREATE TABLE acustomerservicerequest (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL, "
|
||||||
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY, "
|
+ "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY, "
|
||||||
|
|||||||
Reference in New Issue
Block a user