diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 3572a271..0f3222fe 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -4097,22 +4097,19 @@ namespace AyaNova.Biz SourceId = newObj.Id, Description = await Translate("WorkOrderItemPart") + $" {newObj.Serials} " + await Translate("EventCreated") }; - if (await pib.CreateAsync(pi) == null) + if (await pib.CreateAsync(pi) == null) { if (pib.HasErrors) { foreach (var e in pib.Errors) { - if (e.Code == ApiErrorCode.INSUFFICIENT_INVENTORY) - AddError(e.Code, "Quantity", e.Message); - else - AddError(e.Code, e.Target, e.Message); + AddError(e.Code, e.Target, e.Message); } } return; } else - { //Append serial numbers from part + { //Append serial numbers from part being returned if (!string.IsNullOrWhiteSpace(newObj.Serials)) await PartBiz.AppendSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); } @@ -4158,73 +4155,160 @@ namespace AyaNova.Biz //UPDATED, HANDLE INVENTORY / UPDATE SERIALS AS REQUIRED if (ayaEvent == AyaEvent.Modified) { - //INVENTORY + //QUANTITY OR PART CHANGE? if (newObj.PartId != oldObj.PartId || newObj.Quantity != oldObj.Quantity) { - //OUT with the old + //OUT with the old object if (oldObj.Quantity != 0)//zero quantity doesn't affect inventory or serials { - dtInternalPartInventory piOld = new dtInternalPartInventory + if (oldObj.Quantity < 0) { - PartId = oldObj.PartId, - PartWarehouseId = oldObj.PartWarehouseId, - Quantity = oldObj.Quantity, - SourceType = null,//null because the po no longer exists so this is technically a manual adjustment - SourceId = null,//'' - Description = await Translate("WorkOrderItemPart") + $" {oldObj.Serials} " + await Translate("EventDeleted") - }; - if (await pib.CreateAsync(piOld) == null) - { - AddError(ApiErrorCode.API_SERVER_ERROR, "generalerror", $"Error updating inventory ({piOld.Description}):{pib.GetErrorsAsString()}"); - return; + //NEGATIVE BLOCK >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + //Was negative so add back to inventory / serials + dtInternalPartInventory pi = + new dtInternalPartInventory + { + PartId = oldObj.PartId, + PartWarehouseId = oldObj.PartWarehouseId, + Quantity = oldObj.Quantity * -1,//was originally returned (negative) so needs to be consumed + SourceType = AyaType.WorkOrderItemPart, + SourceId = oldObj.Id, + Description = await Translate("WorkOrderItemPart") + $" {oldObj.Serials} " + await Translate("EventDeleted") + }; + if (await pib.CreateAsync(pi) == null) + { + if (pib.HasErrors) + { + foreach (var e in pib.Errors) + { + if (e.Code == ApiErrorCode.INSUFFICIENT_INVENTORY) + AddError(e.Code, "Quantity", e.Message); + else + AddError(e.Code, e.Target, e.Message); + } + } + return; + } + else + { //Consume serial numbers from part + if (!string.IsNullOrWhiteSpace(oldObj.Serials)) + await PartBiz.RemoveSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId); + } + //<<<<<<<<<<<<<<<<<<<<<< NEGATIVE BLOCK } else - { //return serial numbers to part - if (!string.IsNullOrWhiteSpace(oldObj.Serials)) - await PartBiz.AppendSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId); + { + dtInternalPartInventory piOld = new dtInternalPartInventory + { + PartId = oldObj.PartId, + PartWarehouseId = oldObj.PartWarehouseId, + Quantity = oldObj.Quantity, + SourceType = null,//null because the po no longer exists so this is technically a manual adjustment + SourceId = null,//'' + Description = await Translate("WorkOrderItemPart") + $" {oldObj.Serials} " + await Translate("EventDeleted") + }; + if (await pib.CreateAsync(piOld) == null) + { + AddError(ApiErrorCode.API_SERVER_ERROR, "generalerror", $"Error updating inventory ({piOld.Description}):{pib.GetErrorsAsString()}"); + return; + } + else + { //return serial numbers to part + if (!string.IsNullOrWhiteSpace(oldObj.Serials)) + await PartBiz.AppendSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId); + } } } - //IN with the new - if (newObj.Quantity != 0) - {//NOTE: zero quantity is considered to be a placeholder and no serials will be consumed, nor inventory affected - dtInternalPartInventory piNew = new dtInternalPartInventory + //IN with the new object + if (newObj.Quantity != 0)//zero quantity is considered to be a placeholder and no serials will be consumed, nor inventory affected + { + if (newObj.Quantity < 0) { - PartId = newObj.PartId, - PartWarehouseId = newObj.PartWarehouseId, - Quantity = newObj.Quantity * -1, - SourceType = AyaType.WorkOrderItemPart, - SourceId = newObj.Id, - Description = await Translate("WorkOrderItemPart") + $" {newObj.Serials} " + await Translate("EventCreated") - }; + //NEGATIVE BLOCK >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + //RETURN INVENTORY + dtInternalPartInventory pi = + new dtInternalPartInventory + { + PartId = newObj.PartId, + PartWarehouseId = newObj.PartWarehouseId, + Quantity = newObj.Quantity,//is negative + SourceType = AyaType.WorkOrderItemPart, + SourceId = newObj.Id, + Description = await Translate("WorkOrderItemPart") + $" {newObj.Serials} " + await Translate("EventCreated") + }; + if (await pib.CreateAsync(pi) == null) + { + if (pib.HasErrors) + { + foreach (var e in pib.Errors) + { + AddError(e.Code, e.Target, e.Message); + } + } + return; + } + else + { //Append serial numbers from part being returned + if (!string.IsNullOrWhiteSpace(newObj.Serials)) + await PartBiz.AppendSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); + } - if (await pib.CreateAsync(piNew) == null) - { - AddError(ApiErrorCode.API_SERVER_ERROR, "generalerror", $"Error updating inventory ({piNew.Description}):{pib.GetErrorsAsString()}"); - return; + //<<<<<<<<<<<<<<<<<<<<<< NEGATIVE BLOCK } else - { //Consume serial numbers from part - if (!string.IsNullOrWhiteSpace(newObj.Serials)) - await PartBiz.RemoveSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); + { + + dtInternalPartInventory piNew = new dtInternalPartInventory + { + PartId = newObj.PartId, + PartWarehouseId = newObj.PartWarehouseId, + Quantity = newObj.Quantity * -1, + SourceType = AyaType.WorkOrderItemPart, + SourceId = newObj.Id, + Description = await Translate("WorkOrderItemPart") + $" {newObj.Serials} " + await Translate("EventCreated") + }; + + if (await pib.CreateAsync(piNew) == null) + { + AddError(ApiErrorCode.API_SERVER_ERROR, "generalerror", $"Error updating inventory ({piNew.Description}):{pib.GetErrorsAsString()}"); + return; + } + else + { //Consume serial numbers from part + if (!string.IsNullOrWhiteSpace(newObj.Serials)) + await PartBiz.RemoveSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); + } } } - } - //SERIALS - else if (newObj.Serials != oldObj.Serials) + return; + }//end block for quantity or part change + else if (newObj.Serials != oldObj.Serials)//SERIALS CHANGE ONLY not quantity or partid so not handled already above { //NOTE: zero quantity is considered to be a placeholder and no serials will be consumed (hence not returned either) - //return serial numbers to part - if (oldObj.Quantity != 0 && !string.IsNullOrWhiteSpace(oldObj.Serials)) - await PartBiz.AppendSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId); - //Consume serial numbers from part - if (newObj.Quantity != 0 && !string.IsNullOrWhiteSpace(newObj.Serials)) - await PartBiz.RemoveSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); + //Old object had serials? + if (!string.IsNullOrWhiteSpace(oldObj.Serials)) + { + //Reverse old object serials transaction... + if (oldObj.Quantity > 0) + await PartBiz.AppendSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId); + if (oldObj.Quantity < 0) + await PartBiz.RemoveSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId); + } + + //New object has serials? + if (!string.IsNullOrWhiteSpace(newObj.Serials)) + { + //do new object serials transaction + if (newObj.Quantity > 0) + await PartBiz.RemoveSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); + if (newObj.Quantity < 0) + await PartBiz.AppendSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); + } } - } - + }//end MODIFIED block } @@ -4538,7 +4622,7 @@ namespace AyaNova.Biz //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 + //validate custom fields } } @@ -5190,7 +5274,7 @@ namespace AyaNova.Biz //validate users choices for required non custom fields RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);//note: this is passed only to add errors - //validate custom fields + //validate custom fields } }