case 4653 - deleting a record still in use is refused with "in use by" instead of a server error

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 14:57:42 -07:00
parent 6d3b169f23
commit e8b3486a9e
16 changed files with 137 additions and 9 deletions

View File

@@ -339,6 +339,12 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("CustomerServiceRequest"));
if (await ct.PurchaseOrder.AnyAsync(m => m.DropShipToCustomerId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PurchaseOrder"));
if (await ct.WorkOrder.AnyAsync(z => z.CustomerId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrder"));
if (await ct.Quote.AnyAsync(z => z.CustomerId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Quote"));
if (await ct.PM.AnyAsync(z => z.CustomerId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PM"));
// await Task.CompletedTask;
}

View File

@@ -120,7 +120,7 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.NOT_FOUND);
return false;
}
ValidateCanDelete(dbObject);
await ValidateCanDeleteAsync(dbObject);
if (HasErrors)
return false;
{
@@ -239,12 +239,12 @@ namespace AyaNova.Biz
}
private void ValidateCanDelete(CustomerServiceRequest inObj)
private async Task ValidateCanDeleteAsync(CustomerServiceRequest inObj)
{
//whatever needs to be check to delete this object
//can't delete if it's accepted
//FOREIGN KEY CHECKS
//an accepted request is linked from the work order item made from it
if (await ct.WorkOrderItem.AnyAsync(z => z.FromCSRId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrder"));
}

View File

@@ -125,7 +125,7 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.NOT_FOUND);
return false;
}
ValidateCanDelete(dbObject);
await ValidateCanDeleteAsync(dbObject);
if (HasErrors)
return false;
{
@@ -230,9 +230,15 @@ namespace AyaNova.Biz
}
private void ValidateCanDelete(LoanUnit inObj)
private async Task ValidateCanDeleteAsync(LoanUnit inObj)
{
//whatever needs to be check to delete this object
//FOREIGN KEY CHECKS
if (await ct.WorkOrderItemLoan.AnyAsync(z => z.LoanUnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemLoan"));
if (await ct.QuoteItemLoan.AnyAsync(z => z.LoanUnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Quote") + " - " + await Translate("WorkOrderItemLoan"));
if (await ct.PMItemLoan.AnyAsync(z => z.LoanUnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PM") + " - " + await Translate("WorkOrderItemLoan"));
}

View File

@@ -467,6 +467,16 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PartStockingLevels"));
if (await ct.PurchaseOrderItem.AnyAsync(m => m.PartId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PurchaseOrder"));
var quotetext = await Translate("Quote");
var pmtext = await Translate("PM");
if (await ct.WorkOrderItemPart.AnyAsync(z => z.PartId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemPart"));
if (await ct.QuoteItemPart.AnyAsync(z => z.PartId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemPart"));
if (await ct.PMItemPart.AnyAsync(z => z.PartId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemPart"));
if (await ct.WorkOrderItemPartRequest.AnyAsync(z => z.PartId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemPartRequest"));
}

View File

@@ -246,6 +246,16 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PartStockingLevels"));
if (await ct.PurchaseOrderItem.AnyAsync(m => m.PartWarehouseId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PurchaseOrder"));
var quotetext = await Translate("Quote");
var pmtext = await Translate("PM");
if (await ct.WorkOrderItemPart.AnyAsync(z => z.PartWarehouseId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemPart"));
if (await ct.QuoteItemPart.AnyAsync(z => z.PartWarehouseId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemPart"));
if (await ct.PMItemPart.AnyAsync(z => z.PartWarehouseId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemPart"));
if (await ct.WorkOrderItemPartRequest.AnyAsync(z => z.PartWarehouseId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemPartRequest"));
}

View File

@@ -236,6 +236,12 @@ namespace AyaNova.Biz
//FOREIGN KEY CHECKS
if (await ct.PurchaseOrder.AnyAsync(m => m.ProjectId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PurchaseOrder"));
if (await ct.WorkOrder.AnyAsync(z => z.ProjectId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrder"));
if (await ct.Quote.AnyAsync(z => z.ProjectId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Quote"));
if (await ct.PM.AnyAsync(z => z.ProjectId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PM"));
}

View File

@@ -273,6 +273,16 @@ namespace AyaNova.Biz
if (await ct.WorkOrderItemScheduledUser.AnyAsync(x => x.ServiceRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemScheduledUser"));
var quotetext = await Translate("Quote");
var pmtext = await Translate("PM");
if (await ct.QuoteItemLabor.AnyAsync(z => z.ServiceRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemLabor"));
if (await ct.PMItemLabor.AnyAsync(z => z.ServiceRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemLabor"));
if (await ct.QuoteItemScheduledUser.AnyAsync(z => z.ServiceRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemScheduledUser"));
if (await ct.PMItemScheduledUser.AnyAsync(z => z.ServiceRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemScheduledUser"));
}

View File

@@ -294,6 +294,34 @@ namespace AyaNova.Biz
if (await ct.WorkOrderItemExpense.AnyAsync(x => x.ChargeTaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemExpense"));
if (await ct.WorkOrderItemOutsideService.AnyAsync(z => z.TaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemOutsideService"));
var quotetext = await Translate("Quote");
var pmtext = await Translate("PM");
if (await ct.QuoteItemTravel.AnyAsync(z => z.TaxCodeSaleId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemTravel"));
if (await ct.PMItemTravel.AnyAsync(z => z.TaxCodeSaleId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemTravel"));
if (await ct.QuoteItemPart.AnyAsync(z => z.TaxPartSaleId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemPart"));
if (await ct.PMItemPart.AnyAsync(z => z.TaxPartSaleId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemPart"));
if (await ct.QuoteItemLoan.AnyAsync(z => z.TaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemLoan"));
if (await ct.PMItemLoan.AnyAsync(z => z.TaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemLoan"));
if (await ct.QuoteItemLabor.AnyAsync(z => z.TaxCodeSaleId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemLabor"));
if (await ct.PMItemLabor.AnyAsync(z => z.TaxCodeSaleId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemLabor"));
if (await ct.QuoteItemExpense.AnyAsync(z => z.ChargeTaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemExpense"));
if (await ct.PMItemExpense.AnyAsync(z => z.ChargeTaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemExpense"));
if (await ct.QuoteItemOutsideService.AnyAsync(z => z.TaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemOutsideService"));
if (await ct.PMItemOutsideService.AnyAsync(z => z.TaxCodeId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemOutsideService"));
}

View File

@@ -579,6 +579,12 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, null, "Can't be deleted in use by one or more Users");
return;
}
if (await ct.CustomerNotifySubscription.AnyAsync(e => e.TranslationId == inObj.Id))
{
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, null, "Can't be deleted in use by one or more customer notification subscriptions");
return;
}
}

View File

@@ -268,6 +268,14 @@ namespace AyaNova.Biz
//FOREIGN KEY CHECKS
if (await ct.ContractTravelRate.AnyAsync(m => m.TravelRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Contract"));
var quotetext = await Translate("Quote");
var pmtext = await Translate("PM");
if (await ct.WorkOrderItemTravel.AnyAsync(z => z.TravelRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemTravel"));
if (await ct.QuoteItemTravel.AnyAsync(z => z.TravelRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemTravel"));
if (await ct.PMItemTravel.AnyAsync(z => z.TravelRateId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemTravel"));
}

View File

@@ -286,6 +286,20 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("LoanUnit"));
if (await ct.CustomerServiceRequest.AnyAsync(z => z.UnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("CustomerServiceRequest"));
var quotetext = await Translate("Quote");
var pmtext = await Translate("PM");
if (await ct.WorkOrderItemUnit.AnyAsync(z => z.UnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemUnit"));
if (await ct.QuoteItemUnit.AnyAsync(z => z.UnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemUnit"));
if (await ct.PMItemUnit.AnyAsync(z => z.UnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemUnit"));
if (await ct.WorkOrderItemOutsideService.AnyAsync(z => z.UnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemOutsideService"));
if (await ct.QuoteItemOutsideService.AnyAsync(z => z.UnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemOutsideService"));
if (await ct.PMItemOutsideService.AnyAsync(z => z.UnitId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemOutsideService"));
}

View File

@@ -284,6 +284,20 @@ namespace AyaNova.Biz
if (await ct.PurchaseOrder.AnyAsync(m => m.VendorId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PurchaseOrder"));
var quotetext = await Translate("Quote");
var pmtext = await Translate("PM");
if (await ct.WorkOrderItemOutsideService.AnyAsync(z => z.VendorSentToId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemOutsideService"));
if (await ct.QuoteItemOutsideService.AnyAsync(z => z.VendorSentToId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemOutsideService"));
if (await ct.PMItemOutsideService.AnyAsync(z => z.VendorSentToId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemOutsideService"));
if (await ct.WorkOrderItemOutsideService.AnyAsync(z => z.VendorSentViaId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItemOutsideService"));
if (await ct.QuoteItemOutsideService.AnyAsync(z => z.VendorSentViaId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", quotetext + " - " + await Translate("WorkOrderItemOutsideService"));
if (await ct.PMItemOutsideService.AnyAsync(z => z.VendorSentViaId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", pmtext + " - " + await Translate("WorkOrderItemOutsideService"));
}

View File

@@ -208,6 +208,10 @@ namespace AyaNova.Biz
//FOREIGN KEY CHECKS
if (await ct.WorkOrderItem.AnyAsync(m => m.WorkOrderItemPriorityId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItem"));
if (await ct.QuoteItem.AnyAsync(z => z.WorkOrderItemPriorityId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Quote"));
if (await ct.PMItem.AnyAsync(z => z.WorkOrderItemPriorityId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PM"));
}

View File

@@ -210,6 +210,10 @@ namespace AyaNova.Biz
//FOREIGN KEY CHECKS
if (await ct.WorkOrderItem.AnyAsync(m => m.WorkOrderItemStatusId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItem"));
if (await ct.QuoteItem.AnyAsync(z => z.WorkOrderItemStatusId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Quote"));
if (await ct.PMItem.AnyAsync(z => z.WorkOrderItemStatusId == inObj.Id))
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PM"));
}