This commit is contained in:
2021-06-03 19:53:43 +00:00
parent 8858abda97
commit e9cf952c1f

View File

@@ -61,44 +61,64 @@ namespace AyaNova.Biz
//
internal async Task<WorkOrder> WorkOrderCreateAsync(WorkOrder newObject, bool populateViz = true)
{
await WorkOrderValidateAsync(newObject, null);
if (HasErrors)
return null;
else
using (var transaction = await ct.Database.BeginTransactionAsync())
{
await WorkOrderBizActionsAsync(AyaEvent.Created, newObject, null, null);
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
await ct.WorkOrder.AddAsync(newObject);
await ct.SaveChangesAsync();
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
await WorkOrderSearchIndexAsync(newObject, true);
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
//Was this a full workorder posted all at once?
//(seeder or api user, not something AyaNova front end would do)
if (newObject.Items.Count > 0)//our front end will post the header alone on new so this indicates a fully populated wo was saved
await WorkOrderValidateAsync(newObject, null);
if (HasErrors)
return null;
else
{
await GetCurrentContractFromContractIdAsync(newObject.ContractId);
if (mContractInEffect != null && mContractInEffect.ResponseTime != TimeSpan.Zero)
newObject.CompleteByDate = DateTime.UtcNow.Add(mContractInEffect.ResponseTime);
//GRANDCHILD BIZ ACTIONS
foreach (WorkOrderItem wi in newObject.Items)
{
foreach (WorkOrderItemPart wip in wi.Parts)
await PartBizActionsAsync(AyaEvent.Created, wip, null, null);
foreach (WorkOrderItemLoan wil in wi.Loans)
await LoanBizActionsAsync(AyaEvent.Created, wil, null, null);
}
await WorkOrderBizActionsAsync(AyaEvent.Created, newObject, null, null);
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
await ct.WorkOrder.AddAsync(newObject);
await ct.SaveChangesAsync();
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
await WorkOrderSearchIndexAsync(newObject, true);
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
//Was this a full workorder posted all at once?
//(seeder or api user, not something AyaNova front end would do)
if (newObject.Items.Count > 0)//our front end will post the header alone on new so this indicates a fully populated wo was saved
{
await GetCurrentContractFromContractIdAsync(newObject.ContractId);
if (mContractInEffect != null && mContractInEffect.ResponseTime != TimeSpan.Zero)
newObject.CompleteByDate = DateTime.UtcNow.Add(mContractInEffect.ResponseTime);
//GRANDCHILD BIZ ACTIONS
foreach (WorkOrderItem wi in newObject.Items)
{
foreach (WorkOrderItemPart wip in wi.Parts)
await PartBizActionsAsync(AyaEvent.Created, wip, null, null);
foreach (WorkOrderItemLoan wil in wi.Loans)
await LoanBizActionsAsync(AyaEvent.Created, wil, null, null);
}
await ct.SaveChangesAsync();
//INVENTORY ADJUSTMENTS
foreach (WorkOrderItem wi in newObject.Items)
{
foreach (WorkOrderItemPart wip in wi.Parts)
{
await PartInventoryAdjustmentAsync(AyaEvent.Created, wip, null, transaction);
if (HasErrors)
{
await transaction.RollbackAsync();
return null;
}
}
}
}
await transaction.CommitAsync();
if (populateViz)
await WorkOrderPopulateVizFields(newObject, true);
await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Created, newObject);
return newObject;
}
if (populateViz)
await WorkOrderPopulateVizFields(newObject, true);
await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Created, newObject);
return newObject;
}
}
@@ -3088,21 +3108,31 @@ namespace AyaNova.Biz
//
internal async Task<WorkOrderItemPart> CreatePartAsync(WorkOrderItemPart newObject)
{
await PartValidateAsync(newObject, null);
if (HasErrors)
return null;
else
using (var transaction = await ct.Database.BeginTransactionAsync())
{
await PartBizActionsAsync(AyaEvent.Created, newObject, null, null);
//newObject.Tags = TagBiz.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, newObject.AyaType, AyaEvent.Created), ct);
await PartSearchIndexAsync(newObject, true);
//await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
await PartPopulateVizFields(newObject);
return newObject;
await PartValidateAsync(newObject, null);
if (HasErrors)
return null;
else
{
await PartBizActionsAsync(AyaEvent.Created, newObject, null, null);
//newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
//newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
await ct.WorkOrderItemPart.AddAsync(newObject);
await ct.SaveChangesAsync();
await PartInventoryAdjustmentAsync(AyaEvent.Created, newObject, null, transaction);
if (HasErrors)
{
await transaction.RollbackAsync();
return null;
}
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, newObject.AyaType, AyaEvent.Created), ct);
await PartSearchIndexAsync(newObject, true);
await transaction.CommitAsync();
//await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
await PartPopulateVizFields(newObject);
return newObject;
}
}
}
@@ -3122,43 +3152,53 @@ namespace AyaNova.Biz
//
internal async Task<WorkOrderItemPart> PartPutAsync(WorkOrderItemPart putObject)
{
WorkOrderItemPart dbObject = await PartGetAsync(putObject.Id, false);
if (dbObject == null)
using (var transaction = await ct.Database.BeginTransactionAsync())
{
AddError(ApiErrorCode.NOT_FOUND, "id");
return null;
}
if (dbObject.Concurrency != putObject.Concurrency)
{
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
return null;
}
//dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags);
//dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields);
await PartValidateAsync(putObject, dbObject);
if (HasErrors) return null;
await PartBizActionsAsync(AyaEvent.Modified, putObject, dbObject, null);
ct.Replace(dbObject, putObject);
try
{
await ct.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!await PartExistsAsync(putObject.Id))
AddError(ApiErrorCode.NOT_FOUND);
else
WorkOrderItemPart dbObject = await PartGetAsync(putObject.Id, false);
if (dbObject == null)
{
AddError(ApiErrorCode.NOT_FOUND, "id");
return null;
}
if (dbObject.Concurrency != putObject.Concurrency)
{
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
return null;
return null;
}
//dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags);
//dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields);
await PartValidateAsync(putObject, dbObject);
if (HasErrors) return null;
await PartBizActionsAsync(AyaEvent.Modified, putObject, dbObject, null);
ct.Replace(dbObject, putObject);
try
{
await ct.SaveChangesAsync();
await PartInventoryAdjustmentAsync(AyaEvent.Modified, putObject, dbObject, transaction);
if (HasErrors)
{
await transaction.RollbackAsync();
return null;
}
}
catch (DbUpdateConcurrencyException)
{
if (!await PartExistsAsync(putObject.Id))
AddError(ApiErrorCode.NOT_FOUND);
else
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
return null;
}
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, putObject.Id, putObject.AyaType, AyaEvent.Modified), ct);
await PartSearchIndexAsync(putObject, false);
//await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags);
await PartHandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject);
await transaction.CommitAsync();
await PartPopulateVizFields(putObject);
return putObject;
}
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, putObject.Id, putObject.AyaType, AyaEvent.Modified), ct);
await PartSearchIndexAsync(putObject, false);
//await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags);
await PartHandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject);
await PartPopulateVizFields(putObject);
return putObject;
}
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -3166,29 +3206,38 @@ namespace AyaNova.Biz
//
internal async Task<bool> PartDeleteAsync(long id, IDbContextTransaction parentTransaction = null)
{
var transaction = parentTransaction ?? await ct.Database.BeginTransactionAsync();
try
// var transaction = parentTransaction ?? await ct.Database.BeginTransactionAsync();
using (var transaction = parentTransaction ?? await ct.Database.BeginTransactionAsync())
{
var dbObject = await PartGetAsync(id, false);
PartValidateCanDelete(dbObject);
if (HasErrors)
return false;
await PartBizActionsAsync(AyaEvent.Modified, null, dbObject, transaction);
ct.WorkOrderItemPart.Remove(dbObject);
await ct.SaveChangesAsync();
//Log event
await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//Fix??
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct);
//await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags);
//await FileUtil.DeleteAttachmentsForObjectAsync(dbObject.AyaType, dbObject.Id, ct);
if (parentTransaction == null)
await transaction.CommitAsync();
await PartHandlePotentialNotificationEvent(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;
try
{
var dbObject = await PartGetAsync(id, false);
PartValidateCanDelete(dbObject);
if (HasErrors)
return false;
await PartBizActionsAsync(AyaEvent.Deleted, null, dbObject, transaction);
ct.WorkOrderItemPart.Remove(dbObject);
await ct.SaveChangesAsync();
await PartInventoryAdjustmentAsync(AyaEvent.Deleted, null, dbObject, transaction);
if (HasErrors)
{
await transaction.RollbackAsync();
return false;
}
//Log event
await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//Fix??
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct);
//await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags);
//await FileUtil.DeleteAttachmentsForObjectAsync(dbObject.AyaType, dbObject.Id, ct);
if (parentTransaction == null)
await transaction.CommitAsync();
await PartHandlePotentialNotificationEvent(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;
}
@@ -3328,7 +3377,51 @@ namespace AyaNova.Biz
//
//
private async Task PartBizActionsAsync(AyaEvent ayaEvent, WorkOrderItemPart newObj, WorkOrderItemPart oldObj, IDbContextTransaction transaction)
{
{
//SNAPSHOT PRICING IF NECESSARY
if (ayaEvent != AyaEvent.Created && ayaEvent != AyaEvent.Modified)
return;
//SNAPSHOT PRICING
bool SnapshotPricing = true;
//if modifed, see what has changed and should be re-applied
if (ayaEvent == AyaEvent.Modified)
{
//If it wasn't a complete part change there is no need to set pricing
if (newObj.PartId == oldObj.PartId)
{
SnapshotPricing = false;
}
}
//Pricing
if (SnapshotPricing)
{
//default in case nothing to apply
newObj.Cost = 0;
newObj.ListPrice = 0;
var s = await ct.Part.AsNoTracking().FirstOrDefaultAsync(z => z.Id == newObj.PartId);
if (s != null)
{
newObj.Cost = s.Cost;
newObj.ListPrice = s.Retail;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//BIZ ACTIONS
//
//
private async Task PartInventoryAdjustmentAsync(AyaEvent ayaEvent, WorkOrderItemPart newObj, WorkOrderItemPart oldObj, IDbContextTransaction transaction)
{
if (AyaNova.Util.ServerGlobalBizSettings.UseInventory)
{
@@ -3453,58 +3546,9 @@ namespace AyaNova.Biz
}
//SNAPSHOT PRICING IF NECESSARY
if (ayaEvent != AyaEvent.Created && ayaEvent != AyaEvent.Modified)
return;
//SNAPSHOT PRICING
bool SnapshotPricing = true;
//if modifed, see what has changed and should be re-applied
if (ayaEvent == AyaEvent.Modified)
{
//If it wasn't a complete part change there is no need to set pricing
if (newObj.PartId == oldObj.PartId)
{
SnapshotPricing = false;
}
}
//Pricing
if (SnapshotPricing)
{
//default in case nothing to apply
newObj.Cost = 0;
newObj.ListPrice = 0;
var s = await ct.Part.AsNoTracking().FirstOrDefaultAsync(z => z.Id == newObj.PartId);
if (s != null)
{
newObj.Cost = s.Cost;
newObj.ListPrice = s.Retail;
}
}
}
// ////////////////////////////////////////////////////////////////////////////////////////////////
// // SET PER UNIT LIST PRICE
// //
// //(called by woitempart save and also by header save on change of contract)
// private static void PartSetListPrice(WorkOrderItemPart o, Contract c)
// {
// if (c == null || c.ServiceRatesOverridePct == 0)
// {
// o.Price = o.ListPrice;//default with no contract
// return;
// }
// if (c.ServiceRatesOverrideType == ContractOverrideType.CostMarkup)
// o.Price = o.Cost + (o.Cost * c.ServiceRatesOverridePct);
// else if (c.ServiceRatesOverrideType == ContractOverrideType.PriceDiscount)
// o.Price = o.ListPrice - (o.ListPrice * c.ServiceRatesOverridePct);
// }
////////////////////////////////////////////////////////////////////////////////////////////////
//VALIDATION