Refactoring the Healthcare System in ERPNext
An attempt to improve the Healthcare System in ERPNext
What is ERPNext Healthcare?
The healthcare system in ERPNext empowers any Healthcare facility to manage Patients, Appointments, Consultations, Laboratory and much more. Healthcare institutions need a lot more than just the Healthcare system to operate efficiently. ERPNext has all of the other modules built-in, out of the box! You can track your Accounting Books, manage Appraisals, Payroll, Leaves, organise your Purchases, Stocks, Fixed Assets, Integration and much more. ERPNext Healthcare is a community-contributed module initiated by Earthians and is being maintained by Frappe (the developers and maintainers of ERPNext).
ERPNext has multiple modules or domains (more than 20). To focus on every module with more dedication, Frappe came up with the concept of module owners. In this model, one or more developers would own a module in ERPNext. This increased the ownership and focus for every developer while reducing the overhead of context-switching. I was given the opportunity to own the Healthcare Module. The Healthcare System in ERPNext wasn’t celebrated like the popular Manufacturing, Retail or Stock modules. It’s a community-contributed module that never got as much love and fixes as it deserved.
This is when I set out to change that. I started going through the documentation, I found it to be in a similar shape like the healthcare system itself, lacking. Things were a bit difficult to understand. So I got my first goal towards growth, writing in-depth documentation for Healthcare. Since the existing documentation wasn't comprehensive enough to understand the module, I dived into the code. I found the code quality to be lacking when compared to the rest of Frappe’s coding standards. Each file triggered my OCD. No spacing after brackets, logical errors, multiple actions dumped into a single function, mixed usage of double and single quotes, raw SQL queries and no signs of ORM, spaces used instead of tabs, strings which were not translation-friendly, missing comments, out-of-context variable, and function-naming, to name a few. Refactoring the entire code became my second goal then.
I started testing the module with Dilpreet, my colleague, only to find a ton of bugs. "Why weren’t they solved during Support?", I wondered. To which Dilpreet reminded me that there weren’t many customers using the ERPNext Healthcare System. Also, there were no test cases written for any DocType which could point out the exact issue. So writing test cases became my third goal. At that point, I literally felt the module was anaath (an orphan) ever since it was added.
While testing, we found many other problems that I tried fixing during the refactoring process. These have been fixed in multiple cases but here are all of them with one example each:
Anti Pattern Processes
Honey, I lost the “Save” button
Field Labels not Justifying to What was Actually Happening
Looking at the label “Procedure”, I assumed a Clinical Procedure had to be selected, but it turns out to be the Clinical Procedure Template which had to be selected. Templates in ERPNext are used to reduce the user’s effort of entering the same data again and again. You have to select a Template while booking an appointment that fetches the generic details, and then you go on to create a Clinical Procedure, derived from the Template and which is specific to that Patient. So, the label here was misleading.
Field Types and Field Ordering
All the related fields should be placed together in a Form. For example, if certain fields have “Fetch From” property set, then they should be placed below the fields from which the data is being fetched. The same applies to fields whose display property depends on the values of some other fields.
In a few forms, link fields were configured as data fields, Child Tables were being used as link fields, which needed refactoring. But some field types needed change for better reasons like improving analytics, providing consistent options across all the Forms, etc. For example, Complaints and Diagnosis fields in Patient Encounter were converted from Small Text to Table Multiselect:
Descriptions are really necessary for DocTypes used as “Settings” because you don’t know what could be the humongous effect of checking a small, innocent-looking checkbox.
Default Messages for Buttons
Initially, most of the buttons would freeze up on clicking because there weren’t any linked documents found for that action. Added messages for them:
Better Error Messages
For billing a Patient Appointment, a Customer should be linked to the Patient document. The Customer is automatically created on Patient creation. In case if this linking is removed, the following error message was displayed earlier:
For a user, this can be confusing since Customer creation happens in the background. So why not tell them straight away. (P.S.: Frappe Team always points out missing titles in error messages, so keep in mind to add it wherever needed.) Also the message should have a link to the document which is causing the trouble.
These issues were among my favorites because they were the easiest to solve and they did not fail to show up in every Healthcare DocType. For example, the “Disabled” status shown as “Enabled”.
This was because the disabled field was hidden and it highlighted one more anti-pattern practice, this action was carried out by a button and not a checkbox.
Dashboards are really important for navigation and quick creation of related documents from within the form. So I added dashboards wherever they were missing:
Replacing the Deprecated Reports
“Appointment Analytics” was earlier created as a TreeGrid Report in Healthcare. But TreeGrid Reports were deprecated later on. So I created a Script Report for the same:
For example, Issues in Fee Validity DocType (a document that keeps track of free follow-ups for Patients)
- The fee validity was getting updated twice, once during the appointment creation and once when the sales invoice was getting submitted.
- The payment related fields shouldn't be mandatory in Patient Appointment if fee validity has been set up.
- Fee Validity is now created only for new patients. Earlier it was creating the Fee Validity again after the first one gets completed.
- It also has a status as Completed or Pending now and the user is not allowed to create it since the creation and update process is handled during appointment creation/cancellation.
- The Fee Validity should not be linked to invoices since appointments within a valid free period should not be invoiced. Hence it now shows up a series of reference appointments that have not been billed due to the fee validity doc.
To sum up my entire "Refactoring Cycle":
I enjoyed this process thoroughly, though I must admit that I am very prone to redundant mistakes which Nabin Hait, the VP Product at Frappe, generously pointed out in the PR Review. All of these were very small changes but they do make a big difference in the user experience and module maintenance. I would like to thank Rushabh Mehta, Founder, and CEO at Frappe, for making me the module DRI! And special thanks to Earthians for such a great contribution. It’s really difficult to create a generic Healthcare System when there are so many medical departments out there with varying requirements! I really hope that after these changes, the Healthcare System in ERPNext is on par with its other modules.
Software Developer at Frappe