Used Revisions Delete

@josecgomez and I made an unexpected discovery today. It appears you can delete Approved Part Revs that have been used on jobs before. The whole thing end to end engineering and all. My assumption would have been that Epicor would Hard No that action but apparently not. Has anyone else noticed this? Tested it on 10.2.200 and 10.2.500 it will let you delete on both. I’m just very surprised by this. Going to submit a ticket to see what the response is on this one. Just thought I would share.

Epicor has this KB article out there stating working as designed since 9 Knowledge Base - EpicCare
I still opened a ticket contesting the design, case CS0001740155

3 Likes

Who knew Db.Delete() would actually delete a record from the Db?!?!!

1 Like

Part tran history doesn’t differentiate between revisions anyways, so I think that’s why they allow it. They will say that general understanding of a revision is that that new one functions in place of the old one, otherwise a new part number should be created. You can’t delete a part number and that’s what the history is tied to.

Agreed, though it is still a dumb thing to allow, someone (IE: @jgiese.wci’s employee can delete a revision on accident and then the entire BOM is gone… ) Sure a BPM can help, but come on!
Also PartTran carries Rev… (sometimes)
#DumbDesignChoice

You can change revisions whenever you want anyways… At Rapat everything is always REV A, even if something is changed. (not best practice I know). So it doesn’t really prevent anything.

1 Like

Kill me now.

cost transactions, part materials and, and transactions where materials are issued to jobs all contain revisions. Really the only thing that doesn’t is inventory which I’ve always found annoying anyways, but that is what it is. Regardless there should be at the least a confirmation box or configurable flag for it, or if it’s approved to me that should always be a hard stop at the very very least. Anyone that wants it here is what I built for it. I didn’t do so here but it might be worth looking to PartTran for records and just using that vs each specific area, dealers choice.

Part.Update > Pre Processing
image

Single custom code block

foreach(var tt in ttPartRev.Where(x => x.Deleted()))
{
  // Check for approved rev
  if(tt.Approved)
  {
    throw new Ice.BLException($"Revision deletion not allowed on approved revisions.");
  }
  
  // Check usage
  string disallowDelete = "";
  if (Db.QuoteDtl.With(LockHint.NoLock).Where(x => x.Company == this.Session.CompanyID && x.PartNum == tt.PartNum && x.RevisionNum == tt.RevisionNum).Any())
  {
    disallowDelete += $"There are Quote lines containing {tt.PartNum}/{tt.RevisionNum}.\r\n";
  }
  if (Db.JobPart.With(LockHint.NoLock).Where(x => x.Company == this.Session.CompanyID && x.PartNum == tt.PartNum && x.RevisionNum == tt.RevisionNum).Any())
  {
    disallowDelete += $"There are existing Jobs with {tt.PartNum}/{tt.RevisionNum}.\r\n";
  }
  if (Db.JobMtl.With(LockHint.NoLock).Where(x => x.Company == this.Session.CompanyID && x.PartNum == tt.PartNum && x.RevisionNum == tt.RevisionNum).Any())
  {
    disallowDelete += $"{tt.PartNum}/{tt.RevisionNum} is a material for existing jobs.\r\n";
  }
  if (Db.PartMtl.With(LockHint.NoLock).Where(x => x.Company == this.Session.CompanyID && x.PartNum == tt.PartNum && x.RevisionNum == tt.RevisionNum).Any())
  {
    disallowDelete += $"{tt.PartNum}/{tt.RevisionNum} is engineered with ops/mtls.\r\n";
  }
  if (Db.OrderDtl.With(LockHint.NoLock).Where(x => x.Company == this.Session.CompanyID && x.PartNum == tt.PartNum && x.RevisionNum == tt.RevisionNum).Any())
  {
    disallowDelete += $"There are Order lines containing {tt.PartNum}/{tt.RevisionNum}.\r\n";
  }
  
  if(!string.IsNullOrEmpty(disallowDelete))
  {
    throw new Ice.BLException($"Revision deletion not allowed:\r\n\r\n{disallowDelete}");
  }
}

3 Likes

I built a hard stop but if you wanted a soft stop with custom messages asking for specific confirmation you could hook onto the Part.CheckAltMethodForDelete > Post Processing and replace opMessage output with whatever you want and get a confirmation box. When deleting a revision this method is first called the CheckConfigForDelete which is product configuration confirmation then the deletion update happens.

This is great! Thanks so much for sharing.

One correction: Your PartMtl check is actually just checking if the revision HAS any materials. The materials are on the field PartMtl.MtlPartNum, and the revision is not saved because it’s determined at the time of Get Details, based on the revision Effective Dates.

1 Like

Copy paste error that was my control for knowing if the part is engineered I need to update my error message thanks for the heads up! I chose to see if the part has material records because if it had empty operations I wouldn’t really care much for our case.

No problem; I’m grabbing your correction too, now. I’ve already got a conversation started with Engineering and Compliance on which conditions should trigger a hard stop vs soft stop.

1 Like

Hi there,
I pasted this code into Part.Update but get the following error.
CS0103: The name ‘ttPartRev’ does not exist in the current context.
Is there a step that I am missing.
Thanks
Alan