All,
What I am attempting to do is take an invoice that exists in GP with a certain number and return that invoice. I believe the goal is to return any items to inventory and credit the customer (and possibly affect the status of the original invoice?).
I admit that I don't really understand how I should be setting this. For instance: Do I use the number of the invoice for the return? For one or both of the properties? (DOCID / SOPNUMBE) If I use another number (I've tried both ways with the same error), how do I link this return to the original invoice (or do I even need to?)
That being said, I am using this code: (ec and ecs are namespace shortcuts that I added in my using statements section)
var salesInvoice = getSalesInvoice(invoiceNumber);
var eConnect = new ec.eConnectMethods();
var ecType = new ecs.eConnectType();
var salesReturn = new ecs.taSopHdrIvcInsert();
salesReturn.SOPTYPE = 4; // RETURN
salesReturn.DOCID = salesInvoice.Key.Id;
salesReturn.SOPNUMBE = salesInvoice.Key.Id;
salesReturn.CUSTNMBR = salesInvoice.CustomerKey.Id;
salesReturn.BACHNUMB = string.Format("RTRN{0}", DateTime.Today.ToString("yyyyMMdd"));
salesReturn.DOCAMNT = salesInvoice.TotalAmount.Value;
salesReturn.DOCDATE = DateTime.Now.ToString("yyyy-MM-dd");
var lines = new List<ecs.taSopLineIvcInsert_ItemsTaSopLineIvcInsert>();
foreach (var invoiceLine in salesInvoice.Lines)
{
var lineItem = new ecs.taSopLineIvcInsert_ItemsTaSopLineIvcInsert();
lineItem.ITEMNMBR = invoiceLine.ItemKey.Id;
lineItem.NONINVEN = (invoiceLine.IsNonInventory.HasValue && invoiceLine.IsNonInventory.Value)
? (Int16) 1
: (Int16) 0;
lineItem.QTYRTRND = invoiceLine.Quantity.Value;
lineItem.QUANTITY = invoiceLine.Quantity.Value;
lineItem.DOCID = salesReturn.DOCID;
lineItem.SOPNUMBE = salesReturn.SOPNUMBE;
lineItem.CUSTNMBR = salesReturn.CUSTNMBR;
lineItem.SOPTYPE = 4; // RETURN
lineItem.DOCDATE = salesReturn.DOCDATE;
lines.Add(lineItem);
}
ecType.SOPTransactionType = new ecs.SOPTransactionType[1];
ecType.SOPTransactionType[0] = new ecs.SOPTransactionType();
ecType.SOPTransactionType[0].taSopHdrIvcInsert = new ecs.taSopHdrIvcInsert();
ecType.SOPTransactionType[0].taSopHdrIvcInsert = salesReturn;
ecType.SOPTransactionType[0].taSopLineIvcInsert_Items = new ecs.taSopLineIvcInsert_ItemsTaSopLineIvcInsert[lines.Count];
ecType.SOPTransactionType[0].taSopLineIvcInsert_Items = lines.ToArray();
var stringWriter = new StringWriter();
var serializer = new XmlSerializer(typeof(ecs.eConnectType));
serializer.Serialize(stringWriter, ecType);
var returnValue = eConnect.eConnect_EntryPoint(connectionString, ec.EnumTypes.ConnectionStringType.SqlClient, stringWriter.ToString(), ec.EnumTypes.SchemaValidationType.None, string.Empty);
When I run it, I get this error:
Microsoft.Dynamics.GP.eConnect.eConnectException: Sql procedure error codes returned:
Error Number = 3441 Stored Procedure taSopLineIvcInsert Error Description = DOCID does not exist for document type
Node Identifier Parameters: taSopLineIvcInsert
SOPNUMBE = 2862083
SOPTYPE = 4
Related Error Code Parameters for Node : taSopLineIvcInsert
DOCID = 2862083
SOPTYPE = 4
The serialized version of my object looks like this:
<eConnect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOPTransactionType>
<eConnectProcessInfo xsi:nil="true" />
<taRequesterTrxDisabler_Items xsi:nil="true" />
<taUpdateCreateItemRcd xsi:nil="true" />
<taUpdateCreateCustomerRcd xsi:nil="true" />
<taCreateCustomerAddress_Items xsi:nil="true" />
<taSopSerial_Items xsi:nil="true" />
<taSopLotAuto_Items xsi:nil="true" />
<taSopLineIvcInsert_Items>
<taSopLineIvcInsert>
<SOPTYPE>4</SOPTYPE>
<SOPNUMBE>2862083</SOPNUMBE>
<CUSTNMBR>VALIDCUST</CUSTNMBR>
<DOCDATE>2013-03-14</DOCDATE>
<ITEMNMBR>A4244</ITEMNMBR>
<QUANTITY>8.00000</QUANTITY>
<QTYRTRND>8.00000</QTYRTRND>
<NONINVEN>1</NONINVEN>
<DOCID>2862083</DOCID>
</taSopLineIvcInsert>
<taSopLineIvcInsert>
<SOPTYPE>4</SOPTYPE>
<SOPNUMBE>2862083</SOPNUMBE>
<CUSTNMBR>VALIDCUST</CUSTNMBR>
<DOCDATE>2013-03-14</DOCDATE>
<ITEMNMBR>A4402</ITEMNMBR>
<QUANTITY>34.00000</QUANTITY>
<QTYRTRND>34.00000</QTYRTRND>
<NONINVEN>1</NONINVEN>
<DOCID>2862083</DOCID>
</taSopLineIvcInsert>
<taSopLineIvcInsert>
<SOPTYPE>4</SOPTYPE>
<SOPNUMBE>2862083</SOPNUMBE>
<CUSTNMBR>VALIDCUST</CUSTNMBR>
<DOCDATE>2013-03-14</DOCDATE>
<ITEMNMBR>A4520</ITEMNMBR>
<QUANTITY>120.00000</QUANTITY>
<QTYRTRND>120.00000</QTYRTRND>
<NONINVEN>1</NONINVEN>
<DOCID>2862083</DOCID>
</taSopLineIvcInsert>
<taSopLineIvcInsert>
<SOPTYPE>4</SOPTYPE>
<SOPNUMBE>2862083</SOPNUMBE>
<CUSTNMBR>VALIDCUST</CUSTNMBR>
<DOCDATE>2013-03-14</DOCDATE>
<ITEMNMBR>A4927</ITEMNMBR>
<QUANTITY>3.00000</QUANTITY>
<QTYRTRND>3.00000</QTYRTRND>
<NONINVEN>1</NONINVEN>
<DOCID>2862083</DOCID>
</taSopLineIvcInsert>
<taSopLineIvcInsert>
<SOPTYPE>4</SOPTYPE>
<SOPNUMBE>2862083</SOPNUMBE>
<CUSTNMBR>VALIDCUST</CUSTNMBR>
<DOCDATE>2013-03-14</DOCDATE>
<ITEMNMBR>A4352</ITEMNMBR>
<QUANTITY>36.00000</QUANTITY>
<QTYRTRND>36.00000</QTYRTRND>
<NONINVEN>1</NONINVEN>
<DOCID>2862083</DOCID>
</taSopLineIvcInsert>
</taSopLineIvcInsert_Items>
<taSopLineIvcInsertComponent_Items xsi:nil="true" />
<taSopTrackingNum_Items xsi:nil="true" />
<taSopCommissions_Items xsi:nil="true" />
<taSopLineIvcTaxInsert_Items xsi:nil="true" />
<taCreateSopPaymentInsertRecord_Items xsi:nil="true" />
<taSopUserDefined xsi:nil="true" />
<taSopDistribution_Items xsi:nil="true" />
<taAnalyticsDistribution_Items xsi:nil="true" />
<taSopMultiBin_Items xsi:nil="true" />
<taSopHdrIvcInsert>
<SOPTYPE>4</SOPTYPE>
<DOCID>2862083</DOCID>
<SOPNUMBE>2862083</SOPNUMBE>
<DOCDATE>2013-03-14</DOCDATE>
<CUSTNMBR>VALIDCUST</CUSTNMBR>
<DOCAMNT>432.39000</DOCAMNT>
<BACHNUMB>RTRN20130314</BACHNUMB>
</taSopHdrIvcInsert>
<taSopToPopLink xsi:nil="true" />
<taSopUpdateCreateProcessHold xsi:nil="true" />
<taCreateSOPTrackingInfo xsi:nil="true" />
<taMdaUpdate_Items xsi:nil="true" />
</SOPTransactionType>
</eConnect>|
Most results that I've found when Googling this point to people not setting their SOP Type on all of the line items or not at all in header or line item. As you can see, I'm not doing either one. I can't find any good actual guidance for the best practice for how to do this at all and I've spent days going through the SDK Documentation.
I would appreciate any and all help not only into that error, but any correction you can offer to the *manner* that I'm going about this. Thank you very much in advance.
*This post is locked for comments