Skip to content

Commit

Permalink
Bring into patch 1 2420E openemr#7405 (openemr#7418)
Browse files Browse the repository at this point in the history
* Bring into patch 1 2420E openemr#7405

* database update I think is needed for tests to run!
  • Loading branch information
sjpadgett authored May 2, 2024
1 parent a56573a commit a758a75
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 44 deletions.
9 changes: 9 additions & 0 deletions interface/forms/newpatient/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,15 @@ function cancelClickedOld() {
</select>
</div>
</div>
<div class="col-sm <?php displayOption('enc_enable_ordering_provider');?>">
<div class="form-group">
<label for='ordering_provider_id' class="text-right"><?php echo xlt('Ordering Provider'); ?>:</label>
<?php
$MBO->genOrderingProviderSelect('ordering_provider_id', '-- ' . xl("Please Select") . ' --', $result["ordering_provider_id"] ?? '');
?>
</select>
</div>
</div>
<div class="col-sm <?php displayOption('enc_enable_facility'); ?>">
<div class="form-group">
<label for='facility_id_sel' class="text-right"><?php echo xlt('Facility'); ?>:</label>
Expand Down
6 changes: 5 additions & 1 deletion interface/forms/newpatient/save.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
$referring_provider_id = $_POST['referring_provider_id'] ?? null;
//save therapy group if exist in external_id column
$external_id = isset($_POST['form_gid']) ? $_POST['form_gid'] : '';
$ordering_provider_id = $_POST['ordering_provider_id'] ?? null;

$discharge_disposition = $_POST['discharge_disposition'] ?? null;
$discharge_disposition = $discharge_disposition != '_blank' ? $discharge_disposition : null;
Expand Down Expand Up @@ -113,6 +114,7 @@
'encounter_type_code' => $encounter_type_code,
'encounter_type_description' => $encounter_type_description,
'in_collection' => $in_collection,
'ordering_provider_id' => $ordering_provider_id,
];

$col_string = implode(" = ?, ", array_keys($data)) . " = ?";
Expand Down Expand Up @@ -153,6 +155,7 @@
$encounter_type_code,
$encounter_type_description,
$in_collection,
$ordering_provider_id,
$id
);
$col_string = implode(" = ?, ", [
Expand All @@ -171,7 +174,8 @@
'referring_provider_id',
'encounter_type_code',
'encounter_type_description',
'in_collection'
'in_collection',
'ordering_provider_id',
]) . " =?";
sqlStatement("UPDATE form_encounter SET $datepart $col_string WHERE id = ?", $sqlBindArray);
} else {
Expand Down
6 changes: 6 additions & 0 deletions library/globals.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -4308,6 +4308,12 @@ function gblTimeZones()
xl('Show Encounter Class option on Encounters'),
],

'enc_enable_ordering_provider' => [
xl('Show Ordering Provider option on Encounters'),
getDefaultRenderListOptions(),
RenderFormFieldHelper::HIDE_ALL,
xl('Display the Ordering Provider option on Encounters'),
],
],
);

Expand Down
43 changes: 2 additions & 41 deletions sql/database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,6 @@ INSERT INTO `background_services` (`name`, `title`, `active`, `running`, `next_r
INSERT INTO `background_services` (`name`, `title`, `active`, `running`, `next_run`, `execute_interval`, `function`, `require_once`, `sort_order`) VALUES
('X12_SFTP', 'SFTP Claims to X12 Partner Service', 0, 0, '2021-01-18 11:25:10', 1, 'start_X12_SFTP', '/library/billing_sftp_service.php', 100);
INSERT INTO `background_services` (`name`, `title`, `active`, `running`, `next_run`, `execute_interval`, `function`, `require_once`, `sort_order`) VALUES
('WenoExchange', 'Weno Log Sync', 0, 0, '2021-01-18 11:25:10', 0, 'start_weno', '/library/weno_log_sync.php', 100);
INSERT INTO `background_services` (`name`, `title`, `active`, `running`, `next_run`, `execute_interval`, `function`, `require_once`, `sort_order`) VALUES
('UUID_Service', 'Automated UUID Creation Service', 1, 0, '2021-01-18 11:25:10', 240, 'autoPopulateAllMissingUuids', '/library/uuid.php', 100);
INSERT INTO `background_services` (`name`, `title`, `active`, `running`, `next_run`, `execute_interval`, `function`, `require_once`, `sort_order`) VALUES
('Email_Service', 'Email Service', 1, 0, '2021-01-18 11:25:10', 2, 'emailServiceRun', '/library/email_service_run.php', 100);
Expand Down Expand Up @@ -1643,44 +1641,6 @@ CREATE TABLE `erx_ttl_touch` (

-- --------------------------------------------------------

--
-- Table structure for table `erx_weno_drugs`
--

DROP TABLE IF EXISTS `erx_weno_drugs`;
CREATE TABLE `erx_weno_drugs` (
`drug_id` int(11) NOT NULL AUTO_INCREMENT,
`rxcui_drug_coded` int(11) DEFAULT NULL,
`generic_rxcui` int(11) DEFAULT NULL,
`drug_db_code_qualifier` text,
`full_name` varchar(250) NOT NULL,
`rxn_dose_form` text,
`full_generic_name` varchar(250) NOT NULL,
`brand_name` varchar(250) NOT NULL,
`display_name` varchar(250) NOT NULL,
`route` text,
`new_dose_form` varchar(100) DEFAULT NULL,
`strength` varchar(15) DEFAULT NULL,
`supress_for` text,
`display_name_synonym` text,
`is_retired` text,
`sxdg_rxcui` varchar(10) DEFAULT NULL,
`sxdg_tty` text,
`sxdg_name` varchar(100) DEFAULT NULL,
`psn_drugdescription` varchar(100) DEFAULT NULL,
`ncpdp_quantity_term` text,
`potency_unit_code` varchar(10) DEFAULT NULL,
`dea_schedule_no` int(2) DEFAULT NULL,
`dea_schedule` varchar(7) DEFAULT NULL,
`ingredients` varchar(100) DEFAULT NULL,
`drug_interaction` varchar(100) DEFAULT NULL,
`unit_source_code` varchar(3) DEFAULT NULL,
`code_list_qualifier` int(3) DEFAULT NULL,
PRIMARY KEY (`drug_id`)
) ENGINE=InnoDB;

-- --------------------------------------------------------

--
-- Table structure for table `erx_rx_log`
--
Expand Down Expand Up @@ -1945,6 +1905,7 @@ CREATE TABLE `form_encounter` (
`date_end` DATETIME DEFAULT NULL,
`in_collection` tinyint(1) default NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`ordering_provider_id` INT(11) DEFAULT '0' COMMENT 'referring provider, if any, for this visit',
PRIMARY KEY (`id`),
UNIQUE KEY `uuid` (`uuid`),
KEY `pid_encounter` (`pid`, `encounter`),
Expand Down Expand Up @@ -8053,7 +8014,7 @@ DROP TABLE IF EXISTS `rule_filter`;
CREATE TABLE `rule_filter` (
`id` varchar(31) NOT NULL DEFAULT '' COMMENT 'Maps to the id column in the clinical_rules table',
`include_flag` tinyint(1) NOT NULL default 0 COMMENT '0 is exclude and 1 is include',
`required_flag` tinyint(1) NOT NULL default 0 COMMENT '0 is required and 1 is optional',
`required_flag` tinyint(1) NOT NULL default 0 COMMENT '0 is optional and 1 is required',
`method` varchar(31) NOT NULL DEFAULT '' COMMENT 'Maps to list_options list rule_filters',
`method_detail` varchar(31) NOT NULL DEFAULT '' COMMENT 'Maps to list_options lists rule__intervals',
`value` varchar(255) NOT NULL DEFAULT '',
Expand Down
4 changes: 4 additions & 0 deletions sql/patch.sql
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ UPDATE list_options SET option_id='DOB' WHERE list_id='recent_patient_columns' A
#IfMissingColumn form_encounter last_update
ALTER TABLE `form_encounter` ADD `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
#EndIf

#IfMissingColumn form_encounter ordering_provider_id
ALTER TABLE `form_encounter` ADD `ordering_provider_id` INT(11) DEFAULT '0' COMMENT 'ordering provider, if any, for this visit';
#EndIf
79 changes: 78 additions & 1 deletion src/Billing/Claim.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Claim
public $provider; // row from users table (rendering provider)
public $referrer; // row from users table (referring provider)
public $supervisor; // row from users table (supervising provider)
public $orderer; // row from users table (ordering provider)
public $insurance_numbers; // row from insurance_numbers table for current payer
public $supervisor_numbers;// row from insurance_numbers table for current payer
public $patient_data; // row from patient_data table
Expand Down Expand Up @@ -81,6 +82,7 @@ public function __construct($pid, $encounter_id, $x12_partner_id)
$this->procs[0]['payer_id'],
$this->encounter['supervisor_id']
);
$this->orderer = (new UserService())->getUser($this->getOrdererId());
}

public function getProcsAndDiags($pid, $encounter_id)
Expand Down Expand Up @@ -190,6 +192,17 @@ public function getReferrerId()
return $referrer_id;
}

public function getOrdererId(): string|int|null
{
if ($this->billing_options['provider_id'] ?? '') {
$orderer_id = $this->billing_options['provider_id'];
} elseif ($this->encounterService->getOrderingProviderID($this->pid, $this->encounter_id) ?? '') {
$orderer_id = $this->encounterService->getOrderingProviderID($this->pid, $this->encounter_id);
}

return $orderer_id ?? '';
}

// This enforces the X12 Basic Character Set. Page A2.
public function x12Clean($str)
{
Expand Down Expand Up @@ -1253,7 +1266,7 @@ public function cptUnits($prockey)
public function cptNDCID($prockey)
{
$ndcinfo = $this->procs[$prockey]['ndc_info'];
if (preg_match('/^N4(\S+)\s+(\S\S)(.*)/', $ndcinfo, $tmp)) {
if (preg_match('/^N4(\S+)\s+(\S\S)(.*)/', $ndcinfo ?? '', $tmp)) {
$ndc = $tmp[1];
if (preg_match('/^(\d+)-(\d+)-(\d+)$/', $ndc, $tmp)) {
return sprintf('%05d%04d%02d', $tmp[1], $tmp[2], $tmp[3]);
Expand Down Expand Up @@ -1831,4 +1844,68 @@ public function getLineItemAdjustments($aarr)

return $this->line_item_adjs;
}

public function ordererLastName()
{
return $this->x12Clean(trim($this->orderer['lname'] ?? ''));
}

public function ordererFirstName()
{
return $this->x12Clean(trim($this->orderer['fname']));
}

public function ordererMiddleName()
{
return $this->x12Clean(trim($this->orderer['mname']));
}

public function ordererNPI()
{
return $this->x12Clean(trim($this->orderer['npi']));
}

public function ordererUPIN()
{
return $this->x12Clean(trim($this->orderer['upin']));
}

public function ordererSSN()
{
return $this->x12Clean(trim(str_replace('-', '', $this->orderer['federaltaxid'])));
}

public function ordererTaxonomy()
{
if (empty($this->orderer['taxonomy'])) {
return '207Q00000X';
}

return $this->x12Clean(trim($this->orderer['taxonomy']));
}

public function ordererStreet()
{
return $this->x12Clean(trim($this->orderer['street']));
}

public function ordererStreetB()
{
return $this->x12Clean(trim($this->orderer['streetb']));
}

public function ordererCity()
{
return $this->x12Clean(trim($this->orderer['city']));
}

public function ordererState()
{
return $this->x12Clean(trim($this->orderer['state']));
}

public function ordererZip()
{
return $this->x12Clean(trim($this->orderer['zip']));
}
}
24 changes: 24 additions & 0 deletions src/Billing/MiscBillingOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,30 @@ public function genReferringProviderSelect($selname, $toptext, $default = 0, $di
echo "</select>\n";
}

public function genOrderingProviderSelect($selname, $toptext, $default = 0, $disabled = false)
{
$query = "SELECT id, lname, fname FROM users WHERE npi != '' ORDER BY lname, fname";
$res = sqlStatement($query);
echo "<select name='" . attr($selname) . "' id='" . attr($selname) . "' class='form-control'";
if ($disabled) {
echo " disabled";
}

echo ">";
echo "<option value=''>" . text($toptext);
while ($row = sqlFetchArray($res)) {
$provid = $row['id'];
echo "<option value='" . attr($provid) . "'";
if ($provid == $default) {
echo " selected";
}

echo ">" . text($row['lname'] . ", " . $row['fname']);
}

echo "</select>\n";
}

public function qual_id_to_description($qual_type, $value)
{
$options = $this->hcfa_date_quals[$qual_type];
Expand Down
17 changes: 16 additions & 1 deletion src/Billing/X125010837P.php
Original file line number Diff line number Diff line change
Expand Up @@ -1509,7 +1509,22 @@ public static function genX12837P(
// Segment NM1 (Loop 2420D Supervising Provider Name) omitted.
// Segment REF (Loop 2420D Supervising Provider Secondary Identification) omitted.

// Loop 2420E, Ordering Provider omitted.
// Loop 2420E, Ordering Provider
if ($claim->orderer ?? null) {
++$edicount;
$out .= "NM1" .
"*" . "DK" .
"*" . "1" .
"*" . $claim->ordererLastName() . '*' . $claim->ordererFirstName() .
"*" .
"*" .
"*" .
"*" . "XX" .
"*" . $claim->ordererNPI() . "~\n";
$out .= "N3" . "*" . $claim->ordererStreet() . "~\n";
$out .= "N4" . "*" . $claim->ordererCity() . "*" .
$claim->ordererState() . "*" . $claim->ordererZip() . "~\n";
}

// Segment NM1 (Referring Provider Name) omitted.
// Segment REF (Referring Provider Secondary Identification) omitted.
Expand Down
18 changes: 18 additions & 0 deletions src/Services/EncounterService.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ class.notes as class_title,
fe.provider_id,
fe.referring_provider_id,
fe.ordering_provider_id,
providers.provider_uuid,
providers.provider_username,
referrers.referrer_uuid,
Expand Down Expand Up @@ -249,6 +250,7 @@ class_code,
discharge_disposition,
pid as encounter_pid,
referring_provider_id,
ordering_provider_id,
last_update
FROM form_encounter
) fe
Expand Down Expand Up @@ -710,6 +712,22 @@ public function getReferringProviderID($pid, $encounter_id)
return [];
}

/**
* Returns the ordering provider for the encounter matching the patient and encounter identifier.
*
* @param $pid The legacy identifier of particular patient
* @param $encounter_id The identifier of a particular encounter
* @return string ordering provider of first row of encounter data (it's an id from the users table)
*/
public function getOrderingProviderID($pid, $encounter_id)
{
$encounterResult = $this->search(['pid' => $pid, 'eid' => $encounter_id], $options = ['limit' => '1']);
if ($encounterResult->hasData()) {
return $encounterResult->getData()[0]['ordering_provider_id'] ?? '';
}
return [];
}

/**
* Return an array of encounters within a date range
*
Expand Down

0 comments on commit a758a75

Please sign in to comment.