Skip to content

Commit

Permalink
Openemr fix telehealth signup locale (#6413) (#6414)
Browse files Browse the repository at this point in the history
* Add save and locale telehealth check instructions

Added a check for the locale settings which should be setup to avoid
clinic problems.

Added instructions that the user needs to log out and log back in after
saving the telehealth settings.

* Fix psr problems.

* Fix telehealth subscription signup.

Include instructions and the subscription id for the user to use when
they signup for the credentials.

Add a copy button and switch the alert of the subscription id to
actually show up in a success message info box.  Before the change the
user had limited understanding on how to proceed to the next steps in
the configuration system.

* Improve signup verbiage, add subscription id

To make the signup process easier for users, we break the signup into
three steps with instructions.  We also add saving the paypal
subscription id so we can check if the paypal process has already
completed and been signed up.

We show progress to the user as they signup.

* Fix if conditions, paypal key

Fixed the paypal key coming back from Sherwin to be the right key value.
Fixed the conditions on the subscription id.

* Include the free verbiage in the description.

* Updated telehealth plan for 14 day free trial.

* Defaulting values to avoid sql error.
  • Loading branch information
adunsulag committed Apr 26, 2023
1 parent 4ab5b6b commit 6abd4c8
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use OpenEMR\Common\Crypto\CryptoGen;
use OpenEMR\Common\Csrf\CsrfUtils;
use Comlink\OpenEMR\Modules\TeleHealthModule\TelehealthGlobalConfig;

$module_config = 1;

Expand All @@ -37,11 +38,12 @@
$content = trim(file_get_contents("php:https://input"));
$credentials = json_decode($content, true);
$cryptoGen = new CryptoGen();
$items['comlink_telehealth_registration_uri'] = $credentials['registrationUri'];
$items['comlink_telehealth_video_uri'] = $credentials['videoApiUri'];
$items['comlink_telehealth_user_id'] = $credentials['ctsiOrgUid'];
$items['comlink_telehealth_user_password'] = $cryptoGen->encryptStandard(trim($credentials['ctsiOrgPwd']));
$items['comlink_telehealth_cms_id'] = $credentials['ctsiOrgId'];
$items[TelehealthGlobalConfig::COMLINK_VIDEO_REGISTRATION_API] = $credentials['registrationUri'] ?? '';
$items[TelehealthGlobalConfig::COMLINK_VIDEO_TELEHEALTH_API] = $credentials['videoApiUri'] ?? '';
$items[TelehealthGlobalConfig::COMLINK_VIDEO_API_USER_ID] = $credentials['ctsiOrgUid'] ?? '';
$items[TelehealthGlobalConfig::COMLINK_VIDEO_API_USER_PASSWORD] = isset($credentials['ctsiOrgPwd']) ? $cryptoGen->encryptStandard(trim($credentials['ctsiOrgPwd'])) : '';
$items[TelehealthGlobalConfig::COMLINK_VIDEO_TELEHEALTH_CMS_ID] = $credentials['ctsiOrgId'] ?? '';
$items[TelehealthGlobalConfig::COMLINK_TELEHEALTH_PAYMENT_SUBSCRIPTION_ID] = $credentials['paypal_subscription_id'] ?? '';
// Save to globals table.
foreach ($items as $key => $credential) {
sqlQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public function __construct(EventDispatcher $dispatcher, ?Kernel $kernel = null)
$this->globalsConfig = new TelehealthGlobalConfig($this->getURLPath(), $this->moduleDirectoryName, $this->twig);
}

public function getGlobalConfig(): TelehealthGlobalConfig
{
return $this->globalsConfig;
}

public function getTemplatePath()
{
return \dirname(__DIR__) . DIRECTORY_SEPARATOR . "templates" . DIRECTORY_SEPARATOR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use Comlink\OpenEMR\Module\GlobalConfig;
use OpenEMR\Common\Crypto\CryptoGen;
use OpenEMR\Common\Database\QueryUtils;
use OpenEMR\Common\Logging\SystemLogger;
use OpenEMR\Services\Globals\GlobalSetting;
use OpenEMR\Services\Globals\GlobalsService;
Expand Down Expand Up @@ -57,7 +58,11 @@ class TelehealthGlobalConfig

public const COMLINK_ONETIME_PASSWORD_LOGIN_TIME_LIMIT = "comlink_onetime_password_login_time_limit";

public const COMLINK_TELEHEALTH_PAYMENT_SUBSCRIPTION_ID = "comlink_telehealth_payment_subscription_id";

public const MAX_LOGIN_LIMIT_TIME = 30;
const LOCALE_TIMEZONE_DEFAULT = "Unassigned";
const LOCALE_TIMEZONE = "gbl_time_zone";

/**
* @var CryptoGen
Expand Down Expand Up @@ -342,6 +347,12 @@ public function getGlobalSettingSectionConfiguration()
,'type' => GlobalSetting::DATA_TYPE_TEXT
,'default' => ''
]
,self::COMLINK_TELEHEALTH_PAYMENT_SUBSCRIPTION_ID => [
'title' => 'Telehealth Payment Subscription ID'
,'description' => 'This is your unique video application payment subscription id. Signup via the Manage Modules configuration screen if you have not received it'
,'type' => GlobalSetting::DATA_TYPE_TEXT
,'default' => ''
]
,self::COMLINK_AUTO_PROVISION_PROVIDER => [
'title' => 'Auto Register Providers For Telehealth'
,'description' => 'Disable this setting if you will manually enable the providers you wish to be registered for Telehealth'
Expand Down Expand Up @@ -420,6 +431,8 @@ public function renderFooterBox($fldid, $fldarray)
$isValidRegistrationUri = filter_var($this->getRegistrationAPIURI(), FILTER_VALIDATE_URL);
$isValidTelehealthApi = filter_var($this->getTelehealthAPIURI(), FILTER_VALIDATE_URL);

$isLocaleConfigured = $this->isLocaleConfigured();

$dataArray = [
'emailNotificationsConfigured' => $emailNotificationsConfigured
,'isThirdPartyConfigurationSetup' => $isThirdPartyConfigurationSetup
Expand All @@ -430,11 +443,27 @@ public function renderFooterBox($fldid, $fldarray)
,'fldarray' => $fldarray
,'verifyInstallationPathUrl' => $this->publicWebPath . 'index.php?action=verify_installation_settings'
,'telehealthCvbUrl' => $this->publicWebPath . 'assets/js/src/cvb.min.js'
,'isLocaleConfigured' => $isLocaleConfigured
];

return $this->twig->render("comlink/admin/telehealth_footer_box.html.twig", $dataArray);
}

private function isLocaleConfigured()
{
// timezone is not set in the $GLOBALS array oddly, not sure why, check against the database
$record = QueryUtils::fetchRecords("SELECT gl_name, gl_index, gl_value FROM globals WHERE gl_name=?", [self::LOCALE_TIMEZONE]);
if (!empty($record)) {
if (empty($record[0]['gl_value'])) {
return false;
// default can get translated so we need to go with that
} else if ($record[0]['gl_value'] == xl(self::LOCALE_TIMEZONE_DEFAULT)) {
return false;
}
}
return true;
}

public function setupConfiguration(GlobalsService $service)
{
global $GLOBALS;
Expand Down Expand Up @@ -474,7 +503,8 @@ private function isOptionalSetting($key)
|| $key == self::DEBUG_MODE_FLAG
|| $key == self::COMLINK_SECTION_FOOTER_BOX
|| $key == self::COMLINK_ONETIME_PASSWORD_LOGIN
|| $key == self::COMLINK_ONETIME_PASSWORD_LOGIN_TIME_LIMIT;
|| $key == self::COMLINK_ONETIME_PASSWORD_LOGIN_TIME_LIMIT
|| $key == self::COMLINK_TELEHEALTH_PAYMENT_SUBSCRIPTION_ID; // we don't require the payment subscription id
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@
});
})(window);
</script>
<p>
{{ "The Telehealth module allows you to conduct video visits with your patients."|xlt }}
{{ "After saving these settings you must log out and log back in for the Telehealth Settings to be applied"|xlt }}
</p>
<div class="alert alert-info">
<details>
<summary class="h4">
Expand Down Expand Up @@ -150,6 +154,20 @@
<li>{{ "SMTP Password for Authentication"|xlt }} - {{ "When using SMTP transport method and SMTP Security Protocol"|xlt }}</li>
</ul>
</li>
<li class="h5">
{{ "Config"|xlt }} -> {{ "Locale"|xlt }} -
{% if isLocaleConfigured %}
<span class="text-success">{{ "Configured"|xlt }}</span>
{% else %}
<span class="text-danger">{{ "Incorrect"|xlt }}</span>
{% endif %}
<p>
{{ "The following settings must be configured in the Config Locale section for Telehealth Calendar Sessions to work properly"|xlt }}
</p>
<ul class="h6">
<li>{{ "Time Zone"|xlt }}</li>
</ul>
</li>
</ul>
</details>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@

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

use Comlink\OpenEMR\Modules\TeleHealthModule\Bootstrap;
use Comlink\OpenEMR\Modules\TeleHealthModule\TelehealthGlobalConfig;

$kernel = $GLOBALS['kernel'];
$bootstrap = new Bootstrap($kernel->getEventDispatcher(), $kernel);
$globalConfig = $bootstrap->getGlobalConfig();
$subscriptionId = $globalConfig->getGlobalSetting(TelehealthGlobalConfig::COMLINK_TELEHEALTH_PAYMENT_SUBSCRIPTION_ID) ?? '';
$isCoreConfigured = $globalConfig->isTelehealthCoreSettingsConfigured() === true;

?>
<!DOCTYPE html>
<html lang="en">
Expand Down Expand Up @@ -71,14 +80,77 @@
</div>
<div class="card-body">

<p><?php echo xlt("To get your telehealth configuration information"); ?>,
<p><?php echo xlt("To get your telehealth configuration information you must first signup for a subscription trial and then setup your telehealth credentials"); ?>,
<?php echo xlt("Please select the subscription button below."); ?></p>
<p>
<?php echo xlt("There is a 7 day trial period included with the subscription"); ?>
</p>
<div id="paypal-button-container-P-25N86285GY8825203MMWZEIY"></div>
<script src="https://www.paypal.com/sdk/js?client-id=AUQ1tRakVcTZ0wIOjQ0CicVxB8K47tXo4l8PucxwmmB1v_LIE4-_pJ-kEZf3fsk3uKZuhb_3WuDasVBC&vault=true&intent=subscription" data-sdk-integration-source="button-factory"></script>
<div id="step-1-subscription-signup" class="<?php if (!empty($subscriptionId)) {
echo 'd-none';} ?>">
<h2><?php echo xlt("Step 1 - Subscription Signup"); ?></h2>
<p>
<?php echo xlt("There is a 14 day free trial period included with the subscription"); ?>
</p>
<div id="paypal-button-container-P-4FU17140CF274883DMREHHFA"></div>
<script src="https://www.paypal.com/sdk/js?client-id=AU0Ql21fQp5jd-Vn2jPU1dCdTse_DFpGiBjfBAsrBW9lEeNNBmEm7NpKim6W3vt3RxOVH-Wa_VFwz3mw&vault=true&intent=subscription" data-sdk-integration-source="button-factory"></script>
</div>
<div id="step-1-subscription-signup-complete" class="<?php if (empty($subscriptionId)) {
echo 'd-none';} ?>">
<h2><?php echo xlt("Step 1 - Subscription Signup"); ?> - <span class="text-success"><?php echo xlt("Complete"); ?></span></h2>
<div class="alert alert-success <?php if (empty($subscriptionId)) {
echo 'd-none';} ?>">
<h3><?php echo xlt("Your payment subscription has been created."); ?></h3>
<p><?php echo xlt("Your Subscription ID / Profile ID is the following"); ?></p>
<h3><input type="text" disabled="disabled" id="paypal-subscription-id" value="<?php echo attr($subscriptionId); ?>" /><i class="ml-2 fa fa-copy" id="btnCopy"></i></h3>
<p><?php echo xlt("Copy your subscription ID / Profile ID for obtaining your telehealth credentials"); ?></p>
<p><small><?php echo xlt("You have been sent an email from Paypal with your subscription information"); ?></small></p>
</div>
</div>
<script>
// handles the copying of the subscription id for the client's reference.
function btnCopy() {
try {
let el = document.querySelector('#paypal-subscription-id');
if (el) {
el.select();
}
let text = el.value;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(() => {
alert(<?php echo xlj("Copied to clipboard"); ?>);
}, (error) => {
console.error(error);
alert(<?php echo xlj("Failed to copy to clipboard"); ?>);
});
} else {
document.execCommand("copy");
alert(<?php echo xlj("Copied to clipboard"); ?>);
}
} catch (error) {
console.error(error);
alert(<?php echo xlj("Failed to copy to clipboard"); ?>);
}
}
function paypalOnApproveHandler(data, actions) {
let el = document.querySelector('.alert-success');
el.classList.remove("d-none");
let el2 = document.querySelector('#paypal-subscription-id');
el2.value = data.subscriptionID;

let el3 = document.querySelector('#step-1-subscription-signup-complete');
el3.classList.remove("d-none");

let payPalSection = document.querySelector('#step-1-subscription-signup');
payPalSection.classList.add('d-none');

let sinupLink = document.querySelector('#signupLink');
// if we want to pass along the subscription_id we can do that, right now that causes the signup page
// to fail.
// sinupLink.href = sinupLink.href + "?subscription_id=" + encodeURIComponent(data.subscriptionID);
}
window.addEventListener("DOMContentLoaded", function() {
let btnCopyElement = document.querySelector('#btnCopy');
btnCopyElement.addEventListener('click', btnCopy);
// uncomment for testing
// paypalOnApproveHandler({subscriptionID: 'testingId1'}, {});
});
paypal.Buttons({
style: {
shape: 'rect',
Expand All @@ -89,17 +161,25 @@
createSubscription: function(data, actions) {
return actions.subscription.create({
/* Creates the subscription */
plan_id: 'P-25N86285GY8825203MMWZEIY',
quantity: 1 // The quantity of the product for a subscription
plan_id: 'P-4FU17140CF274883DMREHHFA'
});
},
onApprove: function(data, actions) {
alert(data.subscriptionID); // You can add optional success message for the subscriber here
}
}).render('#paypal-button-container-P-25N86285GY8825203MMWZEIY'); // Renders the PayPal button
onApprove: paypalOnApproveHandler
}).render('#paypal-button-container-P-4FU17140CF274883DMREHHFA'); // Renders the PayPal button
</script>
<div class="<?php if ($isCoreConfigured) {
echo 'd-none';} ?>">
<h2><?php echo xlt("Step 2 - Credentials Signup"); ?></h2>
<p><h3><a id='signupLink' href="https://credentials.affordablecustomehr.com/customer"><?php echo xlt("Click Here to get credentials after subscribing"); ?></a></h3></p>
</div>
<div class="<?php if (!$isCoreConfigured) {
echo 'd-none';} ?>">
<h2><?php echo xlt("Step 2 - Credentials Signup"); ?> - <span class="text-success"><?php echo xlt("Complete"); ?></span></h2>
<p><?php echo xlt("Your credentials have been setup and saved in the Telehealth configuration"); ?></p>
</div>
<div>
<p><h3><a href="https://credentials.affordablecustomehr.com/customer"><?php echo xlt("Click Here to get credentials after subscribing"); ?></a></h3></p>
<h3><?php echo xlt("Step 3 - Complete Telehealth Configuration"); ?></h3>
<p><?php echo xlt("Finish the telehealth configuration and verify your setup is fully functionining in the Admin -> Config -> Telehealth settings section"); ?></p>
</div>
</div>
</section>
Expand Down

0 comments on commit 6abd4c8

Please sign in to comment.