Forum OpenACS Q&A: Re: Project-manager integration with logger
Project manager is getting pretty close to being able to be released as a beta. The last major bit of coding that needs to be done is to integrate it with logger in some fashion. (I also need to fix notifications, but that's pretty minor). And then there is a lot of cleanup to do. Anyway...
This is a pretty long post, but it describes integration between logger and project-manager. I'm directing this mostly to Lars and Peter, but comments from others are welcome!
-------------
Logger currently contains these tables:
---------------------------------
* logger_projects
These are the projects that one logs time to. Logger was designed to eventually replace this table with projects from project-manager.
However, some people (like Malte in this thread) have suggested making that optional, so that logger could also exist on its own.
Q: do we integrate them more closely, or allow logger to exist independently. Right now, I'm leaning towards letting it exist independently.
* logger_project_pkg_map
Allows the projects to be mounted in multiple package instances.
* logger_variables
Hours, or time, the units tracked within the projects.
* logger_project_var_map
Keeps track of which variables are tracked within each project.
* logger_projections
Projections are used to compare the variables logged versus what is expected. They have a variable, a start date, end date, and expected value. This isn't exposed much in the UI, however, so I'm not sure exactly how it is supposed to be used. Lars suggested using this for projected task completion times. I'm not sure exactly how that will work, for reasons that I detail later.
* logger_entries
This is where the time or expenses are actually stored. A timestamp, variable, and value.
Project Manager contains these tables that relate to logger:
--------------------------------------------------
* pm_projects
Inherits from cr_revisions, and keeps track of all the information of a project. Tables which inherit from PM projects should inherit from cr_items.
* pm_tasks
Inherits from cr_items. A task associated with a project.
* pm_tasks_revisions
Inherits from cr_revisions. The revisions of a task. Currently stores estimated completion time for tasks, and the total amount of time worked on each task.
Potential paths to integrating logger and project-manager
-------------------------------------------------
1) Replace the logger_projects table with the pm_projects table.
I would need to write (and test) upgrade scripts, and this would have the disadvantage of requiring both logger and project_manager to be installed. It would also get a little complicated, because both packages would depend on each other, creating a circular reference in the APM. Lars and I talked about this a little bit, and this could be resolved by splitting project-manager into two packages or possibly some other mechanism. This sounds like a lot of work, and I'm leaning away from this, partially because I only have 3-4 days to spend on this effort, and if it exceeds this, I may just have to postpone the integration.
2) Write wrappers around logger_projects in project-manager, that create both the logger_project and pm_project, and relate the two. logger_project has a foreign key reference on acs_objects. This would look something like this:
In pm::project::new
create pm_project
call logger::project::new with the same object_id
Issues: since logger::project::new creates a new object, I'm not sure they could share the same object_id. If they could, that would simplify things, because it would eliminate the need for a mapping table. If that doesn't work, then we could either create a mapping table, or change the logger::project::new function to only create a new object_id if it does not already exist. It may already do that -- I'll need to check that out.
This would mean that you can create extra (logger) projects in logger, and they wouldn't show up in project-manager. However, any project you create in project manager would show up in logger. Perhaps one solution to this would be for logger to check if project manager were installed, and if so, to redirect or suggest to the administrator that they need to do it in project-manager instead.
3) Each project-manager Project has a reference to a logger Project (add logger_project as a foreign key to the pm_projects table)
In pm::project::new
set logger_project [logger::project::new ...]
create pm_project with logger_project = $logger_project
This is a pretty easy solution, actually. It also allows us to directly get the logger_entries by using the value stories in pm_projects. That would be fairly convenient.
Note that in all we've talked about so far, logger_entries are logged against a project instead of a task. Currently, the project-manager data model logs all time against tasks.
What is the alternative? Well, we could say project-manager Tasks are equivalent to logger Projects.
Log to Projects versus Log to Tasks
------------------------------
What are the advantages of each?
There are several populations we're trying to serve, both of whom have slightly different interests.
Workers typically would want to log their time against Tasks, because that makes more sense. You do work on Something. However, if you don't have a Task to log against, I guess you would log against the Project.
Managers more typically would want to see the time logged per project.
The best solution would be to do both: log time against tasks, but allow managers to be able to see it broken down by project. Or to log time against the task if you're working with the task, but allow it the other way as well.
Alternate solutions include allowing logger projects to map to either one, or to only link logger projects to project-manager projects, but to have a mapping table that keeps track of what task logged a particular logger entry. That last solution may actually be the best of both world.
It seems to me that the best solution is this: create a pm_task_logger_proj_map table. This table is only used when the user logs time against a task. In that case, the time is logged, and an entry is added into pm_task_logger_proj_map, which contains the entry, and the task.
Then, when you are looking at a task, the UI pulls up all the hours logged against that task, and allows you to log more hours against that task.
However, when you're looking at a project, it pulls up all hours logged against that project.
Lars or Peter: any thoughts on this?
Storage of logged entries
---------------------
The basic idea is to move the data storage to logger, and out of project-manager. PM's pm_task_revisions table will keep the same entries, but they will just be denormalized from logger -- logger will have the definitive values. That will allow queries to be fast, but will slow down inserts. Probably not a big deal.
Projections
---------
The logger_projection table is not very exposed in the logger UI, so I'm not totally confident of how I'm going to use it.
I'm not totally sure how I would use logger_projections at this point, because they also map against projects, at least in how the tables are names. Theoretically, they could be used against Tasks, because they are a foreign key reference on acs_objects. Lars actually suggested this. Lars, is that what you would like me to do?
If we did use the logger_projections, then I'm not quite sure what to do with the start_time and end_time. I guess I would update those any time I got the chance. But with project-manager tasks, there no strict start_time and end_time. Well, there can be an end_time if a deadline is specified, but otherwise, these things are computed based on other tasks and based on today's date. So they would be changing all the time. I'm not sure if it would be important to keep the projections up to date as well.
Conclusion
---------
Well, hopefully soon we'll have this mess behind us. Right now, I'm thinking the best solution is as follows:
1) Add a column to pm_projects, which tracks which logger_project it is associated with.
2) Change the related project-manager functions to handle ::new and ::delete appropriately.
3) Add in the UI to the appropriate pages in project-manager to add in new logger_entries, and show logger_entries, and edit logger_entries. (Lars has spelled out in detail to me how to do this portion of it -- thank you, Lars).
When a logger entry is made from a task, associate it with that task via a new table pm_task_logger_proj_map.
4) Every pm_tasks will also keep track of an associated logger_projection, which tracks the estimated amount of work for that projection. I'm not sure if this allows for any sort of meaningful use of the logger_projection table, however. How would you compare the hours logged versus the hours projected, except manually?
I'd appreciate any comments on this. Sorry it's so exhaustive -- integration sucks and is often complicated. But at least it's not as bad as migrations are :)