protected virtual void INKitSpecStkDet_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row == null)
            {
                return;
            }
            if ((e.Operation & PXDBOperation.Command) == PXDBOperation.Delete)
            {
                return;
            }

            PXSelectBase <INKitSpecStkDet> select = new PXSelect <INKitSpecStkDet,
                                                                  Where <INKitSpecStkDet.kitInventoryID, Equal <Current <INKitSpecHdr.kitInventoryID> >,
                                                                         And <INKitSpecStkDet.revisionID, Equal <Current <INKitSpecHdr.revisionID> >,
                                                                              And <INKitSpecStkDet.compInventoryID, Equal <Required <INKitSpecStkDet.compInventoryID> >,
                                                                                   And <INKitSpecStkDet.compSubItemID, Equal <Required <INKitSpecStkDet.compSubItemID> > > > > > >(this);

            PXResultset <INKitSpecStkDet> res = select.Select(row.CompInventoryID, row.CompSubItemID);

            if (res.Count > 1)
            {
                InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, row.CompInventoryID);

                if (sender.RaiseExceptionHandling <INKitSpecStkDet.compInventoryID>(e.Row, item.InventoryCD, new PXException(Messages.KitItemMustBeUniqueAccrosSubItems)))
                {
                    throw new PXRowPersistingException(typeof(INKitSpecStkDet.compInventoryID).Name, item.InventoryCD, Messages.KitItemMustBeUniqueAccrosSubItems);
                }
            }
        }
        protected virtual void INKitSpecStkDet_CompInventoryID_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                PXSelectBase <INKitSpecStkDet> select = new PXSelect <INKitSpecStkDet,
                                                                      Where <INKitSpecStkDet.kitInventoryID, Equal <Current <INKitSpecHdr.kitInventoryID> >,
                                                                             And <INKitSpecStkDet.revisionID, Equal <Current <INKitSpecHdr.revisionID> >,
                                                                                  And <INKitSpecStkDet.compInventoryID, Equal <Required <INKitSpecStkDet.compInventoryID> >,
                                                                                       And <INKitSpecStkDet.compSubItemID, Equal <Required <INKitSpecStkDet.compSubItemID> > > > > > >(this);

                PXResultset <INKitSpecStkDet> res = select.Select(e.NewValue, row.CompSubItemID);

                if (res.Count > 0)
                {
                    InventoryItem component = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, row.CompInventoryID);

                    var ex = new PXSetPropertyException(Messages.KitItemMustBeUniqueAccrosSubItems);
                    ex.ErrorValue = component?.InventoryCD;
                    RaiseOnKitNotUniqueException(e, ex);
                }

                PXSelectBase <InventoryItem> selectItemWithLotSerClass = new PXSelectJoin <InventoryItem,
                                                                                           LeftJoin <INLotSerClass, On <INLotSerClass.lotSerClassID, Equal <InventoryItem.lotSerClassID> > >,
                                                                                           Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > >(this);
                foreach (PXResult <InventoryItem, INLotSerClass> kitRes in selectItemWithLotSerClass.Select(Hdr.Current.KitInventoryID))                //single record
                {
                    InventoryItem kit            = (InventoryItem)kitRes;
                    INLotSerClass kitLotSerClass = (INLotSerClass)kitRes;

                    foreach (PXResult <InventoryItem, INLotSerClass> compRes in selectItemWithLotSerClass.Select(e.NewValue))                   //single record
                    {
                        INLotSerClass compLotSerClass = (INLotSerClass)compRes;
                        InventoryItem component       = (InventoryItem)compRes;

                        //Serial number components are valid only for serial numbered kit validation:
                        if (kit.StkItem == true && kitLotSerClass.LotSerTrack != INLotSerTrack.SerialNumbered && compLotSerClass.LotSerTrack == INLotSerTrack.SerialNumbered)
                        {
                            var ex = new PXSetPropertyException(Messages.SNComponentInSNKit);
                            ex.ErrorValue = component.InventoryCD;
                            RaiseSNComponentInSNKitException(e, ex);
                        }

                        //IsUnassigned components are not supported in kits.
                        if (kit.StkItem != true && compLotSerClass.IsUnassigned)
                        {
                            var ex = new PXSetPropertyException(Messages.WhenUsedComponentInKit);
                            ex.ErrorValue = component.InventoryCD;

                            RaiseUnassignedComponentInKitException(e, ex);
                        }
                    }
                }
            }
        }
        protected virtual void INKitSpecStkDet_CompInventoryID_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                PXSelectBase <INKitSpecStkDet> select = new PXSelect <INKitSpecStkDet,
                                                                      Where <INKitSpecStkDet.kitInventoryID, Equal <Current <INKitSpecHdr.kitInventoryID> >,
                                                                             And <INKitSpecStkDet.revisionID, Equal <Current <INKitSpecHdr.revisionID> >,
                                                                                  And <INKitSpecStkDet.compInventoryID, Equal <Required <INKitSpecStkDet.compInventoryID> >,
                                                                                       And <INKitSpecStkDet.compSubItemID, Equal <Required <INKitSpecStkDet.compSubItemID> > > > > > >(this);

                PXResultset <INKitSpecStkDet> res = select.Select(e.NewValue, row.CompSubItemID);

                if (res.Count > 0)
                {
                    InventoryItem component = InventoryItem.PK.Find(this, row.CompInventoryID);
                    var           ex        = new PXSetPropertyException(Messages.KitItemMustBeUniqueAccrosSubItems);
                    ex.ErrorValue = component?.InventoryCD;
                    RaiseOnKitNotUniqueException(e, ex);
                }

                InventoryItem kit = InventoryItem.PK.Find(this, Hdr.Current.KitInventoryID);
                if (kit != null)
                {
                    INLotSerClass kitLotSerClass = INLotSerClass.PK.Find(this, kit.LotSerClassID) ?? new INLotSerClass();

                    InventoryItem component = InventoryItem.PK.Find(this, (int?)e.NewValue);
                    if (component != null)
                    {
                        INLotSerClass compLotSerClass = INLotSerClass.PK.Find(this, component.LotSerClassID) ?? new INLotSerClass();

                        //Serial number components are valid only for serial numbered kit validation:
                        if (kit.StkItem == true && kitLotSerClass.LotSerTrack != INLotSerTrack.SerialNumbered && compLotSerClass.LotSerTrack == INLotSerTrack.SerialNumbered)
                        {
                            var ex = new PXSetPropertyException(Messages.SNComponentInSNKit);
                            ex.ErrorValue = component.InventoryCD;
                            RaiseSNComponentInSNKitException(e, ex);
                        }

                        //Manually assigned components are not supported in kits.
                        if (kit.StkItem != true && compLotSerClass.IsManualAssignRequired == true)
                        {
                            var ex = new PXSetPropertyException(Messages.WhenUsedComponentInKit);
                            ex.ErrorValue = component.InventoryCD;

                            RaiseUnassignedComponentInKitException(e, ex);
                        }
                    }
                }
            }
        }
        protected virtual void INKitSpecStkDet_CompInventoryID_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                InventoryItem item = InventoryItem.PK.Find(this, row.CompInventoryID);
                if (item != null)
                {
                    row.UOM = item.BaseUnit;
                }
            }
        }
        protected virtual void INKitSpecStkDet_CompInventoryID_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, row.CompInventoryID);

                if (item != null)
                {
                    row.UOM = item.BaseUnit;
                }
            }
        }
        protected virtual void INKitSpecStkDet_UOM_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                InventoryItem component = InventoryItem.PK.Find(this, row.CompInventoryID);
                INLotSerClass lsClass   = INLotSerClass.PK.Find(this, component?.LotSerClassID);
                if (lsClass != null &&
                    lsClass.LotSerTrack == INLotSerTrack.SerialNumbered &&
                    !string.Equals(component.BaseUnit, (string)e.NewValue, StringComparison.InvariantCultureIgnoreCase))
                {
                    var ex = new PXSetPropertyException(Messages.SerialNumberedComponentMustBeInBaseUnitOnly, component.BaseUnit);
                    ex.ErrorValue = e.NewValue;
                    RaiseSerialTrackedComponentIsNotInBaseUnitException(e, ex);
                }
            }
        }
        protected virtual void INKitSpecStkDet_UOM_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                PXSelectBase <InventoryItem> selectSerialTrackedComponent = new PXSelectJoin <InventoryItem,
                                                                                              InnerJoin <INLotSerClass, On <INLotSerClass.lotSerClassID, Equal <InventoryItem.lotSerClassID> > >,
                                                                                              Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> >,
                                                                                                     And <INLotSerClass.lotSerTrack, Equal <INLotSerTrack.serialNumbered> > > >(this);

                InventoryItem component = selectSerialTrackedComponent.Select(row.CompInventoryID);
                if (component != null && !string.Equals(component.BaseUnit, (string)e.NewValue, StringComparison.InvariantCultureIgnoreCase))
                {
                    var ex = new PXSetPropertyException(Messages.SerialNumberedComponentMustBeInBaseUnitOnly, component.BaseUnit);
                    ex.ErrorValue = e.NewValue;
                    RaiseSerialTrackedComponentIsNotInBaseUnitException(e, ex);
                }
            }
        }
        protected virtual void INKitSpecStkDet_RowUpdating(PXCache sender, PXRowUpdatingEventArgs e)
        {
            INKitSpecStkDet row = e.NewRow as INKitSpecStkDet;

            if (row != null)
            {
                if (row.AllowQtyVariation == true)
                {
                    if (((row.MinCompQty != null) && (row.DfltCompQty < row.MinCompQty)) ||
                        ((row.MaxCompQty != null) && (row.DfltCompQty > row.MaxCompQty)))
                    {
                        throw new PXSetPropertyException(Messages.DfltQtyShouldBeBetweenMinAndMaxQty);
                    }
                }

                //if (row.KitInventoryID == row.CompInventoryID)
                //{
                //   throw new PXSetPropertyException(Messages.KitMayNotIncludeItselfAsComponentPart);
                //}
            }
        }
        protected virtual void INKitSpecStkDet_CompSubItemID_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                PXSelectBase <INKitSpecStkDet> select = new PXSelect <INKitSpecStkDet,
                                                                      Where <INKitSpecStkDet.kitInventoryID, Equal <Current <INKitSpecHdr.kitInventoryID> >,
                                                                             And <INKitSpecStkDet.revisionID, Equal <Current <INKitSpecHdr.revisionID> >,
                                                                                  And <INKitSpecStkDet.compInventoryID, Equal <Required <INKitSpecStkDet.compInventoryID> >,
                                                                                       And <INKitSpecStkDet.compSubItemID, Equal <Required <INKitSpecStkDet.compSubItemID> > > > > > >(this);

                PXResultset <INKitSpecStkDet> res = select.Select(row.CompInventoryID, e.NewValue);

                if (res.Count > 0)
                {
                    e.Cancel = true;
                    sender.RaiseExceptionHandling <INKitSpecStkDet.compSubItemID>(e.Row, e.NewValue, new PXSetPropertyException(Messages.KitItemMustBeUniqueAccrosSubItems));
                }
            }
        }
        protected virtual void INKitSpecStkDet_CompSubItemID_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            INKitSpecStkDet row = e.Row as INKitSpecStkDet;

            if (row != null)
            {
                PXSelectBase <INKitSpecStkDet> select = new PXSelect <INKitSpecStkDet,
                                                                      Where <INKitSpecStkDet.kitInventoryID, Equal <Current <INKitSpecHdr.kitInventoryID> >,
                                                                             And <INKitSpecStkDet.revisionID, Equal <Current <INKitSpecHdr.revisionID> >,
                                                                                  And <INKitSpecStkDet.compInventoryID, Equal <Required <INKitSpecStkDet.compInventoryID> >,
                                                                                       And <INKitSpecStkDet.compSubItemID, Equal <Required <INKitSpecStkDet.compSubItemID> > > > > > >(this);

                PXResultset <INKitSpecStkDet> res = select.Select(row.CompInventoryID, e.NewValue);

                if (res.Count > 0)
                {
                    INSubItem subitem = INSubItem.PK.Find(this, (int?)e.NewValue);
                    var       ex      = new PXSetPropertyException(Messages.KitItemMustBeUniqueAccrosSubItems);
                    ex.ErrorValue = subitem?.SubItemCD;
                    throw ex;
                }
            }
        }