Xavier LARTEM
Xavier LARTEM

Reputation: 139

acumatica c# / Add SOPackageDetailEx

I have this error when I try to add a line of package Error : Another process has added the "SOPackagedetail" record. Your changes will be lost.

error

My c# code is this :
protected virtual void creationColis()      
{
SOShipment ship=Base.CurrentDocument.Select();
SOPackageDetailEx colis = new SOPackageDetailEx();
colis.BoxID="COLIS";
colis.PackageType="M";
colis.ShipmentNbr=ship.ShipmentNbr;
    
SOShipmentEntry graph = PXGraph.CreateInstance<SOShipmentEntry>();  
graph.Packages.Insert(colis); //insertion de l'enregistrement
graph.Packages.Update(colis);
graph.Actions.PressSave();
graph.Clear();      
}

Do you know what I must to change please ? Thanks so much Xavier

Upvotes: 0

Views: 178

Answers (1)

Brian Stevens
Brian Stevens

Reputation: 1941

Your question needs more context. For starters, where does your code reside? Given that you reference Base.CurrentDocument.Select, I'm going to assume you are extending SOShipmentEntry to add your code.

In this case, you would just use the Base.Packages view rather than initializing your own instance of SOShipmentEntry where your example goes into trying to use graph.Packages. Regardless, there are 2 parts here that need to be addressed.

  1. Packages is not the primary view of SOShipmentEntry. When you create an instance of a graph, you must tell the graph what record is needed in the primary view. In your example where you create a new instance of a graph, you might do something like this:

    graph.Document.Current = graph.Document.Search<SOShipment.shipmentNbr>(myShipmentNbr);

If you are working on a graph extension of SOShipmentEntry, then you probably don't need to create a new instance of the graph. Just make sure graph.Document.Current isn't null before you add your package record - see bullet 2.

  1. Once you have a shipment selected, you can then insert your package information. However, the way you have done it here effectively is trying to add a random package to a null shipment (by the structure of the views) but forcing the record to attach to the right shipment by sheer brute force. The views don't like to work that way.

A better way to add your package once you have a current shipment (Document) is like this:

// Find the current shipment (from the primary view Document)
SOShipment ship = Base.Document.Current();

if(ship?.ShipmentNbr != null) {

    // Insert a record into the Packages view of the current shipment and return the record into colis
    SOPackageDetailEx colis = Base.Packages.Insert(colis);

    // Set the custom values
    colis.BoxID="COLIS";
    colis.PackageType="M";

    // Update the Packages cache with the modified fields
    Base.Packages.Update(colis);

    // If more fields need to be updated after those changes were applied, instead do this...
    colis = Base.Packages.Update(colis);
    colis.FieldA = ValueA;
    colis.FieldB = ValueB;
    Base.Packages.Update(colis);

    // If a save is needed, now is the time
    Base.Save.Press();

}

Notice that I didn't assign ShipmentNbr. That is because the DAC has that field defined to pull the ShipmentNbr from SOShipment through these 2 attributes.

[PXParent(typeof(FK.Shipment))]
[PXDBDefault(typeof(SOShipment.shipmentNbr))]

This means that when the record is created, Acumatica should lookup the parent SOShipment record via the Key and do a DBDefault on the field to assign it to the SOShipment.ShipmentNbr value (from the parent). Important side note: PXDefault and PXDBDefault are NOT interchangeable. We use PXDefault a lot, but off the top of my head I can't think of a case of PXDBDefault outside of defaulting from a database value like this specific usage.

Upvotes: 2

Related Questions