My latest experiments give me hope that my UOMs can be fixed. Here’s what I’ve discovered so far. Note that all these experiments are with conversions that have not been marked used.
Creating a part creates PartUOM rows for all part-specific UOMConvs in the part’s UOM class. This seems to be unnecessary database clutter.
Subsequently adding a part-specific UOMConv to the class does not create PartUOM rows for parts already in the class. This does not seem to cause any problems, which is why creating the PartUOM rows when a part is created is just clutter. The new part-specific UOMConv appears in the part UI even though there’s no PartUOM row. The conversion is usable for the part as if a PartUOM row existed. The conversion factor is the default from UOMConv. Using it still does not create a PartUOM row. Only editing the factor actually creates a PartUOM row.
Removing a part-specific UOMConv from a class leaves orphaned PartUOM rows. There is no indication in PartUOM that the row is orphaned. Even PartUOM.Active is still true. But the UI view model apparently combines PartUOM and UOMConv. The orphaned PartUOM is still visible in the part’s UOM tab, but it’s no longer editable, and part-specific appears unchecked despite it still being true in PartUOM. Most importantly, the UOM is no longer selectable for quantities of the part. So again, database clutter but no real harm aside from a slightly confusing presentation in the UOM tab.
If a PartUOM row exists and you uncheck part-specific on the UOMConv, the PartUOM row is not removed. PartUOM.Active remains true. But as with a deleted UOMConv, the UOM tab shows the conversion as non-part-specific. If the PartUOM factor differed from the UOMConv factor, the UI reverts to the UOMConv factor. Again, database clutter but no real harm.
The database clutter only becomes an issue if you’re writing BAQs or otherwise accessing the PartUOM table. You cannot tell from a PartUOM row whether a part actually has an effective part-specific conversion. You can only determine if a PartUOM row is “real” by joining on UOMConv.