Tribute to Banon
Sunday, April 15th, 2007I worked almost all day today. I got a lot done. I get so much more done on the weekends. I wish that I had the option to skip a day of work during the week and work a Saturday or Sunday instead if I was incredibly busy. However, that would probably sound strange to my boss. If I’m that busy, shouldn’t I work now instead of later? Yeah, probably.
In any case, my day was filled with productivity. Work flows! Buckets! Advancers! Returners! All sorts of fun stuff! Returners are really just the name that I gave to an instantiation of a bucket, but I needed to make the Final Fantasy VI reference for the sake of Banon. My Returners actually make usability strides where I was having engineering troubles, so I am grateful to them.
So what did I really do? Efforts now move through most statuses of the system now. Each object in the system may take on a status by being placed into a bucket, which they need to have completed. This allows objects to have arbitrary steps assigned to them, and even steps interjected as needed. There are different screens to display what’s in a bucket. Each one has a unique set of actions that can be performed on that object. Objects either advance through each screen or they don’t.
If the advancement option is chosen on the screen, an advancer is run. However, depending on the job associated with that object, it may actually have a different work flow than another item on the list. Each work flow has its own implementation of the advancer and smaller advancing classes. When processing the action advancements trigger the advancer to call that work flow’s advancer on the fly, passing in the bucket that the object’s in, from which it can determine which object had which action complete. The current bucket is deactivated and any other qualifying buckets are activated.
There are still problems with this system, but all in all, it works out pretty well. In the future, advancers are going to include a rejection method so that if the action is not a confirming one, the logic for rolling things back can be placed by the logic to move them forward. That way, it can vary by work flow. I also want to include a custom action method when the choise isn’t as simple as advancement and rejection.
Right now, the rejection code lives in the processing screen, which I’m not all that fond of. Keeping the code to generate presentation separate from the code to do database stuff makes each easier to read. Spreading it out across files can make hunting down the right file kind of hard, but that’s what makes the same action able to trigger different events work in the first place.
Finally, what’s a Returner? It’s a simple query string passed from the job screen to highlight the job’s entry on the action screen and once the action has been processed, return the user back to the job screen instead of the action screen. This helps me from having to re-implement various forms and validations for the job screen. This also has the added usability feature that if the user is redirected to a batch entry screen, they can complete not only the highlighted entry, but a bunch more before returning. I think that’s neat.
I think that’s enough downloading what I did at work the last two days for tonight.