Community Server as a Business App – Job Slips

In our last episode we finished the modules that gather purchased and truck inventory charges in our Community Server-based Jobs Management Application, and so it was time to start doing something useful with all of that data.  A Job Slips module was the first application, giving Project Managers the ability to generate a printout of the day’s time and material charges on the job site at the end of the day, with the day’s charges approved by client signature.  This was previously a task performed through faxing hand-completed forms to the office, with office personnel hand-generating the job slip and then faxing it back to the PM.  With the day’s labor and charge entries now automated, the natural next step was to automate the day’s job slip creation process as well.

The pages below (with some original data purposely obscured) are custom Chameleon controls with a new JobSlipPost object and re-purposed Labor, Purchased Material and Truck Material Chameleon controls we’ve seen in previous modules.  As I’ve touched on before, Chameleon data is context-aware and so a Labor list control needs to know its context, or in our case, what day’s charges to generate.  The most simple approach to this is recognizing that the ObjectData.cs control will always know its context through its ObjectControlUtility GetCurrentObjectPost(Control) method, with the context logic residing in ObjectList.cs DataSource(). 

Another interesting aspect of this application from a CS technical perspective was adding paging to the Prior Slip Description list on the first screen’s right-hand column shown below.  One thing to note here is that the key to binding a custom list control to the CS Pager is that it is performed in the custom page’s code-behind and not in the control.  Rather than using a BindData() with, say, a WeblogPostList control, the custom page’s BindData() method would be something like

protected void BindJobSlipData(Repeater repeater, IPager pager, List<JobSlipPost> jobSlipPosts,
    JobSlipPostThreadQuery query)

with the query start and end values passed from the Pager’s PageIndex querystring value, if it exists.

As I mentioned in a Bit Post the other night, the final page that is printed as shown below and handed to the customer for signature is based on a blank master page.  It was an interesting experience to create a Community Server page based on a completely blank page.

Apart from what is shown below, each day’s labor and material charge entry forms are locked when a Job Slip is printed.  This insures that the job charge data that will be used for generating invoices in a future module will be accurate and match that day’s Job Slip data.  I’ll cover adding record locking in the Chameleon Forms in a separate post.   Thus, the “Unlock charge records for Revision” function in the first screen is a pre-requisite for generating a revision that includes modifying labor or material charges.


Article written by

A long time developer, I was an early adopter of Linux in the mid-90's for a few years until I entered corporate environments and worked with Microsoft technologies like ASP, then .NET. In 2008 I released Sueetie, an Online Community Platform built in .NET. In late 2012 I returned to my Linux roots and locked in on Java development. Much of my work is available on GitHub.