A Django site.
January 18, 2010
» Facility Data updates

It's been a while since I last updated on the progress of the Facility Data Module. So without farther adieu here we go:

  • The relation between the FacilityDataFormSchema and FacilityDataFormSection is now Many to Many meaning that sections can now be re-used between several form schemas (or reports).
  • It now runs without errors on OpenMRS 1.5.x
The first item was a big problem that was a sore spot for this project since it wasn't too intuitive, ideally a user should be able to re-use a section. The second item was a freebie since the errors were likely all due to the incorrect modeling.

What's next on my list is the following:
  1. Allow for sections to be re-ordered within the schema (this is currently not possible and is a show-stopper.
  2. Fix up the calendar management pages -- those are horribly ugly, but this is after all a first pass, so that is to be expected right?
  3. Currently, it does not validate inputs for Numeric data types -- It need to.
  4. There still needs to be the ability to analyze the data that exists in the system to submit to funding sources; those pages need to be implemented but that is phase two of the project.
  5. There are likely other sore spots that exist that I do not see at this point and time that will be fixed at a later date.
That is all for now.

August 31, 2009
» GSoC 2008: Progress report

I have made a lot of progress on my Google Summer of Code Project.

First, I've completed the code for the generation of the directory structure for the forms. This is done using the form id, which is the name with all illegal characters removed. The only valid characters left are alpha-numeric and periods. Let me tell you, the regular expression to replace all of those characters was hell to write. But, thanks to the help of Jason Davis, I was able to make it much more readable and easier digest. You've gotta see it to get an idea of how bad it was, so here goes:


/**
* Removes all illegal characters, then removes all spaces and makes it all lower-case.
*
* @param str the form name
* @return a viable form id.
*/
public static String formNameToFormId(String str) {
return str.replaceAll("[\\$\\(\\)%`~!@#&;:\\^=\\+\\?
\"\\*\\\\////\\\\{\\}'\\]\\[\\|\\s+]", "").toLowerCase();

}

That is pretty much hell on earth to read, and it was hell on earth to type. Here's the *MUCH* simpler version:


/**
* Removes all illegal characters, then removes all spaces and makes it all lower-case.
*
* @param str the form name
* @return a viable form id.
*/
public static String formNameToFormId(String str) {
return str.replaceAll("[^a-zA-Z0-9.]", "").toLowerCase();

}

Note, you can clearly see that i'm negating that entire sequence. It does the SAME thing, but is MUCH more readable. That reads: "replace everything that isn't a letter from A to Z *OR* a to z(lower case letters) *OR* from 0 through 9 *OR* a period. Whereas the above just excluded the invalid characters explicitly but was a MONSTER of a regular expression.

Secondly, metadata persistence is written in, I'm using xstream. It's a great tool for XML serialization.

That's it. Oh, by the way, these are the things I earmarked TWO WEEKS FOR! Now, I push domain class model processing up, will work on that tomorrow.

August 28, 2009
» GSoC 2008: Week 1

Okay, week 1 is nearing an end.I accomplished alot of things.

First, I completed the meta-data storage code. I wrote some tests, which revealed some bugs that needed fixing, and they were. I am happy to say, that the metadata storage works!

Writing the test was difficult due to the fact I store the forms in the system using a static List in my container class. I wound up updating to JUnit 4 to get at the @BeforeClass annotation so that the only one set of forms gets loaded into the container class. This helped me greatly. Additionally, the @AfterClass annotation was handy for cleaning up from the tests.

Secondly, Writing the code for interrogating the model was a piece of cake, thanks to groovy. All code for interrogating the model has 50 lines! That includes a model class I wrote to hold the field types and field names. I'll show you, but before I do, I should note that return statements are optional, and the final statement will be returned.


package org.openmrs.module.groovyforms.util

import java.lang.reflect.Field
import org.openmrs.module.groovyforms.metadata.model.GroovyFormsDomainModel

/*
* Utility class containing methods for class interrogation.
*/
class GroovyFormsClassUtil {
/**
* Interrogates the class for all declared fields and
* stores the type and name in a container class
* @param the {@link Class#getCanonicalName() canonical name of the class}
* @see Class#getCanonicalName()
* @return a reference to a container class containing the type
*/
static def getModel(fields) {
def domainModel = new GroovyFormsDomainModel()
def names = domainModel.fieldNames.&add;
def types = domainModel.fieldTypes.&add;
def f = fields.each {Field field ->
names field.name
types field.type.canonicalName
}
domainModel
}
}

With groovy, it's so easy and concise (as you can see). Let's explain what's going on. First, I pass in the Field array I get from Field.getDeclaredFields(). Now, groovy adds methods onto the standard JDK classes, one of those methods is a method named each() which takes a closure. Now, back to the point, I pass a Field into the closure. That closure is executed for each element (in this case, a Field). Then I add the name, and the type to a List stored in a container class, now that container class is also written in groovy!


package org.openmrs.module.groovyforms.metadata.model

/*
* Ths class holds information about the properties of the model.
*/
class GroovyFormsDomainModel {

/**
* The field names
*/
def fieldNames = []

/**
* The field types
*/
def fieldTypes = []

}

Now, the fields are Lists, not arrays. Anyways, I've gotten off on a tangent here, so let me get back on track.

What I accomplished:


Week 1:

Code to generate the directory structure, serialization of metadata back/forth between XML and POJOs (Plain Old Java Objects), Wrote tests to ensure everything works in that regard. Additionally, I wrote the code to interrogate the domain model which I will generate the forms from.

Next Week

Write up the templates for the view/controller and write code to do the generation of the view/controller. Write some tests to ensure everything generates correctly.

Unrelated to that, my stored-value card from google came today. It feels nice to be $500 richer! This is going to be the best summer, I'm already having fun doing this. It's amazing seeing the whole project evolve into something amazing.

August 26, 2009
» Google Summer of Code 2009 wrap-up

Google Summer of Code 2009 officially ended on August 17, 2009 at 19:00 UTC (12:00 PDT). I had an amazing time this summer. While stressful at times, it was well worth it.

I would like to thank the following people for my success this summer:

My mentor Mike Seaton for helping me throughout various misunderstandings surrounding the project's requirements. I probably made him work more than he had to. I attribute the success this summer to that one factor. This man is quite brilliant and knows his stuff.

My backup mentor Darius Jazayeri, for stepping in and helping at times and providing guidance when necessary. He is truly a brilliant man.

Ben Wolfe for answering any questions I had. He didn't have to help, but he did. I am very grateful.

Paul Biondich and Burke Mamlin for believing in me and giving me a second chance this summer. Did I mention these guys are doctors? Burke, an internist and Paul a pediatrician. Sorry for clumping you guys together.

Finally, without Leslie Hawthorn, Cat Allman, and Ellen Ko from Google, this program would not exist. They deserve a huge thank you. These three women are amazing. Thank you so much!!

August 21, 2009
» Facility Data Module User Guide

The Facility Data Module is a tool to collect non-patient centric aggregate data for reporting to external funding sources.

To download it use the svn version: do a checkout:
svn co http://svn.openmrs.org/openmrs-modules/facilitydata

To create a report:

1) Create all your questions

2) Create all of your form sections

3) Finally add all the sections to your form schema

I'll go into detail how to do each:

Creating/Managing questions

From the admin screen: select "Manage Questions."



Now, once on the question management page you will see a list of existing questions. under the "Action" column is a garbage can image -- this deletes the question from the database and is irreversible.

Once created, a question's data type cannot be changed, this is due to the design.


Now, once on the "Add New Question" page there are several properties. Most of which are required.

1) name - required
2) question data type - required
3) aggregation method - required
4) description - optional

Question Data Types are as follows:

NumericQuestion - a question that has a numeric answer (optionally has a min/max value and whether or not to allow decimal values.) -- these fields show only if you select "NumericQuestion."

BooleanCodedQuestion - a coded question with 3 answers: "t","f","not applicable"

StockQuestion - a question that tracks stock of vaccines, supplies, etc. This is a special coded question with the following answers: "not_stocked_out", "stocked_out", "expired", "not_applicable" and the comments field used to track the numbers of days stocked out and reason.

To add more questions after you save a question -- click "Add New Question" link above the form box.

Creating/Managing Form Sections

Once you have created all of your questions -- it's time to organize them into sections. You can easily navigate to the "Manage Form Sections" page from the "Add New Question" page.


Now, once on the section management page -- you'll see a list of all sections saved and the associated schema. Next, you'll want to click "Add New Form Section"


Now, once on the add questions page: you'll enter:

1) Display Name - required
2) Description - optional
3) Form Schema -optional (can be deferred)

Mentioned seperately is questions you're adding to the section (these are referred to as form questions by the system).
1) Name
2) Question Number
3) Question
4) Description
To add a question: click "Add New Question" to remove a question, click the "Remove" button next to the button (see image after the one below).


The section below is a section that was defined programmatically in a mock schema that was designed and used throughout the summer.
As you can see, there is a "Remove" button next to each Form Question in the section.

Creating/Managing Form Schemas


From the Section creation page: click "Manage Form Schemas"

After clicking that link you will see the page below. It allows you to delete a schema, and information relevant to te form schema.


Now, after clicking the "Add New Form Schema" link you will see the page below. The following information is needed:
1) Display Name - required
2) Data Entry Frequency -required
3) Validity Period -optional
4) Description - optional
5) Sections specified in this form schema (and the ordering) -- just drag them into the left-side of the pane.

Now, for the shortcomings:

  • Ordering of questions cannot be changed once saved

  • Sections cannot be associated with two schemas at once.





Viewing and Entering Data


Will be completed at a later date.

August 4, 2009
» Project Update

So we're in the home stretch folks! 13 days to go until the "Pencils Down" date! Hope everybody's project is going well. Here's how mine is going:

  • Reports can be saved and reloaded (with all relevant data filled out (fields etc -- reports can be viewed in editable or "view only" mode).
  • Each component of the report (Questions, Form Questions(allows a question to exist on multiple reports), and Sections can be created in isolation
  • A page to view the status of a report (complete, partially complete or incomplete) is done for reports that are to be entered daily in a monthly calendar view; monthly still needs to be completed.
Overall, i feel the project is progressing well -- I expect to finish either on time, or early. (Let's hope for early!)

Cheers!

February 8, 2009
» Groovy Forms Module is NOT dead

Hey folks!

I'm still alive and not dead. The Groovy Forms Module is not a dead project, and WILL be finished. I plan on getting work started back up on it soonish. School is back in session for me. I'm sorry for the long delay.

That is all.

September 10, 2008
» GSoC wrap-up

The program officially ended on August 18th. I'm awaiting the arrival of my t-shirt!!

Now, I didn't quite have time to finish my project prior to that date since my uncle suddenly passed away on August 10th.

The project itself is about 80 percent completed. All that is left is to get the rendering working and finish up the management page to edit the form metadata as it appears in the system.

My time is now limited since school started up again for me, so as much time as I can I'm going to devote to finishing up this project.

I'd like to thank the following:


  • Burke Mamlin for helping me and answering all the questions I had and guiding me when I was lost.


  • Ben Wolfe for putting up with me and helping me when Burke was MIA.


  • OpenMRS and its wonderful worldwide network of developers for making this project into what it has become.


  • Paul Biondich for encouraging me (along with Burke) to apply for summer of code.


  • Last, but certainly not least, Leslie Hawthorn for managing this program and every problem that popped up. She must have super human powers or something.




The list can only be so long, I feel like I'm accepting an academy award here. It was a great experience, and I will definately continue to maintain my project in whatever free time I can find.

August 10, 2008
» GSoC 2008: We're in the home stretch

Well folks, I can't believe it's almost over. What a journey. I never imagined I'd be able to do this. I have an (almost) working project. I have a few more things that need to be done.

Let's highlight what IS done:

  1. GroovyForm and its related metadata is stored
  2. Model class is interrogated for its properties and those are stored in a container class.
  3. From the data collected in the container class, I generate markup checking for a predefined set of data types.
  4. The view and its related controller is generated -- sneaking in some groovy magic of course!
  5. GroovyForms are successfully saved into the system, along with their respective, model, view and controller.
  6. Forms are persisted when the module is shutdown and reloaded when it is restarted
What's left:
  1. Editing metadata related to the forms currently in the system
  2. Writing the servlet which handles submissions
  3. Create some sample forms
  4. Documentation
I did plan to add a lot of other stuff such as the ability to create custom form widgets, however there were a few problems which caused me to redirect my focus. These will come in after I finish with Summer of Code.

May 27, 2008
» Ready...Set...Code: Google Summer of Code has started!

Today was the official start of Google Summer of Code 2008 Hopefully everybody is finding it a pleasant experience. I have yet to start coding as today was a US Holiday (Memorial Day).

The project plan for the summer has been finalized. I decided to set two-week blocks, rather than do a weekly thing. I chose this, as it's extremely flexible and can scale items either back or forward.

The project plan can be found here. A Google Doc which my mentor and I used to plan the project can be found here. Finally, See my general plan written as a previous blog post.

Best of luck to all the summer of code students!