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_TEMPORARY_SERVER_FILES": "c:\\temp\\RavenTestData\\tempfiles",
|
||||
"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_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_13\\bin\\"
|
||||
},
|
||||
|
||||
@@ -233,4 +233,4 @@ https://en.wikipedia.org/wiki/Non-functional_requirement
|
||||
|
||||
|
||||
## 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]
|
||||
PMItem = 22,
|
||||
[CoreBizObject]
|
||||
PMTemplate = 23,
|
||||
unused23 = 23,
|
||||
[CoreBizObject]
|
||||
PMTemplateItem = 24,
|
||||
unused24 = 24,
|
||||
[CoreBizObject]
|
||||
Project = 25,
|
||||
[CoreBizObject]
|
||||
@@ -66,9 +66,9 @@ namespace AyaNova.Biz
|
||||
[CoreBizObject]
|
||||
QuoteItem = 28,
|
||||
[CoreBizObject]
|
||||
QuoteTemplate = 29,
|
||||
unused29 = 29,
|
||||
[CoreBizObject]
|
||||
QuoteTemplateItem = 30,
|
||||
unused30 = 30,
|
||||
[CoreBizObject]
|
||||
Unit = 31,
|
||||
[CoreBizObject]
|
||||
@@ -100,9 +100,9 @@ namespace AyaNova.Biz
|
||||
WorkOrderItemUnit = 44,
|
||||
//---
|
||||
[CoreBizObject]
|
||||
WorkOrderTemplate = 45,
|
||||
unused45 = 45,
|
||||
[CoreBizObject]
|
||||
WorkOrderTemplateItem = 46,
|
||||
unused46 = 46,
|
||||
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
|
||||
Backup = 49,
|
||||
|
||||
@@ -56,10 +56,7 @@ namespace AyaNova.Biz
|
||||
return await ct.PM.AnyAsync(z => z.Id == id);
|
||||
case AyaType.PMItem:
|
||||
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:
|
||||
return await ct.Project.AnyAsync(z => z.Id == id);
|
||||
case AyaType.PurchaseOrder:
|
||||
@@ -68,10 +65,7 @@ namespace AyaNova.Biz
|
||||
return await ct.Quote.AnyAsync(z => z.Id == id);
|
||||
case AyaType.QuoteItem:
|
||||
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:
|
||||
return await ct.Unit.AnyAsync(z => z.Id == id);
|
||||
case AyaType.UnitModel:
|
||||
@@ -104,10 +98,7 @@ namespace AyaNova.Biz
|
||||
case AyaType.WorkOrderItemOutsideService:
|
||||
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:
|
||||
return await ct.Report.AnyAsync(z => z.Id == id);
|
||||
case AyaType.Reminder:
|
||||
|
||||
@@ -64,8 +64,6 @@ namespace AyaNova.Biz
|
||||
|
||||
case AyaType.PM:
|
||||
return new PMBiz(ct, userId, translationId, roles);
|
||||
case AyaType.PMTemplate:
|
||||
return new PMTemplateBiz(ct, userId, translationId, roles);
|
||||
|
||||
case AyaType.Project:
|
||||
return new ProjectBiz(ct, userId, translationId, roles);
|
||||
@@ -74,8 +72,6 @@ namespace AyaNova.Biz
|
||||
case AyaType.Quote:
|
||||
return new QuoteBiz(ct, userId, translationId, roles);
|
||||
|
||||
case AyaType.QuoteTemplate:
|
||||
return new QuoteTemplateBiz(ct, userId, translationId, roles);
|
||||
|
||||
case AyaType.Unit:
|
||||
return new UnitBiz(ct, userId, translationId, roles);
|
||||
@@ -98,8 +94,6 @@ namespace AyaNova.Biz
|
||||
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
|
||||
//---
|
||||
case AyaType.WorkOrderTemplate:
|
||||
return new WorkOrderTemplateBiz(ct, userId, translationId, roles);
|
||||
|
||||
case AyaType.Reminder:
|
||||
return new ReminderBiz(ct, userId, translationId, roles);
|
||||
|
||||
@@ -269,25 +269,7 @@ namespace AyaNova.Biz
|
||||
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
|
||||
@@ -400,25 +382,6 @@ namespace AyaNova.Biz
|
||||
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
|
||||
@@ -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
|
||||
|
||||
@@ -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<PM> PM { 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<PurchaseOrder> PurchaseOrder { 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<UnitModel> UnitModel { 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<WorkOrderItemStatus> WorkOrderItemStatus { get; set; }
|
||||
|
||||
//WorkOrderTemplate
|
||||
public virtual DbSet<WorkOrderTemplate> WorkOrderTemplate { get; set; }
|
||||
public virtual DbSet<WorkOrderTemplateItem> WorkOrderTemplateItem { get; set; }
|
||||
//Quote
|
||||
public virtual DbSet<Quote> Quote { 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<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.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
@@ -6,8 +7,6 @@ using AyaNova.Biz;
|
||||
|
||||
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
|
||||
{
|
||||
@@ -16,37 +15,148 @@ namespace AyaNova.Models
|
||||
|
||||
[Required]
|
||||
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 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; }
|
||||
|
||||
|
||||
//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]
|
||||
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
|
||||
|
||||
}//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
|
||||
await ExecQueryAsync("CREATE TABLE aquotetemplate (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 )");
|
||||
|
||||
//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 )");
|
||||
// //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 )");
|
||||
|
||||
|
||||
|
||||
//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, "
|
||||
@@ -929,14 +927,6 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
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 )");
|
||||
|
||||
//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
|
||||
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, "
|
||||
|
||||
Reference in New Issue
Block a user