public static function recalculateClaims(self $visit, $newClaim = false) { $fees = $visit->calculateFees(true); $hasProcedure = false; if ($newClaim) { $claimId = WebVista_Model_ORM::nextSequenceId('claimSequences'); } $copay = $visit->getCopay(); $totalPaid = 0; $personId = (int) $visit->patientId; $userId = (int) Zend_Auth::getInstance()->getIdentity()->personId; $visitId = (int) $visit->visitId; $discountPayerId = InsuranceProgram::lookupSystemId('Discounts'); // ID of System->Discounts $creditPayerId = InsuranceProgram::lookupSystemId('Credit'); // ID of System->Credit $payerId = InsuranceProgram::lookupSystemId('Self Pay'); // ID of System->Self Pay foreach ($fees['details'] as $id => $values) { // update claim or create if not exists $fee = (double) $values['fee']; $feeDiscounted = (double) $values['feeDiscounted']; $claimLine = new ClaimLine(); $claimLine->populateWithPatientProcedure($values['orm'], $visit); if ($newClaim) { $claimLine->claimLineId = 0; $claimLine->claimId = $claimId; } $claimLine->baseFee = $fee; $claimLine->adjustedFee = $feeDiscounted; $claimLine->persist(); $claimLineId = (int) $claimLine->claimLineId; $billable = $feeDiscounted; /*$discount = 0; if ($feeDiscounted > 0) $discount = $fee - $feeDiscounted; if ($discount < 0) $discount = 0;*/ $discount = (double) $values['writeoff']; if ($newClaim && $discount > 0) { // add writeoffs $writeOff = new WriteOff(); $writeOff->personId = $personId; $writeOff->claimLineId = $claimLineId; $writeOff->visitId = $visitId; $writeOff->appointmentId = $visit->appointmentId; $writeOff->amount = $discount; $writeOff->userId = $userId; $writeOff->timestamp = date('Y-m-d H:i:s'); $writeOff->title = 'discount'; $writeOff->payerId = $discountPayerId; $writeOff->persist(); $billable -= $discount; } if ($newClaim && $billable > 0) { foreach ($copay['details'] as $paymentId => $payment) { $amount = (double) $payment->unallocated; if (!$amount > 0) { unset($copay['details'][$paymentId]); continue; } if ($amount > $billable) { $amount = $billable; } $payment->allocated += $amount; $payment->payerId = $payerId; $payment->persist(); $copay['details'][$paymentId] = $payment; $totalPaid += $amount; $postingJournal = new PostingJournal(); $postingJournal->paymentId = (int) $payment->paymentId; $postingJournal->patientId = $personId; $postingJournal->payerId = $payerId; $postingJournal->claimLineId = $claimLineId; $postingJournal->visitId = $visitId; $postingJournal->amount = $amount; $postingJournal->note = 'copay posting'; $postingJournal->userId = $userId; $dateTime = date('Y-m-d H:i:s'); $postingJournal->datePosted = $dateTime; $postingJournal->dateTime = $dateTime; $postingJournal->persist(); $billable -= $amount; if ($billable <= 0) { break; } } } $hasProcedure = true; } if ($newClaim && $copay['total'] > $totalPaid) { // if copay is greater than all claimlines reamining dollars are posted to credit program foreach ($copay['details'] as $paymentId => $payment) { $amount = (double) $payment->unallocated; $payment->allocated += $amount; $payment->persist(); $postingJournal = new PostingJournal(); $postingJournal->paymentId = (int) $payment->paymentId; $postingJournal->patientId = $personId; $postingJournal->payerId = $creditPayerId; $postingJournal->visitId = $visitId; $postingJournal->amount = $amount; $postingJournal->note = 'remaining copay balance'; $postingJournal->userId = $userId; $dateTime = date('Y-m-d H:i:s'); $postingJournal->datePosted = $dateTime; $postingJournal->dateTime = $dateTime; $postingJournal->persist(); } } if (!$hasProcedure) { $visitId = $visit->visitId; $payment = new Payment(); foreach ($payment->getIteratorByVisitId($visitId) as $row) { // If visit has copay then at closing copay should be turned into unallocated payment (not associated with visit). $row->visitId = 0; $row->persist(); } } else { $visit = ClaimRule::checkRules($visit, $fees); } return $visit; }
public static function checkRules(Visit $visit, array $fees = array()) { if (!isset($fees['details'])) { $fees = $visit->calculateFees(true); } $visitId = (int) $visit->visitId; $payerId = (int) $visit->activePayerId; $procedures = null; $iterator = new ClaimRuleIterator(); foreach (self::listGroups() as $groupId => $values) { // TODO: use operators $matched = false; $iterator->setFilters(array('groupId' => $groupId)); foreach ($iterator as $claimRule) { $type = $claimRule->type; switch ($type) { case self::TYPE_PROCEDURE: case self::TYPE_DIAGNOSIS: if ($procedures === null) { $procedures = array(); $patientProcedureIterator = new PatientProcedureIterator(); $patientProcedureIterator->setFilters(array('visitId' => $visitId)); foreach ($patientProcedureIterator as $patientProcedure) { $procedures[] = $patientProcedure; } } $code = $claimRule->code; foreach ($procedures as $procedure) { if ($type == self::TYPE_PROCEDURE) { if ($procedure->code == $code) { $matched = true; break; } } else { for ($i = 1; $i <= 8; $i++) { $key = 'diagnosisCode' . $i; if ($procedure->{$key} == $code) { $matched = true; break 2; } } } } break; case self::TYPE_INSURANCE_PROGRAM: if ($claimRule->value == $payerId) { $matched = true; } break; case self::TYPE_MODIFIER: break; case self::TYPE_LINE_AMOUNT: break; case self::TYPE_CLAIM_TOTAL: break; } } if ($matched) { $visit->_claimRule = $values; } } return $visit; }
public function paymentReceiptAction() { // d96de46c-be90-45b0-b5f9-0b4abee76483 $referenceId = $this->_getParam('referenceId'); $personId = (int) $this->_getParam('personId'); $visitId = (int) $this->_getParam('visitId'); $data = $this->_getAttachmentData($referenceId); $patient = new Patient(); $patient->personId = $personId; if ($personId > 0) { $patient->populate(); } $person = $patient->person; $visit = new Visit(); $visit->visitId = $visitId; if ($visitId > 0) { $visit->populate(); } $practiceId = (int) $visit->practiceId; if (!$practiceId > 0) { $buildingId = (int) $visit->buildingId; if ($buildingId > 0) { $building = new Building(); $building->buildingId = $buildingId; $building->populate(); $practiceId = (int) $building->practiceId; } else { $roomId = (int) $visit->roomId; if ($roomId > 0) { $room = new Room(); $room->roomId = $roomId; $room->populate(); $practiceId = (int) $room->building->practiceId; } } } $practice = new Practice(); $practice->practiceId = $practiceId; if ($practiceId > 0) { $practice->populate(); } $primaryAddress = $practice->primaryAddress; $xml = new SimpleXMLElement('<data/>'); $xmlPractice = $xml->addChild('practice'); $this->_addChild($xmlPractice, 'name', $practice->name); $this->_addChild($xmlPractice, 'primaryLine1', $primaryAddress->line1); $primaryCityStateZip = $primaryAddress->city . ' ' . $primaryAddress->state . ' ' . $primaryAddress->postalCode; $this->_addChild($xmlPractice, 'primaryCityStateZip', $primaryCityStateZip); $this->_addChild($xmlPractice, 'mainPhone', $practice->mainPhone->number); $xmlPatient = $xml->addChild('patient'); $name = $person->firstName . ' ' . $person->middleName . ' ' . $person->lastName; $this->_addChild($xmlPatient, 'name', $name); $addresses = Address::listAddresses($personId); if (isset($addresses[Address::TYPE_BILLING])) { $address = $addresses[Address::TYPE_BILLING]; } else { if (isset($addresses[Address::TYPE_HOME])) { $address = $addresses[Address::TYPE_HOME]; } else { if (isset($addresses[Address::TYPE_MAIN])) { $address = $addresses[Address::TYPE_MAIN]; } else { if (isset($addresses[Address::TYPE_SEC])) { $address = $addresses[Address::TYPE_SEC]; } else { if (isset($addresses[Address::TYPE_OTHER])) { $address = $addresses[Address::TYPE_OTHER]; } else { $address = array_pop($addresses); } } } } } $billingCityStateZip = $address->city . ' ' . $address->state . ' ' . $address->postalCode; $this->_addChild($xmlPatient, 'billingLine1', $address->line1); $this->_addChild($xmlPatient, 'billingCityStateZip', $billingCityStateZip); $iterator = new PatientProcedureIterator(); $iterator->setFilters(array('visitId' => $visitId)); $procedures = array(); foreach ($iterator as $row) { $procedures[] = $row->code; } $iterator = new PatientDiagnosisIterator(); $iterator->setFilters(array('visitId' => $visitId)); $diagnoses = array(); foreach ($iterator as $row) { $diagnoses[] = $row->code; } $xmlNotes = $xmlPatient->addChild('notes'); $note = implode(',', $procedures) . " \t " . implode(',', $diagnoses) . " \t " . date('m/d/y', strtotime($visit->dateOfTreatment)); $this->_addChild($xmlNotes, 'note', $note); $today = date('Y-m-d'); $todaysTotal = 0; $iterator = new PaymentIterator(); $iterator->setFilters(array('visitId' => $visitId, 'company' => 'System', 'paymentDate' => $today)); $payments = array(); foreach ($iterator as $row) { $payments[] = $row; } $iterator->setFilters(array('personId' => $personId, 'unallocated' => true, 'paymentDate' => $today)); foreach ($iterator as $row) { $payments[] = $row; } foreach ($payments as $row) { $xmlPayment = $xmlPatient->addChild('payments'); $paymentDate = date('m/d/y', strtotime($row->paymentDate)); $this->_addChild($xmlPayment, 'date', $paymentDate); $this->_addChild($xmlPayment, 'description', $row->title . ' .... Thank You'); $this->_addChild($xmlPayment, 'method', $row->paymentType); $amount = (double) $row->amount; $todaysTotal += $amount; $this->_addChild($xmlPayment, 'amount', '-' . number_format($amount, 2)); $this->_addChild($xmlPayment, 'insurance', $row->insuranceDisplay); } $fees = $visit->calculateFees(); $previousBalance = $fees['total']; $this->_addChild($xmlPatient, 'previousBalance', number_format($previousBalance, 2)); $this->_addChild($xmlPatient, 'todaysTotal', '-' . number_format($todaysTotal, 2)); $totalDue = $previousBalance - $todaysTotal; $this->_addChild($xmlPatient, 'totalDue', number_format($totalDue, 2)); $totalDueFromPatient = $previousBalance; $this->_addChild($xmlPatient, 'totalDueFromPatient', number_format($totalDueFromPatient, 2)); try { $content = ReportBase::mergepdfset($xml, $data); $this->getResponse()->setHeader('Content-Type', 'application/pdf'); } catch (Exception $e) { $content = '<script>alert("' . $e->getMessage() . '")</script>'; } $this->view->content = $content; $this->render('binary-template'); }
public function listCodesAction() { $claimId = (int) $this->_getParam('claimId'); $visitId = (int) $this->_getParam('visitId'); $rows = array(); $visit = new Visit(); $visit->visitId = $visitId; $visit->populate(); $fees = $visit->calculateFees(); foreach ($fees['details'] as $patientProcedureId => $values) { $patientProcedure = $values['orm']; $claimLine = $patientProcedure->claimLine; $fee = $values['fee']; $feeDiscounted = $values['feeDiscounted']; $paid = $claimLine->totalPaid($claimId); $writeoff = $claimLine->totalWriteOff($claimId); $carry = $fee - ($paid + $writeoff); $row = array(); $row['id'] = $patientProcedureId; $row['data'] = array(); $row['data'][] = $claimLine->procedureCode . ' : ' . $claimLine->procedure; $row['data'][] = abs($fee); $row['data'][] = ''; $row['data'][] = ''; $row['data'][] = abs($carry); $row['data'][] = abs($paid); $row['data'][] = abs($writeoff); $rows[] = $row; } $json = Zend_Controller_Action_HelperBroker::getStaticHelper('json'); $json->suppressExit = true; $json->direct(array('rows' => $rows)); }