This commit is contained in:
@@ -9,6 +9,7 @@ using AyaNova.Models;
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
|
||||||
namespace AyaNova.Biz
|
namespace AyaNova.Biz
|
||||||
{
|
{
|
||||||
@@ -41,54 +42,57 @@ namespace AyaNova.Biz
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//CREATE (adjustment version)
|
//CREATE (adjustment version)
|
||||||
//
|
//
|
||||||
internal async Task<PartInventory> CreateAsync(dtPartInventory newDtObject)
|
internal async Task<PartInventory> CreateAsync(dtPartInventory newDtObject, IDbContextTransaction parentTransaction = null)
|
||||||
{
|
{
|
||||||
using (var transaction = await ct.Database.BeginTransactionAsync())
|
IDbContextTransaction transaction = null;
|
||||||
|
if (parentTransaction == null)
|
||||||
|
transaction = await ct.Database.BeginTransactionAsync();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
//get the last record if exists (will not if opening balance)
|
||||||
|
var LastEntry = await ct.PartInventory.OrderByDescending(m => m.EntryDate).FirstOrDefaultAsync(m => m.PartId == newDtObject.PartId && m.PartWarehouseId == newDtObject.PartWarehouseId);
|
||||||
|
PartInventory newObject = new PartInventory();
|
||||||
|
newObject.Description = newDtObject.Description;
|
||||||
|
newObject.EntryDate = DateTime.UtcNow;
|
||||||
|
newObject.PartId = newDtObject.PartId;
|
||||||
|
newObject.PartWarehouseId = newDtObject.PartWarehouseId;
|
||||||
|
newObject.SourceId = null;
|
||||||
|
newObject.SourceType = null;
|
||||||
|
newObject.Quantity = newDtObject.Quantity;
|
||||||
|
|
||||||
|
if (LastEntry != null)
|
||||||
{
|
{
|
||||||
//get the last record if exists (will not if opening balance)
|
newObject.LastEntryDate = LastEntry.EntryDate;
|
||||||
var LastEntry = await ct.PartInventory.OrderByDescending(m => m.EntryDate).FirstOrDefaultAsync(m => m.PartId == newDtObject.PartId && m.PartWarehouseId == newDtObject.PartWarehouseId);
|
newObject.LastBalance = LastEntry.Balance;
|
||||||
PartInventory newObject = new PartInventory();
|
newObject.Balance = LastEntry.Balance + newObject.Quantity;
|
||||||
newObject.Description = newDtObject.Description;
|
|
||||||
newObject.EntryDate = DateTime.UtcNow;
|
|
||||||
newObject.PartId = newDtObject.PartId;
|
|
||||||
newObject.PartWarehouseId = newDtObject.PartWarehouseId;
|
|
||||||
newObject.SourceId = null;
|
|
||||||
newObject.SourceType = null;
|
|
||||||
newObject.Quantity = newDtObject.Quantity;
|
|
||||||
|
|
||||||
if (LastEntry != null)
|
|
||||||
{
|
|
||||||
newObject.LastEntryDate = LastEntry.EntryDate;
|
|
||||||
newObject.LastBalance = LastEntry.Balance;
|
|
||||||
newObject.Balance = LastEntry.Balance + newObject.Quantity;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newObject.Balance = newObject.Quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
await ValidateAsync(newObject);
|
|
||||||
if (HasErrors)
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
await ct.PartInventory.AddAsync(newObject);
|
|
||||||
await ct.SaveChangesAsync();
|
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
|
||||||
await SearchIndexAsync(newObject, true);
|
|
||||||
await transaction.CommitAsync();
|
|
||||||
return newObject;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch
|
else
|
||||||
{
|
{
|
||||||
//Just re-throw for now, let exception handler deal, but in future may want to deal with this more here
|
newObject.Balance = newObject.Quantity;
|
||||||
throw;
|
}
|
||||||
|
|
||||||
|
await ValidateAsync(newObject);
|
||||||
|
if (HasErrors)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await ct.PartInventory.AddAsync(newObject);
|
||||||
|
await ct.SaveChangesAsync();
|
||||||
|
//all good do the commit if it's ours
|
||||||
|
if (parentTransaction == null)
|
||||||
|
await transaction.CommitAsync();
|
||||||
|
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
||||||
|
await SearchIndexAsync(newObject, true);
|
||||||
|
return newObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
//Just re-throw for now, let exception handler deal, but in future may want to deal with this more here
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,7 +187,7 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (proposedObj.SourceType != null && proposedObj.SourceId != null && !await BizObjectExistsInDatabase.ExistsAsync((AyaType)proposedObj.SourceType, (long)proposedObj.SourceId, ct))
|
if (proposedObj.SourceType != null && proposedObj.SourceId != null && !await BizObjectExistsInDatabase.ExistsAsync((AyaType)proposedObj.SourceType, (long)proposedObj.SourceId, ct))
|
||||||
{
|
{
|
||||||
AddError(ApiErrorCode.NOT_FOUND, "generalerror", $"PartInventory source object causing inventory change specified doesn't exist [type:{proposedObj.SourceType}, id:{proposedObj.SourceId}]");
|
AddError(ApiErrorCode.NOT_FOUND, "generalerror", $"PartInventory source object causing inventory change specified doesn't exist [type:{proposedObj.SourceType}, id:{proposedObj.SourceId}]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,16 +48,21 @@ namespace AyaNova.Biz
|
|||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await BizActionsAsync(newObject, null);
|
using (var transaction = await ct.Database.BeginTransactionAsync())
|
||||||
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
|
{
|
||||||
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
|
||||||
await ct.PurchaseOrder.AddAsync(newObject);
|
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
|
||||||
await ct.SaveChangesAsync();
|
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
await ct.PurchaseOrder.AddAsync(newObject);
|
||||||
await SearchIndexAsync(newObject, true);
|
await BizActionsAsync(AyaEvent.Created, newObject, null, transaction);
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
await ct.SaveChangesAsync();
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Created, newObject);
|
await transaction.CommitAsync();
|
||||||
return newObject;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,32 +119,33 @@ namespace AyaNova.Biz
|
|||||||
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
|
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
putObject.Tags = TagBiz.NormalizeTags(putObject.Tags);
|
putObject.Tags = TagBiz.NormalizeTags(putObject.Tags);
|
||||||
putObject.CustomFields = JsonUtil.CompactJson(putObject.CustomFields);
|
putObject.CustomFields = JsonUtil.CompactJson(putObject.CustomFields);
|
||||||
await ValidateAsync(putObject, dbObject);
|
await ValidateAsync(putObject, dbObject);
|
||||||
if (HasErrors) return null;
|
if (HasErrors) return null;
|
||||||
|
using (var transaction = await ct.Database.BeginTransactionAsync())
|
||||||
await BizActionsAsync(putObject, dbObject);
|
|
||||||
|
|
||||||
ct.Replace(dbObject, putObject);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
await ct.SaveChangesAsync();
|
await BizActionsAsync(AyaEvent.Modified, putObject, dbObject, transaction);
|
||||||
|
ct.Replace(dbObject, putObject);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ct.SaveChangesAsync();
|
||||||
|
await transaction.CommitAsync();
|
||||||
|
}
|
||||||
|
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(putObject, false);
|
||||||
|
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, putObject.Tags, dbObject.Tags);
|
||||||
|
await HandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject);
|
||||||
|
return putObject;
|
||||||
}
|
}
|
||||||
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(putObject, false);
|
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, putObject.Tags, dbObject.Tags);
|
|
||||||
await HandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject);
|
|
||||||
return putObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -161,6 +167,7 @@ namespace AyaNova.Biz
|
|||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
return false;
|
return false;
|
||||||
ct.PurchaseOrder.Remove(dbObject);
|
ct.PurchaseOrder.Remove(dbObject);
|
||||||
|
await BizActionsAsync(AyaEvent.Deleted, null, dbObject, transaction);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Serial.ToString(), ct);
|
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Serial.ToString(), ct);
|
||||||
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
||||||
@@ -246,6 +253,7 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
private async Task ValidateCanDeleteAsync(PurchaseOrder inObj)
|
private async Task ValidateCanDeleteAsync(PurchaseOrder inObj)
|
||||||
{
|
{
|
||||||
|
//only if none received right? Or do we allow it and just reverse the whole shebang?
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,10 +263,33 @@ namespace AyaNova.Biz
|
|||||||
//BIZ ACTIONS
|
//BIZ ACTIONS
|
||||||
//
|
//
|
||||||
|
|
||||||
private async Task BizActionsAsync(PurchaseOrder proposedObj, PurchaseOrder currentObj)
|
private async Task BizActionsAsync(AyaEvent ayaEvent, PurchaseOrder proposedObj, PurchaseOrder currentObj, Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction transaction)
|
||||||
{
|
{
|
||||||
//TODO: BIZ ACTIONS TO FIXUP INVENTORY ON CHANGES ETC
|
//TODO: BIZ ACTIONS TO FIXUP INVENTORY ON CHANGES ETC
|
||||||
|
|
||||||
|
//If received now less than before need to take out of inventory
|
||||||
|
//If received now more than before need to put into inventory
|
||||||
|
|
||||||
|
//MIGRATE_OUTSTANDING - woitempart request update
|
||||||
|
//if received on woitempartrequest then need to update woitempartrequest (notification separate not a concern here)
|
||||||
|
//if workorderitempartrequest item removed, need to fixup woitempartrequest
|
||||||
|
|
||||||
|
switch (ayaEvent)
|
||||||
|
{
|
||||||
|
case AyaEvent.Created:
|
||||||
|
//any received go into inventory
|
||||||
|
var inventoryAffectingItems = proposedObj.Items.Where(z => z.QuantityReceived > 0).ToList();
|
||||||
|
foreach(var poItem in inventoryAffectingItems){
|
||||||
|
//make inventory adjustment here
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AyaEvent.Modified:
|
||||||
|
break;
|
||||||
|
case AyaEvent.Deleted:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -413,20 +444,14 @@ namespace AyaNova.Biz
|
|||||||
{
|
{
|
||||||
var p = (PurchaseOrder)proposedObj;
|
var p = (PurchaseOrder)proposedObj;
|
||||||
var c = (PurchaseOrder)currentObj;
|
var c = (PurchaseOrder)currentObj;
|
||||||
//PartRequestReceived event?
|
|
||||||
|
//# PartRequestReceived
|
||||||
{
|
{
|
||||||
//get a list of all items with part requests and received inventory
|
//get a list of all items with part requests and received inventory
|
||||||
var proposedRequestItems = p.Items.Where(z => z.WorkorderItemPartRequestId != null && z.QuantityReceived != 0);
|
var proposedRequestItems = p.Items.Where(z => z.WorkorderItemPartRequestId != null && z.QuantityReceived != 0);
|
||||||
//are there any potential notify items?
|
//are there any potential notify items?
|
||||||
if (proposedRequestItems.Count() > 0)
|
if (proposedRequestItems.Count() > 0)
|
||||||
{
|
{
|
||||||
List<NotifySubscription> subs = null;
|
|
||||||
//are any of them new, or a change from before?
|
|
||||||
|
|
||||||
// var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.PartRequestReceived).ToListAsync();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Look for new receipts of requested parts
|
//Look for new receipts of requested parts
|
||||||
foreach (var proposedRequestItem in proposedRequestItems)
|
foreach (var proposedRequestItem in proposedRequestItems)
|
||||||
{
|
{
|
||||||
@@ -437,15 +462,29 @@ namespace AyaNova.Biz
|
|||||||
{
|
{
|
||||||
//is there a subscriber for this user id and event?
|
//is there a subscriber for this user id and event?
|
||||||
var sub = await ct.NotifySubscription.FirstOrDefaultAsync(z => z.EventType == NotifyEventType.PartRequestReceived && z.UserId == proposedRequestItem.PartRequestedById);
|
var sub = await ct.NotifySubscription.FirstOrDefaultAsync(z => z.EventType == NotifyEventType.PartRequestReceived && z.UserId == proposedRequestItem.PartRequestedById);
|
||||||
|
if (sub != null)
|
||||||
|
{
|
||||||
|
//yes. So we have a subscriber, a change in received for a request, time to notify
|
||||||
|
//not for inactive users
|
||||||
|
if (!await UserBiz.UserIsActive(sub.UserId)) continue;
|
||||||
|
|
||||||
|
NotifyEvent n = new NotifyEvent()
|
||||||
|
{
|
||||||
|
EventType = NotifyEventType.PartRequestReceived,
|
||||||
|
UserId = sub.UserId,
|
||||||
|
AyaType = AyaType.WorkOrderItemPartRequest,
|
||||||
|
ObjectId = (long)proposedRequestItem.WorkorderItemPartRequestId,
|
||||||
|
NotifySubscriptionId = sub.Id,
|
||||||
|
Name = BizObjectNameFetcherDirect.Name(AyaType.WorkOrderItemPartRequest, (long)proposedRequestItem.WorkorderItemPartRequestId, ct)
|
||||||
|
};
|
||||||
|
await ct.NotifyEvent.AddAsync(n);
|
||||||
|
log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
|
||||||
|
await ct.SaveChangesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}//end of process notifications
|
}//end of process notifications
|
||||||
|
|||||||
Reference in New Issue
Block a user