This commit is contained in:
@@ -266,7 +266,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion workorderstate
|
#endregion quotestate
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion workorderitem
|
#endregion quoteitem
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -524,10 +524,10 @@ namespace AyaNova.Api.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get QuoteItemLabor object
|
/// Get QuoteItemLabor object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="workOrderItemLaborId"></param>
|
/// <param name="QuoteItemLaborId"></param>
|
||||||
/// <returns>A single QuoteItemLabor</returns>
|
/// <returns>A single QuoteItemLabor</returns>
|
||||||
[HttpGet("items/labors/{workOrderItemLaborId}")]
|
[HttpGet("items/labors/{QuoteItemLaborId}")]
|
||||||
public async Task<IActionResult> GetQuoteItemLabor([FromRoute] long workOrderItemLaborId)
|
public async Task<IActionResult> GetQuoteItemLabor([FromRoute] long QuoteItemLaborId)
|
||||||
{
|
{
|
||||||
if (!serverState.IsOpen)
|
if (!serverState.IsOpen)
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
||||||
@@ -536,7 +536,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
return BadRequest(new ApiErrorResponse(ModelState));
|
||||||
var o = await biz.LaborGetAsync(workOrderItemLaborId);
|
var o = await biz.LaborGetAsync(QuoteItemLaborId);
|
||||||
if (o == null)
|
if (o == null)
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
||||||
return Ok(ApiOkResponse.Response(o));
|
return Ok(ApiOkResponse.Response(o));
|
||||||
@@ -574,10 +574,10 @@ namespace AyaNova.Api.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete QuoteItemLabor
|
/// Delete QuoteItemLabor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="workOrderItemLaborId"></param>
|
/// <param name="QuoteItemLaborId"></param>
|
||||||
/// <returns>NoContent</returns>
|
/// <returns>NoContent</returns>
|
||||||
[HttpDelete("items/labors/{workOrderItemLaborId}")]
|
[HttpDelete("items/labors/{QuoteItemLaborId}")]
|
||||||
public async Task<IActionResult> DeleteQuoteItemLabor([FromRoute] long workOrderItemLaborId)
|
public async Task<IActionResult> DeleteQuoteItemLabor([FromRoute] long QuoteItemLaborId)
|
||||||
{
|
{
|
||||||
if (!serverState.IsOpen)
|
if (!serverState.IsOpen)
|
||||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
||||||
@@ -586,7 +586,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
QuoteBiz biz = QuoteBiz.GetBiz(ct, HttpContext);
|
QuoteBiz biz = QuoteBiz.GetBiz(ct, HttpContext);
|
||||||
if (!Authorized.HasDeleteRole(HttpContext.Items, AyaType.QuoteItemLabor))
|
if (!Authorized.HasDeleteRole(HttpContext.Items, AyaType.QuoteItemLabor))
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||||
if (!await biz.LaborDeleteAsync(workOrderItemLaborId))
|
if (!await biz.LaborDeleteAsync(QuoteItemLaborId))
|
||||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
return BadRequest(new ApiErrorResponse(biz.Errors));
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3696,7 +3696,6 @@ namespace AyaNova.Biz
|
|||||||
//newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
//newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
||||||
await ct.QuoteItemPart.AddAsync(newObject);
|
await ct.QuoteItemPart.AddAsync(newObject);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
await PartInventoryAdjustmentAsync(AyaEvent.Created, newObject, null, transaction);
|
|
||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
{
|
{
|
||||||
await transaction.RollbackAsync();
|
await transaction.RollbackAsync();
|
||||||
@@ -3755,7 +3754,6 @@ namespace AyaNova.Biz
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
await PartInventoryAdjustmentAsync(AyaEvent.Modified, putObject, dbObject, transaction);
|
|
||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
{
|
{
|
||||||
await transaction.RollbackAsync();
|
await transaction.RollbackAsync();
|
||||||
@@ -3795,8 +3793,7 @@ namespace AyaNova.Biz
|
|||||||
return false;
|
return false;
|
||||||
await PartBizActionsAsync(AyaEvent.Deleted, null, dbObject, transaction);
|
await PartBizActionsAsync(AyaEvent.Deleted, null, dbObject, transaction);
|
||||||
ct.QuoteItemPart.Remove(dbObject);
|
ct.QuoteItemPart.Remove(dbObject);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
await PartInventoryAdjustmentAsync(AyaEvent.Deleted, null, dbObject, transaction);
|
|
||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
{
|
{
|
||||||
await transaction.RollbackAsync();
|
await transaction.RollbackAsync();
|
||||||
@@ -4009,152 +4006,7 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//BIZ ACTIONS
|
|
||||||
//
|
|
||||||
//
|
|
||||||
private async Task PartInventoryAdjustmentAsync(AyaEvent ayaEvent, QuoteItemPart newObj, QuoteItemPart oldObj, IDbContextTransaction transaction)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if (AyaNova.Util.ServerGlobalBizSettings.Cache.UseInventory)
|
|
||||||
{
|
|
||||||
PartInventoryBiz pib = new PartInventoryBiz(ct, UserId, UserTranslationId, CurrentUserRoles);
|
|
||||||
|
|
||||||
//DELETED, HANDLE INVENTORY / RETURN SERIALS
|
|
||||||
if (ayaEvent == AyaEvent.Deleted && oldObj.Quantity != 0)
|
|
||||||
{
|
|
||||||
dtInternalPartInventory pi =
|
|
||||||
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("QuoteItemPart") + $" {oldObj.Serials} " + await Translate("EventDeleted")
|
|
||||||
};
|
|
||||||
if (await pib.CreateAsync(pi) == null)
|
|
||||||
{
|
|
||||||
AddError(ApiErrorCode.API_SERVER_ERROR, "generalerror", $"Error updating inventory ({pi.Description}):{pib.GetErrorsAsString()}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ //return serial numbers to part
|
|
||||||
if (!string.IsNullOrWhiteSpace(oldObj.Serials))
|
|
||||||
await PartBiz.AppendSerialsAsync(oldObj.PartId, oldObj.Serials, ct, UserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//CREATED, HANDLE INVENTORY / CONSUME SERIALS
|
|
||||||
if (ayaEvent == AyaEvent.Created && newObj.Quantity != 0)//allow zero quantity parts on quote as placeholder, serials will not be consumed
|
|
||||||
{
|
|
||||||
dtInternalPartInventory pi =
|
|
||||||
new dtInternalPartInventory
|
|
||||||
{
|
|
||||||
PartId = newObj.PartId,
|
|
||||||
PartWarehouseId = newObj.PartWarehouseId,
|
|
||||||
Quantity = newObj.Quantity * -1,
|
|
||||||
SourceType = AyaType.QuoteItemPart,
|
|
||||||
SourceId = newObj.Id,
|
|
||||||
Description = await Translate("QuoteItemPart") + $" {newObj.Serials} " + await Translate("EventCreated")
|
|
||||||
};
|
|
||||||
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(ApiErrorCode.API_SERVER_ERROR, "generalerror", $"Error updating inventory ({pi.Description}):{pib.GetErrorsAsString()}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ //Consume serial numbers from part
|
|
||||||
if (!string.IsNullOrWhiteSpace(newObj.Serials))
|
|
||||||
await PartBiz.RemoveSerialsAsync(newObj.PartId, newObj.Serials, ct, UserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//UPDATED, HANDLE INVENTORY / UPDATE SERIALS AS REQUIRED
|
|
||||||
if (ayaEvent == AyaEvent.Modified)
|
|
||||||
{
|
|
||||||
//INVENTORY
|
|
||||||
if (newObj.PartId != oldObj.PartId || newObj.Quantity != oldObj.Quantity)
|
|
||||||
{
|
|
||||||
//OUT with the old
|
|
||||||
if (oldObj.Quantity != 0)//zero quantity doesn't affect inventory or serials
|
|
||||||
{
|
|
||||||
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("QuoteItemPart") + $" {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
|
|
||||||
{
|
|
||||||
PartId = newObj.PartId,
|
|
||||||
PartWarehouseId = newObj.PartWarehouseId,
|
|
||||||
Quantity = newObj.Quantity * -1,
|
|
||||||
SourceType = AyaType.QuoteItemPart,
|
|
||||||
SourceId = newObj.Id,
|
|
||||||
Description = await Translate("QuoteItemPart") + $" {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)
|
|
||||||
{
|
|
||||||
//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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -3318,7 +3318,7 @@ namespace AyaNova.Util
|
|||||||
o.InternalReferenceNumber = "irf-" + Fake.Finance.Account(4);
|
o.InternalReferenceNumber = "irf-" + Fake.Finance.Account(4);
|
||||||
//o.ServiceDate = woDate;
|
//o.ServiceDate = woDate;
|
||||||
|
|
||||||
int woItemCount = Fake.Random.Int(1, 4);
|
int woItemCount = Fake.Random.Int(1, 2);
|
||||||
for (int y = 0; y < woItemCount; y++)
|
for (int y = 0; y < woItemCount; y++)
|
||||||
{
|
{
|
||||||
var woItem = new QuoteItem()
|
var woItem = new QuoteItem()
|
||||||
|
|||||||
Reference in New Issue
Block a user