I am attempting to issue a check to a vendor through the Intuit.IPP API (Interop.QBFC12) using the following code:
IMsgSetRequest messageSet = session.CreateMsgSetRequest("US", 7, 0);
ICheckAdd cheque = messageSet.AppendCheckAddRq();
cheque.AccountRef.ListID.SetValue(vendor.ListID.GetValue());
cheque.AccountRef.FullName.SetValue("myAccountName");
cheque.TxnDate.SetValue(DateTime.Today);
IMsgSetResponse responseSet = session.DoRequests(messageSet);
IResponse response = responseSet.ResponseList.GetAt(0);
responseType = (ENResponseType)response.Type.GetValue();
if (responseType == ENResponseType.rtCheckAddRq)
returnMessage = response.StatusMessage;
The resulting response.StatusMessage = "Object 80000005-1374598713 specified in the request cannot be found. " The object ID specified is the ListID I pulled for the vendor.
I'm coding pretty much blind as I'm not finding the IPP documentation very helpful or up to date for version 12.
What am I missing?
This:
cheque.AccountRef.ListID.SetValue(vendor.ListID.GetValue());
cheque.AccountRef.FullName.SetValue("myAccountName");
Is what's causing you the problem.
The AccountRef node is for specifying an Account, not a Vendor. An Account is something from the QuickBooks Chart of Accounts (an "Account" object). A Vendor is something from the vendor list (a "Vendor" object) and they are not interchangable objects.
Since you're already setting an AccountRef/FullName:
cheque.AccountRef.FullName.SetValue("myAccountName");
You don't need to set a AccountRef/ListID.
You should always either set a ListID or a FullName - there's no reason to set both (it's just alternative ways to reference the same object - both are "foreign keys" of sorts to QuickBooks).
What you probably meant to do is set the AccountRef like you meant to, but also set the PayeeEntityRef. For example:
cheque.PayeeEntityRef.ListID.SetValue(vendor.ListID.GetValue());
Also, regarding this:
I'm coding pretty much blind as I'm not finding the IPP documentation
very helpful or up to date for version 12.
IPP is an entirely different API from what you're using. The IPP docs aren't going to be useful to you, because it's not anywhere close to the API you're using.
What you should be using for reference is the QuickBooks OSR:
https://member.developer.intuit.com/qbSDK-current/Common/newOSR/index.html
And also the QuickBooks SDK downloadable .EXE, which has a bunch of relevant PDF documentation.
Related
I have a C# tool that I wrote to sync orders from a DB to QB, and every step has been a giant pain.
I'm trying to create the line items that we have in our DB in QB so I can attach the invoice items correctly, but our system allows sales staff to enter custom words, so I can't just add all the possible line items to QB through the QB interface.
I have this piece of code here
IMsgSetRequest AddItemRequestMsgSet = sessionManager.CreateMsgSetRequest("US", 8, 0);
AddItemRequestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
IItemServiceAdd itemAddRq = AddItemRequestMsgSet.AppendItemServiceAddRq();
itemAddRq.Name.SetValue(Item);
// itemAddRq.ORSalesPurchase.
IMsgSetResponse ItemAddResponseMsgSet = sessionManager.DoRequests(AddItemRequestMsgSet);
IResponse ItemAddResponse = ItemAddResponseMsgSet.ResponseList.GetAt(0);
But this is throwing an error that:
ORSalesPurchase: required field is missing
I haven't the slightest idea of what that means, and for the life of me I can't find anything about ORSalesPurchase or IItemServiceAdd elsewhere on the Internet, including their docs.
I can tell with Visual Studio's autocomplete that itemAddRq.ORSalesPurchase has a bunch of options, but I haven't been able to infer from that what QB is asking for.
What are the required fields for adding a service item to QB?
And if someone can point me to where this is in their docs that would be extra wonderful:)
Stack trace:
System.Runtime.InteropServices.COMException (0x80040307):
ItemServiceAdd ORSalesPurchase: required field is missing End of
ItemServiceAdd
at QBFC12Lib.IQBSessionManager.DoRequests(IMsgSetRequest request)
at SterlingQBExport.Form1.CheckNewInvoices(Object source,
ElapsedEventArgs e) in C:\Users\brian\Documents\Visual Studio
2015\Projects\SterlingQBExport\SterlingQBExport\Form1.cs:line 537
Based on an article I found while searching for ORSalesPurchase ...
C# .NET Application with QuickBooks Desktop Edition
This article is an introduction on how to integrate a .NET application with QuickBooks Desktop Edition using the QuickBooks Foundation Classes (QBFC) Library and C#.
... and the error message, it would seem that you are missing certain fields expected to be part of the requests ORSalesPurchase
Using a sample from the article I would suspect it looks something like the following
//Create the message set request object to hold our request
IMsgSetRequest addItemRequestMsgSet = sessionManager.CreateMsgSetRequest("US", 8, 0);
addItemRequestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
IItemServiceAdd itemServiceAddRq = addItemRequestMsgSet.AppendItemServiceAddRq();
itemServiceAddRq.Name.SetValue(Item.Name);
itemServiceAddRq.ORSalesPurchase.SalesOrPurchase.Desc.SetValue(Item.Description);
itemServiceAddRq.ORSalesPurchase.SalesOrPurchase.ORPrice.Price.SetValue(Item.Price);
itemServiceAddRq.ORSalesPurchase.SalesOrPurchase.AccountRef.FullName.SetValue("Some custom service description here");
//...
Now there was more which seems to infer that the fields set differ based on the items already having a quickbooks id where it was set using
itemServiceModRq.ListID.SetValue(Item.QuickBooksID);
Now, I am not entirely certain what the required fields are at this point, but this should be a good starting point to check if providing the fields above helps.
I am not a c# guy. Needless to say that I don't have experience on this topic.
I bought a software and I installed it on my computer. Now I thought of using some of it's functions on my software(that I make to plan in c#). So I messaged the person who sold me the software and he send me a two page pdf file explaining what to do.
It states:
This software features a COM interface.
And it goes saying it's API contains a function "stackAPI".
and the parameters used are apiname type string, apipass type string.
Return values type long. 0 for sucess and 1 for error.
That's all it states, I tired searching google, it could not help me at all. So how do I start?
when I write the following code on c# it gives me error.
string[] apiname;
string[] apipass;
stackAPI(apiname, apipass);
I know if I was using dll I would import it as
[DllImport("example.dll"]
But no dll is provided.
Do I need to add the path to the folder where the software is installed to call the API ?
To get started:
using example.dll;
Then in your main class:
example.CustomService api = new example.CustomService();
var response = api.Dostuff();
Console.WriteLine(response);
If anyone wants to know how I did it. After a week of searching I was able to find the solution today. I wanted to call the function stackAPI(apiname, apipass);.
stackAPI(apiname, apipass) was the member of stack.callapi
So I wrote:
dynamic lifestohack = Activator.CreateInstance(Type.GetTypeFromProgID("stack.callapi"));
than just you can call the function like this.
int rv;
string[] apiname;
string[] apipass;
rv=lifestoahck.stackAPI(apiname, apipass);
Hope it may help someone.
The host property of a familyInstance returns a RevitLinkInstance when the host is placed within a linked document. I there a way to get the real Element (or its ID) instead of the RevitLinkInstance?
I was hoping that the stableREpresentation could give me more information, but unfortunatly, it doesn't.
Reference hostFaceReference = instance.HostFace;
string stableRepresentation = hostFaceReference.ConvertToStableRepresentation(instance.Document);
this would give "ac669fa6-4686-4f47-b1d0-5d7de6a40550-000a6a4a:0:RVTLINK:234297:0:218" where 234297 is the ID of the referenced element, in this case, still the RevitLinkInstance.
Have you tried this?
ElementId hostFaceReferenceId = instance.HostFace.LinkedElementId;
You could then try getting the Element via the linkedDocument.
Document LinkedDoc = RevitLinkInstance01.GetLinkDocument();
Element linkedEl = LinkedDoc.GetElement(hostFaceReferenceId);
Depending on the host you may have to go about it a few ways. For example, with a wall you could try the following (this is using LINQ by the way):
// filter the Host's document's items
FilteredElementCollector linkdocfec = new FilteredElementCollector(elem_inst.Host.Document);
// establish the host's type
linkdocfec.OfClass(elem_inst.Host.GetType());
// find the host in the list by comparing the UNIQUEIDS
Element hostwallinlinkedfile = (from posshost in linkdocfec
where posshost.UniqueId.ToString().Equals(elem_inst.Host.UniqueId.ToString())
select posshost).First();
// check the different faces of the host (wall in this case) and select the exterior one
Reference linkrefface = HostObjectUtils.GetSideFaces((hostwallinlinkedfile as HostObject), ShellLayerType.Exterior).First<Reference>();
// create a reference to the linked face in the the CURRENT document (not the linked document)
Reference linkref = linkrefface.CreateLinkReference(rvtlink_other);
Ultimately, according to the docs anyway, you're supposed to utilize the CreateReferenceInLink method to get your item.
I am using C# to connect with QuickBooks desktop 2013. I need to record payments against a bill, but cannot figure out why it is not working. My current code keeps throwing an error of 3120 saying it can't find the bill, even though the bill object is open in my control. I've used the IDN Unified OSR provided by intuit for the BillPaymentCheckAdd object structure, but the "data" they pass in is just random and not helpful for what I actually need to pass in as values. So I could use some help. Here is my code for the pay bill method:
IBillPaymentCheckAdd paymentAdd = requestMsgSet.AppendBillPaymentCheckAddRq();
paymentAdd.PayeeEntityRef.ListID.SetValue(vendorId);
paymentAdd.TxnDate.SetValue(DateTime.Now);
paymentAdd.BankAccountRef.ListID.SetValue(bankAccount.ListID.GetValue());
paymentAdd.ORCheckPrint.IsToBePrinted.SetValue(true);
paymentAdd.Memo.SetValue(bankAccount.Name.GetValue());
IAppliedToTxnAdd appliedToTxnAdd = paymentAdd.AppliedToTxnAddList.Append();
appliedToTxnAdd.TxnID.SetValue(bill.TxnID.GetValue());
appliedToTxnAdd.PaymentAmount.SetValue((double)amount);
ISetCredit setCredit = appliedToTxnAdd.SetCreditList.Append();
setCredit.CreditTxnID.SetValue(bill.TxnID.GetValue());
setCredit.AppliedAmount.SetValue((double)amount);
paymentAdd.IncludeRetElementList.Add(bankAccount.Name.GetValue());
IMsgSetResponse responseMsgSet = sessionManager.DoRequests(requestMsgSet);
IResponse response = responseMsgSet.ResponseList.GetAt(0);
IBillPaymentCheckRet paymentRet = (IBillPaymentCheckRet)response.Detail;
I think the error that you are getting is referring to the setCredit section. The credits are used to apply a previous vendor credit to a bill. You are passing in the Bill TxnID as the credit, but it's a bill transaction, not a credit transaction so QuickBooks is saying it can't find the credit transaction as it doesn't really exist.
If you remove the 4 line section for the ISetCredit, your payment should go through correctly.
I started with the solution here http://social.technet.microsoft.com/wiki/contents/articles/20547.biztalk-server-dynamic-schema-resolver-real-scenario.aspx
which matches my scenario perfectly except for the send port, but that isn't necessary. I need the receive port to choose the file and apply a schema to disassemble. From their the orchestration does the mapping, some of it custom, etc.
I've done everything in the tutorial but I keep getting the following error.
"There was a failure executing the receive pipeline... The body part is NULL"
The things I don't get from the tutorial but don't believe they should be an issue are:
I created a new solution and project to make the custompipeline component (reference figure 19) and thus the dll file. Meaning it is on it's own namespace. However, it looks like from the tutorial they created the project within the main biztalk solution (ie the one with the pipeline and the orchestration) and thus the namespace has "TechNetWiki.SchemaResolver." in it. Should I make the custompipeline component have the namespace of my main solution? I'm assuming this shouldn't matter because I should be able to use this component in other solutions as it is meant to be generic to the business rules that are associated with the biztalk application.
The other piece I don't have is Figure 15 under the "THEN Action" they have it equal the destination schema they would like to disassemble to but then they put #Src1 at the end of "http://TechNetWiki.SchemaResolver.Schemas.SRC1_FF#Src1". What is the #Src1 for?
In the sample you've linked to, the probe method of the pipeline component is pushing the first 4 characters from the filename into a typed message that is then passed into the rules engine. Its those 4 characters that match the "SRC1" in the example.
string srcFileName = pInMsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties This link is external to TechNet Wiki. It will open in a new window. ").ToString();
srcFileName = Path.GetFileName(srcFileName);
//Substring the first four digits to take source code to use to call BRE API
string customerCode = srcFileName.Substring(0, 4);
//create an instance of the XML object
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(string.Format(#"<ns0:Root xmlns:ns0='http://TechNetWiki.SchemaResolver.Schemas.SchemaResolverBRE This link is external to TechNet Wiki. It will open in a new window. '>
<SrcCode>{0}</SrcCode>
<MessageType></MessageType>
</ns0:Root>", customerCode));
//retreive source code in case in our cache dictionary
if (cachedSources.ContainsKey(customerCode))
{
messageType = cachedSources[customerCode];
}
else
{
TypedXmlDocument typedXmlDocument = new TypedXmlDocument("TechNetWiki.SchemaResolver.Schemas.SchemaResolverBRE", xmlDoc);
Microsoft.RuleEngine.Policy policy = new Microsoft.RuleEngine.Policy("SchemaResolverPolicy");
policy.Execute(typedXmlDocument);
So the matching rule is based on the 1st 4 characters of the filename. If one isn't matched, the probe returns a false - i.e. unrecognised.
The final part is that the message type is pushed into the returned message - this is made up of the namespace and the root schema node with a # separator - so your #src1 is the root node.
You need to implement IProbeMessage near to class
I forgot to add IProbeMessage in the code of article. It is updated now.
but it is there in sample source code
Src1 is the the root node name of schema. I mentioned that in article that message type is TargetNamespace#Root
I recommend to download the sample code
I hope this will help you