Sign in to participate
Be Kind, Be Helpful
Ask a question, answer a question, and get to know the fine people in the Harvest community.
How to report on uninvoiced time for each project?
What’s the easiest way to report on uninvoiced time? Basically, my use case is that I want to know which projects have uninvoiced time for some billing period.
Looking at the API docs, it seems that the best supported route would be to get a list of all projects, and then for each one, get all uninvoiced time entries for the period:
GET /projects/#{project_id}/entries?from=YYYYMMDD&to=YYYYMMDD&only_unbilled=yes
However, another possible way is to try to do a detailed report on time entries for any project, like:
GET /reports/details/32/2011/59/2011/any/any/any/ign/yes/ign/any?only_unbilled=yes
Then, I can just slice and dice the time entries by project to see which projects need to be billed.
However, this latter approach doesn’t seem to work. I don’t get any XML data back.
Thanks for your help brainstorming.
-Jim
OK, I’ve discovered a potential flaw with trying to get unbilled time entries from active projects: a project can be archived before all its time is billed. So, it seems that the best approach is to find all uninvoiced time for some period. However, I don’t see a way to do that for all projects and all people. So, is the most effective mechanism to iterate each user using the /people/#{user_id}/entries? API call?
Short version: it depends on your account profile, but looping through user reports is probably best.
If you have a ton more projects than people in your account, I think running through the user reporting API with the only_unbilled flag and a time period will be the best route. For most accounts, I think this would be the case. Especially given looping through projects would include inactive projects and I suspect many of those would not have any time entries for the time period you are targeting.
If you have a fair number of archived users, you could also limit the number of users you report on by excluding those with an updated_at timestamp prior to your target time period. Most likely that updated_at timestamp on a user record will be the time the user was archived.
Hi Barry: Thanks for the tips. I’ll play around with this and let you know what I come up with. As a suggestion, it would be nice if we could get at the reporting via the API and slice and dice the data any way we choose, without having to specify a project or user (which requires iterative over projects or users, respectively).
The reason the reporting API is atomic (by project/user) is to protect the health of the Harvest system for everyone using it. If a large account hit a large timeframe for all reporting data a few times it could slow down Harvest performance for everyone. And since large accounts are frequent API users, that potentiality is very real. There are certainly other ways to protect the health of the system, such as more draconian API throttle limits. I suspect the average API customer would not appreciate that technique.
My suggestion if you are going to do a ton of reporting is to sync data to your own local store and report from there. The recent addition of an updated_since filter on the reporting API should help reduce the size of the responses and ease syncing on your side. Looping through a list of projects in itself is a pretty trivial programming problem. You should be able to limit archived projects with the methods described in my previous comment.
Hi Barry,
A few points, in response to your “to protect the health of Harvest” argument:
- The harvest API already has throttling built into it.
- I can still get at the same data by jumping through hoops, but it requires pulling even more data (all projects or users) from Harvest, in addition to the actual time entries, thus making the load on Harvest even worse
- It’s possible to implement a “paging” system that only returns data in clumps (pages of 50 records at a time, for example) — this already happens, I think, when getting time entries via the time tracking API (as opposed to the reporting API)
- If the reporting API provided more rich server-side queries (like letting me report on the total uninvoiced time for a specific project, or get a list of projects with uninvoiced time), then it would obviate the need for me to pull all the data and do a client-side crunch on it.
- If harvest’s web UI had the features I needed, then I wouldn’t have to write my own code to do this.
:)
Thanks,
-Jim
Thanks for the feedback, Jim. We definitely have thought about each and every one of these things. We try our best to address what we can with the time we have.
I’m having the same need as Jim – I just want to extract all billable hours in a period (over months) but across projects. I cant use “active” projects, as the projects could have been archived in the meantime.
I’m doing financial widgets in geckoboard, that’s why I want some “live-data”.
Local sync could be an option, but I really just want the data I can get from the Reporting on the site, e.g. /reports/detailed/244/2011/244/2011/any/any/any/ign/yes/ign/any?group=dates
(just a bigger period).
Again, I don’t get the argument that this should be heavier on the API, I’ll be hammering the API otherwise with looping through each project/user instead…