Skip to content

Commit

Permalink
feat: support loop 2420E
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenwaite committed Apr 24, 2024
1 parent a7a58d3 commit 963ff27
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 3 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_proivider_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::SHOW_ALL,
xl('Display the Ordering Provider option on Encounters'),
],
],
);

Expand Down
4 changes: 4 additions & 0 deletions sql/7_0_2-to-7_0_3_upgrade.sql
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,8 @@ ALTER TABLE `form_encounter` ADD `last_update` timestamp NOT NULL DEFAULT CURREN
#IfNotRow4D supported_external_dataloads load_type CQM_VALUESET load_source NIH_VSAC load_release_date 2023-05-04 load_filename ec_only_cms_20230504.xml.zip
INSERT INTO `supported_external_dataloads` (`load_type`, `load_source`, `load_release_date`, `load_filename`, `load_checksum`) VALUES
('CQM_VALUESET', 'NIH_VSAC', '2023-05-04', 'ec_only_cms_20230504.xml.zip', 'b77b3c2a88d23de0ec427c1cfc5088ce');
#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
1 change: 1 addition & 0 deletions sql/database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1905,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
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()
{
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 963ff27

Please sign in to comment.