Accessing customer contact details with QBSDK - qbxml

According to the QBSDK v12 and v13 OSR documentation, the SDK returns contact details (phone, email, etc.) for each of the contacts associated with a customer. In other words, tags within the contact. But when I query a customer that has multiple contacts associated with it, all I get is:
<Contact>Thing One</Contact> (for the contact flagged as primary)
<AltContact>Thing Two</AltContact> (for the contact flagged as secondary)
<AdditionalContactRef>
<ContactName>Main Phone</ContactName> (the main phone # for CUSTOMER, not contact)
<ContactValue>425-555-1212</ContactValue>
</AdditionalContactRef>
etc...
The phone # and email set up for each contact is not included in the response XML. This is with QB Premier 2014 and QBSDK v13. Am I missing something, or does QB not yet return the contact details, which are supposedly supported by the SDK?

If I understand the question correctly, you are looking for the ContactsRet element.
You should be able to request ContactsRet element using the IncludeRetElement element.
From the OSR:
<CustomerRet>
<ContactsRet> <!-- optional, may repeat -->
<ListID> IDTYPE </ListID> <!-- required -->
<TimeCreated> DATETIMETYPE </TimeCreated> <!-- required -->
<TimeModified> DATETIMETYPE </TimeModified> <!-- required -->
<EditSequence> STRTYPE </EditSequence> <!-- required -->
<Contact> STRTYPE </Contact> <!-- optional -->
<Salutation> STRTYPE </Salutation> <!-- optional -->
<FirstName> STRTYPE </FirstName> <!-- required -->
<MiddleName> STRTYPE </MiddleName> <!-- optional -->
<LastName> STRTYPE </LastName> <!-- optional -->
<JobTitle> STRTYPE </JobTitle> <!-- optional -->
<AdditionalContactRef> <!-- must occur 0 - 5 times -->
<ContactName>STRTYPE</ContactName> <!-- required -->
<ContactValue>STRTYPE</ContactValue> <!-- required -->
</AdditionalContactRef>
</ContactsRet>
</CustomerRet>

Related

How to ignore cHash when working with urls that contain an id?

The website that I'm working on uses cooluri to format the urls. In the case of news, the "parameters" column of the "link_cache" table stores the parameters like this:
a:3:{s:5:"cHash";s:32:"eea2db734d63b661abaab43d86fd3bb5";s:2:"id";s:5:"15503";s:18:"tx_ttnews[tt_news]";s:6:"142085";}
, or in a more readable way:
{
"cHash":"eea2db734d63b661abaab43d86fd3bb5",
"id":"15503",
"tx_ttnews[tt_news]":"142085"
}
My problem is, that there are lots of pages where these urls are inserted in content elements like in the example below, and ofcourse the cHash parameters don't match.
website.com/news/some-title/431731b3f9d391a54c9ee48467ca4bb4.html
Now because of this I get the following error message on the news single view page:
no news_id given
Is there a clean way to solve this issue? I was told that changing the links in the backend is not an option. Also, the links are very old, and the option "oldlinksvalidfor" is set to 365.
Your configuration goes in the block. Here is a configuration for Ext:CoolUri. This working fine for me (with tt_news) this will remove cHash from the URL. You have an additional configuration for managing caching and all.
<predefinedparts>
<part>
<parameter>no_cache</parameter>
</part>
<part>
<parameter>cHash</parameter>
</part>
<!-- common patterns -->
<!-- parts defined this way will be removed from URL -->
<part>
<parameter>paramC</parameter>
</part>
<!-- this will prefix a value with "prefix-". Cannot be localized.
-->
<part key="prefix-(.*)" regexp="1">
<parameter>paramD</parameter>
</part>
<part key="page-(.*)" regexp="1">
<parameter>array[k5]</parameter>
</part>
<!-- if parameter matches value, key will be added to URL
with mutliple values, use valuemaps
-->
<part key="thisWillAppearInUrl">
<parameter>paramE</parameter>
<value>ifParamEMatcesThisValue</value>
</part>
</predefinedparts>
Hope this will helpful to you.
Greetings!

No DataSerializerFactory registered for namespace: 0 - hazelcast 3.5.5

I'm using hazelcast- 3.5.5 and hazelcast-client - 3.5.5. As per the documentation it was fixed in 3.4.x, but I'm still facing this issue in 3.5.5.
Here is my code:
val hazelcastConfig = new XmlConfigBuilder(System.getProperty("hazelcast.config")).build()
hazelcastConfig.setClassLoader(getClass.getClassLoader)
config.getSerializationConfig().addSerializerConfig(sc);
val instance :HazelcastInstance= Hazelcast.newHazelcastInstance(hazelcastConfig)
Below is my hazelcast.xml
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.5.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!--<group>-->
<!--<name>devtestme</name>-->
<!--<password>dev-passtestme</password>-->
<!--</group>-->
<!--<management-center enabled="false">http://localhost:3210/mancenter</management-center>-->
<network>
<port auto-increment="false" port-count="100">5701</port>
<outbound-ports>
<!--
Allowed port range when connecting to other nodes.
0 or * means use system provided port.
-->
<ports>0</ports>
</outbound-ports>
<join>
<multicast enabled="false">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="true">
<member-list>
<member>myip1</member>
<member>myip2</member>
</member-list>
<!--<interface>myip1 </interface>-->
</tcp-ip>
<aws enabled="false">
<access-key>my-access-key</access-key>
<secret-key>my-secret-key</secret-key>
<!--optional, default is us-east-1 -->
<region>us-west-1</region>
<!--optional, default is ec2.amazonaws.com. If set, region shouldn't be set as it will override this property -->
<host-header>ec2.amazonaws.com</host-header>
<!-- optional, only instances belonging to this group will be discovered, default will try all running instances -->
<security-group-name>hazelcast-sg</security-group-name>
<tag-key>type</tag-key>
<tag-value>hz-nodes</tag-value>
</aws>
</join>
<!--<interfaces enabled="false">-->
<!--<interface>10.10.1.*</interface>-->
<!--</interfaces>-->
</network>
<map name="user_id">
<map-store enabled="true">
<!--
Name of the class implementing MapLoader and/or MapStore.
The class should implement at least of these interfaces and
contain no-argument constructor. Note that the inner classes are not supported.
-->
<class-name>myclass</class-name>
<!--
Number of seconds to delay to call the MapStore.store(key, value).
If the value is zero then it is write-through so MapStore.store(key, value)
will be called as soon as the entry is updated.
Otherwise it is write-behind so updates will be stored after write-delay-seconds
value by calling Hazelcast.storeAll(map). Default value is 0.
-->
<write-delay-seconds>0</write-delay-seconds>
<!--
Used to create batch chunks when writing map store.
In default mode all entries will be tried to persist in one go.
To create batch chunks, minimum meaningful value for write-batch-size
is 2. For values smaller than 2, it works as in default mode.
-->
<write-batch-size>1</write-batch-size>
</map-store>
</map>
<map name="boolean_cache">
</map>
<map name="inapp_templates">
<map-store enabled="true">
<!--
Name of the class implementing MapLoader and/or MapStore.
The class should implement at least of these interfaces and
contain no-argument constructor. Note that the inner classes are not supported.
-->
<class-name>myclass</class-name>
<!--
Number of seconds to delay to call the MapStore.store(key, value).
If the value is zero then it is write-through so MapStore.store(key, value)
will be called as soon as the entry is updated.
Otherwise it is write-behind so updates will be stored after write-delay-seconds
value by calling Hazelcast.storeAll(map). Default value is 0.
-->
<write-delay-seconds>0</write-delay-seconds>
<!--
Used to create batch chunks when writing map store.
In default mode all entries will be tried to persist in one go.
To create batch chunks, minimum meaningful value for write-batch-size
is 2. For values smaller than 2, it works as in default mode.
-->
<write-batch-size>1</write-batch-size>
<!--
Remove after the idle time
-->
</map-store>
</map>
Below is the error I'm getting when I'm trying to connect to two machines
WARNING: [ip]:7060 [devtestme] [3.5.5] hz._hzInstance_1_devtestme.IO.thread-in-1 Closing socket to endpoint null, Cause:com.hazelcast.nio.serialization.HazelcastSerializationException: No DataSerializerFactory registered for namespace: 0
#4000000056e9be5d36796194 com.hazelcast.nio.serialization.HazelcastSerializationException: No DataSerializerFactory registered for namespace: 0
#4000000056e9be5d36796194 at com.hazelcast.nio.serialization.DataSerializer.read(DataSerializer.java:98)
#4000000056e9be5d3679d6c4 at com.hazelcast.nio.serialization.DataSerializer.read(DataSerializer.java:39)
#4000000056e9be5d3679daac at com.hazelcast.nio.serialization.StreamSerializerAdapter.read(StreamSerializerAdapter.java:41)
Can someone please help me to fix this, I have spent a lot of time on this. Thanks in advance.
I have a mergeStrategy for jackson libraries in my build.sbt. Removing it has resolved the issue.

XPath: what's the different between "begin with one slash" and "begin with 2 slashes"?

I read some Xpath code, some begin with "/xxxx", some begin with "//xxxx". What're their differences? Do they have different behavior just in "Select" or different also in other behaviors?
I didn't find corresponding explanations on this site, any hints?
Thanks.
Beginning an XPath with one slash will retrieve the root of the document, so that /xxxx will match only the <xxxx> element that is the root of the XML.
Example:
<?xml version="1.0"?>
<xxxx> <!-- this one will match -->
<level>
<xxxx /> <!-- this one won't -->
</level>
</xxxx>
Whereas //xxxx will match all <xxxx> elements anywhere in the document.
Example:
<?xml version="1.0"?>
<xxxx> <!-- this one will match -->
<level>
<xxxx /> <!-- this one will match as well -->
<sublevel>
<xxxx /> <!-- and also this one -->
</sublevel>
</level>
</xxxx>

Usage of Float and Integer in DynaActionForm properties and retrieving them with struts-html.tld tags

I have a DynaActionForm element in my struts-config.xml like:
<form-bean name="myActionForm" type="org.apache.struts.action.DynaActionForm">
<!-- Control Params -->
<form-property name="action" type="java.lang.String" />
<form-property name="list" type="java.lang.String" initial="master_document_list.data"/>
<!-- Business params -->
<form-property name="code" type="java.lang.String"/>
<form-property name="name" type="java.lang.String"/>
<form-property name="description" type="java.lang.String"/>
<form-property name="sequenceNumber" type="java.lang.Float"/>
</form-bean>
And the jsp page where I am trying to use it:
<!-- struts-html.tld imported with prefix html -->
<html:form>
<table>
<tr>
<td>Sequence No.</td>
<td><html:text property="sequenceNumber" maxlength="15" style="width:75%"/></td>
</tr>
<table>
</html:form>
but when i do this I am getting a JspException saying "No getter method for property sequenceNumber. I am quite sure that the name is correct. Is it the type that is not getting accepted then? I thought the DynaActionForm allowed types are all major java types including the Thread-Safe Wrappers (e.g. Float, Integer, Short, Long, etc.).
N.B. I am using struts1
After digging apache documentation, i figured out that
<html:text> tag has got the following settings:
name= Name of the form bean
property= Name of the property associated to the form-property tag for the bean above
Althernatively, using ${myBean.map.myProp} will point me to the right direction.
Thanks all,

How do you categorize Items into Service, Product, Discount, Discount %, Other Charge, Other Charge %

In Quickbooks desktop each item is categorized as a product, service, or discount etc. In Quickbooks online I need to download the list of items and have noticed they are no longer categorized.
The code I'm using is like this:
list = commonService.FindAll(new Intuit.Ipp.Data.Qbo.Item(), currentPage, itemListPageSize) as IEnumerable;
When I download this list from Quickbooks Online, I need to know if it's a product/service/discount so that I can import it into our system like we did for QB Desktop.
How do I go about getting the category of this item?
QuickBooks Online does not have multiple different item types. It's a different product which works significantly differently from QuickBooks for Windows/Mac.
The Intuit Anywhere/IDS APIs do not support any concept of inventory for QuickBooks Online right now, though QuickBooks Online itself does support the concept.
QuickBooks Online does not have a concept of a "discount" item at all (discounts are just another rate/amount field on an invoice, vs. a line item like in QuickBooks for Windows).
Here's a screenshot of the QuickBooks Online interface:
Notice that I have added a 10% discount, but that 10% discount does not show up as a normal line item. It's just a field on the invoice that accepts a discount amount. Because it's not a line item, it doesn't require an item type at all.
This is reflected in the APIs as well.
Here's a qbXML example (notice: it's not a line item, and doesn't refer to an item type at all):
<DiscountLineAdd> <!-- optional -->
<!-- BEGIN OR -->
<Amount >AMTTYPE</Amount> <!-- optional -->
<!-- OR -->
<RatePercent >PERCENTTYPE</RatePercent> <!-- optional -->
<!-- END OR -->
<IsTaxable >BOOLTYPE</IsTaxable> <!-- optional -->
<AccountRef> <!-- optional -->
<ListID >IDTYPE</ListID> <!-- optional -->
<FullName >STRTYPE</FullName> <!-- optional -->
</AccountRef>
</DiscountLineAdd>
Here's an IPP example (again, notice isn't not a line item, and doesn't refer to an item type at all):
<Header>
<DocNumber>00010</DocNumber>
<TxnDate>2010-08-07-07:00</TxnDate>
<Msg>No Black Ink Pens</Msg>
<Note>Blue Ink pens only</Note>
<CustomerId>5</CustomerId>
<SalesTaxCodeId idDomain="QBO">1</SalesTaxCodeId>
<SalesTaxCodeName>IS_TAXABLE</SalesTaxCodeName>
<SubTotalAmt>200.00</SubTotalAmt>
<TaxAmt>100.00</TaxAmt>
<TotalAmt>298.75</TotalAmt>
<DueDate>2010-08-16-07:00</DueDate>
<BillEmail>john_doe#digitalinsight.com</BillEmail>
<DiscountAmt>-1.25</DiscountAmt>
</Header>