Mifos Collection Sheet Interface

About Mifos Collection Sheet functionality - Jan 6th 2010Contents::
Collection Sheets allow for the bulk processing of:

  1. Loan disbursements and repayments (plus any associated fees & charges);
  2. Savings account deposits and withdrawals;
  3. Customer account fees and charges;

for a hierarchy of customers.

This hierarchy usually begins with a Center (representing a village or area or nominal high level catchment) containing a number of Groups with each Group containing a number of Clients.
Collection Sheet "retrieves" and "saves" are currently required to be linked to the Center's meeting schedule.

Collection Sheet functionality currently requires client attendance records to be maintained.

Besides this Collection Sheet approach, Mifos also supports the Teller Model approach where client financial transactions are processed singly and not in bulk. Both approaches are built on top of a common support for processing loans, savings and fees (financial transactions). However, some differences in functionality have arisen between the two approaches e.g. you can disburse multiple loans to a client for a particular loan product via the collection sheet but not if using the Teller approach.

This Collection Sheet Interface and How to Use It

It is called CollectionSheetService in Package "org.mifos.application.servicefacade".

It consists of a method to retrieve a Collection Sheet and a method to save a Collection Sheet.

The implementation class is called "CollectionSheetServiceImpl". Without have a Spring initialised bean the current way of setting up the interface is:

To Declare:

private CollectionSheetService collectionSheetService;

To Initialise:

collectionSheetService = DependencyInjectedServiceLocator.locateCollectionSheetService();

The only current 'client' of the interface (outside of functional and performance tests) is the Mifos Collection Sheet web pages (transaction flow below).

Any new functionality (for example, an offline collection sheet capability) that needs to retrieve and/or save collection sheets should use this interface. If the current Mifos web pages were redeveloped, the redevelopment would use this interface (and its related DTO's) and not those^ of the currently used CollectionSheetServiceFacade interface (which handles the current complicated data structure for web page implementation)

This interface contains a lot of increased validation and there was a big focus on making the data interface as simple as possible. However, it's quite probable that any new 'client' for the interface will identify changes but they should be minor.

^ generateCollectionSheetEntryGridView, previewCollectionSheetEntry and saveCollectionSheet

Note: There is another interface called "CollectionSheetService" in Package "org.mifos.application.reports.business.service". This is currently unused and is likely to be removed or refactored soon.

Mifos Web Pages And Their Use of CollectionSheetService Interface

The SaveCollectionSheetDto Structure and Notes About it (Important Bit)

The SaveCollectionSheetDto Class defines the data structure required to save a collection sheet. A key point to note is how "individual savings accounts" are handled. Class SaveCollectionSheetCustomerDto contains a comment explaining this.

SaveCollectionSheetDto and all the "SaveCollectionSheetXXXDto" classes it uses have no 'setters'... just a constructor and "getters".

Additional Stuff in the Dto!

SaveCollectionSheetDto and all the "SaveCollectionSheetXXXDto" classes perform self-validation (more on validation under a separate heading).

SaveCollectionSheetDto also has a "Print" method which writes the collection sheet details to "System.out.println" (wasn't sure what level of Debug I could use or if it was worth it).

SaveCollectionSheetDto also calculates some summary values based on its contents. The Save Collection Sheet Hibernate Caching Class/method (see associated link) uses these.

The reason the self-validation, Print method and summary values are mentioned is that some might find it strange for them to appear in a Dto. I think its okay as none of it is business model behaviour and none of it impact (except positively) on a developer who wishes to assemble this structure in order to save a collection sheet. And it was really handy when coding and testing to be able to "print" the structure.

I also put a "Print" method on CollectionSheetDto (the structure the retrieveCollectionSheet method creates) for the same coding and testing benefit. I popped a "Print" in CollectionSheetErrorsView (the structure the saveCollectionSheet method uses to track account and database errors) too (smile)

Examples of Generating SaveCollectionSheetDto as Input to the saveCollectionSheet method

The SaveCollectionSheetDto structure is much simpler than the previously available structure used to save collection sheets... but being made up of customers in a hierarchy with their customer, loan and savings accounts its not completely trivial to assemble one. So, if you are developing something such as offline collection sheets or are performance testing at interface level the following examples should help.

Example 1: Create from the output of retrieveCollectionSheet (CollectionSheetDto)

TestSaveCollectionSheetUtils assembleSaveCollectionSheetDto (CollectionSheetDto collectionSheet, LocalDate transactionDate)

Example 2: Create from the output of the old legacy data structure

SaveCollectionSheetFromLegacyAssembler fromWebTierLegacyStructuretoSaveCollectionSheetDto (previousCollectionSheetEntryDto, userId)

Save Collection Sheet and Error Processing

There are two Error Processing strands when saving a collection sheet

  1. SaveCollectionSheetException - Programming errors (NOT for end user)
  2. CollectionSheetErrorsView - Notices of accounts not updated (for end user)

SaveCollectionSheetException

The saveCollectionSheet method throws SaveCollectionSheetException. If you get one of these the game is up i.e. A programming or corruption error that can only be fixed by a developer (not an end user).

As a developer you'd handle it something like this: throw new MifosRuntimeException(e.printInvalidSaveCollectionSheetReasons());

This gives up the ghost but the "print" method nicely shows the developer the exact reason(s) for the failure. Very handy during initial development too.

The reason I added this new exception was because a lot of extra, tighter validation was required if the saveCollectionSheet method were to be used by a client other than the current Mifos collection sheet web pages. Having gone to the trouble of itemising all the errors I thought I might as well pay it forward to the developer trying to work with and debug the interface.

enum InvalidSaveCollectionSheetReason lists all the reasons a saveCollectionSheet might fail. Some failures are picked up when the SaveCollectionSheetDto is being assembled and the remainder are picked up when processing a saveCollectionSheet request by the following: new SaveCollectionSheetStructureValidator().execute(saveCollectionSheet);

CollectionSheetErrorsView

The saveCollectionSheet method returns CollectionSheetErrorsView. Besides being able to record a major database error this is really used to hold lists of accounts that were not processed (updated) due to errors whilst building up the business object model prior to persisting. There a separate list for loan repayments, loan disbursals, savings account deposits, savings account withdrawals and customer account payments.

Note that although the name implies an error has happened... it doesn't mean the save was unsuccessfull. Quite the opposite. The save was successful and any accounts listed in CollectionSheetErrorsView are just warnings of accounts not processed that the user might want to investigate.

This idea works for the current Mifos web pages but for a different 'client' of the interface perhaps there should be an option to not save any of the accounts in the collection sheet if any fail.

Interface Validation TODO's

Typically, "userId" is authenticated and authorisation (permission) is checked. With the current Mifos web page client, the authentication/authorisation is determined in a struts action. I think any use of this collection sheet interface would need to do the same rather than that responsibility resting with this interface (but I'm not sure). So, currently, the interface doesn't authenticate or authorise based on userId.

House Keeping TODO's

Packageing: Need to decide which package collectSheetService interface goes into.

May be naming standard changes.

Printing Collection Sheets

http://groups.google.com.au/group/mifosdeveloper/msg/83cd8b4cff3d3e47?hl=en

from keithw - what does the linked discussion have to do with printing collection sheets?

from johnw - here's the specific excerpt. Basically, mifos is hanging onto old, unused functionality that was part of printing collection sheets... Van thought GK rolled their own because of performance probs... I'm just offering to help put the facility back in mifos if its worth it (and delete the unused stuff).

"That's all nice to know but as people have pointed out this (collection sheet reporting) functionality isn't currently used and I'm pretty sure the test doesnt quite work either (e.g. it tries to offset schedules by a number of days - it misses the "group" customer schedule and I can't see why that would be intentional.)

Van made this reply to Keith W a while ago http://groups.google.com.au/group/mifosdeveloper/msg/c2675c488be96004.

The speed aspect mentioned should be okay now. If there is still a need to ship functionality to print collecion sheet reports I'd be happy to look at it with anyone who can hold up the functional requirements end. I'd even be happy to see how GK currently do it and see how we could bring it or something like it back into mifos. "