Question Status

Verified
Luca Hostettler asked a question on 23 Mar 2015 5:25 AM

Hi There,


I'm struggling some hours now of adding a "invoice"detail record to my invoice though code.

I know that this is possible, as I already found some good material to work with:


--> Create, QuoteDetail entity methods, CreateRequest(),...

But I'm just not able to add my DetailPos Item.


Here is my code of how I'm trying it:

First loading the invoice:

using (OrganizationServiceProxy organizationProxy = CRMLoginHelper.GetProxy(_organisationUrl, _userName, _password, _domain))
                        {
                            String strInvoiceNumber = "20150024";
                            String strProductId = "c2807776-f7ad-e411-a7b9-d89d67640040";
                            ISECRMBaselibrary.ISEInvoice xInvoice= new ISECRMBaselibrary.ISEInvoice(organizationProxy);
                            xInvoice.LoadBy_Iseid(strInvoiceNumber);
                            xInvoice.AddPos(strProductId, "Test Titel", "Testbeschrieb");
                        }
                    }

As you can see I'm getting the Invoice at: LoadBy_Iseid() this gives me the correct invoice. Than in the AddPos() Method:

        public void AddPos(String ProductId, String Title, String Description)
        {

            Entity detailPos = new Entity(InvoiceDetailEntityName);
            Entity Product = GetProduct(ProductId);

            Guid UomId = Utilities.GetEntityRefernceId(Product, "defaultuomid");

            Utilities.SetEntityRefernceId(detailPos, "invoiceid", InvoiceDetailEntityName, m_invoice.Id);
            Utilities.SetEntityRefernceId(detailPos, "productid", ProductEntityName, Product.Id);
            Utilities.SetEntityRefernceId(detailPos, "uomid", ProductEntityName, UomId);
            
            Guid newPosId = m_organizationService.Create(detailPos);

        }

First I'm creating the detailPos Entity for loading the attributes later. Than I'm getting my Product which I want to add to the InvoiceDetail Position. Than I fill the attibutes of the product and invoice to my invoiceDetail Entity. At least I try to .Create() my detailPos entity?

I just wanted to ask if that is the correct way of doing this or is there any better / easier way?

Reply
Bruno Lucas responded on 23 Mar 2015 5:36 AM

have you tried to add a try catch around it to see more details (some error message)

try{

}

catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)

{

// You can handle an exception here or pass it back to the calling method.

      throw;

}

msdn.microsoft.com/.../gg334754.aspx

looking to this line you are using late bind:

Entity detailPos = new Entity(InvoiceDetailEntityName);

is InvoiceDetailEntityName a string variable with the correct name of the entity?

overall the code looks correct, but with late bind you need to make sure you enter the correct parameter name for each field

Bruno Lucas, Senior CRM Consultant

DynamicDay CRM Blog 

Please mark my post as "Verified" If it helped to solve your problem 

Reply
Guido Preite responded on 23 Mar 2015 5:36 AM

there are several ways to do the same thing, so it's hard to say: it's the correct way or you can use an easier way from 2 methods you show here.

Just a thing: this line

 Utilities.SetEntityRefernceId(detailPos, "uomid", ProductEntityName, UomId);

I think that the parameter should not be ProductEntityName, but a variable that contains "uom" the logical name of UoM (Unit) Entity

EDIT: also this line

Utilities.SetEntityRefernceId(detailPos, "invoiceid", InvoiceDetailEntityName, m_invoice.Id);

the logicalname should be the one for invoice, not for the detail (because you are setting an entityreference to an invoice lookup)

Reply
Luca Hostettler responded on 23 Mar 2015 6:03 AM

Hi Thanks for looking into my issue, "InvoiceDetailEntityName" just holds the String = "invoicedetail" so it will create a new Entity "invoicedetail" I'm just checking my parameters now if they are correct, errorhandling is already built-in.

Error is: {"Invoice With Id = 8992521b-1ca3-e411-9d5a-d89d67640040 Does Not Exist"}

But the funny thing is that I'm never!! assigning this value,

xInvoice.LoadBy_Iseid(strInvoiceNumber); Here I can click on xInvoice --> go to invoiceid and don't have that "899..." number!

Hi

As you mentioned I changed my line there. But just keep in mind that SetEntityRefernceId is called with: (Entity x, string AttributeName, string ReferenceEntityName, Guid xvalue). So I have "uomid" as AttributeName and than the EntityReference which is the Product I want to add so Product right?

Reply
Verified Answer
Guido Preite responded on 23 Mar 2015 6:07 AM

No, the EntityReference should contain the logical name of the entity the lookup is pointing, not the source entity.

I assume that the code of your SetEntityRefernceId is something like

x[AttributeName] = new EntityReference(ReferenceEntityName, xvalue);

so you need to pass the logicalname of the entity related to the Guid you are passing. you pass a uom Guid the reference name should me uom, you pass an invoice Guid, the reference name should be invoice

Reply
Luca Hostettler responded on 23 Mar 2015 6:52 AM

Hi

Sorry for the question but as you can see this is my code for SetEntityRefernceId.

Thanks alot for your explanation. I was able to add a "empty" product to the invoice! Big step ahead ^^

Now I'm trying to set the EntityReference to a product, that I could load.. Will return to this thread if I got any problems.
Thanks!

Reply
RasmusH responded on 23 Mar 2015 7:52 AM

What Guido Preite is saying, is that you are supplying the wrong arguments to your SetEntityRefernceId method:

//Wrong, invoiceid likely doesnt reference entity of type InvoiceDetailEntityName
Utilities.SetEntityRefernceId(detailPos, "invoiceid", InvoiceDetailEntityName, m_invoice.Id);

//Correct, productid likely references entity of type ProductEntityName
Utilities.SetEntityRefernceId(detailPos, "productid", ProductEntityName, Product.Id);

//Wrong, uomid likely doesnt reference entity of type ProductEntityName
Utilities.SetEntityRefernceId(detailPos, "uomid", ProductEntityName, UomId);

Notice the use of "likely" above, since we really dont know the values of InvoiceDetailEntityName and ProductEntityName - they aren't part of your example code. To simplify, please replace these variables by their intended string values, eg:

Utilities.SetEntityRefernceId(detailPos, "productid", "WriteEntityNameOfProductHere", Product.Id);

A further note: SetEntityRefernceId looks shaky: If attributes already contains key, you make the assumption that EntityName matches. Probably safer to do:

x.Attributes[AttributName] = new EntityReference(ReferenceEntityName, xvalue);

Reply
Verified Answer
Guido Preite responded on 23 Mar 2015 6:07 AM

No, the EntityReference should contain the logical name of the entity the lookup is pointing, not the source entity.

I assume that the code of your SetEntityRefernceId is something like

x[AttributeName] = new EntityReference(ReferenceEntityName, xvalue);

so you need to pass the logicalname of the entity related to the Guid you are passing. you pass a uom Guid the reference name should me uom, you pass an invoice Guid, the reference name should be invoice

Reply