Skip to content

Commit

Permalink
Fixed openemr#7164, Insurance Add/Edit/Search
Browse files Browse the repository at this point in the history
Made the add edit search work properly when updating an insurance
policy, creating a new one, etc.  It all funnels through the same
javascript mechanism now and populates the provider correctly.

Fixed a bug where the display name wasn't populating properly when you
enter in an insurance company as it didn't respect the globals settings
for insurance company display.

Also fixed issue openemr#7164 by fixing up the phone number update statements.

Also includes style fixes.
  • Loading branch information
adunsulag committed Jan 18, 2024
1 parent 1958a59 commit 0b2c956
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 66 deletions.
55 changes: 37 additions & 18 deletions interface/practice/ins_search.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,29 @@ function dosearch() {

// The ins_list.php window calls this to set the selected insurance.
function set_insurance(ins_id, ins_name) {
if (opener.closed || ! opener.set_insurance)
alert('The target form was closed; I cannot apply your selection.');
else
opener.set_insurance(ins_id, ins_name);
dlgclose('InsSaveClose',false);
window.top.restoreSession(); // make sure to restore the session before we do anything else
if (!window.opener) {
return; // nothing to do here as somehow we got here without the opener
}
let postMessage = {
action: 'insurance-search-set-insurance'
,insuranceId: ins_id
,insuranceName: ins_name
};
// fire off a message so we can decouple things so we don't have to have a specific function
// name in the global scope of the opener
opener.postMessage(postMessage, window.location.origin);
if (opener.closed) {
alert('The target form was closed; I cannot apply your selection.');
}
else if (opener.set_insurance) {
opener.set_insurance(ins_id, ins_name);
dlgclose('InsSaveClose', false);
} else {
// if we don't have a set_insurance function then we will just close the window as the opener is
// using post message to receive events.
dlgclose('InsSaveClose', false);
}
}

// This is set to true on a mousedown of the Save button. The
Expand Down Expand Up @@ -140,7 +158,7 @@ function clearForm() {
f.form_city.value = '';
f.form_state.value = '';
f.form_country.value = '';
f.form_zip.value = '';
f.form_zip.value = '';
f.form_phone.value = '';
f.form_cms_id.value = '';
f.form_ins_type_code.value = '';
Expand Down Expand Up @@ -225,9 +243,10 @@ function clearForm() {
echo " alert(" . js_escape($info_msg) . ");\n";
}

echo " top.restoreSession();\n";
echo " if (opener.set_insurance) opener.set_insurance(" . js_escape($ins_id) . "," . js_escape($ins_name) . ");\n";
echo " dlgclose();\n";
// we need to follow the global settings for the display of this name so we will return the name in the set_insurance method
$ins_name = (new InsuranceCompanyService())->getInsuranceDisplayName($ins_id);
// call the set_insurance method in our header
echo " set_insurance(" . js_escape($ins_id) . "," . js_escape($ins_name) . ");\n";
echo "</script></body></html>\n";
exit();
} else {
Expand Down Expand Up @@ -267,23 +286,23 @@ function clearForm() {
<tr>
<td class="font-weight-bold" nowrap><?php echo xlt('Attention');?>:</td>
<td>
<input type='text' size='20' name='form_attn' maxlength='35' class='form-control form-control-sm' title='<?php echo xla('Contact name'); ?>'
<input type='text' size='20' name='form_attn' maxlength='35' class='form-control form-control-sm' title='<?php echo xla('Contact name'); ?>'
value='<?php echo attr($ins_co['attn'] ?? ''); ?>' />
</td>
</tr>

<tr>
<td class="font-weight-bold" nowrap><?php echo xlt('Address1'); ?>:</td>
<td>
<input type='text' size='20' name='form_addr1' maxlength='35' class='form-control form-control-sm' title='First address line'
<input type='text' size='20' name='form_addr1' maxlength='35' class='form-control form-control-sm' title='First address line'
value='<?php echo attr($ins_co_address['line1'] ?? ''); ?>' />
</td>
</tr>

<tr>
<td class="font-weight-bold" nowrap><?php echo xlt('Address2'); ?>:</td>
<td>
<input type='text' size='20' name='form_addr2' maxlength='35' class='form-control form-control-sm' title='Second address line, if any'
<input type='text' size='20' name='form_addr2' maxlength='35' class='form-control form-control-sm' title='Second address line, if any'
value='<?php echo attr($ins_co_address['line2'] ?? ''); ?>' />
</td>
</tr>
Expand All @@ -292,11 +311,11 @@ function clearForm() {
<td class="font-weight-bold" nowrap><?php echo xlt('City/State'); ?>:</td>
<td class="form-row">
<div class="col">
<input type='text' size='20' name='form_city' maxlength='25' class='form-control form-control-sm' title='City name'
<input type='text' size='20' name='form_city' maxlength='25' class='form-control form-control-sm' title='City name'
value='<?php echo attr($ins_co_address['city'] ?? ''); ?>' />
</div>
<div class="col">
<input type='text' size='3' name='form_state' maxlength='35' class='form-control form-control-sm' title='State or locality'
<input type='text' size='3' name='form_state' maxlength='35' class='form-control form-control-sm' title='State or locality'
value='<?php echo attr($ins_co_address['state'] ?? ''); ?>' />
</div>
</td>
Expand All @@ -306,11 +325,11 @@ function clearForm() {
<td class="font-weight-bold" nowrap><?php echo xlt('Zip/Country:'); ?></td>
<td class="form-row">
<div class="col">
<input type='text' size='20' name='form_zip' maxlength='10' class='form-control form-control-sm' title='Postal code'
<input type='text' size='20' name='form_zip' maxlength='10' class='form-control form-control-sm' title='Postal code'
value='<?php echo attr(($ins_co_address['zip'] ?? '') . ($ins_co_address['plus_four'] ?? '')); ?>' />
</div>
<div class="col">
<input type='text' size='20' class="form-control form-control-sm" name='form_country' value='USA' maxlength='35' title='Country name'
<input type='text' size='20' class="form-control form-control-sm" name='form_country' value='USA' maxlength='35' title='Country name'
value='<?php echo attr($ins_co_address['country'] ?? ''); ?>' />
</div>
</td>
Expand All @@ -324,14 +343,14 @@ function clearForm() {
($ins_co_phone['area_code'] ?? '') .
($ins_co_phone['prefix'] ?? '') .
($ins_co_phone['number'] ?? '')
)); ?>'
)); ?>'
/>
</td>
</tr>
<tr>
<td class="font-weight-bold" nowrap><?php echo xlt('Payer ID'); ?>:</td>
<td>
<input type='text' size='20' name='form_cms_id' maxlength='15' class='form-control form-control-sm' title='Identifier assigned by CMS'
<input type='text' size='20' name='form_cms_id' maxlength='15' class='form-control form-control-sm' title='Identifier assigned by CMS'
value='<?php echo attr($ins_co['cms_id'] ?? ''); ?>' />
</td>
</tr>
Expand Down
37 changes: 35 additions & 2 deletions library/js/oeUI/insurance/EditPolicyScreenController.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ export class EditPolicyScreenController
}
if (evt.data && evt.data.hasOwnProperty('action')) {
if (evt.data.action == 'insurance-patient-browser-selected') {
let patientUuid = evt.data.patientUuid;
let insuranceUuid = evt.data.insuranceUuid;
let patientUuid = evt.data.patientUuid || null;
let insuranceUuid = evt.data.insuranceUuid || null;
if (!patientUuid || !insuranceUuid) {
alert(window.top.xl("No patient was selected to copy values from."));
return;
Expand All @@ -129,6 +129,19 @@ export class EditPolicyScreenController
});
this.render();
}
else if (evt.data.action == 'insurance-search-set-insurance') {
let insuranceCompanyId = evt.data.insuranceId || null;
let insuranceCompanyName = evt.data.insuranceName || null;
if (!insuranceCompanyId || !insuranceCompanyName) {
alert(window.top.xl("An error occurred while loading the insurance company information."));
console.error("Failed to find insurance company id or name in event data, this should not happen and is a bug.Event: ", evt);
return;
}
this.selectedInsurance.provider = insuranceCompanyId;
this.__insurancePolicyService.addInsuranceProviderToList(insuranceCompanyId, insuranceCompanyName);
this.__insuranceProviderList = this.__insurancePolicyService.getInsuranceProvidersList();
this.render();
}
}
});
}
Expand Down Expand Up @@ -233,6 +246,26 @@ export class EditPolicyScreenController
let id = (new Date()).getTime();
window.open(dlgUrl, id, 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=400,height=450,left = 440,top = 362');
});

insuranceInfoContainer.querySelector('.insurance-search-open-finder').addEventListener('click', (evt) => {
let input = evt.target;
let url = new URL(input.href);
if (this.selectedInsurance && this.selectedInsurance.provider) {
url.searchParams.set('ins', this.selectedInsurance.provider);
}
let relativeUrl = url.pathname + url.search;
evt.preventDefault();
dlgopen('', '', 700, 600, '', input.dataset['modalTitle'], {
buttons: [
{text: window.top.xl('Close'), close: true, style: 'default btn-sm'}
],
allowResize: true,
allowDrag: true,
dialogId: '',
type: 'iframe',
url: relativeUrl
});
});
}

#setupAddressValidation(selectedInsurance) {
Expand Down
3 changes: 3 additions & 0 deletions library/js/oeUI/insurance/InsurancePolicyService.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export class InsurancePolicyService
})
.then(result => result.json());
}
addInsuranceProviderToList(insuranceCompanyId, insuranceCompanyName) {
this.__insuranceProviderList[insuranceCompanyId] = insuranceCompanyName;
}

getInsuranceProvidersList() {
return this.__insuranceProviderList;
Expand Down
34 changes: 3 additions & 31 deletions library/patient.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use OpenEMR\Services\PatientService;
use OpenEMR\Services\SocialHistoryService;
use OpenEMR\Billing\InsurancePolicyTypes;
use OpenEMR\Services\InsuranceCompanyService;

require_once(dirname(__FILE__) . "/dupscore.inc.php");

Expand Down Expand Up @@ -116,37 +117,8 @@ function getInsuranceProvidersExtra()
$rez = sqlStatement($sql);

for ($iter = 0; $row = sqlFetchArray($rez); $iter++) {
switch ($GLOBALS['insurance_information']) {
case $GLOBALS['insurance_information'] = '0':
$returnval[$row['id']] = $row['name'];
break;
case $GLOBALS['insurance_information'] = '1':
$returnval[$row['id']] = $row['name'] . " (" . $row['line1'] . ", " . $row['line2'] . ")";
break;
case $GLOBALS['insurance_information'] = '2':
$returnval[$row['id']] = $row['name'] . " (" . $row['line1'] . ", " . $row['line2'] . ", " . $row['zip'] . ")";
break;
case $GLOBALS['insurance_information'] = '3':
$returnval[$row['id']] = $row['name'] . " (" . $row['line1'] . ", " . $row['line2'] . ", " . $row['state'] . ")";
break;
case $GLOBALS['insurance_information'] = '4':
$returnval[$row['id']] = $row['name'] . " (" . $row['line1'] . ", " . $row['line2'] . ", " . $row['state'] .
", " . $row['zip'] . ")";
break;
case $GLOBALS['insurance_information'] = '5':
$returnval[$row['id']] = $row['name'] . " (" . $row['line1'] . ", " . $row['line2'] . ", " . $row['city'] .
", " . $row['state'] . ", " . $row['zip'] . ")";
break;
case $GLOBALS['insurance_information'] = '6':
$returnval[$row['id']] = $row['name'] . " (" . $row['line1'] . ", " . $row['line2'] . ", " . $row['city'] .
", " . $row['state'] . ", " . $row['zip'] . ", " . $row['cms_id'] . ")";
break;
case $GLOBALS['insurance_information'] = '7':
preg_match("/\d+/", $row['line1'], $matches);
$returnval[$row['id']] = $row['name'] . " (" . $row['zip'] .
"," . $matches[0] . ")";
break;
}
$displayName = InsuranceCompanyService::getDisplayNameForInsuranceRecord($row);
$returnval[$row['id']] = $displayName;
}

return $returnval;
Expand Down
5 changes: 3 additions & 2 deletions src/RestControllers/InsuranceRestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public function getAll($searchParams)
$serviceResult = $this->insuranceService->search($searchParams);
return RestControllerHelper::handleProcessingResult($serviceResult, null, 200);
}
public function getOne($insuranceUuid, $puuid) {
public function getOne($insuranceUuid, $puuid)
{
$searchParams = [];
// we do this again cause we have to handle the 404 result here.
$searchParams['uuid'] = new TokenSearchField('uuid', $insuranceUuid, true);
Expand All @@ -48,7 +49,7 @@ public function getOne($insuranceUuid, $puuid) {
return RestControllerHelper::handleProcessingResult($processingResult, 404);
}

return RestControllerHelper::handleProcessingResult($processingResult, 200, false );
return RestControllerHelper::handleProcessingResult($processingResult, 200, false);
}
public function put($puuid, $insuranceUuid, $data)
{
Expand Down
57 changes: 53 additions & 4 deletions src/Services/InsuranceCompanyService.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,55 @@ public function __construct()
parent::__construct(self::INSURANCE_TABLE);
}

public function getInsuranceDisplayName($insuranceId)
{
$searchResults = $this->search(['id' => $insuranceId]);
$insuranceCompany = null;
if ($searchResults->hasData()) {
$insuranceCompany = $searchResults->getData()[0];
}
if (!empty($insuranceCompany)) {
return self::getDisplayNameForInsuranceRecord($insuranceCompany);
} else {
return "";
}
}
public static function getDisplayNameForInsuranceRecord($insuranceCompany)
{
switch ($GLOBALS['insurance_information']) {
case '1':
$returnval = $insuranceCompany['name'] . " (" . $insuranceCompany['line1'] . ", " . $insuranceCompany['line2'] . ")";
break;
case '2':
$returnval = $insuranceCompany['name'] . " (" . $insuranceCompany['line1'] . ", " . $insuranceCompany['line2'] . ", " . $insuranceCompany['zip'] . ")";
break;
case '3':
$returnval = $insuranceCompany['name'] . " (" . $insuranceCompany['line1'] . ", " . $insuranceCompany['line2'] . ", " . $insuranceCompany['state'] . ")";
break;
case '4':
$returnval = $insuranceCompany['name'] . " (" . $insuranceCompany['line1'] . ", " . $insuranceCompany['line2'] . ", " . $insuranceCompany['state'] .
", " . $insuranceCompany['zip'] . ")";
break;
case '5':
$returnval = $insuranceCompany['name'] . " (" . $insuranceCompany['line1'] . ", " . $insuranceCompany['line2'] . ", " . $insuranceCompany['city'] .
", " . $insuranceCompany['state'] . ", " . $insuranceCompany['zip'] . ")";
break;
case '6':
$returnval = $insuranceCompany['name'] . " (" . $insuranceCompany['line1'] . ", " . $insuranceCompany['line2'] . ", " . $insuranceCompany['city'] .
", " . $insuranceCompany['state'] . ", " . $insuranceCompany['zip'] . ", " . $insuranceCompany['cms_id'] . ")";
break;
case '7':
preg_match("/\d+/", $insuranceCompany['line1'], $matches);
$returnval = $insuranceCompany['name'] . " (" . $insuranceCompany['zip'] .
"," . $matches[0] . ")";
break;
case '0':
default:
$returnval = $insuranceCompany['name'];
break;
}
return $returnval;
}
public function getUuidFields(): array
{
return ['uuid'];
Expand All @@ -65,7 +114,7 @@ public function search($search, $isAndCondition = true)
$sql .= " i.x12_receiver_id,";
$sql .= " i.x12_default_partner_id,";
$sql .= " i.alt_cms_id,";
$sql .= " i.inactive,work_number.id as work_id,fax_number.id AS fax_id,";
$sql .= " i.inactive,work_number.work_id,fax_number.fax_id,";
$sql .= " CONCAT(
COALESCE(work_number.country_code,'')
,COALESCE(work_number.area_code,'')
Expand All @@ -85,18 +134,18 @@ public function search($search, $isAndCondition = true)
$sql .= " a.zip,";
$sql .= " a.country";
$sql .= " FROM insurance_companies i ";
$sql .= " JOIN addresses a ON i.id = a.foreign_id";
$sql .= " JOIN (SELECT line1,line2,city,state,zip,country,foreign_id FROM addresses) a ON i.id = a.foreign_id";
// the foreign_id here is a globally unique sequence so there is no conflict.
// I don't like the assumption here as it should be more explicit what table we are pulling
// from since OpenEMR mixes a bunch of paradigms. I initially worried about data corruption as phone_numbers
// foreign id could be ambigious here... but since the sequence is globally unique @see \generate_id() we can
// join here safely...
$sql .= " LEFT JOIN (
SELECT id,foreign_id,country_code, area_code, prefix, number
SELECT id AS work_id,foreign_id,country_code, area_code, prefix, number
FROM phone_numbers WHERE number IS NOT NULL AND type = " . self::TYPE_WORK . "
) work_number ON i.id = work_number.foreign_id";
$sql .= " LEFT JOIN (
SELECT id,foreign_id,country_code, area_code, prefix, number
SELECT id AS fax_id,foreign_id,country_code, area_code, prefix, number
FROM phone_numbers WHERE number IS NOT NULL AND type = " . self::TYPE_FAX . "
) fax_number ON i.id = fax_number.foreign_id";

Expand Down
3 changes: 2 additions & 1 deletion src/Services/InsuranceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public function validate($data)
return $this->coverageValidator->validate($data);
}

public function getOneByPatientUuidAndInsuranceType($puuid, $type) {
public function getOneByPatientUuidAndInsuranceType($puuid, $type)
{
return $this->search(['puuid' => $puuid, 'type' => $type]);
}

Expand Down
9 changes: 4 additions & 5 deletions src/Services/PhoneNumberService.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ public function update($data, $foreignId)
$phoneNumbersSql .= " country_code=?,";
$phoneNumbersSql .= " area_code=?,";
$phoneNumbersSql .= " prefix=?,";
$phoneNumbersSql .= " number=?,";
$phoneNumbersSql .= " type=?";
$phoneNumbersSql .= " WHERE foreign_id=?";
$phoneNumbersSql .= " number=? ";
$phoneNumbersSql .= " WHERE foreign_id=? AND type=?";

$phoneNumbersSqlResults = sqlStatement(
$phoneNumbersSql,
Expand All @@ -102,8 +101,8 @@ public function update($data, $foreignId)
$this->area_code ,
$this->prefix,
$this->number,
$this->type,
$this->foreignId
$this->foreignId,
$this->type
)
);

Expand Down
Loading

0 comments on commit 0b2c956

Please sign in to comment.