Skip to main content

Hello All,

I am trying to create a POAddress record from C#.
But I get exception after insert that “CustomerID' cannot be empty.”
This is very confusing because Customer ID Is not empty, as seen in the sample screenshot.

Please tell me what I am doing wrong here?

 


 

@hnasir could you please share a minimal, reproducible example?

How to create a Minimal, Reproducible Example

When asking a question, people will be better able to provide help if you provide code that they can easily understand and use to reproduce the problem. This is referred to by community members as creating a minimal, reproducible example (reprex), a minimal, complete and verifiable example (mcve), or a minimal, workable example (mwe). Regardless of how it's communicated to you, it boils down to ensuring your code that reproduces the problem follows the following guidelines:

Your code examples should be…

  • …Minimal – Use as little code as possible that still produces the same problem
  • …Complete – Provide all parts someone else needs to reproduce your problem in the question itself
  • …Reproducible – Test the code you're about to provide to make sure it reproduces the problem

The rest of this help article provides guidance on these aspects of writing a minimal, reproducible example. 

Minimal

The more code there is to go through, the less likely people can find your problem. Streamline your example in one of two ways:

  1. Restart from scratch. Create a new program, adding in only what is needed to see the problem. Use simple, descriptive names for functions and variables – don’t copy the names you’re using in your existing code.
  2. Divide and conquer. If you’re not sure what the source of the problem is, start removing code a bit at a time until the problem disappears – then add the last part back. 

Minimal and readable

Don't sacrifice clarity for brevity when creating a minimal example. Use consistent naming and indentation, and include code comments if needed. Use your code editor’s shortcut for formatting code. Also, use spaces instead of tabs – tabs might not get correctly formatted on Stack Overflow.

Complete

Make sure all information necessary to reproduce the problem is included in the question itself:

  • If the problem requires some server-side code as well as some XML-based configuration, include code for both. If a web page problem requires HTML, some JavaScript, and a stylesheet, include code for all three. The problem might not be in the code that you think it is in.

  • Use individual code blocks for each file or snippet you include. Provide a description for the purpose of each block.

  • Use Stack Snippets to include runnable HTML, JavaScript, or CSS.

  • DO NOT use images of code. Copy the actual text from your code editor, paste it into the question, then format it as code. This helps others more easily read and test your code.

Reproducible

To help you solve your problem, others will need to verify that it exists:

  • Describe the problem. "It doesn't work" isn't descriptive enough to help people understand your problem. Instead, tell other readers what the expected behavior should be. Tell other readers what the exact wording of the error message is, and which line of code is producing it. Use a brief but descriptive summary of your problem as the title of your question.

  • Eliminate any issues that aren't relevant to the problem. If your question isn’t about a compiler error, ensure that there are no compile-time errors. Use a program such as JSLint to validate interpreted languages. Validate any HTML or XML. 

  • Double-check that your example reproduces the problem! If you inadvertently fixed the problem while composing the example but didn't test it again, you'd want to know that before asking someone else to help.

It might help to shut the system down and restart it, or transport the example to a fresh environment to confirm it really does provide an example of the problem.


please find the code sample below. please replace the customer id with any customer already in database .

 

public class EisSOAddressMaint : PXGraph<EisSOAddressMaint>
{
        public PXSave<SOAddress> POSave;
        public PXInsert<SOAddress> POInsert;

        public SelectFrom<SOAddress>.View SOAddress;
}


public class MyTestClass
{

        >TestMethod]
        public void TestSOAddress()
        {
            var addressGraph = PXGraph.CreateInstance<EisSOAddressMaint>();
            var newAddress = new SOAddress()
            {
                CustomerID = 7048,
                BAccountID = 7048,
                RevisionID = 1,
                AddressLine1 = "add line 1",
                AddressLine2 = "add line 2",
                AddressLine3 = "add line 3",
                CountryID = "DE",
                City = "Ismaning",
                State = "BY",
                PostalCode = "85737"
            };

            var address = addressGraph.SOAddress.Insert(newAddress);
            addressGraph.SOAddress.Cache.Persist(PXDBOperation.Insert);

            Assert.IsTrue(true);
        }
}

 

 


The SOAddress table is meant to be used in the context of a sales order, with the SOOrderEntry graph. Your graph only defines a view on the SOAddress table and nothing else. The SOAddress.CustomerID field has a PXParent attribute that references the current sales order:

 

        protected Int32? _CustomerID;
PXDBInt()]
PXDBDefault(typeof(SOOrder.customerID))]
public virtual Int32? CustomerID
{
get
{
return this._CustomerID;
}
set
{
this._CustomerID = value;
}
}

I wouldn’t recommend inserting data directly into this table without going through the SOOrderEntry graph, an even then I’d be careful not to use this to store arbitrary addresses since I don’t think the developers intended this view to be used for anything other than the bill to and ship to addresses.

P.S. you don’t have to set the BAccountID, it is simply mirroring the same internal value.


Thank you for your reply. I was able to create a simple sales order using the SOOrderEntry  graph with following code.

SOORderGraph.Billing_Address.Insert(billToSOAddress);
SOORderGraph.Shipping_Address.Insert(shipToSOAddress);
SOORderGraph.Caches<SOOrder>().Insert(SalesOrder);
SOORderGraph.Actions.PressSave();

 

Problem now is that it is always inserting the default shipping and billing addresses from customer. I want to have the address that I supply it in 

SOORderGraph.Billing_Address.Insert(billToSOAddress);

 

Please guide me, thanks.


@hnasir you don’t have to insert the billing address yourself. It is set automatically when you set the Customer ID based on the customer configuration.

What are you trying to accomplish exactly? I’m missing the big picture here...


I am just trying to override the billing address. I dont want to take the default billing address configured for the customer. 


Typing this from memory, but here’s how the logic should look like:

//TODO: Insert order, set CustomerID and other required fields before overriding address
graph.Billing_Address.Current.OverrideAddress = true;
graph.Billing_Address.Update(graph.Billing_Address.Current);
graph.Billing_Address.AddressLine1 = “Line 1”;
//TODO: set other properties in the address
graph.Billing_Address.Update(graph.Billing_Address.Current);
graph.Actions.PressSave();

 

 

 


Thank you for quick response . I will try it now.


Just some feedback, I could create SOAddress records using your code but the Sales Order was still referencing the old shipping and bill to address Ids. I had to update it manually using the following code.

 

currentOrder.BillAddressID = updatedBillingAdd.AddressID;
currentOrder.ShipAddressID = updatedShippingAdd.AddressID;

Is this the right approach?


Reply