How do I filter Purchase Order query in QBXML to only return records that are not fully received? - quickbooks

When doing a PurchaseOrderQuery in QBXML I am trying to get Quickbooks to only return purchase orders that are not yet processed (i.e. "IsFullyReceived" == false). The response object contains the IsFullyReceived flag, but the query object doesn't seem to have a filter for it??
This means I have to get every single Purchase Order whether or not it's received, then do the filtering logic in my application - which slows down Web Connector transactions.
Any ideas?
Thanks!

You can't.
The response object contains the IsFullyReceived flag, but the query object doesn't seem to have a filter for it??
Correct, there is no filter for it.
You can see this in the docs:
https://developer-static.intuit.com/qbSDK-current/Common/newOSR/index.html
This means I have to get every single Purchase Order whether or not it's received, then do the filtering logic in my application - which slows down Web Connector transactions.
Yep, probably.
Any ideas?
Try querying for only Purchase Orders changed or modified (ModifiedDateRangeFilter) since the last time you synced.
Or, instead of pulling every single PO, keep track of a list of POs that you think may not have been received yet, and then only query for those specific POs based on RefNumber.
Or, watch the ItemReceipt and BillPayment objects, and use that to implement logic about which POs may have been recently filled, since BillPayment andItemReceipt` objects should get created as the PO is fulfilled/received.

Related

How to optimize performance of Results change listeners in Realm (Swift) with a deep hierarchy?

We're using Realm (Swift binding currently in version 3.12.0) from the earliest days in our project. In some early versions before 1.0 Realm provided change listeners for Results without actually giving changeSets.
We used this a lot in order to find out if a specific Results list changed.
Later the guys at Realm exchanged this API with changeSet providing methods. We had to switch and are now mistreating this API just in order to find out if anything in a specific List changed (inserts, deletions, modifications).
Together with RxSwift we wrote our own implementation of Results change listening which looks like this:
public var observable: Observable<Base> {
return Observable.create { observer in
let token = self.base.observe { changes in
if case .update = changes {
observer.onNext(self.base)
}
}
observer.onNext(self.base)
return Disposables.create(with: {
observer.onCompleted()
token.invalidate()
})
}
}
When we now want to have consecutive updates on a list we subscribe like so:
someRealm.objects(SomeObject.self).filter(<some filter>).rx.observable
.subscribe(<subscription code that gets called on every update>)
//dispose code missing
We wrote the extension on RealmCollection so that we can subscribe to List type as well.
The concept is equal to RxRealm's approach.
So now in our App we have a lot of filtered lists/results that we are subscribing to.
When data gets more and more we notice significant performance losses when it comes to seeing a change visually after writing something into the DB.
For example:
Let's say we have a Car Realm Object class with some properties and some 1-to-n and some 1-to-1 relationships. One of the properties is a Bool, namely isDriving.
Now we have a lot of cars stored in the DB and bunch of change listeners with different filters listing to changes of the cars collection (collection observers listening for changeSets in order to find out if the list was changed).
If I take one car of some list and set the property of isDriving from false to true (important: we do writes in the background) ideally the change listener fires fast and I have the nearly immediate correct response to my write on the main thread.
Added with edit on 2019-06-19:
Let's make the scenario still a little more real:
Let's change something down the hierarchy, let's say the tires manufacturer's name. Let's say a Car has a List<Tire>, a Tire has a Manufacturer and a Manufacturer has aname.
Now we're still listing toResultscollection changes with some more or less complex filters applied.
Then we're changing the name of aManufacturer` which is connected to one of the tires which are connected to one of the cars which is in that filtered list.
Can this still be fast?
Obviously when the length of results/lists where change listeners are attached to gets longer Realm's internal change listener takes longer to calculate the differences and fires later.
So after a write we see the changes - in worst case - much later.
In our case this is not acceptable. So we are thinking through different scenarios.
One scenario would be to not use .observe on lists/results anymore and switch to Realm.observe which fires every time anything did change in the realm, which is not ideal, but it is fast because the change calculation process is skipped.
My question is: What can I do to solve this whole dilemma and make our app fast again?
The crucial thing is the threading stuff. We're always writing in the background due to our design. So the writes itself should be very fast, but then that stuff needs to synchronize to the other threads where Realms are open.
In my understanding that happens after the change detection for all Results has run through, is that right?
So when I read on another thread, the data is only fresh after the thread sync, which happens after all notifications were sent out. But I am not sure currently if the sync happens before, that would be more awesome, did not test it by now.

Only read new events from Firebase Database

I was halfway done with implementing Core Data in my iOS app when I realized that Firebase has offline capabilities that would pretty much mimic what I was trying to accomplish the whole time.
In my database which is structured as such:
- Users
- user1
- user2
- Groups
- group1
- members
- user1
- events
- event1_By_Auto_Key
- event2_By_Auto_Key
I wanted to locally store all the events that have already been fetched by a user so that I wouldn't have to read all of them every single time I need to get a group's events. Now that I think I'm just going to stick with Firebase's offline capabilities instead of using Core Data, I have a question regarding how to efficiently read events from the database.
As seen from my database's structure the events are stored using the childByAutoId().setValue(data) method, meaning the keys are unknown when inserted. So my console for a given group might look like this:
My question is: how can I only read the new events from a group? The reason I was implementing Core Data was so that I could cache already fetched events, but I'm not sure how I can make sure that I don't re-read data.
There are a few strategies you could use. Since the ids generated are always lexically greater than any existing, you can use startAt() on your query with the newest record you already have. You just need to skip the record that matches the last ID you have. If you keep a timestamp in the events, you can use orderByChild() and the last timestamp and increment by one ms then you don't get any records you already have. It would be something like:
function getNewEvents(group, arrayOfExistingIds) {
let lastId = arrayOfExistingIds.sort().pop(),
ref = admin.database().ref('/Groups/' + group + '/events')
.orderByKey().startAt(lastId).on('value', function(snap){
if (snap.key === lastId) return;
console.log('New record: ' + snap.key);
})
}
Firebase provide you 10MB persistent memory to cache recently fetch records. In normal scenario 10MB is enough space.
You need to enable offline capabilities.

Getting all expenses from Quickbooks Desktop

I'm able to read all expenses from QuickBooks Desktop with C# code using QuickBooks SDK. Once I have the expenses I need to copy them to Salesforce and when new expenses arrive those need to move to Salesforce as well.
So I'm able to connect to the app and get a collection of expenses. Here's the code.
//Connect to QuickBooks and begin a session
sessionManager.OpenConnection("", "test");
connectionOpen = true;
sessionManager.BeginSession(#"C:\TEST.qbw", ENOpenMode.omDontCare);
sessionBegun = true;
ICreditCardChargeQuery creditQuery = requestMsgSet.AppendCreditCardChargeQueryRq();
creditQuery.IncludeLineItems.SetValue(true);
IMsgSetResponse msgSetRs = sessionManager.DoRequests(requestMsgSet);
IResponse response = msgSetRs.ResponseList.GetAt(0);
ICreditCardChargeRetList checkRetList = (ICreditCardChargeRetList)response.Detail;
I have two questions.
Do I have to read CreditCard and Check separately or is there a way to get all expenses from one place?
Is there a way to get only latest data? Say I get all the expenese up to today. Tomorrow two more get added. Is there a way to get only the two that were added? I can do this by date of the expense but I'm asking if there a system way of handling this. Maybe mark it as received and only read received ones or is there a way to say give me expenses in a date range as opposed to the way I'm doing it.
Do I have to read CreditCard and Check separately or is there a way to get all expenses from one place?
QuickBooks does support a TransactionQuery request type that you could use to get this data in a single request, but it only returns summary details -- it doesn't return details such as individual line items, etc.
Chances are, you'll probably have to reach them seperately if you want any sort of meaningful details.
You can refer to the OSR for reference:
https://developer-static.intuit.com/qbSDK-current/Common/newOSR/index.html
Is there a way to get only latest data?
You can use the ModifiedDateRangeFilter filters to do this. e.g.:
//Set field value for FromModifiedDate
CheckQueryRq.ORTxnQuery.TxnFilter.ORDateRangeFilter.ModifiedDateRangeFilter.FromModifiedDate.SetValue(DateTime.Parse("12/15/2007 12:15:12"),false);
//Set field value for ToModifiedDate
CheckQueryRq.ORTxnQuery.TxnFilter.ORDateRangeFilter.ModifiedDateRangeFilter.ToModifiedDate.SetValue(DateTime.Parse("12/15/2007 12:15:12"),false);
You can refer to the QuickBooks OSR for full details.

Cancelling NSJSONSerialization - Search as you type, requests overlapping

Similar to the iPhone Facebook app search function, I am implementing search as you type functionality into my application although I have a problem when decoding the data into JSON format.
Basically what happens is because some searches take longer than others, they return at different intervals and this causes some small visual issues when the data is presenting on the screen.
I have set an NSLOG after each decode using NSJSONSerialization for the keyword 'industry'
2013-04-09 23:38:18.941 Project Name [42836:1d03] http://fooWebAddress/json/?method=search&limit=10&q=indus
2013-04-09 23:38:19.776 Project Name [42836:3e07] http://fooWebAddress/json/?method=search&limit=10&q=indu
2013-04-09 23:38:20.352 Project Name [42836:8803] http://fooWebAddress/json/?method=search&limit=10&q=indust
2013-04-09 23:38:21.814 Project Name [42836:4e03] http://fooWebAddress/json/?method=search&limit=10&q=industr
2013-04-09 23:38:23.434 Project Name [42836:8803] http://fooWebAddress/json/?method=search&limit=10&q=ind
2013-04-09 23:38:24.070 Project Name [42836:7503] http://fooWebAddress/json/?method=search&limit=10&q=industry
As you can see it is all out of order.
Does anyone have any way of stopping NSJSONSerialization for the previous connection.
Or possibly any other way to go about this problem?
Steps up to NSJSONSerialization...
NSURLRequest (initwithURL)
NSOperationQueue
NSURLConnection (asynchronous)
NSJSONSerialization
Thanks in advance.
When the user starts typing more text, you could cancel your previous connections and ignore any further delegate callbacks you receive from them. Then make the new request for the current text.
You can do this by maintaining some sort of lastRequest or lastOperation reference. When the user starts typing, call [self.lastRequestOrOperation cancel] and ignore any further notifications from that request with a check like if (request != self.lastRequest) { return; } in whatever callbacks you have.
However this has the problem that if the user keeps typing for a while you are constantly cancelling requests and they may not see any results until they have stopped typing.
A better solution would be to add sequencing so that each request is associated with an increasing sequence ID. You then only parse the result and update the UI when the sequence of the response is higher than the last one you received. If you receive any out-of-band responses from earlier, you just ignore them.
This is a much more complex issue than just being able to cancel the NSJSONSerialization. My suggestion is to use NSFetchedResultsController to populate your table view that shows the search results. Use the search term as one of the predicate variable in the NSFetchRequest attached to NSFetchedResultsController. And then, when you parse the results using NSJSONSerialization, store the results with the search term associated with that request. As soon as the search term changed (which you can detect when the user types more characters), re-create the NSFetchedResultsController and reload your table view. In addition, you can also try to cancel the call to parse the previous results if you launched it using performSelector:withObject:afterDelay. Beware that this cannot be always relied upon as the call may have been initiated by the time you are trying to cancel.
Kinda basic, but you could always maintain an nsdictionary of sub-classed NSURLRequests (sub-classed to provide a tag).
Start request - add request to dicationary with tag = array.count - 1, with key matching tag
Connection returns - is the request the most recent request, if so, parse json
Parse JSON - is the request the most recent request, if so, show results, if not, only display if there are no previous results displayed
Request handling - remove key from dictionary
most recent request = does the dictionary contain an object with a higher key value
Currently what you are doing is, you type each character and calling web-service. Why to call web-service for each letter you type. If user is type continuously, then it will increase the load, so call the web-service only when user stops for a particular interval of time. and then pass that string to call web-service or what ever method you are calling.
[NSObject cancelPerformSelectorsWithTarget:self]; // This will cancel your all req which is going to make when user typing without stopping
[self performSelector:#selector(sendSearchRequest) withObject:searchText afterDelay:0.1f]; // This will pass the string to call a web-service method, on which user hold for some time.

Eventbrite VenueID is missing

I am making a call to;
https://www.eventbrite.com/xml/organizer_list_events?id=MYID
and getting a collection of event returned. I am integrating this data into an internal event system.
However, periodically I will get a venue without an ID. This means I cant add the venue into the system as I have no way of checking for duplicates before it is imported.
Show the VenueID always be returned? If not, under what circumstances would it not be returned?
The venue Id will not be returned if there is no venue, e.g. if the event is a webinar / online only event or the venue is not yet chosen

Resources