Skip to content

Commit

Permalink
Weno ez integration (openemr#6648)
Browse files Browse the repository at this point in the history
* vehr remmediation

* Weno Pharmacy Service

Handles all Pharmacy related queries for weno ez integration

* Weno Pharmacy Ajax Request

File handles all the pharmacy search using the Weno Pharmacy Selector

* WenoFragment

Display a fragment below Vitals Fragment to show list of only Weno Rx.

* Weno Pharmacy Selector Interface

pharmacy_list_form: Form that allows weno primary and alternate pharmacy selection.
pharmacy_list_display: displays the selected pharmacies

* saving weno pharmacy on update demographics_save.php

* create new weno pharmacies new_comprehensive_save.php

* include Weno Pharmacy form and display pages options.inc.php

* Include weno installation instructions globals.inc.php

* Added truncate table before importing weno pharmacies LogDataInsert.php

* include download pharmacies to Weno Management tab

* Download Weno Zipped File file_download.php

* Updated TransmitProperties.php

Validates patient data, provider data before consuming weno api

* weno fix globals, broken download link, clearing insurance data

* remove vehr items

* modularize weno and refactor

* resolve import

* removed old weno & unused files, refactoring

* refactoring

remove custom css files, animations, unused files, sql refactoring

* refactoring

* sql refactoring 2

* Delete FacilityController.php

* restore claim rev menu item

* change prescription log download from 24hrs to 30mins

* Update table.sql

* Included encounter ID to prescriptions

LogDataInsert.php
LogImportBuild.php
TransmitProperties.php

* Update LogDataInsert.php

date added field is added field default to current datetime

* Update LogDataInsert.php

* Create version.php

Included version file

* introduced services

introduced services, move files around and resolved imports

* Further fixes sql structure, removed unused code

* php styling, weno log background service

* - resolve and refactor old weno_provider_username and weno_provider_password  that at some point was changed to weno_admin_username and weno_admin_password
- fix pathings
- fix table global update where weno_provider_username and weno_admin_username values are wrongly swapped
- remove unused weno_fragment from core directory tree
- remove unnecessary global $GLOBALS statements
- run module through CS
- add conditional test if pharmacy download directory exist and create if not

* - fix event classes style for CS

* - more CS

* - fix docblock unsure why my code sniffer didn't fix!

* - fix menu build where misplace breaks was prevent full menu scan.
- patched out location header for Weno eRx render. Header was overriding the tabs iFrame html and title was missing for tab. One or the other but safer using tab.
- fix translations in TransmitProperties class. Show an example of at least ensuring user can see error messages regardless of theme. i.e a dark theme will appear as a reverse white screen.
- Remove unused global $GLOBALS
- IMPORTANT! the user setting required for several work flows wasn't being set in globals because it is required that a companion global be available. I fixed in another PR.

* - crypto not decrypt weno properties because misspelled property
- escaping

* - add button role to sync
- move section before event to actual top i.e. above Billing.
- render module at top of demographics center column. Below prescriptions.

---------

Co-authored-by: dataengr <[email protected]>
Co-authored-by: Jerry Padgett <[email protected]>
  • Loading branch information
3 people authored Jan 27, 2024
1 parent 174fb4b commit 2fece8e
Show file tree
Hide file tree
Showing 53 changed files with 3,740 additions and 470 deletions.
30 changes: 0 additions & 30 deletions interface/main/tabs/menu/menus/standard.json
Original file line number Diff line number Diff line change
Expand Up @@ -1239,21 +1239,6 @@
"global_req": [
"erx_enable"
]
},
{
"label":"Weno Management",
"menu_id":"adm0",
"target":"adm",
"url":"/interface/weno/facilities.php",
"children":[],
"requirement":0,
"acl_req": [
"admin",
"super"
],
"global_req": [
"weno_rx_enable"
]
}
],
"requirement": 0,
Expand Down Expand Up @@ -1328,21 +1313,6 @@
],
"global_req": "!disable_prescriptions"
},
{
"label":"Prescription Log",
"menu_id":"rep0",
"target":"rep",
"url":"/interface/weno/rxlogmanager.php",
"children":[],
"requirement":0,
"acl_req": [
"patients",
"rx"
],
"global_req": [
"weno_rx_enable"
]
},
{
"label": "Patient List Creation",
"menu_id": "rep0",
Expand Down
1 change: 0 additions & 1 deletion interface/modules/custom_modules/README

This file was deleted.

Empty file.
674 changes: 674 additions & 0 deletions interface/modules/custom_modules/oe-module-weno/LICENSE

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions interface/modules/custom_modules/oe-module-weno/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Weno EZ Integration Module for OpenEMR
This module enables prescribers to make ePrescription through Weno's iFrame.

## To Install the Weno EZ Integration Module
- On the top menu Modules -> Manage Modules. Click the unregistered button to display all unregistered modules.
- Find the Weno EZ Integration Module and click the "Register Button".
- On the Registered tab, click install and enable.
- After successful installation, headover to Admin -> Config -> Weno to enter the weno Admin settings. To register for an account, visit www.online.wenoexchange.com
- Follow the instructions on the Developer Page to configure your Weno EZ integration.
Empty file.
20 changes: 20 additions & 0 deletions interface/modules/custom_modules/oe-module-weno/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "openemr/oe-module-weno",
"description": "Weno EZ Integration Module",
"type": "openemr-module",
"minimum-stability": "stable",
"license": "GPL-3.0",
"authors": [
{
"name": "Kofi Appiah",
"email": "[email protected]"
}
],
"require": {
},
"conflict": {
"openemr/openemr": ">=7.0.1"
},
"config": {
}
}
1 change: 1 addition & 0 deletions interface/modules/custom_modules/oe-module-weno/info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Weno EZ Integration Module
15 changes: 15 additions & 0 deletions interface/modules/custom_modules/oe-module-weno/moduleConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

/**
*
* package OpenEMR
* link http://www.open-emr.org
* author Sherwin Gaddis <[email protected]>
* copyright Copyright (c )2021. Sherwin Gaddis <[email protected]>
* license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*
*/

require_once dirname(__FILE__, 4) . '/globals.php';

$module_config = 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/**
*
* @package OpenEMR Weno Module
* @link https://online.wenoexchange.com
*
* @author Kofi Appiah <[email protected]>
* 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
*/

$classLoader->registerNamespaceIfNotExists('OpenEMR\\Modules\\WenoModule\\', __DIR__ . DIRECTORY_SEPARATOR . 'src');

/**
* @global EventDispatcher $eventDispatcher Injected by the OpenEMR module loader;
*/

$bootstrap = new Bootstrap($eventDispatcher, $GLOBALS['kernel']);
$bootstrap->subscribeToEvents();
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
function sync_weno(){
var syncIcon = document.getElementById("sync-icon");
var syncAlert = document.getElementById("sync-alert");
const url = '../../modules/custom_modules/oe-module-weno/templates/synch.php';

syncIcon.classList.add("fa-spin");

let formData = new FormData();
formData.append("key", "sync");

fetch(url, {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
// If the response status code is not in the 200-299 range, reject the promise
throw new Error('Server responded with an error status: ' + response.status);
} else {
//setting alert details
wenoAlertManager("success",syncAlert,syncIcon);
}

}).catch(error=> {
console.log(error.message)
wenoAlertManager("failed",syncAlert,syncIcon);
});
}

function wenoAlertManager(option, element, spinElement){
spinElement.classList.remove("fa-spin");
if(option == "success"){
element.classList.remove("d-none");
element.classList.add("alert", "alert-success");
element.innerHTML = "Successfully updated";
window.location.reload();
setTimeout(
function(){
element.classList.add("d-none");
element.classList.remove("alert", "alert-success");
element.innerHTML = "";
}, 3000
);

} else {
setTimeout(function(){
element.classList.add("d-none");
element.classList.remove("alert", "alert-danger");
element.innerHTML = "";
}, 3000);
element.classList.remove("d-none");
element.classList.add("alert", "alert-danger");
element.innerHTML = "An error occurred";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<?php

// Disable PHP timeout
@ini_set('max_execution_time', '0');

require_once dirname(__DIR__, 5) . "/globals.php";

use OpenEMR\Common\Logging\EventAuditLogger;

use OpenEMR\Common\Crypto\CryptoGen;
use OpenEMR\Modules\WenoModule\Services\LogDataInsert;
use OpenEMR\Modules\WenoModule\Services\WenoLogService;
use OpenEMR\Modules\WenoModule\Services\PharmacyService;

$cryptoGen = new CryptoGen();
$weno_username = $GLOBALS['weno_admin_username'];
$weno_password = $cryptoGen->decryptStandard($GLOBALS['weno_admin_password']);
$encryption_key = $cryptoGen->decryptStandard($GLOBALS['weno_encryption_key']);
$baseurl = "https://online.wenoexchange.com/en/EPCS/DownloadPharmacyDirectory";

$data = array(
"UserEmail" => $weno_username,
"MD5Password" => md5($weno_password),
"ExcludeNonWenoTest" => "N",
"Daily" => "N"
);

if (date("l") == "Monday") { //if today is Monday download the weekly file
$data["Daily"] = "N";
}

//check if there is history of download, if not do a weekly file
// $pharmacyService = new PharmacyService();
// $db_exist = $pharmacyService->checkWenoPharmacyLog();
// if($db_exist != "empty"){
// $data["Daily"] = "Y";
// }


$json_object = json_encode($data);
$method = 'aes-256-cbc';

$key = substr(hash('sha256', $encryption_key, true), 0, 32);

$iv = chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0);

$encrypted = base64_encode(openssl_encrypt($json_object, $method, $key, OPENSSL_RAW_DATA, $iv));

$fileUrl = $baseurl . "?useremail=" . urlencode($weno_username) . "&data=" . urlencode($encrypted);
$storelocation = $GLOBALS['OE_SITE_DIR'] . "/documents/logs_and_misc/weno/weno_pharmacy.zip";
$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)
{
$fp = fopen($zipped_file, 'w+');

$ch = curl_init($fileUrl);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1000);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_exec($ch);

curl_close($ch);
fclose($fp);
}

download_zipfile($fileUrl, $storelocation);

$zip = new ZipArchive();

$wenolog = new WenoLogService();

if ($zip->open($storelocation) === true) {
$zip->extractTo($path_to_extract);

$files = glob($path_to_extract . "/*.csv");
if ($files) {
$csvFile = $files[1];
$filename = basename($csvFile);
$csvFilename = $filename;

EventAuditLogger::instance()->newEvent("prescriptions_log", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "File extracted successfully.");
echo 'File extracted successfully.';
echo 'CSV filename: ' . text($csvFilename);
$zip->close();
unlink($storelocation);
} else {
EventAuditLogger::instance()->newEvent("prescriptions_log", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "No CSV file found in the zip archive.");
echo 'No CSV file found in the zip archive.';
}
} else {
EventAuditLogger::instance()->newEvent("prescriptions_log", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "Failed to extract the file.");
echo 'Failed to extract the file.';
}

$insertPharmacy = new PharmacyService();

if ($data['Daily'] == 'N') {
$insertPharmacy->removeWenoPharmacies();
}

$insertdata = [];

$l = 0;
if (file_exists($csvFile)) {
$records = fopen($csvFile, "r");

while (!feof($records)) {
$line = fgetcsv($records);

if ($l <= 1) {
$l++;
continue;
}
if (!isset($line[1])) {
continue;
}
if (!isset($line[1])) {
continue;
}
if (!empty($line)) {
if ($data['Daily'] == 'N') {
$ncpdp = str_replace(['[', ']'], '', $line[3]);
$npi = str_replace(['[', ']'], '', $line[5]);
$business_name = $line[6];
$address_line_1 = $line[7];
$address_line_2 = $line[8];
$city = $line[9];
$state = $line[10];
$zipcode = str_replace(['[', ']'], '', $line[11]);
$country = $line[12];
$international = $line[13];
$pharmacy_phone = str_replace(['[', ']'], '', $line[16]);
$on_weno = $line[21];
$test_pharmacy = $line[17];
$state_wide_mail = $line[18];
$fullDay = $line[22];
} else {
$ncpdp = str_replace(['[', ']'], '', $line[3]);
$npi = str_replace(['[', ']'], '', $line[7]);
$business_name = $line[8];
$city = $line[11];
$state = $line[12];
$zipcode = str_replace(['[', ']'], '', $line[14]);
$country = $line[15];
$address_line_1 = $line[9];
$address_line_2 = $line[10];
$international = $line[16];
$pharmacy_phone = str_replace(['[', ']'], '', $line[20]);
$county = $line[33];
$on_weno = $line[37];
$compounding = $line[41];
$medicaid_id = $line[45];
$dea = $line[44];
$test_pharmacy = $line[29];
$fullDay = $line[40];
$state_wide_mail = $line[47];
}

$insertdata['ncpdp'] = $ncpdp;
$insertdata['npi'] = $npi;
$insertdata['business_name'] = $business_name;
$insertdata['address_line_1'] = $address_line_1;
$insertdata['address_line_2'] = $address_line_2;
$insertdata['city'] = $city;
$insertdata['state'] = $state;
$insertdata['zipcode'] = $zipcode;
$insertdata['country'] = $country;
$insertdata['international'] = $international;
$insertdata['pharmacy_phone'] = $pharmacy_phone;
$insertdata['on_weno'] = $on_weno;
$insertdata['test_pharmacy'] = $test_pharmacy;
$insertdata['state_wide_mail'] = $state_wide_mail;
$insertdata['fullDay'] = $fullDay;

if ($data['Daily'] == 'Y') {
$insertPharmacy->updatePharmacies($insertdata);
} else {
$insertPharmacy->insertPharmacies($insertdata);
}

++$l;
}
}
$wenolog->insertWenoLog("pharmacy", "Success");
fclose($records);
foreach ($files as $file) {
if (is_file($file)) {
unlink($file);
}
}
error_log("Pharmacy Imported");
} else {
$wenolog->insertWenoLog("pharmacy", "Failed");
error_log("file missing");
}
Loading

0 comments on commit 2fece8e

Please sign in to comment.