Easy way is to prevent new ShipDtl records from being added with the disallowed line. You could do that on CustShip.GetOrderLineInfo.
If you need it to stay on the shipment and just not allow it to close, I’d do pre-processing on CustShip.ChangeStatus.
Based on a trace, it looks like pre-processing data doesn’t have the ShipHead data, only the SysRowID, so you’ll probably have to look up the Order / Line by searching for the ShipHead record by SysRowID, then the ShipDtl record by PackNum, the the order info by Order / Line on ShipDtl. If the ChangeStatus variable ipStatus == "CLOSE" and the field you query is true, throw an exception.
I do mine in a DD on ShipHead. I have two fields hold set ShipHold_c and ShipReleased_c to show a hold existed and was completed. I sanited it, but left all of the other checks we do. I had several sets and went to a UD setup with the not in the UD LongDesc, so I did not have to make a program change for every new hold they came up with.
/* set code to hold type comment */
/* set header shipvia from order/line/release */
Erp.Tables.ShipVia ShipVia;
string payMethod = string.Empty;
string InfoMsg = string.Empty;
DateTime today = DateTime.Now.Date;
foreach (var ttShipHeadRow in ttShipHead.Where(ttShipHead_Row => ttShipHead_Row.Company == Session.CompanyID))
{
var holdList = (from sd in Db.ShipDtl.With(LockHint.NoLock)
join sh in Db.ShipHead.With(LockHint.NoLock)
on new { sd.Company, sd.PackNum } equals new { sh.Company, sh.PackNum }
join c in Db.Customer.With(LockHint.NoLock)
on new { sh.Company, sh.CustNum } equals new { c.Company, c.CustNum }
join od in Db.OrderDtl.With(LockHint.NoLock)
on new { sd.Company, sd.OrderNum, sd.OrderLine } equals new { od.Company, od.OrderNum, od.OrderLine }
join rel in Db.OrderRel.With(LockHint.NoLock)
on new { sd.Company, sd.OrderNum, sd.OrderLine, sd.OrderRelNum } equals new { rel.Company, rel.OrderNum, rel.OrderLine, rel.OrderRelNum }
join p in Db.Part.With(LockHint.NoLock)
on new { sd.Company, sd.PartNum } equals new { p.Company, p.PartNum }
join ud in Db.UDCodes.With(LockHint.NoLock)
on new { od.Company, Code = od.HoldType_c } equals new { ud.Company, Code = ud.CodeID }
into udj
from ud in udj.DefaultIfEmpty()
where sd.Company == ttShipHeadRow.Company && ttShipHeadRow.PackNum == sd.PackNum
&& (
|| (od.ShipHold_c == true && od.ShipReleased_c == false)
|| (od.FARequired_c == true && od.FAComplete_c == false)
|| rel.ReqDate > today
|| (c.CreditHold == true && c.CreditHoldSource == "MANUAL")
)
select new {od.OrderNum,od.QC1980_c, od.QC1980Complete_c, od.FARequired_c, od.FAComplete_c, od.ShipHold_c, od.ShipReleased_c, ud.LongDesc, p.ULRequired_c, p.CheckBox11, rel.ReqDate, c.CreditHold, c.CreditHoldSource}
).ToList();
foreach(var holdRow in holdList)
{
if(holdRow.QC_c == true && holdRow.QCComplete_c == false )
{
InfoMsg = "DO NOT ship this pack out until the form is filed with Quality. \n\nSee if you have questions.";
}
if(holdRow.FARequired_c == true && holdRow.FAComplete_c == false)
{
InfoMsg = "DO NOT ship this pack out until the First Article paperwork is completed. \n\nPlease see if you have questions.";
}
if(holdRow.ShipHold_c == true && holdRow.ShipReleased_c == false)
{
InfoMsg = holdRow.LongDesc;
}
if(holdRow.ReqDate > today)
{
InfoMsg = $"Ship Date {holdRow.ReqDate:d} later than today";
}
if(holdRow.CreditHold == true && holdRow.CreditHoldSource == "MANUAL")
{
InfoMsg = "Customer is Credit Hold. No shipments Allowed.";
}
}
if(!string.IsNullOrEmpty(InfoMsg))
{
throw new Ice.BLException(InfoMsg);
}
}