This commit is contained in:
2020-05-07 22:16:03 +00:00
parent a12065e8f3
commit 80a43b1576
3 changed files with 224 additions and 38 deletions

View File

@@ -145,6 +145,7 @@ namespace AyaNova.Api.Controllers
// 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
//NO, NOT HERE, in biz object surely?
return Ok(ApiOkResponse.Response(o, !Authorized.HasModifyRole(HttpContext.Items, biz.BizType)));
}
@@ -177,6 +178,7 @@ namespace AyaNova.Api.Controllers
if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType))
return StatusCode(403, new ApiNotAuthorizedResponse());
biz.PutAsync(id, updatedObject);
//todo: handle concurrency in biz object, what to do?
// var o = await biz.PutAsync(id, updatedObject);

View File

@@ -272,88 +272,270 @@ namespace AyaNova.Biz
// }
#endregion workorder level
#region WorkOrderItem level
////////////////////////////////////////////////////////////////////////////////////////////////
//EXISTS
internal async Task<bool> ItemExistsAsync(long id)
{
return await ct.WorkOrderItem.AnyAsync(e => e.Id == id);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//CREATE
//
internal async Task<WorkOrder> CreateItemAsync(WorkOrderItem newObject)
internal async Task<WorkOrderItem> CreateItemAsync(WorkOrderItem newObject)
{
await ValidateAsync(newObject, null);
await ItemValidateAsync(newObject, null);
if (HasErrors)
return null;
else
{
newObject.Serial = ServerBootConfig.WORKORDER_SERIAL.GetNext();
newObject.Tags = TagUtil.NormalizeTags(newObject.Tags);
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
await ct.WorkOrder.AddAsync(newObject);
await ct.WorkOrderItem.AddAsync(newObject);
await ct.SaveChangesAsync();
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
await SearchIndexAsync(newObject, true);
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItem, AyaEvent.Created), ct);
await ItemSearchIndexAsync(newObject, true);
await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
return newObject;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
//VALIDATION
//
//Can save or update?
private async Task ValidateItemAsync(WorkOrderItem proposedObj, WorkOrderItem currentObj)
//
private async Task ItemValidateAsync(WorkOrderItem proposedObj, WorkOrderItem currentObj)
{
//run validation and biz rules
bool isNew = currentObj == null;
// //Name required
// if (string.IsNullOrWhiteSpace(proposedObj.Name))
// AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name");
// //Name must be less than 255 characters
// if (proposedObj.Name.Length > 255)
// AddError(ApiErrorCode.VALIDATION_LENGTH_EXCEEDED, "Name", "255 max");
// //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.WorkOrder.AnyAsync(m => m.Name == proposedObj.Name && m.Id != proposedObj.Id))
// {
// AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name");
// }
// }
//does it have a valid workorder id
if (proposedObj.WorkorderId == 0)
AddError(ApiErrorCode.VALIDATION_REQUIRED, "WorkorderId");
else if (!await WorkOrderExistsAsync(proposedObj.WorkorderId))
{
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkorderId");
}
//Any form customizations to validate?
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(x => x.FormKey == AyaType.WorkOrder.ToString());
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(x => x.FormKey == AyaType.WorkOrderItem.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);
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);//note: this is passed only to add errors
//validate custom fields
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
}
}
//Can delete?
// private void ValidateCanDelete(WorkOrder inObj)
// //Can delete?
// private void ValidateCanDeleteItem(WorkOrderItem inObj)
// {
// //whatever needs to be check to delete this object
// }
private async Task ItemSearchIndexAsync(WorkOrderItem obj, bool isNew)
{
//SEARCH INDEXING
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, AyaType.WorkOrderItem);
SearchParams.AddText(obj.Notes).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields);
if (isNew)
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
else
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
}
public async Task<Search.SearchIndexProcessObjectParameters> ItemGetSearchResultSummary(long id)
{
var obj = await ct.WorkOrderItem.SingleOrDefaultAsync(m => m.Id == id);
var SearchParams = new Search.SearchIndexProcessObjectParameters();
if (obj != null)
SearchParams.AddText(obj.Notes).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields);
return SearchParams;
}
#endregion work order item level
#region WorkOrderItemLabor level
////////////////////////////////////////////////////////////////////////////////////////////////
//EXISTS
internal async Task<bool> LaborExistsAsync(long id)
{
return await ct.WorkOrderItemLabor.AnyAsync(e => e.Id == id);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//CREATE
//
internal async Task<WorkOrderItemLabor> LaborCreateAsync(WorkOrderItemLabor newObject)
{
await LaborValidateAsync(newObject, null);
if (HasErrors)
return null;
else
{
newObject.Tags = TagUtil.NormalizeTags(newObject.Tags);
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
await ct.WorkOrderItemLabor.AddAsync(newObject);
await ct.SaveChangesAsync();
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemLabor, AyaEvent.Created), ct);
await LaborSearchIndexAsync(newObject, true);
await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
return newObject;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//VALIDATION
//
private async Task LaborValidateAsync(WorkOrderItemLabor proposedObj, WorkOrderItemLabor currentObj)
{
//run validation and biz rules
bool isNew = currentObj == null;
if (proposedObj.WorkorderItemId == 0)
AddError(ApiErrorCode.VALIDATION_REQUIRED, "WorkorderItemId");
else if (!await ItemExistsAsync(proposedObj.WorkorderItemId))
{
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkorderItemId");
}
//Any form customizations to validate?
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(x => x.FormKey == AyaType.WorkOrderItemLabor.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);//note: this is passed only to add errors
//validate custom fields
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
}
}
// //Can delete?
// private void LaborValidateCanDelete(WorkOrderItemLabor inObj)
// {
// //whatever needs to be check to delete this object
// }
private async Task LaborSearchIndexAsync(WorkOrderItemLabor obj, bool isNew)
{
//SEARCH INDEXING
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, AyaType.WorkOrderItemLabor);
SearchParams.AddText(obj.Notes).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields);
if (isNew)
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
else
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
}
public async Task<Search.SearchIndexProcessObjectParameters> LaborGetSearchResultSummary(long id)
{
var obj = await ct.WorkOrderItemLabor.SingleOrDefaultAsync(m => m.Id == id);
var SearchParams = new Search.SearchIndexProcessObjectParameters();
if (obj != null)
SearchParams.AddText(obj.Notes).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields);
return SearchParams;
}
#endregion work order item LABOR level
#region WorkOrderItemPart level
////////////////////////////////////////////////////////////////////////////////////////////////
//EXISTS
internal async Task<bool> PartExistsAsync(long id)
{
return await ct.WorkOrderItemPart.AnyAsync(e => e.Id == id);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//CREATE
//
internal async Task<WorkOrderItemPart> PartCreateAsync(WorkOrderItemPart newObject)
{
await PartValidateAsync(newObject, null);
if (HasErrors)
return null;
else
{
newObject.Tags = TagUtil.NormalizeTags(newObject.Tags);
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
await ct.WorkOrderItemPart.AddAsync(newObject);
await ct.SaveChangesAsync();
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemPart, AyaEvent.Created), ct);
await PartSearchIndexAsync(newObject, true);
await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
return newObject;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//VALIDATION
//
private async Task PartValidateAsync(WorkOrderItemPart proposedObj, WorkOrderItemPart currentObj)
{
//run validation and biz rules
bool isNew = currentObj == null;
if (proposedObj.WorkorderItemId == 0)
AddError(ApiErrorCode.VALIDATION_REQUIRED, "WorkorderItemId");
else if (!await ItemExistsAsync(proposedObj.WorkorderItemId))
{
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkorderItemId");
}
//Any form customizations to validate?
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(x => x.FormKey == AyaType.WorkOrderItemPart.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);//note: this is passed only to add errors
//validate custom fields
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
}
}
// //Can delete?
// private void PartValidateCanDelete(WorkOrderItemPart inObj)
// {
// //whatever needs to be check to delete this object
// }
private async Task PartSearchIndexAsync(WorkOrderItemPart obj, bool isNew)
{
//SEARCH INDEXING
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, AyaType.WorkOrderItemPart);
SearchParams.AddText(obj.Notes).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields);
if (isNew)
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
else
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
}
public async Task<Search.SearchIndexProcessObjectParameters> PartGetSearchResultSummary(long id)
{
var obj = await ct.WorkOrderItemPart.SingleOrDefaultAsync(m => m.Id == id);
var SearchParams = new Search.SearchIndexProcessObjectParameters();
if (obj != null)
SearchParams.AddText(obj.Notes).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields);
return SearchParams;
}
#endregion work order item LABOR level
////////////////////////////////////////////////////////////////////////////////////////////////
//JOB / OPERATIONS

View File

@@ -42,6 +42,8 @@ namespace AyaNova.Models
public virtual DbSet<Vendor> Vendor { get; set; }
public virtual DbSet<WorkOrder> WorkOrder { get; set; }
public virtual DbSet<WorkOrderItem> WorkOrderItem { get; set; }
public virtual DbSet<WorkOrderItemLabor> WorkOrderItemLabor { get; set; }
public virtual DbSet<WorkOrderItemPart> WorkOrderItemPart { get; set; }
public virtual DbSet<WorkOrderTemplate> WorkOrderTemplate { get; set; }
public virtual DbSet<WorkOrderTemplateItem> WorkOrderTemplateItem { get; set; }
@@ -123,7 +125,7 @@ namespace AyaNova.Models
.WithOne(i => i.User)
.HasForeignKey<Widget>(b => b.UserId)
.OnDelete(DeleteBehavior.NoAction);
// //Workorder
// modelBuilder.Entity<WorkOrderItem>()
// .HasOne(p => p.WorkOrder)