Skip to main content
Answer

Creating a Delete Log Record when SOShipment is Deleted

  • July 3, 2025
  • 2 replies
  • 56 views

Forum|alt.badge.img

I am trying to create a delete log record if a shipment is deleted after item has been picked and/or packed.  I do not know what event to use that will allow me to save to the table.

protected void SOShipLine_RowDeleting(PXCache sender, PXRowDeletingEventArgs e)
{
    var row = (SOShipLine)e.Row;
    if (row == null) return;


    foreach (SOShipLineSplit split in SelectFrom<SOShipLineSplit>
        .Where<SOShipLineSplit.shipmentNbr.IsEqual<PX.Data.BQL.@P.AsString>
        .And<SOShipLineSplit.lineNbr.IsEqual<PX.Data.BQL.@P.AsInt>>>
        .View.Select(Base, row.ShipmentNbr, row.LineNbr))
    {
        if (split.PickedQty > 0 || split.PackedQty > 0)
        {
            MSPSOShipmentDeleteLog newLog = new MSPSOShipmentDeleteLog()
            {
                OrderType = row.OrigOrderType,
                OrderNbr = row.OrigOrderNbr,
                LineNbr = row.LineNbr,
                SiteID = row.SiteID,
                SplitLineNbr = split.SplitLineNbr,
                InventoryID = split.InventoryID,
                ShipmentNbr = split.ShipmentNbr,
                Qty = (int?)split.Qty,
                PickedQty = (int?)split.PickedQty,
                PackedQty = (int?)split.PackedQty,
            };
            var newRes = Base.Caches[typeof(MSPSOShipmentDeleteLog)].Insert(newLog);
            
        }
    }
}

 

Any help would be appreciated.

Best answer by skalb11

I got this to work with help from Kyle Vanderstoep.

Added a view:

public SelectFrom<MSPSOShipmentDeleteLog>        .Where<MSPSOShipmentDeleteLog.shipmentNbr.IsEqual<SOShipment.shipmentNbr.FromCurrent>>.View deleteFilter;

 

Used RowDeleted Event:

protected void SOShipment_RowDeleted(PXCache sender, PXRowDeletedEventArgs e)
{
    SOShipment row = (SOShipment)e.Row;

    if (row == null)
        return;

    // Get all shipment lines for the deleted shipment
    var shipLines = PXSelect<SOShipLine,
        Where<SOShipLine.shipmentNbr, Equal<Required<SOShipLine.shipmentNbr>>>>
        .Select(Base, row.ShipmentNbr);

    foreach (SOShipLine line in shipLines)
    {
        foreach (SOShipLineSplit split in SelectFrom<SOShipLineSplit>
        .Where<SOShipLineSplit.shipmentNbr.IsEqual<PX.Data.BQL.@P.AsString>
        .And<SOShipLineSplit.lineNbr.IsEqual<PX.Data.BQL.@P.AsInt>>>
        .View.Select(Base, line.ShipmentNbr, line.LineNbr))
        {
            if (split.PickedQty > 0 || split.PackedQty > 0)
            {
                MSPSOShipmentDeleteLog newLog = new MSPSOShipmentDeleteLog()
                {
                    OrderType = line.OrigOrderType,
                    OrderNbr = line.OrigOrderNbr,
                    LineNbr = line.LineNbr,
                    SiteID = line.SiteID,
                    SplitLineNbr = split.SplitLineNbr,
                    InventoryID = split.InventoryID,
                    ShipmentNbr = split.ShipmentNbr,
                    Qty = (int?)split.Qty,
                    PickedQty = (int?)split.PickedQty,
                    PackedQty = (int?)split.PackedQty,
                };
                var newRes = Base.Caches[typeof(MSPSOShipmentDeleteLog)].Insert(newLog);
            }
        }
    }
}

 

Dac:

using System;
using MCB_Custom.MspData;
using MspComment.DAC;
using PX.Data;
using PX.Data.BQL;
using PX.Objects.AR;
using PX.Objects.CS;
using PX.Objects.IN;
using PX.Objects.SO;
using PX.TM;

namespace MCB_Custom.MspCustom.DAC
{
    [Serializable]
    [PXCacheName("MSPSOShipmentDeleteLog")]
    public class MSPSOShipmentDeleteLog : PXBqlTable, IBqlTable
    {
        #region OrderType
        [PXDBString(2, IsKey = true, IsFixed = true)]
        [PXUIField(DisplayName = "Order Type", Visible = false, Enabled = false)]
        [PXSelector(typeof(Search<SOOrderType.orderType>), CacheGlobal = true)]
        public virtual string OrderType { get; set; }
        public abstract class orderType : BqlString.Field<orderType> { }
        #endregion

        #region OrderNbr
        [PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
        [PXDBDefault(typeof(SOOrder.orderNbr), DefaultForUpdate = false)]
        [PXUIField(DisplayName = "Order Nbr.", Visible = false, Enabled = false)]
        public virtual string OrderNbr { get; set; }
        public abstract class orderNbr : BqlString.Field<orderNbr> { }
        #endregion

        #region SiteID
        [PXDBInt(IsKey = true)]
        public abstract class siteID : PX.Data.BQL.BqlInt.Field<siteID> { }
        [PXUIField(DisplayName = "Warehouse ID", Visible = true)]
        [Site]
        public virtual int? SiteID { get; set; }
        #endregion

        #region ShipmentNbr
        [PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
        [PXDBDefault(typeof(SOShipment.shipmentNbr))]
        [PXUIField(DisplayName = "Shipment Nbr.", Visible = false, Enabled = false)]
        public virtual string ShipmentNbr { get; set; }
        public abstract class shipmentNbr : BqlString.Field<shipmentNbr> { }
        #endregion

        #region LineNbr 
        [PXDBInt(IsKey = true)]
        [PXLineNbr(typeof(SOOrder.lineCntr))]
        [PXUIField(DisplayName = "Line Nbr.", Visible = false)]
        public virtual int? LineNbr { get; set; }
        public abstract class lineNbr : BqlInt.Field<lineNbr> { }
        #endregion

        #region SplitLineNbr 
        [PXDBInt(IsKey = true)]
        [PXDefault(typeof(SOShipLine.origSplitLineNbr))]
        [PXUIField(DisplayName = "Split Line Nbr.", Visible = false)]
        public virtual int? SplitLineNbr { get; set; }
        public abstract class splitLineNbr : BqlInt.Field<splitLineNbr> { }
        #endregion

        #region InventoryID
        [PXDBInt()]
        public virtual int? InventoryID { get; set; }
        public abstract class inventoryID : BqlInt.Field<inventoryID> { }
        #endregion

                #region Qty
        [PXDBInt()]
        [PXUIField(DisplayName = "Qty")]
        public virtual int? Qty { get; set; }
        public abstract class qty : BqlInt.Field<qty> { }
        #endregion

        #region PickedQty
        [PXDBInt()]
        [PXUIField(DisplayName = "Picked Qty")]
        public virtual int? PickedQty { get; set; }
        public abstract class pickedQty : BqlInt.Field<pickedQty> { }
        #endregion

        #region PackedQty
        [PXDBInt()]
        [PXUIField(DisplayName = "Packed Qty")]
        public virtual int? PackedQty { get; set; }
        public abstract class packedQty : BqlInt.Field<packedQty> { }
        #endregion

        #region CreatedByID
        protected Guid? _CreatedByID;
        [PXDBCreatedByID()]
        [PXUIField(DisplayName = "Created By")]
        public virtual Guid? CreatedByID { get; set; }
        public abstract class createdByID : PX.Data.BQL.BqlGuid.Field<createdByID> { }
        #endregion

        #region CreatedByScreenID
        [PXDBCreatedByScreenID()]
        public virtual string CreatedByScreenID { get; set; }
        public abstract class createdByScreenID : PX.Data.BQL.BqlString.Field<createdByScreenID> { }
        #endregion

        #region CreatedDateTime
        protected DateTime? _CreatedDateTime;
        [PXDBCreatedDateTime()]
        [PXUIField(DisplayName = PXDBLastModifiedByIDAttribute.DisplayFieldNames.CreatedDateTime, Enabled = false, IsReadOnly = true)]
        public virtual DateTime? CreatedDateTime { get; set; }
        public abstract class createdDateTime : PX.Data.BQL.BqlDateTime.Field<createdDateTime> { }
        #endregion

        #region LastModifiedByID
        protected Guid? _LastModifiedByID;
        [PXDBLastModifiedByID()]
        [PXUIField(DisplayName = "Last Modified By")]
        public virtual Guid? LastModifiedByID { get; set; }
        public abstract class lastModifiedByID : PX.Data.BQL.BqlGuid.Field<lastModifiedByID> { }
        #endregion

        #region LastModifiedByScreenID
        [PXDBLastModifiedByScreenID()]
        public virtual string LastModifiedByScreenID { get; set; }
        public abstract class lastModifiedByScreenID : PX.Data.BQL.BqlString.Field<lastModifiedByScreenID> { }
        #endregion

        #region LastModifiedDateTime
        protected DateTime? _LastModifiedDateTime;
        [PXDBLastModifiedDateTime()]
        [PXUIField(DisplayName = PXDBLastModifiedByIDAttribute.DisplayFieldNames.LastModifiedDateTime, Enabled = false, IsReadOnly = true)]
        public virtual DateTime? LastModifiedDateTime { get; set; }
        public abstract class lastModifiedDateTime : PX.Data.BQL.BqlDateTime.Field<lastModifiedDateTime> { }
        #endregion

        #region Tstamp
        [PXDBTimestamp()]
        [PXUIField(DisplayName = "Tstamp")]
        public virtual byte[] Tstamp { get; set; }
        public abstract class tstamp : PX.Data.BQL.BqlByteArray.Field<tstamp> { }
        #endregion
    }
}
 

2 replies

Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • Answer
  • July 10, 2025

I got this to work with help from Kyle Vanderstoep.

Added a view:

public SelectFrom<MSPSOShipmentDeleteLog>        .Where<MSPSOShipmentDeleteLog.shipmentNbr.IsEqual<SOShipment.shipmentNbr.FromCurrent>>.View deleteFilter;

 

Used RowDeleted Event:

protected void SOShipment_RowDeleted(PXCache sender, PXRowDeletedEventArgs e)
{
    SOShipment row = (SOShipment)e.Row;

    if (row == null)
        return;

    // Get all shipment lines for the deleted shipment
    var shipLines = PXSelect<SOShipLine,
        Where<SOShipLine.shipmentNbr, Equal<Required<SOShipLine.shipmentNbr>>>>
        .Select(Base, row.ShipmentNbr);

    foreach (SOShipLine line in shipLines)
    {
        foreach (SOShipLineSplit split in SelectFrom<SOShipLineSplit>
        .Where<SOShipLineSplit.shipmentNbr.IsEqual<PX.Data.BQL.@P.AsString>
        .And<SOShipLineSplit.lineNbr.IsEqual<PX.Data.BQL.@P.AsInt>>>
        .View.Select(Base, line.ShipmentNbr, line.LineNbr))
        {
            if (split.PickedQty > 0 || split.PackedQty > 0)
            {
                MSPSOShipmentDeleteLog newLog = new MSPSOShipmentDeleteLog()
                {
                    OrderType = line.OrigOrderType,
                    OrderNbr = line.OrigOrderNbr,
                    LineNbr = line.LineNbr,
                    SiteID = line.SiteID,
                    SplitLineNbr = split.SplitLineNbr,
                    InventoryID = split.InventoryID,
                    ShipmentNbr = split.ShipmentNbr,
                    Qty = (int?)split.Qty,
                    PickedQty = (int?)split.PickedQty,
                    PackedQty = (int?)split.PackedQty,
                };
                var newRes = Base.Caches[typeof(MSPSOShipmentDeleteLog)].Insert(newLog);
            }
        }
    }
}

 

Dac:

using System;
using MCB_Custom.MspData;
using MspComment.DAC;
using PX.Data;
using PX.Data.BQL;
using PX.Objects.AR;
using PX.Objects.CS;
using PX.Objects.IN;
using PX.Objects.SO;
using PX.TM;

namespace MCB_Custom.MspCustom.DAC
{
    [Serializable]
    [PXCacheName("MSPSOShipmentDeleteLog")]
    public class MSPSOShipmentDeleteLog : PXBqlTable, IBqlTable
    {
        #region OrderType
        [PXDBString(2, IsKey = true, IsFixed = true)]
        [PXUIField(DisplayName = "Order Type", Visible = false, Enabled = false)]
        [PXSelector(typeof(Search<SOOrderType.orderType>), CacheGlobal = true)]
        public virtual string OrderType { get; set; }
        public abstract class orderType : BqlString.Field<orderType> { }
        #endregion

        #region OrderNbr
        [PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
        [PXDBDefault(typeof(SOOrder.orderNbr), DefaultForUpdate = false)]
        [PXUIField(DisplayName = "Order Nbr.", Visible = false, Enabled = false)]
        public virtual string OrderNbr { get; set; }
        public abstract class orderNbr : BqlString.Field<orderNbr> { }
        #endregion

        #region SiteID
        [PXDBInt(IsKey = true)]
        public abstract class siteID : PX.Data.BQL.BqlInt.Field<siteID> { }
        [PXUIField(DisplayName = "Warehouse ID", Visible = true)]
        [Site]
        public virtual int? SiteID { get; set; }
        #endregion

        #region ShipmentNbr
        [PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
        [PXDBDefault(typeof(SOShipment.shipmentNbr))]
        [PXUIField(DisplayName = "Shipment Nbr.", Visible = false, Enabled = false)]
        public virtual string ShipmentNbr { get; set; }
        public abstract class shipmentNbr : BqlString.Field<shipmentNbr> { }
        #endregion

        #region LineNbr 
        [PXDBInt(IsKey = true)]
        [PXLineNbr(typeof(SOOrder.lineCntr))]
        [PXUIField(DisplayName = "Line Nbr.", Visible = false)]
        public virtual int? LineNbr { get; set; }
        public abstract class lineNbr : BqlInt.Field<lineNbr> { }
        #endregion

        #region SplitLineNbr 
        [PXDBInt(IsKey = true)]
        [PXDefault(typeof(SOShipLine.origSplitLineNbr))]
        [PXUIField(DisplayName = "Split Line Nbr.", Visible = false)]
        public virtual int? SplitLineNbr { get; set; }
        public abstract class splitLineNbr : BqlInt.Field<splitLineNbr> { }
        #endregion

        #region InventoryID
        [PXDBInt()]
        public virtual int? InventoryID { get; set; }
        public abstract class inventoryID : BqlInt.Field<inventoryID> { }
        #endregion

                #region Qty
        [PXDBInt()]
        [PXUIField(DisplayName = "Qty")]
        public virtual int? Qty { get; set; }
        public abstract class qty : BqlInt.Field<qty> { }
        #endregion

        #region PickedQty
        [PXDBInt()]
        [PXUIField(DisplayName = "Picked Qty")]
        public virtual int? PickedQty { get; set; }
        public abstract class pickedQty : BqlInt.Field<pickedQty> { }
        #endregion

        #region PackedQty
        [PXDBInt()]
        [PXUIField(DisplayName = "Packed Qty")]
        public virtual int? PackedQty { get; set; }
        public abstract class packedQty : BqlInt.Field<packedQty> { }
        #endregion

        #region CreatedByID
        protected Guid? _CreatedByID;
        [PXDBCreatedByID()]
        [PXUIField(DisplayName = "Created By")]
        public virtual Guid? CreatedByID { get; set; }
        public abstract class createdByID : PX.Data.BQL.BqlGuid.Field<createdByID> { }
        #endregion

        #region CreatedByScreenID
        [PXDBCreatedByScreenID()]
        public virtual string CreatedByScreenID { get; set; }
        public abstract class createdByScreenID : PX.Data.BQL.BqlString.Field<createdByScreenID> { }
        #endregion

        #region CreatedDateTime
        protected DateTime? _CreatedDateTime;
        [PXDBCreatedDateTime()]
        [PXUIField(DisplayName = PXDBLastModifiedByIDAttribute.DisplayFieldNames.CreatedDateTime, Enabled = false, IsReadOnly = true)]
        public virtual DateTime? CreatedDateTime { get; set; }
        public abstract class createdDateTime : PX.Data.BQL.BqlDateTime.Field<createdDateTime> { }
        #endregion

        #region LastModifiedByID
        protected Guid? _LastModifiedByID;
        [PXDBLastModifiedByID()]
        [PXUIField(DisplayName = "Last Modified By")]
        public virtual Guid? LastModifiedByID { get; set; }
        public abstract class lastModifiedByID : PX.Data.BQL.BqlGuid.Field<lastModifiedByID> { }
        #endregion

        #region LastModifiedByScreenID
        [PXDBLastModifiedByScreenID()]
        public virtual string LastModifiedByScreenID { get; set; }
        public abstract class lastModifiedByScreenID : PX.Data.BQL.BqlString.Field<lastModifiedByScreenID> { }
        #endregion

        #region LastModifiedDateTime
        protected DateTime? _LastModifiedDateTime;
        [PXDBLastModifiedDateTime()]
        [PXUIField(DisplayName = PXDBLastModifiedByIDAttribute.DisplayFieldNames.LastModifiedDateTime, Enabled = false, IsReadOnly = true)]
        public virtual DateTime? LastModifiedDateTime { get; set; }
        public abstract class lastModifiedDateTime : PX.Data.BQL.BqlDateTime.Field<lastModifiedDateTime> { }
        #endregion

        #region Tstamp
        [PXDBTimestamp()]
        [PXUIField(DisplayName = "Tstamp")]
        public virtual byte[] Tstamp { get; set; }
        public abstract class tstamp : PX.Data.BQL.BqlByteArray.Field<tstamp> { }
        #endregion
    }
}
 


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • July 11, 2025

Thank you for sharing the solution with the community ​@skalb11 and ​@Kyle Vanderstoep for the assist!