Skip to content

Commit

Permalink
Some finishing touches (openemr#7306)
Browse files Browse the repository at this point in the history
* Weno fixup and credential API
- change fa font size
- prevent old styles loading

* - add acl to setup
- validate vitals for under age
- fix popup error for invalid action
- add validation and default to change events
- better validate setting requirements

* - New WenoValidate class to verift keys and user credentials
- verify and reset encryption key if needed for phamacy downloads.
- temporally chang testing URL to weno dev server until new api goes online.
- setup weno module for using upgrade in pre for auto upgrade feature.

* - update code stamdards and do a little cleanup of our utility.js
- numerous validation additions.
- add all weno required settings (weno user id, facility location id and admin credentials validation) to module setup page.

* - moved the custom modules to top of managers list. appears I have a bias!
- add a simple but useful help panel to top of list table.
- color coded module name for clarity if laminas or custom.

* - had to create a separate setup_facilities script for setup so can use when module isn't enabled.
- add a help button to MM and help_requested event listener
- refactor controller for readability
- add some security

* - fix pathing problems
- refactor reloads to replace page with new version

* - too full of myself. utility Cleanup failed.
- add new dowdlog log viewer
- fix download create directory

* - fix download won't break on duplicate key
- auto save weno id in facilities section.
- some setup refactor

* - prevent resave of demographics on dialog close

* - prevent demos from throwing warning in upgrade for old weno table population. v5.0.1 I believe.
- files clean out
- remove a chance for a race condition in background tasks

* - change and move help
- refactor to use the online api from dev api

* - refactor and consoladate weno menu from Other to Weno eRx Tools
- add Module setup and new Dowmload log viewer for admin to manage
- add traps for internet off line.
- remove unused class methods and cleanup WenoValidate class for readability.

* - combine the download facility download viewer page

* Some finishing touches
- don't expose sensitive data
- change datepicker option. though it would work in US not so muct Europe's day/m/Y

* - refactor weno_log_sync for better readability and separation of concerns. This script was driving me crazy!
- reformat various errors
- ensure we have valid credentials and encryp key for downloads. If not reset so we can complete the important initial downloads at least.
- added new info to download manager
- I don't know take a look...

* Remove unused code
Add link to modules wiki

* a couple log errors

* review

* module manager help method

* Fix log escaping

* Add exception to decryptStandard so we can tell where the heck error occurs

* no message

* Resubmit for missing yag that is not missing!

* missing return in format function. Things are disappearing in my local!

* add test pharmacies
finish coredecrypt exceptions
error messages refactors

* Main fix here is adding logic for weno test pahramcies
refactors of phamacy search and bud fix
add logic to keep weno provider ids upto date and validated.
escaping and xlating some js

* Trying out updated linting
- more global management for the module
- escaping
- pharmacy search alerts
- add additional ease of setup options to setup. User Setting for logged in admin
- had to refactor provider username to provider_email for weno legacy
- add Brady's fix in core encryption service for dynamic properties. One less thing to worry about!. clean up comments

* - more clean up. This is a very nice class.

* - move validate actions up in form.
- more fiddling around.

* - add new action for listener reset_module active when the register icon is clicked. I used to remove all DB.
- contiueing project messages and search fine tuning.
- crypto updates

* - fix edit_globals magins and padding
- more runtime safety
- review note

* Update ModuleService.php

* - reset back to dev server for testing
- format messages

* - refactor to online production API domain.
- Add new items for setup and a complete module reset
- refactore MM to separate cust and laminas section lists.
  • Loading branch information
sjpadgett authored Apr 16, 2024
1 parent 9be12b8 commit 5c5001f
Show file tree
Hide file tree
Showing 29 changed files with 847 additions and 504 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function moduleManagerAction($methodName, $modId, string $currentActionSt

/**
* Required method to return namespace
* If namespace isn't provided return empty
* If namespace isn't provided return empty string
* and register namespace at top of this script..
*
* @return string
Expand Down Expand Up @@ -107,11 +107,9 @@ private function install($modId, $currentActionStatus): mixed
private function help_requested($modId, $currentActionStatus): mixed
{
// must call a script that implements a dialog to show help.
// I can't find a way to override the Laminas UI except using a dialog.
try {
include 'show_help.php';
} catch (Exception $e) {
return $e->getMessage();
// I can't find a way to override the Lamina's UI except using a dialog.
if (file_exists(__DIR__ . '/show_help.php')) {
include __DIR__ . '/show_help.php';
}
return $currentActionStatus;
}
Expand Down Expand Up @@ -166,6 +164,45 @@ private function unregister($modId, $currentActionStatus): mixed
return $currentActionStatus;
}

/**
* @param $modId
* @param $currentActionStatus
* @return mixed
*/
private function reset_module($modId, $currentActionStatus): mixed
{
$rtn = true;
$modService = new ModuleService();
$logMessage = ''; // Initialize an empty string to store log messages

if (!$modService::getModuleState($modId)) {
$sql = "DELETE FROM `user_settings` WHERE `setting_label` LIKE 'global:weno%'";
$rtn = sqlQuery($sql);
$logMessage .= "DELETE FROM `user_settings`: " . (empty($rtn) ? "Success" : "Failed") . "\n";

$sql = "DELETE FROM `globals` WHERE `gl_name` LIKE 'weno%'";
$rtn = sqlQuery($sql);
$logMessage .= "DELETE FROM `globals`: " . (empty($rtn) ? "Success" : "Failed") . "\n";

$sql = "DROP TABLE IF EXISTS `weno_pharmacy`";
$rtn = sqlQuery($sql);
$logMessage .= "DROP TABLE `weno_pharmacy`: " . (empty($rtn) ? "Success" : "Failed") . "\n";

$sql = "DROP TABLE IF EXISTS `weno_assigned_pharmacy`";
$rtn = sqlQuery($sql);
$logMessage .= "DROP TABLE `weno_assigned_pharmacy`: " . (empty($rtn) ? "Success" : "Failed") . "\n";

$sql = "DROP TABLE IF EXISTS `weno_download_log`";
$rtn = sqlQuery($sql);
$logMessage .= "DROP TABLE `weno_download_log`: " . (empty($rtn) ? "Success" : "Failed") . "\n";

error_log(text($logMessage));
}

// return log messages to the MM to show user.
return text($logMessage);
}

/**
* @param $modId
* @param $currentActionStatus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@
/**
*
* @package OpenEMR Weno Module
* @link https://online.wenoexchange.com
*
* @author Jerry Padgett <[email protected]>
* @author Kofi Appiah <[email protected]>
* Copyright (c) 2023 Omega Systems Group Corp <omegasystemsgroup.com>
* Copyright (c) 2023 Omega Systems Group Corp <omegasystemsgroup.com>
* @license GNU General Public License 3
*
*/

namespace OpenEMR\Modules\WenoModule;

use OpenEMR\Core\ModulesClassLoader;

/**
* @global OpenEMR\Core\ModulesClassLoader $classLoader
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ function renderDialog(action, uid, event) {
const actionUrl = `${urls[action]}${urlPart}id=${encodeURIComponent(uid)}&csrf_token_form=${encodeURIComponent(csrf)}`;

// Open modal dialog
dlgopen('', 'dialog-mod', '900', 'full', '', '', {
dlgopen('', 'dialog-mod', 'modal-lg', 'full', '', '', {
buttons: [
{
text: jsText('Return to eRx Widget'),
close: true,
style: 'primary'
text: jsText('Return to eRx Widget'),
close: true,
style: 'primary'
}
],
allowResize: true,
Expand All @@ -91,6 +91,7 @@ function renderDialog(action, uid, event) {
dialogId: 'error-dialog',
type: 'iframe',
resolvePromiseOn: 'close',
sizeHeight: 'full',
url: top.webroot_url + actionUrl
}).then(function (dialog) {
top.restoreSession();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use OpenEMR\Common\Crypto\CryptoGen;
use OpenEMR\Common\Logging\EventAuditLogger;
use OpenEMR\Modules\WenoModule\Services\PharmacyService;
use OpenEMR\Modules\WenoModule\Services\TransmitProperties;
use OpenEMR\Modules\WenoModule\Services\WenoLogService;

$cryptoGen = new CryptoGen();
Expand Down Expand Up @@ -44,7 +43,7 @@
$path_to_extract = $GLOBALS['OE_SITE_DIR'] . "/documents/logs_and_misc/weno/";

// takes URL of image and Path for the image as parameter
function download_zipfile($fileUrl, $zipped_file)
function download_zipfile($fileUrl, $zipped_file): void
{
$fp = fopen($zipped_file, 'w+');

Expand Down Expand Up @@ -74,8 +73,8 @@ function download_zipfile($fileUrl, $zipped_file)
download_zipfile($fileUrl, $storelocation);

$zip = new ZipArchive();
$wenolog = new WenoLogService();

$wenoLog = new WenoLogService();
$csvFile = '';
if ($zip->open($storelocation) === true) {
$zip->extractTo($path_to_extract);

Expand All @@ -95,13 +94,13 @@ function download_zipfile($fileUrl, $zipped_file)
}
} else {
$rpt = file_get_contents($storelocation);
$isError = $wenolog->scrapeWenoErrorHtml($rpt);
$isError = $wenoLog->scrapeWenoErrorHtml($rpt);
if ($isError['is_error']) {
error_log('Pharmacy download failed: ' . $isError['messageText']);
$wenolog->insertWenoLog("pharmacy", "Exceeded_download_limits");
error_log('Pharmacy download failed: ' . errorLogEscape($isError['messageText']));
$wenoLog->insertWenoLog("pharmacy", "Exceeded download limits");
}
EventAuditLogger::instance()->newEvent("pharmacy_log", $_SESSION['authUser'], $_SESSION['authProvider'], 0, $isError['messageText']);
$wenolog->insertWenoLog("pharmacy", "Failed");
EventAuditLogger::instance()->newEvent("pharmacy_log", $_SESSION['authUser'], $_SESSION['authProvider'], 0, ($isError['messageText']));
$wenoLog->insertWenoLog("pharmacy", "Failed");
// no need to continue
// send error to UI alert
die(js_escape($isError['messageText']));
Expand Down Expand Up @@ -221,7 +220,7 @@ function download_zipfile($fileUrl, $zipped_file)
0,
"Pharmacy Import download failed SQL Insert error."
);
$wenolog->insertWenoLog("pharmacy", "Failed");
$wenoLog->insertWenoLog("pharmacy", "Failed");
error_log("User Initialed Pharmacy Import Failed Insert error");
}
// let's brag about it.
Expand All @@ -232,8 +231,8 @@ function download_zipfile($fileUrl, $zipped_file)
1,
"User Initiated Pharmacy Download was Imported Successfully."
);
$wenolog->insertWenoLog("pharmacy", "Success");
error_log("User Initialed Pharmacy Imported");
$wenoLog->insertWenoLog("pharmacy", "Success");
error_log("User Initiated Pharmacy Imported");
} else {
EventAuditLogger::instance()->newEvent(
"pharmacy_log",
Expand All @@ -242,6 +241,6 @@ function download_zipfile($fileUrl, $zipped_file)
0,
"Pharmacy Import download failed."
);
$wenolog->insertWenoLog("pharmacy", "Failed");
$wenoLog->insertWenoLog("pharmacy", "Failed");
error_log("User Initialed Pharmacy Import Failed File Missing");
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,110 @@
use OpenEMR\Common\Crypto\CryptoGen;
use OpenEMR\Common\Logging\EventAuditLogger;
use OpenEMR\Modules\WenoModule\Services\LogProperties;
use OpenEMR\Modules\WenoModule\Services\WenoLogService;
use OpenEMR\Modules\WenoModule\Services\WenoPharmaciesJson;
use OpenEMR\Modules\WenoModule\Services\WenoValidate;

/**
* Download Weno Pharmacy data.
*/
function downloadWenoPharmacy()
{
// Check if the encryption key is valid. If not, request a new key and then set it.
$wenoValidate = new WenoValidate();
$isKey = $wenoValidate->validateAdminCredentials(true); // auto reset on invalid.
$isKey = $wenoValidate->validateAdminCredentials(true, "pharmacy");

if ((int)$isKey >= 998) {
EventAuditLogger::instance()->newEvent(
"pharmacy_background",
$_SESSION['authUser'],
$_SESSION['authProvider'],
1,
text("Background Initiated Pharmacy download attempt failed. Internet problem!")
);
error_log('Background Initiated Pharmacy Download not ran. Internet problem: ' . text($isKey));
die;
handleDownloadError("Background Initiated Pharmacy download attempt failed. Internet problem!");
}

if ($isKey === false) {
requireGlobals();
}
error_log('Background Initiated Encryption Verify returned: ' . text($isKey == '1' ? 'Verified key is valid.' : 'Invalid Key'));

$cryptoGen = new CryptoGen();
$localPharmacyJson = new WenoPharmaciesJson($cryptoGen);
// Check if the background service is active. Intervals are set to once a day
$localPharmacyJson = new WenoPharmaciesJson(new CryptoGen());
$value = $localPharmacyJson->checkBackgroundService();

if ($value == 'active' || $value == 'live') {
error_log('Background Initiated Pharmacy Download Started.');

$status = $localPharmacyJson->storePharmacyDataJson();

EventAuditLogger::instance()->newEvent(
"pharmacy_background",
$_SESSION['authUser'],
$_SESSION['authProvider'],
1,
"Background Initiated Pharmacy Download Completed with Status:" . text($status)
);
error_log('Background Initiated Weno Pharmacies download completed with status:' . text($status));
die;
$wenoLog = new WenoLogService();
$wenoLog->insertWenoLog("pharmacy", "Download started");

performPharmacyDownload($localPharmacyJson);
}
}

/**
* Perform the pharmacy data download.
*
* @param WenoPharmaciesJson $localPharmacyJson
*/
function performPharmacyDownload(WenoPharmaciesJson $localPharmacyJson)
{
error_log('Background Initiated Pharmacy Download Started.');

$status = $localPharmacyJson->storePharmacyDataJson();

EventAuditLogger::instance()->newEvent(
"pharmacy_background",
$_SESSION['authUser'],
$_SESSION['authProvider'],
1,
"Background Initiated Pharmacy Download Completed with Status:" . ($status)
);

error_log('Background Initiated Weno Pharmacies download completed with status:' . text($status));
}

/**
* Download Weno Prescription log.
*
* @throws Exception
*/
function downloadWenoPrescriptionLog(): void
{
$wenoValidate = new WenoValidate();
$isKey = $wenoValidate->validateAdminCredentials(true);

if ((int)$isKey >= 998) {
handleDownloadError("Prescription download attempt failed. Internet problem!");
}

if ($isKey === false) {
requireGlobals();
}

$logSync = new LogProperties();
if (!$logSync->logSync()) {
error_log("Background services failed for prescription log.");
}
}

/**
* Handle download errors.
*
* @param string $errorMessage
*/
function handleDownloadError(string $errorMessage)
{
EventAuditLogger::instance()->newEvent(
"pharmacy_background",
$_SESSION['authUser'],
$_SESSION['authProvider'],
1,
($errorMessage)
);

error_log(errorLogEscape($errorMessage));
die;
}

/**
* Require global variables.
*/
function requireGlobals(): void
{
// Key has been reset, reload globals
// This is the problem when using globals for anything in a function.
// They need to be reloaded when dynamically changed or JIT global values.
// TODO: We need to address this in the future.
require_once dirname(__DIR__, 4) . "/globals.php";
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@
$weno_coverage = $_GET['coverage'] ?? false ?: '';
$weno_state = $_GET['weno_state'] ?? false ?: '';
$weno_city = $_GET['weno_city'] ?? false ?: '';
$full_day = !empty($_GET['full_day']) ? 'Yes' : '';
$weno_only = !empty($_GET['weno_only']) ? 'True' : '';
$weno_zipcode = $_GET['weno_zipcode'] ?? false ?: '';
$weno_test_pharmacies = !empty($_GET['test_pharmacy']) ? 'True' : '';
$weno_only = $_GET['weno_only'] == 'true' ? 'True' : '';
$full_day = $_GET['full_day'] == 'true' ? 'Yes' : '';
$weno_test_pharmacies = $_GET['test_pharmacy'] == 'true' ? 'True' : '';

if (!empty($weno_coverage)) {
$sql .= " AND state_wide_mail_order = ?";
Expand Down Expand Up @@ -111,8 +111,9 @@
$weno_coverage = $_GET['coverage'] ?: '';
$weno_state = $_GET['weno_state'] ?: '';
$weno_city = $_GET['weno_city'] ?: '';
$full_day = $_GET['full_day'] ? 'Yes' : '';
$weno_zipcode = $_GET['weno_zipcode'] ?: '';
$weno_only = $_GET['weno_only'] == 'true' ? 'True' : '';
$full_day = $_GET['full_day'] == 'true' ? 'Yes' : '';
$weno_test_pharmacies = $_GET['test_pharmacy'] == 'true' ? 'True' : '';

// if a zip, search by it and forget city and state
Expand Down
11 changes: 11 additions & 0 deletions interface/modules/custom_modules/oe-module-weno/src/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,16 @@ public function addCustomMenuItem(MenuEvent $event): MenuEvent
$setupMenu->children = [];
$setupMenu->acl_req = ["admin", "super"];
$setupMenu->global_req = ["weno_rx_enable"];
// Background Services
$serviceMenu = new \stdClass();
$serviceMenu->requirement = 0;
$serviceMenu->target = 'rpt0';
$serviceMenu->menu_id = 'rep';
$serviceMenu->label = xlt("Background Services (Convenience)");
$serviceMenu->url = "/interface/reports/background_services.php";
$serviceMenu->children = [];
$serviceMenu->acl_req = ["admin", "super"];
$serviceMenu->global_req = ["weno_rx_enable"];
// Write the menu items to the menu
foreach ($menu as $item) {
if ($item->menu_id == 'admimg') {
Expand All @@ -271,6 +281,7 @@ public function addCustomMenuItem(MenuEvent $event): MenuEvent
if ($other->label == 'Weno eRx Tools') {
$other->children[] = $dlMenu;
$other->children[] = $setupMenu;
$other->children[] = $serviceMenu;
break;
}
}
Expand Down
Loading

0 comments on commit 5c5001f

Please sign in to comment.