Main title frame will load patient and encounters information without need for loading of demographics frame. Currently the title frame calls demographics which then updates the patient data in title frame.
Instead of loading encounter and document history, we automatically load the last encounter. For many practices, it is common to have patients with 50-100 encounters.
Not included in this commit are changes to demographics.php - that remove code that fills patient & encounter blocks.
Patient dashboard is most frequently used interface component. All users need ability to add/remove and rearrange components that they use. Unfortunately current structure does not lend itself to any flexibility.
For starters, this commit :
Deconstructs existing code into fragments with a requirement that each fragment (for now) have its php, html and scripts in a single file.
Introduces a class that is used for constructing fragment objects.
Maps the page into an array making it possible to add/remove or rearrange the fragments.
In next step, these fragments would become providers of data for one of the views of underlying emr objects.
I looked briefly through the code and anything that breaks large massive files like the demographics.php into smaller logical chunks that can be better reasoned about is fine by me.
My understanding is that you are not wanting to make this into a pull request at this point? Is that just due to concerns about meeting PSR2 standards or what?
I actually like the approach of the fragments because it allows us to filter those array components using the event dispatcher if we want to extend / customize this via module extensions.
Stephen: These commits are based on our fork at 5.0. In the past we have tried to provide PRs of individual features that got obsolete - (e.g. in the code you will notice include for globals.php does not have hard coded path) . We also have switched to latest bootstrap 4 and will soon move to standardized view classes targeted for tablets.
As the forks diverge, creating each PR becomes prohibitively expensive. At the same time we feel the standard code could use these as hints/suggestions or just our 2 cents worth of contribution to this good project.
Been awhile since i’ve boned up on bootstrap. Can BS3 and BS4 coexist? I’m all for anything that breaks down demographics especially from a performance point of view. Also if BS4 is the goto for better responsiveness then am onboard as well. So how difficult would it be to stage BS4 into codebase?
Didn’t try but I suppose the script injector can be directed to select specific version. Good news here is BS isn’t widely used in the project as your efforts show.
Performance issues in current 2000 lines of demographics.php are architectural - it tries to do everything for everybody. As an example, if an user while reading messages wants to see documents for that patient, they go to demographics which loads issues, appointments (2-3 times), all encounters, all issues, prescriptions and birthday cake . As a bonus, the rules popup 2-3 alert boxes that need to be closed before they can click to see list of documents by category. If that patient has 50-60 encounters and 100+ documents, this check takes more than few minutes.
Then the user moves to the next message for another patient!
Now that basic rant is over, as far as demographics is concerned, BS version is not an issue - towards the end there are 4-5 lines that do overall remapping that can be removed in standard code. Bulk of the effort will be :
Validating if fragments is the approach community wants to take
Explode current (5.0.2) code to their respective fragments (php, js and html)
Test full set of fragments and then possibly with few fragments removed from the array.
Effort for RTop is basically removing code from the updaters/callers without impacting frames users. We have removed left_nav from our code and have no idea if anything breaks there.
Bootstrap code can be very verbose. Recently came across old library that provides well structured classes to support forms. Just posted a basic wrapper class around that library to make it usable in emr setting.
If anyone is interested, they can follow these steps to see the basic form with some of the validation built-in :
PFBC wrapper (0)
Pull current dev version of the library avbdr/php-bootstrap-form from mdsupport repo.
PFBC wrapper (2)
A simple script that uses email and password fields. Check the pre-built validation classes that examine the email address entry. The test script uses New Assets Manager class that provides method for starting a standardized html document.
We plan to use this setup as basic engine for all forms on tablets / small devices.
@sjpadgett and others have gone through hoops to make dialog library work for frames and iframes interfaces. If frames interface is dropped, project can move towards delegating modal dialogs to native bootstrap. Here is a recipe for eliminating use of dlgopen by Popups menu -
function popMenuDialog(url, title) {
let notlike = title.toLowerCase();
// If mainmodal is available, display finder in modal
if (typeof(showMainModal)==='function') {
showMainModal({
src: url,
title: title
}
);
return true;
}
dlgopen(url, 'menupopup', 'modal-mlg', 500, '', title, {
sizeHeight: notlike.search('label') !== -1 ? 'full' : 'auto'
});
}
Other scripts can invoke the modal by using top.showMainModal.
Current code allows (or in many cases requires) the modal dialog to invoke functions in initiating script. As part of the migration, it may be better to put together a mechanism by which the dialog notifies top that it should be closed due to a given action. top.closeMainModal acting as controller, closes the dialog and takes follow-up actions.
Issues are functionally central to patient care. Unfortunately, this and most other systems focus on encounter and documentation features mostly needed for billing . As we look at bringing in issue management related enhancements, first step is to provide consistent display of the issues throughout the application. Following query currently forms the core of ptIssue class.
SELECT iss.* FROM lists iss
INNER JOIN issue_types it ON iss.type = it.type
LEFT JOIN list_options occ ON iss.occurrence = occ.option_id and occ.list_id = "occurrence"
WHERE iss.pid=? and it.active=1 and occ.activity=1
ORDER BY it.ordering, occ.seq DESC,
(IFNULL(iss.enddate,0)=0) DESC,
IFNULL(iss.begdate,iss.date) DESC,
IFNULL(iss.enddate,0) DESC, title ASC
demographics.php is the only way to navigate to all data related to this patient - may be selected from calendar. All links to are then visible but unresponsive until everything is loaded. In addition to large number of ajax calls for patient data, this process also includes display of encounters. If your practice has patients with several years of visits, it is now starting to take 30-45 seconds and beyond to get your clicks accepted by the browser.
In frames era that was tolerable since each frame responds when ready in its container. Encounters frame was immediately visible and needed to be updated. In case of tabs interface, the user ends up paying the penalty of waiting till encounter tab is populated in the background and in more than 90% of times does not use that list anyway.
Since we changed the navigation as part of Demographics v5+ : Title block (0), the loading of enc tab is now discontinued. If required, users can now choose list or specific encounter from title block. This has cut the wait in half.
Memcached integration with emr will offer an option for users to communicate across sessions at run time.
Has anyone already implemented this or any other caching functionality, could you please share your experience and code if possible?
Starting a PoC to cache calendar page(s) for small practices. Daily view is fetched by every user multiple times during normal hours when probably 99% of time there are no updates. So the code will cache a generated page that will expire at end of day. All appointment updates for cached dates will mark the cached entry as dirty. ‘Refresh’ action by any user will also invalidate current cached entry.
TLDR
Our public repository provides a database-centric approach to implement modifications to standard emr.
Like windows registry or linux package managers, dev_obj table stores various “things”. The dev_component table implements the relationship between defined objects. All “objects” are then supported by specific code that implements specific actions. As an example, DevFile object can be leveraged to control actions of standard scripts. Object versioning implements ability to support custom behavior for different emr versions or specific installations. guids implement integrity of objects globally.
Currently the code includes objects that works for MySQL or compatible engines. Interested developers can also look at the stored functions that use dbengine to generate guids as an alternative to emr code.
Changes needed to standard code:
Review and install tables in database.
Depending on your dbengine version, you may need to set uuid default to null and use the polyfill + trigger mechanism to manage uuid values.
In case you are frustrated by infamous Site ID message, change main.php and reminder counters, another annoying background task that runs with hard-coded frequency.
Neither the underlying scripts or this fix belong in a good package. But here it goes.
Use your account to download latest codes from loinc.org.
Add LOINC as code_type in EMR.
Run LOINC import tool in console with --help to see expected parameters with defaults.
php /var/www/html/emr7d/vendor/mdsupport/mdpub/oemods/cli/import_loinc.php --help
…
Options
–zipIn, -z Set the staged Loinc package archive - Loinc_.zip [default: /home/emrsys/Loinc_2.75.zip]
–site, -s Set the EMR site [default: default]
Import the downloaded codes by overriding the default filename used by -z option