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
|
||||
// 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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user