This commit is contained in:
@@ -145,6 +145,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
|
|
||||||
// NOTE: HERE would be the second check of biz rules before returning the object
|
// 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
|
// 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)));
|
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))
|
if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType))
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||||
|
|
||||||
|
biz.PutAsync(id, updatedObject);
|
||||||
//todo: handle concurrency in biz object, what to do?
|
//todo: handle concurrency in biz object, what to do?
|
||||||
|
|
||||||
// var o = await biz.PutAsync(id, updatedObject);
|
// var o = await biz.PutAsync(id, updatedObject);
|
||||||
|
|||||||
@@ -272,88 +272,270 @@ namespace AyaNova.Biz
|
|||||||
// }
|
// }
|
||||||
#endregion workorder level
|
#endregion workorder level
|
||||||
|
|
||||||
|
|
||||||
#region WorkOrderItem level
|
#region WorkOrderItem level
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//EXISTS
|
||||||
|
internal async Task<bool> ItemExistsAsync(long id)
|
||||||
|
{
|
||||||
|
return await ct.WorkOrderItem.AnyAsync(e => e.Id == id);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//CREATE
|
//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)
|
if (HasErrors)
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newObject.Serial = ServerBootConfig.WORKORDER_SERIAL.GetNext();
|
|
||||||
newObject.Tags = TagUtil.NormalizeTags(newObject.Tags);
|
newObject.Tags = TagUtil.NormalizeTags(newObject.Tags);
|
||||||
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
||||||
await ct.WorkOrder.AddAsync(newObject);
|
await ct.WorkOrderItem.AddAsync(newObject);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItem, AyaEvent.Created), ct);
|
||||||
await SearchIndexAsync(newObject, true);
|
await ItemSearchIndexAsync(newObject, true);
|
||||||
await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
||||||
return newObject;
|
return newObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//VALIDATION
|
//VALIDATION
|
||||||
//
|
//
|
||||||
|
private async Task ItemValidateAsync(WorkOrderItem proposedObj, WorkOrderItem currentObj)
|
||||||
//Can save or update?
|
|
||||||
private async Task ValidateItemAsync(WorkOrderItem proposedObj, WorkOrderItem currentObj)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
//run validation and biz rules
|
//run validation and biz rules
|
||||||
bool isNew = currentObj == null;
|
bool isNew = currentObj == null;
|
||||||
|
|
||||||
// //Name required
|
//does it have a valid workorder id
|
||||||
// if (string.IsNullOrWhiteSpace(proposedObj.Name))
|
if (proposedObj.WorkorderId == 0)
|
||||||
// AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name");
|
AddError(ApiErrorCode.VALIDATION_REQUIRED, "WorkorderId");
|
||||||
|
else if (!await WorkOrderExistsAsync(proposedObj.WorkorderId))
|
||||||
// //Name must be less than 255 characters
|
{
|
||||||
// if (proposedObj.Name.Length > 255)
|
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkorderId");
|
||||||
// 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");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//Any form customizations to validate?
|
//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)
|
if (FormCustomization != null)
|
||||||
{
|
{
|
||||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
//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
|
//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
|
//validate custom fields
|
||||||
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
|
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// //Can delete?
|
||||||
//Can delete?
|
// private void ValidateCanDeleteItem(WorkOrderItem inObj)
|
||||||
// private void ValidateCanDelete(WorkOrder inObj)
|
|
||||||
// {
|
// {
|
||||||
// //whatever needs to be check to delete this object
|
// //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
|
#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
|
//JOB / OPERATIONS
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ namespace AyaNova.Models
|
|||||||
public virtual DbSet<Vendor> Vendor { get; set; }
|
public virtual DbSet<Vendor> Vendor { get; set; }
|
||||||
public virtual DbSet<WorkOrder> WorkOrder { get; set; }
|
public virtual DbSet<WorkOrder> WorkOrder { get; set; }
|
||||||
public virtual DbSet<WorkOrderItem> WorkOrderItem { 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<WorkOrderTemplate> WorkOrderTemplate { get; set; }
|
||||||
public virtual DbSet<WorkOrderTemplateItem> WorkOrderTemplateItem { get; set; }
|
public virtual DbSet<WorkOrderTemplateItem> WorkOrderTemplateItem { get; set; }
|
||||||
|
|
||||||
@@ -123,7 +125,7 @@ namespace AyaNova.Models
|
|||||||
.WithOne(i => i.User)
|
.WithOne(i => i.User)
|
||||||
.HasForeignKey<Widget>(b => b.UserId)
|
.HasForeignKey<Widget>(b => b.UserId)
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
.OnDelete(DeleteBehavior.NoAction);
|
||||||
|
|
||||||
// //Workorder
|
// //Workorder
|
||||||
// modelBuilder.Entity<WorkOrderItem>()
|
// modelBuilder.Entity<WorkOrderItem>()
|
||||||
// .HasOne(p => p.WorkOrder)
|
// .HasOne(p => p.WorkOrder)
|
||||||
|
|||||||
Reference in New Issue
Block a user