diff --git a/docs/8.0/ayanova/docs/svc-workorders.md b/docs/8.0/ayanova/docs/svc-workorders.md index 21425917..4bd6537d 100644 --- a/docs/8.0/ayanova/docs/svc-workorders.md +++ b/docs/8.0/ayanova/docs/svc-workorders.md @@ -8,5 +8,5 @@ Inventory changes from v7 with new workorder system No "Used in service", now Parts are consumed immediately from inventory when selected on workorder and saved Work order item part records consume or return inventory immediately upon save or delete or changes Serial numbers are likewise immediately consumed / returned to the pool upon edits to workorder item part records - + A zero quantity part will be considered a "placeholder" and will neither affect inventory nor serial numbers until a quantity is entered and saved diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 1309274c..9e5c8fb7 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -3454,7 +3454,7 @@ namespace AyaNova.Biz //CREATED, HANDLE INVENTORY / CONSUME SERIALS - if (ayaEvent == AyaEvent.Created) + if (ayaEvent == AyaEvent.Created && newObj.Quantity != 0)//allow zero quantity parts on workorder as placeholder, serials will not be consumed { dtInternalPartInventory pi = new dtInternalPartInventory @@ -3492,68 +3492,78 @@ namespace AyaNova.Biz //UPDATED, HANDLE INVENTORY / UPDATE SERIALS AS REQUIRED if (ayaEvent == AyaEvent.Modified) { - //determine if any changes affecting inventory + //INVENTORY if (newObj.PartId != oldObj.PartId || newObj.Quantity != oldObj.Quantity) { //OUT with the old - dtInternalPartInventory piOld = new dtInternalPartInventory + if (oldObj.Quantity != 0)//zero quantity doesn't affect inventory or serials { - 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); + 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 - 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 (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 + { + 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); + 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); + } } } - else if (newObj.Serials != oldObj.Serials) + //SERIALS + if (newObj.Serials != oldObj.Serials) { - //Only a serial number adjustment so in and out all serials to be safe and not try to parse too closely + //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 (!string.IsNullOrWhiteSpace(oldObj.Serials)) + if (oldObj.Quantity != 0 && !string.IsNullOrWhiteSpace(oldObj.Serials)) await PartBiz.AppendSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId); + //Consume serial numbers from part - if (!string.IsNullOrWhiteSpace(newObj.Serials)) + if (newObj.Quantity != 0 && !string.IsNullOrWhiteSpace(newObj.Serials)) await PartBiz.RemoveSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId); } + + } - - }