Files
streamline-emr/docker/streamline-src/app/Http/Helpers/Functions.php
T
alec.turner a424394109 Build modified streamline images
The official image from streamline does not currently work for the arm64
platform. As a temporary measure, the source code and docker build scripts
have been lifted from the official images and are used to build locally.

Some additional modifications are made to reduce overall image size, these
are documented in docker/README.md
2024-03-10 16:17:50 -07:00

7661 lines
343 KiB
PHP
Executable File

<?php
use AfricasTalking\SDK\AfricasTalking;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Streamline\Models\AnteNatalClinicRegistration;
use Streamline\Models\Banking;
use Streamline\Models\ChartOfAccount;
use Streamline\Models\ChronicPatient;
use Streamline\Models\Consultation;
use Streamline\Models\Dental;
use Streamline\Models\DependantsConsumption;
use Streamline\Models\DischargeMortalityRisk;
use Streamline\Models\Donors;
use Streamline\Models\Drug;
use Streamline\Models\FamilyAccount;
use Streamline\Models\FamilyAccountConsumption;
use Streamline\Models\GeneralItem;
use Streamline\Models\GeneralSettings;
use Modules\WardManagement\Http\Controllers\InpatientController;
use Streamline\Models\InpatientBedCategory;
use Streamline\Models\InpatientInfo;
use Streamline\Models\InsuranceClaim;
use Streamline\Models\InsuranceMemberConsumption;
use Streamline\Models\InsuranceSubscription;
use Streamline\Models\Lab;
use Streamline\Models\OrderedService;
use Streamline\Models\Patient;
use Streamline\Models\PatientAccountConsumption;
use Streamline\Models\PatientDiscount;
use Streamline\Models\PatientEpisode;
use Streamline\Models\PriceListCategories;
use Streamline\Models\Radiology;
use Streamline\Models\StaffPaymentConfiguration;
use Streamline\Models\StaffPerformedService;
use Streamline\Models\StockWatcher;
use Streamline\Models\Sundry;
use Streamline\Models\TrackInvoice;
use Streamline\Models\TrackReceipt;
use Streamline\Models\User;
use Streamline\Models\Investigation;
use Streamline\Models\Procedure;
use Streamline\Models\Services;
use Illuminate\Support\Facades\Auth;
use Streamline\Models\DebtPlan;
use Streamline\Models\InpatientBill;
use Streamline\Models\InpatientWardDiscounts;
use Streamline\Models\InvestigationResults;
use Streamline\Models\OrderedInvestigation;
use Streamline\Models\OrderedProcedure;
use Streamline\Models\OrderedSundry;
use Streamline\Models\PatientCategoryInvoice;
use Streamline\Models\ServiceDeposit;
use Streamline\Models\Treatment;
use Streamline\Models\WardBedStay;
use Streamline\Models\WardConsultationsAndService;
use Streamline\Models\WardInvestigationPricing;
use Streamline\Models\WardProcedure;
use Streamline\Models\WardSundryDispensation;
use Streamline\Models\WardTreatmentDispensation;
use Streamline\Models\BatchStockWatcher;
function get_name($id, $id_column, $name_column, $table) {
$result = DB::table($table)->where($id_column, $id)->first();
if (!$result) {
return 'N/A';
} else {
return $result->$name_column;
}
}
function split_string($string, $position) {
$arr = explode(",", $string);
return $arr[$position];
}
function is_patient_category_pay_later($category_id) {
$category = \Streamline\Models\PatientDiscount::where('patient_category', $category_id)->first();
if (!is_null($category) && $category->pay_later == 1) {
return true;
} else {
return false;
}
}
function get_claim_number($episode_id) {
$episode = \Streamline\Models\PatientEpisode::find($episode_id);
if ($episode) {
return $episode->claim_number;
} else {
return "";
}
}
function get_clinic_name($episode_id) {
$episode = PatientEpisode::find($episode_id);
if ($episode) {
if ($episode->clinic_id == 0) {
return "OPD";
} else {
return is_null($episode->clinic_id) ? "N/A" : get_name($episode->clinic_id, 'id', 'name', 'clinics');
}
}
return "";
}
function patient_category($patient_id)
{
$category_id = get_name($patient_id, "id", "category_id", "patients");
$category_name = get_name($category_id, "id", "name", "patient_categories");
return $category_name;
}
function get_ward_name($patient_id, $episode_id)
{
$inpatient_info = InpatientInfo::where(['inpatient_info.patient_id' => $patient_id])
->where(['inpatient_info.episode_id' => $episode_id])
->first();
if ($inpatient_info) {
return get_name($inpatient_info->ward_id, 'id', 'name', 'wards');
} else {
return "N/A";
}
}
function get_discount_tracking_expense_account($patient_category)
{
$patient_discount = PatientDiscount::where('patient_category', $patient_category)->first();
if ($patient_discount) {
return $patient_discount->tracking_expense_account;
} else {
return null;
}
}
function patient_insurance_status_old($patient_id): int {
if (!is_chi_enabled()) {
return 0;
}
$patient_details = DB::table('patients')
->leftJoin('insurance_members', 'insurance_members.patient_id', '=', 'patients.id')
->leftJoin('insurance_subscriptions', 'insurance_subscriptions.group_id', '=', 'insurance_members.group_id')
->where('patients.id', $patient_id)->orderBy('insurance_subscriptions.end_date', 'desc')
->first(['patients.insurance_status', 'patients.first_name', 'patients.last_name', 'insurance_members.id as insurance_member_id',
'insurance_members.group_id', 'insurance_subscriptions.end_date', 'insurance_subscriptions.covered_member_ids', 'insurance_subscriptions.covered_member_premiums_paid']);
//get insurance status
$insured = $patient_details->insurance_status ?? 0;
if ($insured != 1 || is_null($patient_details->insurance_member_id)) {
return 0;
}
$amount_paid = 0;
$insurance_status = 0;
// check if the date is still valid
if (!is_null($patient_details->end_date) && date('Y-m-d') < $patient_details->end_date) {
$insurance_status = 1;
//get amount paid by family
$covered_members_array = explode(",", $patient_details->covered_member_ids);
$covered_member_premiums_array = explode(",", $patient_details->covered_member_premiums_paid);
$key = array_search($patient_details->insurance_member_id, $covered_members_array);
if ($key !== false) {
$amount_paid = $covered_member_premiums_array[$key] ?? 0;
}
}
if ($insurance_status == 1 && $amount_paid > 0) {
return 1; // member with green flag
} else {
return 2; // member with red flag
}
}
function patient_insurance_status($patient_id): int {
if (!is_chi_enabled()) {
return 0;
}
$patient_details = DB::table('patients')
->leftJoin('insurance_members', 'insurance_members.patient_id', '=', 'patients.id')
->where('patients.id', $patient_id)
->first(['patients.insurance_status', 'insurance_members.current_insurance_end_date', 'insurance_members.current_insurance_amount_paid', 'insurance_members.id as insurance_member_id']);
//get insurance status
$insured = $patient_details->insurance_status ?? 0;
if ($insured != 1 || is_null($patient_details->insurance_member_id)) {
return 0;
}
if (!is_null($patient_details->current_insurance_end_date) && date('Y-m-d') < $patient_details->current_insurance_end_date &&
!(is_null($patient_details->current_insurance_amount_paid)) && $patient_details->current_insurance_amount_paid > 0) {
return 1; // member with green flag
} else {
return 2; // member with red flag
}
}
/**
* Check if patient was insured on the pay date
*
* @param int $patient_id - the patient id
* @param mixed $pay_date - the pay date
* @return boolean
*/
function patient_was_insured($patient_id, $pay_date) {
$pay_date = date("Y-m-d", strtotime($pay_date));
$patient_details = DB::table('insurance_members')->where('patient_id', $patient_id)->first();
if ($patient_details) {
$insurance_subscriptions = DB::table('insurance_subscriptions')->where('group_id', $patient_details->group_id)->orderBy('id', 'desc')->get();
foreach ($insurance_subscriptions as $record) {
$insurance_start_date = $record->start_date;
$insurance_end_date = $record->end_date;
if ($insurance_start_date < $pay_date && $insurance_end_date > $pay_date) {
$covered_members_array = explode(",", $record->covered_member_ids);
$covered_member_premiums_array = explode(",", $record->covered_member_premiums_paid);
$key = array_search($patient_details->id, $covered_members_array);
if ($key !== false) {
$amount_paid = $covered_member_premiums_array[$key] ?? 0;
if ($amount_paid > 0) {
return true;
}
}
}
}
}
return false;
}
function subtractDates($date_s, $subtractNumber)
{
$date = date_create($date_s);
date_sub($date, date_interval_create_from_date_string($subtractNumber));
return date_format($date, 'Y-m-d');
}
//insurance flag for insurance members
function insurance_flag($patient_id) {
$patient_details = DB::table('patients')->where('id', $patient_id)->first(['first_name', 'last_name']);
if ($patient_details) {
//get names and convert to lower case ucwords
$patient_name = ucwords(strtolower($patient_details->first_name . " " . $patient_details->last_name));
$insurance_status = patient_insurance_status($patient_id);
$non_insured_flag = asset('uploads/insurance_flags/non_insured.png');
$insured_flag = asset('uploads/insurance_flags/insured.png');
if ($insurance_status == 1) {
return $patient_name . '<sup><img src="' . $insured_flag . '" alt="Insured" /></sup>';
} elseif ($insurance_status == 2) {
return $patient_name . '<sup><img src="' . $non_insured_flag . '" alt="Expired Insurance" /></sup>';
} else {
return $patient_name;
}
} else {
return "";
}
}
function is_serialized($data, $strict = true)
{
// if it isn't a string, it isn't serialized.
if (!is_string($data)) {
return false;
}
$data = trim($data);
if ('N;' == $data) {
return true;
}
if (strlen($data) < 4) {
return false;
}
if (':' !== $data[1]) {
return false;
}
if ($strict) {
$lastc = substr($data, -1);
if (';' !== $lastc && '}' !== $lastc) {
return false;
}
} else {
$semicolon = strpos($data, ';');
$brace = strpos($data, '}');
// Either ; or } must exist.
if (false === $semicolon && false === $brace) {
return false;
}
// But neither must be in the first X characters.
if (false !== $semicolon && $semicolon < 3) {
return false;
}
if (false !== $brace && $brace < 4) {
return false;
}
}
$token = $data[0];
switch ($token) {
case 's':
if ($strict) {
if ('"' !== substr($data, -2, 1)) {
return false;
}
} elseif (false === strpos($data, '"')) {
return false;
}
// or else fall through
case 'a':
case 'O':
return (bool) preg_match("/^{$token}:[0-9]+:/s", $data);
case 'b':
case 'i':
case 'd':
$end = $strict ? '$' : '';
return (bool) preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
}
return false;
}
// check if insurance group's subscription is upto date
function check_insurance_group_status($group_id)
{
$insurance_subscription = InsuranceSubscription::where('group_id', $group_id)->orderBy('id', 'desc')->first();
if ($insurance_subscription) {
$startDate = $insurance_subscription->start_date;
$endDate = $insurance_subscription->end_date;
//check insurance status at this point
if (date('Y-m-d') < $endDate) {
$result = 1;
} else {
$result = 0;
}
return $result . "/" . $startDate . "/" . $endDate;
} else {
return "0/NA/NA";
}
}
// check if insurance group's subscription is upto date
function check_insurance_family_status($group_id, $family_id)
{
$insurance_subscription = InsuranceSubscription::where('group_id', $group_id)->orderBy('id', 'desc')->first();
if (isset($insurance_subscription) && !is_null($insurance_subscription)) {
$startDate = $insurance_subscription->start_date;
$endDate = $insurance_subscription->end_date;
$family_paid = explode(",", $insurance_subscription->family_heads);
$family_amount = explode(",", $insurance_subscription->family_amount);
if (array_search($family_id, $family_paid)) {
$keySearch = array_search($family_id, $family_paid);
$amount_paid = $family_amount[$keySearch];
} else {
$amount_paid = 0;
}
//check insurance status at this point
if (date('Y-m-d') < $endDate) {
$result = 1;
} else {
$result = 0;
}
return $result . "/" . $startDate . "/" . $endDate . "/" . $amount_paid;
} else {
return "0/NA/NA/0";
}
}
// will return a currency formatting e.g. 55,000 UGX
function ugandan_shillings($value): string{
try {
$value = number_format($value);
} catch (Error|Exception $e) { $value = 0; }
return $value . " " . get_name(1, 'id', 'currency_code', 'general_settings');
}
function ugandan_shillings_with_decimals($value): string{
try {
if(is_string($value)){
$value = floatval($value);
}
if(fmod($value, 1) !== 0.0000){
// your code if its decimals has a value
$value = number_format($value, 2);
} else {
// your code if the decimals are .00, or is an integer
$value = number_format($value);
}
} catch (Error|Exception $e) { $value = 0; }
return $value . " " . get_name(1, 'id', 'currency_code', 'general_settings');
}
function commas($value) {
try {
$value = number_format($value);
} catch (Error|Exception $e) { $value = 0; }
return $value;
}
//Returns the date in an english formatted manner. eg 24th January 2016
function streamline_date($date) {
try {
$create_date = date_create($date);
$new_date = date_format($create_date, 'l, jS M Y');
} catch (Error|Exception $exception) {
return "N/A";
}
return $new_date;
}
//Returns the date in an english formatted manner. eg 24-01-2016
function streamline_date_plain($date) {
try {
$create_date = date_create($date);
return date_format($create_date, 'd-m-Y');
} catch (Error|Exception $exception) {
return "N/A";
}
}
//Returns the date in an english formatted manner but this time with the specific time. eg 24th January 2016 at 09:00 am
function streamline_date_time($date) {
try {
$create_date = date_create($date);
return date_format($create_date, 'l, jS F Y \a\t g:ia');
} catch (Error|Exception $exception) {
return "N/A";
}
}
//Returns the time from a datetime eg 09:00am
function streamline_time($date) {
try {
$create_date = date_create($date);
return date_format($create_date, 'g:ia');
} catch (Error|Exception $exception) {
return "N/A";
}
}
//Returns the date in an english formatted manner eg 24 jan 16 at 09:00am
function streamline_date_time_short($date) {
try {
$create_date = date_create($date);
return date_format($create_date, 'jS M y \a\t g:ia');
} catch (Error|Exception $exception) {
return "N/A";
}
}
function get_audit_trail_action_description($auditableType, $userId, $auditableId, $url, $event, $recordAffected)
{
if ($auditableType === "Streamline\Models\User") {
if ($userId === $auditableId && str_contains($url, 'login')) {
return get_full_name($userId, 'id', 'first_name', 'last_name', 'users') . ' logged into their account';
}
if ($userId !== $auditableId && !str_contains($url, 'login')) {
$user = get_full_name($userId, 'id', 'first_name', 'last_name', 'users');
$updatedUser = get_full_name($auditableId, 'id', 'first_name', 'last_name', 'users');
return $user . ' updated account of ' . $updatedUser;
}
}
$user = get_full_name($userId, 'id', 'first_name', 'last_name', 'users');
return $user . ' ' . $event . ' ' . __('audit_trail.a') . ' ' . $recordAffected . ' ' . __('audit_trail.record');
}
function format_audit_trail_values($audit, $valuesType)
{
$values = $valuesType === 'old' ? $audit->old_values : $audit->new_values;
if ($values && $audit->auditable_type !== "Streamline\Models\User") {
$output = '<span style="color:blue">';
$output .= read_more(json_encode($values), 'comments_short' . $audit->id, 'comments_long' . $audit->id);
$output .= '<div id="comments_long' . $audit->id . '" style="display: none;">';
$output .= json_encode($values) . '<br />';
$output .= '<a class="read_more" style="color: #0099CC;" onclick="hide(\'comments_long' . $audit->id . '\');show(\'comments_short' . $audit->id . '\');">';
$output .= __('patient_episode.read_less') . '</a>';
$output .= '</div>';
$output .= '</span>';
} else {
$output = '';
}
return $output;
}
function group_amount_sum($id)
{
$sum = DB::table('insurance_subscriptions')
->where('group_id', $id)
->sum('amount');
return $sum;
}
function group_amount_sum_period($id, $start, $end)
{
$sum = DB::table('insurance_subscriptions')
->where('group_id', $id)
->whereBetween('payment_date', [DATE($start), DATE($end)])
->sum('amount');
return $sum;
}
function generateReceiptNumberFromDB($reason = "N/A")
{
// track the receipt
$track_receipt = new TrackReceipt();
$track_receipt->reason = $reason;
$track_receipt->created_by = auth()->user()->id;
$track_receipt->save();
$receipt_number = sprintf("%04u", $track_receipt->id);
return $receipt_number;
}
function generateInvoiceNumberFromDB($reason = "N/A")
{
// track the invoice
$track_invoice = new TrackInvoice();
$track_invoice->reason = $reason;
$track_invoice->created_by = auth()->user()->id;
$track_invoice->save();
$invoice_number = sprintf("%04u", $track_invoice->id);
return $invoice_number;
}
function quadLimit($number)
{
$new_number = sprintf("%04d", $number);
return $new_number;
}
function removeSpaces($string)
{
$myString = str_replace(' ', '', $string);
return $myString;
}
function calcDate($date, $interval)
{
$dateCalc = date_create($date);
date_add($dateCalc, date_interval_create_from_date_string($interval));
return date_format($dateCalc, 'Y-m-d');
}
function convert_number_to_words($number)
{
$hyphen = '-';
$conjunction = ' and ';
$separator = ', ';
$negative = 'negative ';
$decimal = ' point ';
$dictionary = array(
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
10 => 'ten',
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
20 => 'twenty',
30 => 'thirty',
40 => 'fourty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety',
100 => 'hundred',
1000 => 'thousand',
1000000 => 'million',
1000000000 => 'billion',
1000000000000 => 'trillion',
1000000000000000 => 'quadrillion',
1000000000000000000 => 'quintillion',
);
if (!is_numeric($number)) {
return false;
}
if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) {
// overflow
trigger_error(
'convert_number_to_words only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX,
E_USER_WARNING
);
return false;
}
if ($number < 0) {
return $negative . convert_number_to_words(abs($number));
}
$string = $fraction = null;
if (strpos($number, '.') !== false) {
list($number, $fraction) = explode('.', $number);
}
switch (true) {
case $number < 21:
$string = $dictionary[$number];
break;
case $number < 100:
$tens = ((int) ($number / 10)) * 10;
$units = $number % 10;
$string = $dictionary[$tens];
if ($units) {
$string .= $hyphen . $dictionary[$units];
}
break;
case $number < 1000:
$hundreds = $number / 100;
$remainder = $number % 100;
$string = $dictionary[$hundreds] . ' ' . $dictionary[100];
if ($remainder) {
$string .= $conjunction . convert_number_to_words($remainder);
}
break;
default:
$baseUnit = pow(1000, floor(log($number, 1000)));
$numBaseUnits = (int) ($number / $baseUnit);
$remainder = $number % $baseUnit;
$string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit];
if ($remainder) {
$string .= $remainder < 100 ? $conjunction : $separator;
$string .= convert_number_to_words($remainder);
}
break;
}
if (null !== $fraction && is_numeric($fraction)) {
$string .= $decimal;
$words = array();
foreach (str_split((string) $fraction) as $number) {
$words[] = $dictionary[$number];
}
$string .= implode(' ', $words);
}
return $string;
}
function read_more($string, $short_id, $long_id, $limit = "25")
{
// strip tags to avoid breaking any html
$string = strip_tags($string);
if (strlen($string) > $limit) {
// truncating the string
$original_string = $string;
$stringCut = substr($string, 0, $limit);
// make sure it ends in a word so assassinate doesn't become ass... hehe
$string = "<div id='" . $short_id . "'>" . $stringCut . ' ... <a class="read_more" onclick= "show(\'' . $long_id . '\');hide(\'' . $short_id . '\')" style="color:#0099CC;">Read More</a></div>';
}
return $string;
}
function get_all_first($columns, $table)
{
$result = DB::table($table)->where($columns)->first();
if (!$result) {
return 'N/A';
} else {
return $result;
}
}
function get_full_name($id, $id_column, $name_column1, $name_column2, $table)
{
$result = DB::table($table)->where($id_column, $id)->first();
if ($id == 'ALL STAFF') {
return 'ALL STAFF';
}
if (!$result) {
return 'N/A';
} else {
return $result->$name_column1 . ' ' . $result->$name_column2;
}
}
function getIdName($current_id, $column_id, $column_name, $table)
{
$result = DB::table($table)
->where($column_id, $current_id)
->pluck($column_name)
->toArray();
return $result;
}
function get_all($columns, $table)
{
$result = DB::table($table)->where($columns);
if (!$result) {
return 'N/A';
} else {
return $result;
}
}
//Function to check if a value exists in a range of numbers
function between($currentValue, $low, $high)
{
if ($currentValue < $low):
return false;
elseif ($currentValue > $high):
return false;
else:
return true;
endif;
}
//This will return an array containing the days , months, years between two dates
function days_months_years($startDate, $endDate)
{
$o_month = substr($startDate, 5, 2);
$o_day = substr($startDate, 8, 2);
$o_year = substr($startDate, 0, 4);
$n_month = substr($endDate, 5, 2);
$n_day = substr($endDate, 8, 2);
$n_year = substr($endDate, 0, 4);
if ($o_day > $n_day):
$r_days = 30 + ($n_day - $o_day);
$o_month++;
else:
$r_days = $n_day - $o_day;
endif;
if ($o_month > $n_month):
$r_month = 12 + ($n_month - $o_month);
$o_year++;
else:
$r_month = $n_month - $o_month;
endif;
$r_year = $n_year - $o_year;
$difference = array($r_days, $r_month, $r_year);
return $difference;
}
//assigned custom colors for the different triage grades
function severe_grade($grade)
{
if ($grade == 1):
$code = '<span style="color: green" >' . __('triage.green') . '</span>';
elseif ($grade == 3):
$code = '<span style="color: red" >' . __('triage.red') . '</span>';
elseif ($grade == 2):
$code = '<span style="color: #FFD700;" >' . __('triage.yellow') . '</span>';
else:
$code = '<span style="font-size: x-small" ><i>N/A</i></span>';
endif;
return $code;
}
// remove seconds from the time stamp date
function removeSeconds($timeStampDate)
{
$explodeDate = explode(" ", $timeStampDate);
$explodeTime = explode(":", $explodeDate[1]);
$explodeDateOnly = explode("-", $explodeDate[0]);
$formatNewDate = "Date: " . $explodeDateOnly[2] . "/" . $explodeDateOnly[1] . "/" . $explodeDateOnly[0] . " Time: " . $explodeTime[0] . ":" . $explodeTime[1];
return $formatNewDate;
}
/*
*function to get column value of a specific where condition
*/
function getTableInfo($tablename, $column_to_return, $where_condition)
{
$sql = "select $column_to_return as alias from $tablename where $where_condition";
$results = DB::select($sql);
$result = isset($results[0]) ? $results[0]->alias : "";
return $result;
}
// Reordering date before insertion into database from 31-05-2010 to 2010-05-31
function reorderDate($date)
{
$dateArray = explode('-', $date);
$reorderedDate = $dateArray[2] . '-' . $dateArray[1] . '-' . $dateArray[0];
return $reorderedDate;
}
//clean entered string input
function clean($str)
{
$str = @trim($str);
$str = stripslashes($str);
return $str;
}
//function to get the patient name from patient_id
function get_patient_name($id)
{
$patient = Patient::find($id);
return $patient->first_name . ' ' . $patient->last_name;
}
function get_donor_name($id)
{
$patient = Donors::find($id);
return $patient->name;
}
//function to get the patient number from patient_id
function get_patient_number($id)
{
$patient = Patient::withTrashed()->find($id);
return $patient->number;
}
//Generate the drug supplier name and address plus phone number
function supplier_address($supplier_id)
{
$address = get_name($supplier_id, "id", "name", "suppliers") . "<br />"
. get_name($supplier_id, "id", "mobile_number", "suppliers") . "<br />" .
get_name($supplier_id, "id", "address", "suppliers");
return $address;
}
function patient_residence($patient_id)
{
$patient = Patient::find($patient_id);
$return_array = [];
$district = get_name($patient->district_id, "id", "name", "districts");
if ($district != "N/A"){
$return_array[] = $district ;
}
$parish = get_name($patient->parish_id, "id", "name", "parishes");
if ($parish != "N/A"){
$return_array[] = $parish ;
}
$subcounty = get_name($patient->subcounty_id, "id", "name", "subcounties");
if ($subcounty != "N/A"){
$return_array[] = $subcounty ;
}
$village = get_name($patient->village_id, "id", "name", "villages");
if ($village != "N/A"){
$return_array[] = $village ;
}
return implode( ", " , $return_array);
}
// Return the days out of stock for an inventory item
function days_out_of_stock($item_id, $from_date, $to_date)
{ // Dates in "Y-m-d" format
$days_out_of_stock = 0;
$query_stock_dates = "SELECT out_of_stock_date, restock_date FROM inventory_stock_dates WHERE item_id = $item_id AND out_of_stock_date BETWEEN '{$from_date}' AND '{$to_date}'";
$stock_dates_results = DB::select($query_stock_dates);
foreach ($stock_dates_results as $result) {
$start_date = ($result->out_of_stock_date != '0000-00-00') ? $result->out_of_stock_date : $from_date;
$end_date = ($result->restock_date != '0000-00-00') ? date("Y-m-d", strtotime($result->restock_date . "+1 days")) : $to_date;
$start_date = date_create($start_date);
$end_date = date_create($end_date);
$date_diff = date_diff($start_date, $end_date);
$total_days = $date_diff->format("%R%a");
if ($total_days >= 0) {
$days_out_of_stock += $total_days;
}
}
return $days_out_of_stock;
}
function custom_search_array_like($needle, $haystack)
{
foreach ($haystack as $item) {
if (strpos($item, $needle) !== false) {
return $item;
break;
}
}
}
// function for populating selects with default as passed id
function custom_dropdown_selected($table_name, $value_column, $name_column, $id, $full_where_clause = "")
{
$query = "select " . $value_column . "," . $name_column . " from " . $table_name . $full_where_clause . " order by " . $name_column . " asc";
$results = DB::select($query);
$custom_dropdown = "<option>-- Select --</option>";
if (count($results) > 0) {
foreach ($results as $result) {
if ($result->$value_column == $id) {
$custom_dropdown .= "<option value='" . $result->$value_column . "' selected>" . ucwords($result->$name_column) . "</option>";
} else {
$custom_dropdown .= "<option value='" . $result->$value_column . "'>" . ucwords($result->$name_column) . "</option>";
}
}
}
return $custom_dropdown;
}
function is_donor_feature_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->donor_feature == 1) {
return true;
} else {
return false;
}
}
function is_sms_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->enable_sms == 1) {
return true;
} else {
return false;
}
}
function get_ward_prescription_model()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->ward_prescription_model;
}
/**
* Check if patient category is attached to price list, if yes return
* the id for the price list else return false
*
* @param $patient_id
* @return mixed
*/
function is_patient_category_attached_to_price_list($patient_id)
{
// get patient category id
$patient_category_id = get_name($patient_id, 'id', 'category_id', 'patients');
if ($patient_category_id != 'N/A') {
// check if the patient category is available in the price list table
$price_list = \Streamline\Models\PriceListCategories::where('patient_category_id', $patient_category_id)->first();
if ($price_list) {
return $price_list->id;
} else {
return false;
}
} else {
return false;
}
}
function get_price_list_category_price($price_list_category_id, $item_category, $item_id)
{
$item_price = 0;
switch ($item_category) {
case 2:
$item = Investigation::find($item_id);
break;
case 3:
$item = Drug::find($item_id);
break;
case 4:
$item = Procedure::find($item_id);
break;
case 5:
$item = Sundry::find($item_id);
break;
case 6:
$item = Services::find($item_id);
break;
default:
$item = false;
}
if ($item){
$price_list_category = !isset($item->price_list_category) ? [] : explode(',', $item->price_list_category);
$price_list_price = !isset($item->price_list_price) ? [] : explode(',', $item->price_list_price);
$key = array_search($price_list_category_id, $price_list_category);
if (isset($price_list_price[$key]) && ($key || $key === 0) && is_numeric($price_list_price[$key])) {
$item_price = $price_list_price[$key];
} else {
$item_price = $item->non_insured_price;
}
}
return $item_price;
}
function get_chi_price_list_category_price($price_list_category_id, $item_category, $item_id) {
$item_price = 0;
switch ($item_category){
case 2:
$item = Investigation::find($item_id);
break;
case 3:
$item = Drug::find($item_id);
break;
case 4:
$item = Procedure::find($item_id);
break;
case 5:
$item = Sundry::find($item_id);
break;
case 6:
$item = Services::find($item_id);
break;
default:
$item = false;
}
if ($item){
$price_list_category = !isset($item->price_list_category) ? [] : explode(',', $item->price_list_category);
$chi_price_list_price = !isset($item->chi_price_list_price) ? [] : explode(',', $item->chi_price_list_price);
$key = array_search($price_list_category_id, $price_list_category);
if (isset($chi_price_list_price[$key]) && ($key || $key === 0) && is_numeric($chi_price_list_price[$key])) {
$item_price = $chi_price_list_price[$key];
} else {
$item_price = $item->non_insured_price;
}
}
return $item_price;
}
function can_price_list_pay_later($price_list_id)
{
$price_list = \Streamline\Models\PriceListCategories::find($price_list_id);
if ($price_list) {
// check if patient category is available in the discounts table with a pay later
$discount = \Streamline\Models\PatientDiscount::where(['patient_category' => $price_list->patient_category_id])->first();
if ($discount && $discount->pay_later == 1 && $price_list->pay_for_invoice == 1) {
return true;
} else {
return false;
}
} else {
return false;
}
}
function get_drug_name($id)
{
$drug = DB::table('drugs')->find($id);
if (show_drug_brand_name() && !is_null($drug->brand_name)) {
return $drug->name . " (" . $drug->brand_name . ")";
} else {
return isset($drug->name) ? $drug->name : " ";
}
}
function show_drug_brand_name()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->show_drug_brand_name == 1) {
return true;
} else {
return false;
}
}
function save_new_cost_of_good($item_id, $item_category_id, $cost_price) {
//$item_category_id i.e 1-Drug, 2-Sundry, 3-dentals, 4-radiologies, 5-labs, 6-general_items'
$cost_of_good = new \Streamline\Models\CostOfGood;
$cost_of_good->item_category = $item_category_id; //drug
$cost_of_good->item_id = $item_id;
$cost_of_good->cost_price = $cost_price;
$cost_of_good->created_by = auth()->user()->id;
$cost_of_good->save();
//update the respective tables
if ($item_category_id == 1) {
//update drugs table
$drug = Drug::withTrashed()->find($item_id);
$drug->cost_price = $cost_price;
$drug->update();
} elseif ($item_category_id == 2) {
//update sundries tables
$sundry = Sundry::withTrashed()->find($item_id);
$sundry->cost_price = $cost_price;
$sundry->update();
} elseif ($item_category_id == 3) {
$dental = Dental::withTrashed()->find($item_id);
$dental->buying_price = $cost_price;
$dental->update();
} elseif ($item_category_id == 4) {
$radio = Radiology::withTrashed()->find($item_id);
$radio->cost_price = $cost_price;
$radio->update();
} elseif ($item_category_id == 5) {
$lab = Lab::withTrashed()->find($item_id);
$lab->cost_price = $cost_price;
$lab->update();
} elseif ($item_category_id == 6) {
//update general items tables
$general_item = GeneralItem::withTrashed()->find($item_id);
$general_item->cost_price = $cost_price;
$general_item->update();
}
}
/* get latest cost of good */
function get_latest_cost_of_good($item_id, $item_category_id)
{
$latest_cost_price_of_item = null;
$latest_cost_of_good = \Streamline\Models\CostOfGood::where(['item_id' => $item_id, 'item_category' => $item_category_id])->orderBy('id', 'desc')->first();
if (!is_null($latest_cost_of_good)) {
$latest_cost_price_of_item = $latest_cost_of_good->cost_price;
} else {
if ($item_category_id == 1) {
$latest_cost_price_of_item = get_name($item_id, "id", "cost_price", "drugs");
} elseif ($item_category_id == 2) {
$latest_cost_price_of_item = get_name($item_id, "id", "cost_price", "sundries");
} elseif ($item_category_id == 4) {
$latest_cost_price_of_item = get_name($item_id, "id", "cost_price", "labs");
}
}
return $latest_cost_price_of_item;
}
function does_episode_have_theatre_information($episode_id)
{
$anaesthesia = DB::table('anaesthesias')->where('episode_id', $episode_id)->get()->first();
$surgery = DB::table('surgeries')->where('episode_id', $episode_id)->get()->first();
// if both are not present, then return false
if (!$surgery && !$anaesthesia) {
return false;
}
$surgery_completed = false;
$anaesthesia_completed = false;
$procedure_name = null;
$surgery_type = null;
$outcome = null;
$comments = null;
if ($surgery) {
$surgery_completed = true;
$procedure_name = get_name($surgery->procedure_id, 'id', 'name', 'procedures');
$surgery_type = $surgery->surgery_type;
if ($surgery_type == 1) {
$surgery_type = "Elective";
} elseif ($surgery_type == 2) {
$surgery_type = "Emergency";
} else {
$surgery_type = "Not Available";
}
$outcome = $surgery->outcome;
// check if the outcome is not an exact integer
$outcome = (is_numeric($outcome)) ? get_name($outcome, 'id', 'name', 'outcomes') : "Not Available";
$comments = $surgery->comments;
} elseif ($anaesthesia) {
$anaesthesia_completed = true;
$procedure_name = get_name($anaesthesia->procedure_id, 'id', 'name', 'procedures');
$surgery_type = "Not Available";
$outcome = "Not Available";
$comments = $anaesthesia->comments;
}
// when surgery has been completed and anaesthesia is also completed but the
// if statement favours the surgery section
if ($anaesthesia) {
$anaesthesia_completed = true;
}
$return_data = [];
$return_data['surgery_completed'] = $surgery_completed;
$return_data['anaesthesia_completed'] = $anaesthesia_completed;
$return_data['procedure_name'] = $procedure_name;
$return_data['surgery_type'] = $surgery_type;
$return_data['outcome'] = $outcome;
$return_data['comments'] = $comments;
return $return_data;
}
function discharge_patient_from_ward($patient_id, $episode_id, $discharged_by, $discharged_on)
{
$inpatient_info = InpatientInfo::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->orderBy('created_at', 'desc')->first();
if ($inpatient_info) {
$inpatient_info->discharged = 1;
$inpatient_info->discharged_on = $discharged_on;
$inpatient_info->discharged_by = $discharged_by;
$inpatient_info->save();
}
}
function check_if_patient_ran_away_without_paying($episode_id)
{
$inpatient_info = InpatientInfo::where(['episode_id' => $episode_id, 'outcome_id' => 8])->orderBy('created_at', 'desc')->first();
return $inpatient_info ? true : false;
}
function get_patients_age($date_of_birth) {
try {
if ((int) Carbon::parse($date_of_birth)->diff(now())->format('%y') > 5) {
return Carbon::parse($date_of_birth)->diff(now())->format('%y years');
} else {
return Carbon::parse($date_of_birth)->diff(now())->format('%y years, %m months and %d days');
}
} catch (\Exception $e) {
return 'Unknown';
}
}
/* check if a family account can consume more than the balance that they have */
function can_family_accounts_consume_more_than_balance() {
$general_settings = GeneralSettings::find(1);
return $general_settings->family_account_over_consumption == 1;
}
/* check if a patient belongs to a family account */
function get_patient_family_account_id($patient_id)
{
$family_account_id = null;
$family_accounts = \Streamline\Models\FamilyAccount::orderBy('id', 'desc')->get();
foreach ($family_accounts as $family_account) {
$family_account_members_string = $family_account->family_members_ids;
$family_account_members_array = explode(",", $family_account_members_string);
for ($i = 0; $i < count($family_account_members_array); $i++) {
if ($patient_id == $family_account_members_array[$i]) {
return $family_account->id;
}
}
}
return $family_account_id;
}
/* store into family consumption table */
function record_family_consumption($patient_id, $episode_id, $family_account_id, $amount_consumed, $reason, $receipt_number)
{
$family_account_consumption = new \Streamline\Models\FamilyAccountConsumption;
$family_account_consumption->patient_id = $patient_id;
$family_account_consumption->episode_id = $episode_id;
$family_account_consumption->family_account_id = $family_account_id;
$family_account_consumption->amount_consumed = $amount_consumed;
$family_account_consumption->expenditure_tag = $reason;
$family_account_consumption->receipt_number = $receipt_number;
$family_account_consumption->created_by = auth()->user()->id;
if ($family_account_consumption->save()) {
//reduce the current balance of this family account with the amount that has been consumed
$family_account = \Streamline\Models\FamilyAccount::find($family_account_id);
$family_account->current_balance = $family_account->current_balance - $amount_consumed;
$family_account->save();
//reduce the balance on "family deposits" chart of accounts table
$chart_of_account_id = get_name("family_account_deposits", "slug", "id", "chart_of_accounts");
$chart_of_account = \Streamline\Models\ChartOfAccount::find($chart_of_account_id);
$chart_of_account->balance = $chart_of_account->balance - $amount_consumed;
$chart_of_account->update();
}
}
function is_family_account_feature_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->family_accounts_feature == 1) {
return true;
} else {
return false;
}
}
function un_fullfilled_patient_appointments($patient_id)
{
$un_fullfilled_patient_appointments = \Streamline\Models\PatientAppointment::where(['patient_id' => $patient_id, 'appointment_fulfilled' => 0])->get();
return $un_fullfilled_patient_appointments;
}
function check_if_episode_is_a_followup($episode_id)
{
$episode_details = \Streamline\Models\PatientEpisode::find($episode_id);
if (!is_null($episode_details)) {
if (!is_null($episode_details->parent_episode_id)) {
return true;
}
}
return false;
}
function batch_calculations_for_item_based_on_fifo($drug_id, $drug_reduction_quantity, $batch_number, $item_type)
{
/*
1.determine the batch to use using FIFO
2.update the drugs table with the details of the batch
*/
if ($item_type == 1) {
$drug = Drug::withTrashed()->find($drug_id);
$batch_number_in_use = $drug->batch_number_in_use;
$quotation_id_of_batch_in_use = $drug->quotation_id_of_batch_in_use;
$quantity_balance_of_batch_in_use = $drug->balance_of_batch_in_use;
} elseif($item_type == 2){
$drug = Sundry::withTrashed()->find($drug_id);
$batch_number_in_use = $drug->batch_number_in_use;
$quotation_id_of_batch_in_use = $drug->quotation_id_of_batch_in_use;
$quantity_balance_of_batch_in_use = $drug->balance_of_batch_in_use;
}
$batch_calculation_status = false;
$batches_whose_quantity_has_reduced_array = [];
$drugs_whose_batches_have_reduced_array = [];
if (is_null($batch_number_in_use)) {
//usually this means that this drug has not been associated with a respective quotation and in ideal circumstances, this is most probably due to first time usage on streamline
/* update the drugs table with new details and also reduce the batch quantity of this particular quotation_id */
$batch_details_to_use = get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fifo($drug_id, $batch_number, $item_type);
if (!is_null($batch_details_to_use)) {
$drug->batch_number_in_use = $batch_details_to_use['batch_number'];
$drug->quotation_id_of_batch_in_use = $batch_details_to_use['quotation_id'];
$drug->balance_of_batch_in_use = $batch_details_to_use['balance_of_batch'] - $drug_reduction_quantity;
$drug->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $batch_details_to_use['quotation_id'], 'batch_number' => $batch_details_to_use['batch_number'], 'drug_id' => $drug_id])->first();
if (!is_null($quotation_details)) {
if ($batch_details_to_use['balance_of_batch'] > $drug_reduction_quantity) {
// if batch has enough items to dispatch from then do this
$quotation_details->batch_balance = $batch_details_to_use['balance_of_batch'] - $drug_reduction_quantity;
$quotation_details->update();
flash('Reduced '.$drug_reduction_quantity.' items from batch number '.$batch_details_to_use['batch_number'])->success();
$batches_whose_quantity_has_reduced_array[$batch_details_to_use['batch_number']] = $drug_reduction_quantity;
$items_whose_batches_have_reduced_array[$batch_details_to_use['batch_number']] = $drug_id;
} else{
//dispatch from two batches since the required amount is more than what is in the first batch
$balance_to_be_reduced_from_next_batch = $drug_reduction_quantity - $batch_details_to_use['balance_of_batch'];
$quotation_details = \Streamline\Models\Quotation::where(['id' => $quotation_id_of_batch_in_use, 'batch_number' => $batch_number_in_use, 'drug_id' => $drug_id])->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $quotation_details->batch_balance - $batch_details_to_use['balance_of_batch'];
$quotation_details->update();
flash('Reduced '.$batch_details_to_use['balance_of_batch'].' items from batch number '.$batch_number_in_use)->success();
$batches_whose_quantity_has_reduced_array[$batch_number_in_use] = $batch_details_to_use['balance_of_batch'];
$items_whose_batches_have_reduced_array[$batch_number_in_use] = $drug_id;
}
$batch_details_to_use = get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fifo($drug_id, $batch_number, $item_type);
if (!is_null($batch_details_to_use)) {
$drug->batch_number_in_use = $batch_details_to_use['batch_number'];
$drug->quotation_id_of_batch_in_use = $batch_details_to_use['quotation_id'];
$drug->balance_of_batch_in_use = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$drug->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $batch_details_to_use['quotation_id'], 'batch_number' => $batch_details_to_use['batch_number'], 'drug_id' => $drug_id])->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$quotation_details->update();
flash('Reduced '.$balance_to_be_reduced_from_next_batch.' items from batch number '.$batch_details_to_use['batch_number'])->success();
$batches_whose_quantity_has_reduced_array[$batch_details_to_use['batch_number']] = $balance_to_be_reduced_from_next_batch;
$items_whose_batches_have_reduced_array[$batch_details_to_use['batch_number']] = $drug_id;
}
}
}
}
}
$batch_calculation_status = true;
} elseif (!is_null($batch_number_in_use) && $quantity_balance_of_batch_in_use < $drug_reduction_quantity) {
# do this if the quantity you are going to reduce is greater than the balance currently on the batch being used
// Note: first reduce the "reducable" quantity from the current batch and then reduce the other from the next batch
//dd('in second if');
/* 1.reduce the batch balance of batch number of this particular quotation id to 0 */
/* 2.update the drugs table with new batch balance and new quotation id */
/* 3.update the quotations table of the newly picked batch number with the new balance */
$balance_to_be_reduced_from_next_batch = $drug_reduction_quantity - $quantity_balance_of_batch_in_use;
$balance_to_reduce_from_current_batch_in_use = $drug_reduction_quantity - $balance_to_be_reduced_from_next_batch;
$quotation_details = \Streamline\Models\Quotation::where(['id' => $quotation_id_of_batch_in_use, 'batch_number' => $batch_number_in_use, 'drug_id' => $drug_id])->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $quotation_details->batch_balance - $balance_to_reduce_from_current_batch_in_use;
$quotation_details->update();
flash('Reduced '.$balance_to_reduce_from_current_batch_in_use.' items from batch number '.$batch_number_in_use)->success();
$batches_whose_quantity_has_reduced_array[$batch_number_in_use] = $balance_to_reduce_from_current_batch_in_use;
$drugs_whose_batches_have_reduced_array[$batch_number_in_use] = $drug_id;
}
$batch_details_to_use = get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fifo($drug_id, $batch_number, $item_type);
if (!is_null($batch_details_to_use)) {
$drug->batch_number_in_use = $batch_details_to_use['batch_number'];
$drug->quotation_id_of_batch_in_use = $batch_details_to_use['quotation_id'];
$drug->balance_of_batch_in_use = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$drug->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $batch_details_to_use['quotation_id'], 'batch_number' => $batch_details_to_use['batch_number'], 'drug_id' => $drug_id])->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$quotation_details->update();
flash('Reduced '.$balance_to_be_reduced_from_next_batch.' items from batch number '.$batch_details_to_use['batch_number'])->success();
$batches_whose_quantity_has_reduced_array[$batch_details_to_use['batch_number']] = $balance_to_be_reduced_from_next_batch;
$drugs_whose_batches_have_reduced_array[$batch_details_to_use['batch_number']] = $drug_id;
}
}
$batch_calculation_status = true;
} elseif (!is_null($batch_number_in_use) && $quantity_balance_of_batch_in_use >= $drug_reduction_quantity) {
# do a reduction of batch balance both on the drugs table and the quotations table for this batch number
$drug->balance_of_batch_in_use = $drug->balance_of_batch_in_use - $drug_reduction_quantity;
$drug->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $quotation_id_of_batch_in_use, 'batch_number' => $batch_number_in_use, 'drug_id' => $drug_id])->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $quantity_balance_of_batch_in_use - $drug_reduction_quantity;
$quotation_details->update();
flash('Reduced '.$drug_reduction_quantity.' items from batch number '.$batch_number_in_use)->success();
$batches_whose_quantity_has_reduced_array[$batch_number_in_use] = $drug_reduction_quantity;
$drugs_whose_batches_have_reduced_array[$batch_number_in_use] = $drug_id;
}
$batch_calculation_status = true;
}
session()->put(['batches_whose_quantity_has_reduced_array' => $batches_whose_quantity_has_reduced_array]);
session()->put(['drugs_whose_batches_have_reduced_array' => $drugs_whose_batches_have_reduced_array]);
return $batch_calculation_status;
}
function get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fifo($drug_id, $batch_number, $item_type)
{
$quotation = null;
if ($batch_number == null) {
$quotation = \Streamline\Models\Quotation::where(['drug_id' => $drug_id, 'quotation_type_id' => $item_type])->where('batch_balance', '!=', 0)->first();
} else {
$quotation = \Streamline\Models\Quotation::where(['drug_id' => $drug_id, 'batch_number' => $batch_number, 'quotation_type_id' => $item_type])->where('batch_balance', '!=', 0)->first();
}
if (!is_null($quotation)) {
$batch_number_and_quotation_id_array = [];
$batch_number_and_quotation_id_array['quotation_id'] = $quotation->id;
$batch_number_and_quotation_id_array['batch_number'] = $quotation->batch_number;
$batch_number_and_quotation_id_array['balance_of_batch'] = $quotation->batch_balance;
return $batch_number_and_quotation_id_array;
}
//?????? what does Mrs.streamline use now if the quotation for that drug does not exist
return null;
}
function get_all_batches_for_this_drug_with_balances($drug_id, $item_type)
{
$quotation_records = \Streamline\Models\Quotation::where(['drug_id' => $drug_id, 'quotation_type_id' => $item_type])->where('batch_balance', '!=', 0)->get();
return $quotation_records;
}
function details_of_batch_currently_in_use($drug_id)
{
$drug = \Streamline\Models\Drug::find($drug_id);
$batch_details = [];
if (!is_null($drug)) {
$batch_details['quotation_id'] = $drug->quotation_id_of_batch_in_use;
$batch_details['batch_number'] = $drug->batch_number_in_use;
$batch_details['balance_of_batch'] = $drug->balance_of_batch_in_use;
return $batch_details;
}
return null;
}
function details_of_batch_currently_in_use_sundries($sundry_id) {
$sundry = Sundry::find($sundry_id);
$batch_details = [];
if (!is_null($sundry)) {
$batch_details['quotation_id'] = $sundry->quotation_id_of_batch_in_use;
$batch_details['batch_number'] = $sundry->batch_number_in_use;
$batch_details['balance_of_batch'] = $sundry->balance_of_batch_in_use;
return $batch_details;
}
return null;
}
function get_batch_details_for_temporary_reconciliation($drug_id, $stock_count_identifier)
{
$records = \Streamline\Models\BatchDetailsForTemporaryStockReconciliation::where(['drug_id' => $drug_id, 'stock_count_identifier' => $stock_count_identifier])->get();
return $records;
}
function get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fefo($drug_id, $batch_number, $item_type)
{
$quotation = null;
if ($batch_number == null) {
$quotation = \Streamline\Models\Quotation::where(['drug_id' => $drug_id, 'quotation_type_id' => $item_type])->where('batch_balance', '!=', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
} else {
$quotation = \Streamline\Models\Quotation::where(['drug_id' => $drug_id, 'batch_number' => $batch_number, 'quotation_type_id' => $item_type])->where('batch_balance', '!=', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
}
if (!is_null($quotation)) {
$batch_number_and_quotation_id_array = [];
$batch_number_and_quotation_id_array['quotation_id'] = $quotation->id;
$batch_number_and_quotation_id_array['batch_number'] = $quotation->batch_number;
$batch_number_and_quotation_id_array['balance_of_batch'] = $quotation->batch_balance;
return $batch_number_and_quotation_id_array;
}
//?????? what does Mrs.streamline use now if the quotation for that drug does not exist
return null;
}
function batch_calculations_for_item_based_on_fefo($item_id, $item_reduction_quantity, $batch_number, $item_type)
{
/*
1.determine the batch to use using FEFO
2.update the item table with the details of the batch
*/
if ($item_type == 1) {
$item = Drug::withTrashed()->find($item_id);
$batch_number_in_use = $item->batch_number_in_use;
$quotation_id_of_batch_in_use = $item->quotation_id_of_batch_in_use;
$quantity_balance_of_batch_in_use = $item->balance_of_batch_in_use;
} elseif($item_type == 2){
$item = Sundry::withTrashed()->find($item_id);
$batch_number_in_use = $item->batch_number_in_use;
$quotation_id_of_batch_in_use = $item->quotation_id_of_batch_in_use;
$quantity_balance_of_batch_in_use = $item->balance_of_batch_in_use;
}
$batch_calculation_status = false;
$batches_whose_quantity_has_reduced_array = [];
$items_whose_batches_have_reduced_array = [];
if (is_null($batch_number_in_use)) {
//usually this means that this drug has not been associated with a respective quotation and in ideal circumstances, this is most probably due to first time usage on streamline
/* update the drugs table with new details and also reduce the batch quantity of this particular quotation_id */
$batch_details_to_use = get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fefo($item_id, $batch_number, $item_type);
if (!is_null($batch_details_to_use)) {
$item->batch_number_in_use = $batch_details_to_use['batch_number'];
$item->quotation_id_of_batch_in_use = $batch_details_to_use['quotation_id'];
$item->balance_of_batch_in_use = $batch_details_to_use['balance_of_batch'] - $item_reduction_quantity;
$item->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $batch_details_to_use['quotation_id'], 'batch_number' => $batch_details_to_use['batch_number'], 'drug_id' => $item_id])->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if (!is_null($quotation_details)) {
if ($batch_details_to_use['balance_of_batch'] > $item_reduction_quantity) {
// if batch has enough items to dispatch from then do this
$quotation_details->batch_balance = $batch_details_to_use['balance_of_batch'] - $item_reduction_quantity;
$quotation_details->update();
flash('Reduced '.$item_reduction_quantity.' items from batch number '.$batch_details_to_use['batch_number'])->success();
$batches_whose_quantity_has_reduced_array[$batch_details_to_use['batch_number']] = $item_reduction_quantity;
$items_whose_batches_have_reduced_array[$batch_details_to_use['batch_number']] = $item_id;
} else{
//dispatch from two batches since the required amount is more than what is in the first batch
$balance_to_be_reduced_from_next_batch = $item_reduction_quantity - $batch_details_to_use['balance_of_batch'];
$quotation_details = \Streamline\Models\Quotation::where(['id' => $quotation_id_of_batch_in_use, 'batch_number' => $batch_number_in_use, 'drug_id' => $item_id])->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $quotation_details->batch_balance - $batch_details_to_use['balance_of_batch'];
$quotation_details->update();
flash('Reduced '.$batch_details_to_use['balance_of_batch'].' items from batch number '.$batch_number_in_use)->success();
$batches_whose_quantity_has_reduced_array[$batch_number_in_use] = $batch_details_to_use['balance_of_batch'];
$items_whose_batches_have_reduced_array[$batch_number_in_use] = $item_id;
}
$batch_details_to_use = get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fefo($item_id, $batch_number, $item_type);
if (!is_null($batch_details_to_use)) {
$item->batch_number_in_use = $batch_details_to_use['batch_number'];
$item->quotation_id_of_batch_in_use = $batch_details_to_use['quotation_id'];
$item->balance_of_batch_in_use = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$item->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $batch_details_to_use['quotation_id'], 'batch_number' => $batch_details_to_use['batch_number'], 'drug_id' => $item_id])->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$quotation_details->update();
flash('Reduced '.$balance_to_be_reduced_from_next_batch.' items from batch number '.$batch_details_to_use['batch_number'])->success();
$batches_whose_quantity_has_reduced_array[$batch_details_to_use['batch_number']] = $balance_to_be_reduced_from_next_batch;
$items_whose_batches_have_reduced_array[$batch_details_to_use['batch_number']] = $item_id;
}
}
}
}
}
$batch_calculation_status = true;
} elseif (!is_null($batch_number_in_use) && $quantity_balance_of_batch_in_use < $item_reduction_quantity) {
# do this if the quantity you are going to reduce is greater than the balance currently on the batch being used
// Note: first reduce the "reducable" quantity from the current batch and then reduce the other from the next batch
/* 1.reduce the batch balance of batch number of this particular quotation id to 0 */
/* 2.update the drugs table with new batch balance and new quotation id */
/* 3.update the quotations table of the newly picked batch number with the new balance */
$balance_to_be_reduced_from_next_batch = $item_reduction_quantity - $quantity_balance_of_batch_in_use;
$balance_to_reduce_from_current_batch_in_use = $item_reduction_quantity - $balance_to_be_reduced_from_next_batch;
$quotation_details = \Streamline\Models\Quotation::where(['id' => $quotation_id_of_batch_in_use, 'batch_number' => $batch_number_in_use, 'drug_id' => $item_id])->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $quotation_details->batch_balance - $balance_to_reduce_from_current_batch_in_use;
$quotation_details->update();
flash('Reduced '.$balance_to_reduce_from_current_batch_in_use.' items from batch number '.$batch_number_in_use)->success();
$batches_whose_quantity_has_reduced_array[$batch_number_in_use] = $balance_to_reduce_from_current_batch_in_use;
$items_whose_batches_have_reduced_array[$batch_number_in_use] = $item_id;
}
$batch_details_to_use = get_batch_and_quotation_id_details_to_use_for_particular_item_based_on_fefo($item_id, $batch_number, $item_type);
if (!is_null($batch_details_to_use)) {
$item->batch_number_in_use = $batch_details_to_use['batch_number'];
$item->quotation_id_of_batch_in_use = $batch_details_to_use['quotation_id'];
$item->balance_of_batch_in_use = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$item->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $batch_details_to_use['quotation_id'], 'batch_number' => $batch_details_to_use['batch_number'], 'drug_id' => $item_id])->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $batch_details_to_use['balance_of_batch'] - $balance_to_be_reduced_from_next_batch;
$quotation_details->update();
flash('Reduced '.$balance_to_be_reduced_from_next_batch.' items from batch number '.$batch_details_to_use['batch_number'])->success();
$batches_whose_quantity_has_reduced_array[$batch_details_to_use['batch_number']] = $balance_to_be_reduced_from_next_batch;
$items_whose_batches_have_reduced_array[$batch_details_to_use['batch_number']] = $item_id;
}
}
$batch_calculation_status = true;
} elseif (!is_null($batch_number_in_use) && $quantity_balance_of_batch_in_use >= $item_reduction_quantity) {
# do a reduction of batch balance both on the items table and the quotations table for this batch number
$item->balance_of_batch_in_use = $item->balance_of_batch_in_use - $item_reduction_quantity;
$item->update();
$quotation_details = \Streamline\Models\Quotation::where(['id' => $quotation_id_of_batch_in_use, 'batch_number' => $batch_number_in_use, 'drug_id' => $item_id])->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if (!is_null($quotation_details)) {
$quotation_details->batch_balance = $quantity_balance_of_batch_in_use - $item_reduction_quantity;
$quotation_details->update();
flash('Reduced '.$item_reduction_quantity.' items from batch number '.$batch_number_in_use)->success();
$batches_whose_quantity_has_reduced_array[$batch_number_in_use] = $item_reduction_quantity;
$items_whose_batches_have_reduced_array[$batch_number_in_use] = $item_id;
}
$batch_calculation_status = true;
}
session()->put(['batches_whose_quantity_has_reduced_array' => $batches_whose_quantity_has_reduced_array]);
session()->put(['drugs_whose_batches_have_reduced_array' => $items_whose_batches_have_reduced_array]);
return $batch_calculation_status;
}
function clean_streamline_database_output($value)
{
return htmlspecialchars($value);
}
function track_items_using_batches()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->item_batch_tracking == 1) {
return true;
} else {
return false;
}
}
function get_session_expiration_time()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->session_expiration_time;
}
function get_dynamic_normal_range($inv_id, $age_id, $gender) {
$result = DB::table('investigations_normal_ranges')
->where('age_group_id', $age_id)
->where('test_id', $inv_id)
->where('is_specialised_variable', 0)
->first();
if (!$result) {
return '';
} else {
if ($gender == 1) {
return $result->male_range;
} else {
return $result->female_range;
}
}
}
function get_patient_age_group($patient_id) {
$dob = get_name($patient_id, 'id', 'date_of_birth', 'patients');
if (!$dob) {
$dob = date("Y-m-d");
}
$age_diff_days = Carbon::createFromFormat('Y-m-d', $dob)->diffInDays(Carbon::now());
$age_group = 0;
$age_group_records = DB::table('age_groups')->whereNull('deleted_at')->get()->toArray();
foreach ($age_group_records as $age_group_record) {
// turn into days
if ($age_group_record->age_type == 3) {
// days
$first_day = $age_group_record->from_age;
$last_day = $age_group_record->to_age;
} elseif ($age_group_record->age_type == 2) {
// months
$first_day = $age_group_record->from_age * 30;
$last_day = $age_group_record->to_age * 30;
} else {
// years
$first_day = $age_group_record->from_age * 365;
$last_day = $age_group_record->to_age * 365;
}
if (between($age_diff_days, $first_day, $last_day)) {
$age_group = $age_group_record->id;
break;
}
}
return $age_group;
}
function get_dynamic_normal_range_specialized($inv_id, $age_id, $gender)
{
$result = DB::table('investigations_normal_ranges')
->where('age_group_id', $age_id)
->where('test_id', $inv_id)
->where('is_specialised_variable', 1)
->first();
if (!$result) {
return '';
} else {
if ($gender == 1) {
return $result->male_range;
} else {
return $result->female_range;
}
}
}
function get_fee_owed_to_staff_for_perfomed_service($service_id, $item_category_id, $staff_id)
{
$fee_record = \Streamline\Models\StaffPaymentConfiguration::where('price_list_category_id', 0)->where(['user_id' => $staff_id, 'item_id' => $service_id, 'item_category' => $item_category_id])->orderBy('created_at', 'desc')->first();
if (!is_null($fee_record)) {
if ($fee_record->payment_type == 0) {
return $fee_record->amount_fee;
} elseif ($fee_record->payment_type == 1) { # get the % of the non insured price
$staff_fee = 0;
if ($fee_record->item_category == 1) { // for procedure
$non_insured_price = get_name($service_id, "id", "non_insured_price", "procedures");
$staff_fee = $fee_record->amount_percentage / 100 * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 2) { // for investigations
$non_insured_price = get_name($service_id, "id", "non_insured_price", "investigations");
$staff_fee = ($fee_record->amount_percentage / 100) * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 3) { // for consultations and services
$non_insured_price = get_name($service_id, "id", "cost_price", "services");
$staff_fee = ($fee_record->amount_percentage / 100) * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
return $staff_fee;
}
}
return 0;
}
function get_fee_owed_to_staff_for_perfomed_service_based_on_category($service_id, $staff_id, $item_category_id)
{
$fee_record = \Streamline\Models\StaffPaymentConfiguration::where(['user_id' => $staff_id, 'item_id' => $service_id, 'item_category' => $item_category_id])->orderBy('created_at', 'desc')->first();
if (!is_null($fee_record)) {
if ($fee_record->payment_type == 0) {
return $fee_record->amount_fee;
} elseif ($fee_record->payment_type == 1) { # get the % of the non insured price
$staff_fee = 0;
if ($fee_record->item_category == 1) { // for procedure
$non_insured_price = get_name($service_id, "id", "non_insured_price", "procedures");
$staff_fee = $fee_record->amount_percentage / 100 * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 2) { // for investigations
$non_insured_price = get_name($service_id, "id", "non_insured_price", "investigations");
$staff_fee = ($fee_record->amount_percentage / 100) * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 3) { // for consultations and services
$non_insured_price = get_name($service_id, "id", "cost_price", "services");
$staff_fee = ($fee_record->amount_percentage / 100) * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
return $staff_fee;
}
}
return 0;
}
function record_staff_that_has_performed_the_service($patient_id, $episode_id, $item_category_id, $item_id, $inpatient_status, $performed_by)
{
$record_perfomed_service = new StaffPerformedService;
$record_perfomed_service->patient_id = $patient_id;
$record_perfomed_service->episode_id = $episode_id;
$record_perfomed_service->item_category = $item_category_id;
$record_perfomed_service->item_id = $item_id;
$patient_details = \Streamline\Models\Patient::withTrashed()->find($patient_id);
$patient_category_id = $patient_details->category_id;
$price_list_category_details = \Streamline\Models\PriceListCategories::where(['patient_category_id' => $patient_category_id])->first();
if ($price_list_category_details) {
$price_list_category_id = $price_list_category_details->id;
$item_price_and_performance_fee_array = get_item_price_and_performance_fee_based_on_price_list_category($performed_by, $item_id, $item_category_id, $price_list_category_id);
$item_price = $item_price_and_performance_fee_array[0];
$performance_fee = $item_price_and_performance_fee_array[1];
} else {
//do this for cases where the there are no price lists for the patient's patient_category
$item_price_and_performance_fee_array = get_item_price_and_performance_fee_array_without_price_list($item_id, $performed_by, $item_category_id);
$item_price = $item_price_and_performance_fee_array[0];
$performance_fee = $item_price_and_performance_fee_array[1];
}
//do this special thing for procedures to get item and performance fee as set when ordering procedure
if ($item_category_id == 1) {
$ordered_procedure_record = \Streamline\Models\OrderedProcedure::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'procedure_id' => $item_id])->first();
if ($ordered_procedure_record && !is_null($ordered_procedure_record->procedure_amount)) {
$item_price = $ordered_procedure_record->procedure_amount;
$performance_fee = $ordered_procedure_record->procedure_amount;
}
}
$record_perfomed_service->item_price = $item_price;
$record_perfomed_service->performance_fee = $performance_fee;
$record_perfomed_service->inpatient = $inpatient_status;
$record_perfomed_service->performed_by = $performed_by;
$record_perfomed_service->date_performed = date('Y-m-d');
$record_perfomed_service->created_by = auth()->user()->id;
$record_perfomed_service->save();
return $record_perfomed_service->id;
}
function record_staff_that_has_performed_the_service_with_price($patient_id, $episode_id, $item_category_id, $item_id,
$inpatient_status, $performed_by, $performance_fee, $date_performed) {
$record_performed_service = new StaffPerformedService;
$record_performed_service->patient_id = $patient_id;
$record_performed_service->episode_id = $episode_id;
$record_performed_service->item_category = $item_category_id;
$record_performed_service->item_id = $item_id;
$patient_details = Patient::withTrashed()->find($patient_id);
$patient_category_id = $patient_details->category_id;
$price_list_category_details = PriceListCategories::where(['patient_category_id' => $patient_category_id])->first();
if ($price_list_category_details) {
$price_list_category_id = $price_list_category_details->id;
$fee_array = get_item_price_and_performance_fee_based_on_price_list_category($performed_by, $item_id, $item_category_id, $price_list_category_id);
$item_price = $fee_array[0];
} else {
//do this for cases where the there are no price lists for the patient's patient_category
$fee_array = get_item_price_and_performance_fee_array_without_price_list($item_id, $performed_by, $item_category_id);
$item_price = $fee_array[0];
}
$record_performed_service->item_price = $item_price;
$record_performed_service->performance_fee = $performance_fee;
$record_performed_service->inpatient = $inpatient_status;
$record_performed_service->performed_by = $performed_by;
$record_performed_service->date_performed = $date_performed;
$record_performed_service->created_by = auth()->user()->id;
$record_performed_service->save();
return $record_performed_service->id;
}
function get_user_consultation_fee($staff_id)
{
$staff_name = get_full_name($staff_id, "id", "first_name", "last_name", "users");
$consultation_fee_for_staff = "Consultation Fee - " . $staff_name;
$fee_record = \Streamline\Models\Services::where(['name' => $consultation_fee_for_staff])->orderBy('created_at', 'desc')->first();
if (!is_null($fee_record)) {
return $fee_record->non_insured_price;
}
return 0;
}
function get_doctor_who_has_done_episode_consultation($patient_id, $episode_id)
{
$consultation_details = \Streamline\Models\Consultation::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->first();
if (!is_null($consultation_details)) {
return $consultation_details->consultation_done_by;
}
return null;
}
function get_consultation_service_id_allocated_at_episode_consultation($patient_id, $episode_id)
{
$consultation_details = \Streamline\Models\Consultation::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->first();
if (!is_null($consultation_details)) {
return $consultation_details->consultation_service_id;
}
return null;
}
function is_doc_consul_fee_paid($episode_id, $consul_id)
{
$invoices = DB::table('service_deposits')
->where('episode_id', $episode_id)->get(['items_ids']);
$services = DB::table('patient_category_invoices')
->where('episode_id', $episode_id)->get(['items_ids']);
foreach ($services as $service) {
if (in_array($consul_id, explode(",", $service->items_ids))) {
return true;
}
}
foreach ($invoices as $service) {
if (in_array($consul_id, explode(",", $service->items_ids))) {
return true;
}
}
return false;
}
function is_incoming_prescriptions_feature_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->incoming_prescription_confirmation_feature == 1) {
return true;
} else {
return false;
}
}
function is_add_stamp_feature_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->add_stamp_to_pdf_feature == 1) return true;
else return false;
}
function is_add_lab_stamp_feature_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->add_lab_stamp_to_pdf_feature == 1) return true;
else return false;
}
function is_dispense_unpaid_prescription_enabled($patient_id): bool {
$general_settings = GeneralSettings::find(1);
// check if the patient is pay later or not and check appropriate permission
if (is_patient_category_pay_later(get_name($patient_id, 'id', 'category_id', 'patients'))) {
return $general_settings->enable_dispensing_non_invoiced_prescription == 1;
} else {
return $general_settings->enable_dipensing_unpaid_prescription== 1;
}
}
function update_ward_stock($ward_id, $item_type, $item_id, $new_ward_stock)
{
$ward_stock = \Streamline\Models\WardStock::where(['ward_id' => $ward_id, 'item_type' => $item_type, 'item_id' => $item_id])->first();
if ($ward_stock) {
$ward_stock->ward_item_stock = $new_ward_stock;
$ward_stock->update();
} else {
$ward_stock = new \Streamline\Models\WardStock;
$ward_stock->ward_id = $ward_id;
$ward_stock->item_type = $item_type;
$ward_stock->item_id = $item_id;
$ward_stock->ward_item_stock = $new_ward_stock;
$ward_stock->created_by = auth()->user()->id;
$ward_stock->save();
}
}
function reduce_ward_stock_with_consumed_quantity($item_id, $used_quantity, $item_type, $ward_id, $patient_id, $episode_id)
{
$ward_stock = \Streamline\Models\WardStock::where(['ward_id'=>$ward_id, 'item_type'=>$item_type, 'item_id'=>$item_id])->first();
reduce_batch_items_from_ward($item_type, $item_id, $used_quantity, $ward_id, $patient_id, $episode_id, "ward_stock", $ward_stock->id ?? 0);
if ($ward_stock) {
$ward_stock->ward_item_stock = $ward_stock->ward_item_stock - $used_quantity;
$ward_stock->update();
} else{
//if not in any ward stock, then reduce the store stock by this amount to ensure double entry
if ($item_type == 1) {
$drug = \Streamline\Models\Drug::withTrashed()->find($item_id);
if ($drug) {
$drug->store_stock = $drug->store_stock - $used_quantity;
$drug->update();
}
}
if ($item_type == 2) {
$sundry = \Streamline\Models\Sundry::withTrashed()->find($item_id);
if ($sundry) {
$sundry->store_stock = $sundry->store_stock - $used_quantity;
$sundry->update();
}
}
}
}
function getDNS1DBarcodePNG($id)
{
$code = sprintf("%04u", $id);
$type = 'S25';
$barCode = DNS1D::getBarcodePNG($code, $type);
echo '<img src="data:image/png;base64,' . $barCode . '" alt="barcode" />';
}
function getDNS1DBarcodePNGOtherOption($id)
{
$code = sprintf("%04u", $id);
$type = 'S25';
$barCode = DNS1D::getBarcodePNG($code, "C39", 3, 33);
echo '<img src="data:image/png,' . $barCode . '" alt="" />';
echo '<img src="data:image/png;base64,' . $barCode . '" alt="" />';
}
function insuranceCardBarcode($id)
{
$code = sprintf("%04u", $id);
$barCode = DNS1D::getBarcodePNG($code, "C39", 3, 33);
echo '<img src="data:image/png;base64,' . $barCode . '" alt="" style="height:26px;" />';
}
function getTodayCarbon()
{
return Carbon::today();
}
function getYesterdayCarbon()
{
return Carbon::yesterday();
}
function getStartOfDayCarbon($date)
{
return Carbon::parse($date)->startOfDay()->toDateTimeString();
}
function getEndOfDayCarbon($date)
{
return Carbon::parse($date)->endOfDay()->toDateTimeString();
}
function get_item_price_and_performance_fee_based_on_price_list_category($staff_id, $item_id, $item_category_id, $price_list_category_id)
{
$price_list_price = 0;
if ($item_category_id == 1) {
//procedures
$price_list_price = get_price_list_category_price($price_list_category_id, 4, $item_id);
} elseif ($item_category_id == 2) {
//investigations
$price_list_price = get_price_list_category_price($price_list_category_id, 2, $item_id);
} elseif ($item_category_id == 3) {
//consultation
$price_list_price = get_price_list_category_price($price_list_category_id, 6, $item_id);
}
$configuration_record = \Streamline\Models\StaffPaymentConfiguration::where(['user_id' => $staff_id, 'item_id' => $item_id, 'item_category' => $item_category_id, 'price_list_category_id' => $price_list_category_id])->orderBy('created_at', 'desc')->first();
$staff_fee = 0;
if (!is_null($configuration_record)) {
if ($configuration_record->payment_type == 0) {
$staff_fee = $configuration_record->amount_fee;
} elseif ($configuration_record->payment_type == 1) { # get the % of the non insured price
if ($configuration_record->item_category == 1) { // for procedure
$staff_fee = $configuration_record->amount_percentage / 100 * $price_list_price;
$staff_fee = round($staff_fee, 0);
}
if ($configuration_record->item_category == 2) { // for investigations
$staff_fee = ($configuration_record->amount_percentage / 100) * $price_list_price;
$staff_fee = round($staff_fee, 0);
}
if ($configuration_record->item_category == 3) { // for consultations and services
$staff_fee = ($configuration_record->amount_percentage / 100) * $price_list_price;
$staff_fee = round($staff_fee, 0);
}
}
}
return [$price_list_price, $staff_fee];
}
function get_item_price_and_performance_fee_array_without_price_list($service_id, $staff_id, $item_category_id)
{
$fee_record = \Streamline\Models\StaffPaymentConfiguration::where('price_list_category_id', 0)->where(['user_id' => $staff_id, 'item_id' => $service_id, 'item_category' => $item_category_id])->orderBy('created_at', 'desc')->first();
$staff_fee = 0;
$item_price = 0;
if ($item_category_id == 1) { // for procedure
$item_price = get_name($service_id, "id", "non_insured_price", "procedures");
}
if ($item_category_id == 2) { // for investigations
$item_price = get_name($service_id, "id", "non_insured_price", "investigations");
}
if ($item_category_id == 3) { // for consultations and services
$item_price = get_name($service_id, "id", "non_insured_price", "services");
}
if (!is_null($fee_record)) {
if ($fee_record->payment_type == 0) {
$staff_fee = $fee_record->amount_fee;
} elseif ($fee_record->payment_type == 1) { # get the % of the non insured price
if ($fee_record->item_category == 1) { // for procedure
$staff_fee = $fee_record->amount_percentage / 100 * $item_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 2) { // for investigations
$staff_fee = ($fee_record->amount_percentage / 100) * $item_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 3) { // for consultations and services
$staff_fee = ($fee_record->amount_percentage / 100) * $item_price;
$staff_fee = round($staff_fee, 0);
}
}
}
return [$item_price, $staff_fee];
}
function inpatient_sheet_audit($patient_id, $episode_id, Request $request)
{
# receive the inpatient sheet request
$inpatient_sheet_audit_record = new \Streamline\Models\InpatientSheetAudit;
$inpatient_sheet_audit_record->patient_id = $patient_id;
$inpatient_sheet_audit_record->episode_id = $episode_id;
$inpatient_sheet_audit_record->inpatient_info_id = $request->info_id;
$inpatient_sheet_audit_record->primary_diagnosis = $request->primary_diagnosis;
$inpatient_sheet_audit_record->other_diagnoses = is_null($request->other_diagnosis) ? null : serialize($request->other_diagnosis);
$inpatient_sheet_audit_record->procedures = is_null($request->procedure_id) ? null : serialize($request->procedure_id);
$inpatient_sheet_audit_record->procedures_performed_by = is_null($request->procedure_done_by) ? null : serialize($request->procedure_done_by);
//sundries
if (is_array($request->sundry_id) && !in_array(null, $request->sundry_id)) {
$sundry_id = $request->sundry_id;
$sundry_quantity = $request->sundry_quantity;
$sundries = array(
"sundries" => $sundry_id,
"quantity" => $sundry_quantity,
);
$inpatient_sheet_audit_record->sundries = serialize($sundries);
} else {
$inpatient_sheet_audit_record->sundries = null;
}
//investigations
$inpatient_sheet_audit_record->investigations = is_null($request->ward_investigation_ids) ? null : implode(",", $request->ward_investigation_ids);
// check if any ward treatments using daily factor are selected
if (isset($request->drugs) && is_array($request->drugs) && !in_array(null, $request->drugs)) {
$drug_id = $request->drugs;
$days = $request->drugs_days;
$treatments = array(
"drugs" => $drug_id,
"days" => $days,
);
$inpatient_sheet_audit_record->ward_treatments_using_daily_factor = serialize($treatments);
} else {
$inpatient_sheet_audit_record->ward_treatments_using_daily_factor = null;
}
//check if any ward treatment is given using the quantity method
$inpatient_sheet_audit_record->ward_drugs_dispensed = is_null($request->ward_dispensed_drug_id) ? null : implode(",", $request->ward_dispensed_drug_id);
$inpatient_sheet_audit_record->ward_quantities_dispensed = is_null($request->ward_quantity_dispensed) ? null : implode(",", $request->ward_quantity_dispensed);
//tta i.e take home drugs
$inpatient_sheet_audit_record->tta = is_null($request->tta_drugs) ? null : implode(",", $request->tta_drugs);
//extras
if (is_array($request->extra_name) && !in_array(null, $request->extra_name)) {
$extra_name = $request->extra_name;
$extra_cost = $request->extra_cost;
$extras = array(
"name" => $extra_name,
"cost" => $extra_cost,
);
$inpatient_sheet_audit_record->extras = serialize($extras);
} else {
$inpatient_sheet_audit_record->extras = null;
}
//consultation and services
if (is_array($request->service_id) && !in_array(null, $request->service_id)) {
$service_id = $request->service_id;
$service_quantities = $request->service_quantity;
$services = array(
"services" => $service_id,
"quantity" => $service_quantities,
);
$inpatient_sheet_audit_record->consultations_and_services = serialize($services);
} else {
$inpatient_sheet_audit_record->consultations_and_services = null;
}
$inpatient_sheet_audit_record->ward_message = $request->comments;
$inpatient_sheet_audit_record->bed_category_id = is_numeric($request->bed_category) ? $request->bed_category : null;
$inpatient_sheet_audit_record->bed_number = $request->bed_no;
$inpatient_sheet_audit_record->speciality_id = $request->speciality;
$inpatient_sheet_audit_record->outcome_id = $request->outcome;
$inpatient_sheet_audit_record->from_ward = $request->from;
$inpatient_sheet_audit_record->to_ward = $request->to;
$inpatient_sheet_audit_record->date_of_transfer = $request->date_of_transfer;
$inpatient_sheet_audit_record->transfer_comments = $request->transfer_comments;
$inpatient_sheet_audit_record->created_by = auth()->user()->id;
$inpatient_sheet_audit_record->save();
}
function service_fee_configured_to_staff($staff_id, $service_id, $price_list_category_id) {
if ($price_list_category_id != 0 && !is_null($price_list_category_id)) {
$fee_record = StaffPaymentConfiguration::where(['user_id' => $staff_id, 'item_id' => $service_id, 'item_category' => 3, 'price_list_category_id' => $price_list_category_id])->orderBy('created_at', 'desc')->first();
} else {
$fee_record = StaffPaymentConfiguration::where(['user_id' => $staff_id, 'item_id' => $service_id, 'item_category' => 3])->where('price_list_category_id', 0)->orderBy('created_at', 'desc')->first();
}
if (!is_null($fee_record)) {
if ($fee_record->payment_type == 0) {
return $fee_record->amount_fee;
} elseif ($fee_record->payment_type == 1) { # get the % of the non_insured price
$staff_fee = 0;
if ($fee_record->item_category == 1) { // for procedure
$non_insured_price = (int)get_name($service_id, "id", "non_insured_price", "procedures");
$staff_fee = $fee_record->amount_percentage / 100 * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 2) { // for investigations
$non_insured_price = (int)get_name($service_id, "id", "non_insured_price", "investigations");
$staff_fee = ($fee_record->amount_percentage / 100) * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
if ($fee_record->item_category == 3) { // for consultations and services
$non_insured_price = (int)get_name($service_id, "id", "cost_price", "services");
$staff_fee = ($fee_record->amount_percentage / 100) * $non_insured_price;
$staff_fee = round($staff_fee, 0);
}
return $staff_fee;
}
}
return 0;
}
function reverse_staff_fee_payment($patient_id, $episode_id, $item_category_id)
{
$staff_payment = \Streamline\Models\StaffPerformedService::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'item_category' => $item_category_id])->first();
if ($staff_payment) {
$staff_payment->delete();
}
}
function is_patient_debt_reminder_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->enable_patient_debt_reminder == 1) {
return true;
} else {
return false;
}
}
function is_episode_safe_to_delete($episode_id)
{
$consultations = DB::table('consultations')->where('episode_id', $episode_id)
->whereNotNull('primary_diagnosis')
->get(['id']);
if (count($consultations) > 0) {
return false;
}
$service_deposits = DB::table('service_deposits')->where('episode_id', $episode_id)
->get(['id']);
if (count($service_deposits) > 0) {
return false;
}
$patient_category_invoices = DB::table('patient_category_invoices')->where('episode_id', $episode_id)
->get(['id']);
if (count($patient_category_invoices) > 0) {
return false;
}
$inpatient_info = DB::table('inpatient_info')->where('episode_id', $episode_id)
->get(['id']);
if (count($inpatient_info) > 0) {
return false;
}
$maternity_inpatients = DB::table('maternity_inpatients')->where('episode_id', $episode_id)
->get(['id']);
if (count($maternity_inpatients) > 0) {
return false;
}
$ordered_eye_glasses = DB::table('ordered_eye_glasses')->where('episode_id', $episode_id)
->get(['id']);
if (count($ordered_eye_glasses) > 0) {
return false;
}
$ordered_investigations = DB::table('ordered_investigations')->where('episode_id', $episode_id)
->get(['id']);
if (count($ordered_investigations) > 0) {
return false;
}
$ordered_procedures = DB::table('ordered_procedures')->where('episode_id', $episode_id)
->get(['id']);
if (count($ordered_procedures) > 0) {
return false;
}
$ordered_services = DB::table('ordered_services')->where('episode_id', $episode_id)
->get(['id']);
if (count($ordered_services) > 0) {
return false;
}
$ordered_sundries = DB::table('ordered_sundries')->where('episode_id', $episode_id)
->get(['id']);
if (count($ordered_sundries) > 0) {
return false;
}
$treatments = DB::table('treatments')->where('episode_id', $episode_id)
->get(['id']);
if (count($treatments) > 0) {
return false;
}
$triage = DB::table('triage')->where('episode_id', $episode_id)
->get(['id']);
if (count($triage) > 0) {
return false;
}
return true;
}
function update_banking_record_balances($expense_date, $bank_id, $last_insert_id, $account_balance_on_expense_date_after_payment)
{
// Using the formula "account_balance = prev_account_balance + present credit - present deposit".
// Recursively update the balance column for records that follow the above inserted record
if (Carbon::parse($expense_date)->toDateString() < Carbon::today()->toDateString()) {
$orderByTransIdQuery = "CAST(trans_id AS DECIMAL(10,0)) ASC";
$previous_bank_record = Banking::where('bank', $bank_id)->whereNull('deleted_at')->whereDate('trans_date', '<', $expense_date)->orderBy('id', 'desc')->first();
if ($previous_bank_record) {
$banking_records = Banking::where('bank', $bank_id)->where('trans_date', '>', Carbon::parse($previous_bank_record->trans_date)->toDateString())
->whereNull('deleted_at')
->where('id', '!=', $previous_bank_record->id)
->orderBy('trans_date', 'asc')
->orderByRaw($orderByTransIdQuery)
->get();
$prev_balance = $previous_bank_record->account_balance;
foreach ($banking_records as $record) {
$prev_balance = $prev_balance + (int)$record->credit - (int)$record->debit;
Banking::where('id', $record->id)->update(['account_balance' => $prev_balance]);
}
} else {
$banking_records = Banking::where('bank', $bank_id)->where('trans_date', '>', Carbon::parse($expense_date)->toDateString())
->whereNull('deleted_at')
->where('id', '!=', $last_insert_id)
->orderBy('trans_date', 'asc')
->orderByRaw($orderByTransIdQuery)
->get();
$prev_balance = $account_balance_on_expense_date_after_payment;
foreach ($banking_records as $record) {
$prev_balance = $prev_balance + (int)$record->credit - (int)$record->debit;
Banking::where('id', $record->id)->update(['account_balance' => $prev_balance]);
}
}
}
}
function getMonthsList()
{
$period = \Carbon\CarbonPeriod::create('2020-01-01', '1 month', '2020-12-31');
$months = [];
foreach ($period as $dt) {
$months[] = $dt->format("M");
}
return $months;
}
function getDaysList()
{
$period = \Carbon\CarbonPeriod::create('2020-01-01', '1 week', '2020-01-07');
$weekdays = [];
foreach ($period as $dt) {
$weekdays[] = $dt->englishDayOfWeek;
}
return $weekdays;
}
function getDaysTillNow($given_date)
{
$difference = Carbon::parse($given_date)->diffInDays();
return ($difference < 1) ? '' : strval($difference) . " days";
}
function possible_patient_record_duplicates($patient_id) {
$possible_duplicates_array = [];
$patient = Patient::withTrashed()->find($patient_id);
$first_name = str_replace("'", '', $patient->first_name);
$last_name = str_replace("'", '', $patient->last_name);
$phone_number = str_replace('"', '', $patient->phone);
$patients_one = DB::table('patients')
->where('first_name', 'LIKE', "%$first_name%")
->where('last_name', 'LIKE', "%$last_name%")
->whereNotIn('id', [$patient_id])
->whereNull('deleted_at')
->get();
$patients_two = DB::table('patients')
->where('first_name', 'LIKE', "%$last_name%")
->where('last_name', 'LIKE', "%$first_name%")
->whereNotIn('id', [$patient_id])
->whereNull('deleted_at')
->get();
$possible_duplicates_array = $patients_one->merge($patients_two);
if (!is_null($phone_number) && $phone_number != "") {
$patients_phone = DB::table('patients')
->where('phone', removeSpaces($phone_number))
->whereNotIn('id', [$patient_id])
->whereNull('deleted_at')
->get();
$possible_duplicates_array = $possible_duplicates_array->merge($patients_phone);
}
if(count($possible_duplicates_array) > 0) {
return $possible_duplicates_array;
} else {
return null;
}
}
function is_perform_unpaid_consultations_enabled($patient_category) {
$general_settings = GeneralSettings::find(1);
return (is_patient_category_pay_later($patient_category) && $general_settings->enable_performing_unpaid_consultations == 2) ||
$general_settings->enable_performing_unpaid_consultations == 1;
}
function is_perform_unpaid_review_consultations_enabled($patient_category) {
$general_settings = GeneralSettings::find(1);
return (is_patient_category_pay_later($patient_category) && $general_settings->enable_performing_unpaid_review_consultations == 2) ||
$general_settings->enable_performing_unpaid_review_consultations == 1;
}
function is_out_of_stock_message_disabled(): bool {
$general_settings = GeneralSettings::find(1);
return $general_settings->disable_out_of_stock_message == 1;
}
function is_prescribing_out_of_stock_drugs_allowed($is_patient_ipd): bool {
$general_settings = GeneralSettings::find(1);
return ($general_settings->allow_prescribing_out_of_stock_drugs == 1) || ($general_settings->allow_prescribing_out_of_stock_drugs == 2 && $is_patient_ipd);
}
function can_dispense_out_of_stock_drugs(): bool {
$general_settings = GeneralSettings::find(1);
return ($general_settings->allow_dispensing_out_of_stock_drugs == 1);
}
function can_issue_out_of_stock_drugs(): bool {
$general_settings = GeneralSettings::find(1);
return ($general_settings->allow_issuing_out_of_stock_drugs == 1);
}
function is_chi_enabled() {
$general_settings = GeneralSettings::find(1);
if ($general_settings->chi_enabled == 1) {
return true;
} else {
return false;
}
}
/**
* Check if this is a new patient by virtue of them having one episode
*/
function is_patient_new($patient_id, $id): bool {
$episodes_count = DB::table('patient_episodes')->where('patient_id', $patient_id)
->where('id', '<', $id)->count();
return ($episodes_count < 1);
}
function is_patient_new_in_clinic($patient_id, $clinic, $id): bool {
$episodes_count = DB::table('patient_episodes')->where('patient_id', $patient_id)
->where('id', '<', $id)
->where('clinic_id', $clinic)->count();
return ($episodes_count < 1);
}
function is_patient_new_in_ward($patient_id, $ward_id, $episode_id): bool {
$episodes_count = DB::table('inpatient_info')->where('patient_id', $patient_id)
->where('episode_id', '<', $episode_id)
->where('ward_id', $ward_id)->count();
return ($episodes_count < 1);
}
function get_first_cost_of_good($item_id, $item_category_id)
{
$first_cost_price_of_item = null;
$first_cost_of_good = \Streamline\Models\CostOfGood::where(['item_id' => $item_id, 'item_category' => $item_category_id])->orderBy('id', 'asc')->first();
if (!is_null($first_cost_of_good)) {
$first_cost_price_of_item = $first_cost_of_good->cost_price;
} else {
if ($item_category_id == 1) {
$first_cost_price_of_item = get_name($item_id, "id", "cost_price", "drugs");
} elseif ($item_category_id == 2) {
$first_cost_price_of_item = get_name($item_id, "id", "cost_price", "sundries");
} elseif ($item_category_id == 4) {
$first_cost_price_of_item = get_name($item_id, "id", "cost_price", "labs");
}
}
return is_numeric($first_cost_price_of_item) ? $first_cost_price_of_item : 0;
}
function is_drug_covered_by_pay_later_category($patient_category, $drug_id): bool {
$categories = explode(",", get_name($drug_id, 'id', 'patient_category_coverage', 'drugs'));
// if it is in array, then it is not covered
return !in_array($patient_category, $categories);
}
function add_doctors_fee_to_patient_services($consultation_id, $completed_by) {
$patient_id = get_name($consultation_id, 'id', 'patient_id', 'consultations');
$episode_id = get_name($consultation_id, 'id', 'episode_id', 'consultations');
$category_id = get_name($patient_id, 'id', 'category_id', 'patients');
$doctor = User::find($completed_by);
$general_settings = GeneralSettings::find(1);
if ($doctor->hasRole('Doctors') && $general_settings->add_service_to_patient_bill != 0 && !is_patient_category_pay_later($category_id)) {
// register the service for doctor's fee
$service_id = DB::table('services')
->where('id', $general_settings->add_service_to_patient_bill)
->first();
if ($service_id) {
// check is any service has been already paid for and do not add mandatory service
$can_service_be_ordered = true;
$ordered_services = OrderedService::where('patient_id', $patient_id)
->where('episode_id', $episode_id)
->get(['service_id']);
foreach ($ordered_services as $ordered_service) {
$split_ordered_service = explode(",", $ordered_service->service_id);
if (!$can_service_be_ordered) {
break;
}
foreach ($split_ordered_service as $split_service_id) {
if ($split_service_id == $service_id->id || get_name($split_service_id, "id", "item_type", "services") == 'Consultation') {
$can_service_be_ordered = false;
break;
}
}
}
if ($can_service_be_ordered) {
// save the service
$new_ordered_service = new Orderedservice;
$new_ordered_service->patient_id = $patient_id;
$new_ordered_service->episode_id = $episode_id;
$new_ordered_service->service_id = $service_id->id;
$new_ordered_service->quantity = 1;
$new_ordered_service->payment_status = 0;
$new_ordered_service->performed = 0;
$new_ordered_service->performed_id = 0;
$new_ordered_service->created_by = $completed_by;
$new_ordered_service->save();
}
}
}
}
function can_investigations_be_performed($patient_category): bool {
$general_settings = GeneralSettings::find(1);
return (is_patient_category_pay_later($patient_category) && $general_settings->enable_performing_unpaid_investigations == 1) ||
$general_settings->enable_performing_unpaid_investigations == 2;
}
function get_progressive_treatment_balance($treatment_id, $patient_id) {
$treatment_record = DB::table('treatments')->find($treatment_id);
if ($treatment_record->is_treatment_progressive != 0) {
// pick up the original prescription
$original_prescription = DB::table('treatments_opd_progressive')->find($treatment_record->is_treatment_progressive);
$drug_explode = explode(",", $original_prescription->drugs);
$quantity_to_dispense = explode(",", $original_prescription->quantities_to_dispense);
$original_treatment_total = 0;
$total_amount_paid_so_far = 0;
for ($x = 0; $x < count($drug_explode); $x++){
// get insurance status for drug
$drug_insurance_status = get_name($drug_explode[$x], "id", "insurance_coverage", "drugs");
// check if the patient category is attached to a price list
$price_list_id = is_patient_category_attached_to_price_list($patient_id);
if ($price_list_id) {
$treatment_amount = get_price_list_category_price($price_list_id, 3, $drug_explode[$x]);
} else {
// check if drug and patient is eligible for insurance
if($drug_insurance_status == 1 && patient_insurance_status($patient_id) == 1){
$treatment_amount = get_name($drug_explode[$x], "id", "insured_price", "drugs");
} else {
$treatment_amount = get_name($drug_explode[$x], "id", "non_insured_price", "drugs");
}
}
if(isset($quantity_to_dispense[$x]) && $quantity_to_dispense[$x] != ""){
$original_treatment_total += ($quantity_to_dispense[$x] * $treatment_amount);
} else {
$original_treatment_total += 0;
}
}
$previous_progressive_treatments = DB::table('treatments')->whereIn('id', explode(",", $original_prescription->treatment_ids))->get();
foreach($previous_progressive_treatments as $treatment) {
$drugs = explode(",", $treatment->drugs);
$quantity_to_dispense = explode(",", $treatment->quantities_dispensed);
for($i=0; $i < count($drugs); $i++) {
// get insurance status for drug
$drug_insurance_status = get_name($drugs[$i], "id", "insurance_coverage", "drugs");
// check if the patient category is attached to a price list
$price_list_id = is_patient_category_attached_to_price_list($patient_id);
if ($price_list_id) {
$treatment_amount = get_price_list_category_price($price_list_id, 3, $drugs[$i]);
} else {
// check if drug and patient is eligible for insurance
if($drug_insurance_status == 1 && patient_insurance_status($patient_id) == 1){
$treatment_amount = get_name($drugs[$i], "id", "insured_price", "drugs");
} else {
$treatment_amount = get_name($drugs[$i], "id", "non_insured_price", "drugs");
}
}
$treatment_subtotal = $quantity_to_dispense[$i] * $treatment_amount;
$total_amount_paid_so_far += $treatment_subtotal;
}
}
$balance = $original_treatment_total - $total_amount_paid_so_far;
return ($balance > 0) ? $balance : 0;
} else {
return 0;
}
}
function is_cashier_receipt_type_print_html(): bool {
$general_settings = GeneralSettings::find(1);
return $general_settings->cashier_receipts_print_format == 0;
}
function reorganise_old_specialsed_invs_results($id, $results_id) {
// now try to reorganize the results already in the table
$specialized_variables = DB::table('investigation_specialised_variables')
->where('investigation_id', $id)
->whereNull('deleted_at')
->orderBy('ranking','asc')
->get(['id'])->toArray();
$variables = [];
foreach ($specialized_variables as $record) {
$variables[] = $record->id;
}
$results = DB::table('investigation_specialised_results')
->where('id', $results_id)
->first();
if ($results && $results->specialised_variable_id !== implode(',', $variables)) {
$specialised_variable_id = explode(',', $results->specialised_variable_id);
$value = explode(',', $results->value);
$comment = explode(',', $results->comment);
$specialised_variable_id_new = [];
$value_new = [];
$comment_new = [];
// iterate through the variables array and order the 4 above in that particular order
foreach ($variables as $variable) {
// find the position of that variable
$key = array_search($variable, $specialised_variable_id);
if ($key !== false) {
$specialised_variable_id_new[] = $specialised_variable_id[$key];
$value_new[] = $value[$key];
$comment_new[] = $comment[$key];
}
}
DB::table('investigation_specialised_results')
->where('id', $results_id)
->update([
'specialised_variable_id' => implode(',', $specialised_variable_id_new),
'value' => implode(',', $value_new),
'comment' => implode(',', $comment_new),
]);
}
}
function reverse_family_consumption_record($receipt_number, $amount_to_refund, $is_full_refund) {
$family_account_consumption = DB::table('family_account_consumptions')
->where('receipt_number', $receipt_number)
->first();
if ($family_account_consumption) {
// begin DB transaction
DB::transaction(function () use ($family_account_consumption, $amount_to_refund, $is_full_refund, $receipt_number) {
$family_account_id = $family_account_consumption->family_account_id;
$amount_consumed = $family_account_consumption->amount_consumed;
$new_amount_consumed = $amount_consumed - $amount_to_refund;
$new_amount_consumed = ($new_amount_consumed > 0) ? $new_amount_consumed : 0;
if ($is_full_refund) {
DB::table('family_account_consumptions')
->where('receipt_number', $receipt_number)
->delete();
$amount_to_refund = $family_account_consumption->amount_consumed;
} else {
$family_account_consumption = FamilyAccountConsumption::find($family_account_consumption->id);
$family_account_consumption->amount_consumed = $new_amount_consumed;
$family_account_consumption->updated_by = auth()->user()->id;
$family_account_consumption->save();
}
//reduce the current balance of this family account with the amount that has been consumed
$family_account = FamilyAccount::find($family_account_id);
$family_account->current_balance = $family_account->current_balance + $amount_to_refund;
$family_account->save();
//reduce the balance on "family deposits" chart of accounts table
$chart_of_account_id = get_name("family_account_deposits", "slug", "id", "chart_of_accounts");
$chart_of_account = ChartOfAccount::find($chart_of_account_id);
$chart_of_account->balance = $chart_of_account->balance + $amount_to_refund;
$chart_of_account->update();
});
}
}
function does_patient_category_have_threshold($patient_category_id)
{
$patient_discounts_records = \Streamline\Models\PatientDiscount::where('patient_category', $patient_category_id)->get();
$threshold_type = null;
$status = false;
if (count($patient_discounts_records) > 0) {
$record = $patient_discounts_records->first();
$threshold_type = $record->threshold_type;
if($threshold_type !== null){
$status = true;
}
}
return $status;
}
function patient_is_a_dependant_of($patient_id)
{
$dependant_records = \Streamline\Models\CategoryPatientDependant::all();
$patient_depended_on = null;
foreach ($dependant_records as $record) {
$dependants_array = explode(",", $record->dependant_patient_ids);
if (in_array($patient_id, $dependants_array) || $patient_id == $record->main_patient_id) {
$patient_depended_on = $record->main_patient_id;
}
}
if(is_null($patient_depended_on)){
//it might be be a patient with no dependants registered dependants yet, so check if category is eligible
$patient_category_id = get_name($patient_id, "id", "category_id", "patients");
$possible_category_discount = PatientDiscount::where('patient_category', $patient_category_id)->first();
if ($possible_category_discount) {
//patient's category has a discount so check threshold & register this patient in dependants table to self
if (!is_null($possible_category_discount->threshold_type)) {
$patient_category_depedants = new \Streamline\Models\CategoryPatientDependant;
$patient_category_depedants->main_patient_id = $patient_id;
$patient_category_depedants->dependant_patient_ids = strval($patient_id);
$patient_category_depedants->patient_category_id = $patient_category_id;
if($patient_category_depedants->save()){
$patient_depended_on = $patient_category_depedants->main_patient_id;
}
}
}
}
return $patient_depended_on;
}
function get_balance_from_category_threshold($main_patient_id)
{
$group_consumed_amount = $balance = $unpaid_balances = 0;
$consumptions = \Streamline\Models\DependantsConsumption::where('main_patient_id', $main_patient_id)->get();
foreach($consumptions as $dependant_consumption){
$group_consumed_amount += $dependant_consumption->amount_consumed;
$unpaid_balances += $dependant_consumption->unpaid_balance;
}
$main_patient_details = Patient::withTrashed()->find($main_patient_id);
$main_patient_category = $main_patient_details->category_id;
$threshold_amount = get_name($main_patient_category, "patient_category", "threshold_amount", "patient_discounts");
$threshold_amount = is_numeric($threshold_amount) ? $threshold_amount : 0;
if ($group_consumed_amount > $threshold_amount) {
$balance = -$unpaid_balances;
} else{
$balance = $threshold_amount - $group_consumed_amount;
}
return $balance;
}
function individual_of_invoice($invoice_number)
{
$main_patient_id = $main_patient_name = null;
$invoices = \Streamline\Models\PatientCategoryInvoice::where('invoice_number', $invoice_number)->get();
if (count($invoices) > 0) {
foreach ($invoices as $record) {
$main_patient_id = $record->is_invoice_for_individual;
}
}
$main_patient_name = is_null($main_patient_id) ? null : get_full_name($main_patient_id, "id", "first_name", "last_name", "patients")."(".get_name($main_patient_id, "id", "number", "patients").")";
return $main_patient_name;
}
function clear_dependants_consumptions($invoice_number)
{
$payment = \Streamline\Models\InvoicePayment::where('invoice_number', $invoice_number)->get()->first();
$consumptions = \Streamline\Models\DependantsConsumption::where('invoice_number', $invoice_number)->where('unpaid_balance', '>', 0)->get();
$total_invoice_amount_paid = $payment->amount_paid;
$invoice_amount_after_one_patient_bill_reduction = $total_invoice_amount_paid;
if (count($consumptions) > 0) {
foreach ($consumptions as $dependant_consumption) {
$patient_invoice_bill = $dependant_consumption->unpaid_balance;
if ($dependant_consumption->unpaid_balance > 0) {
if (($invoice_amount_after_one_patient_bill_reduction > $patient_invoice_bill) || ($invoice_amount_after_one_patient_bill_reduction == $patient_invoice_bill)) {
\Streamline\Models\DependantsConsumption::where('id', $dependant_consumption->id)->update([
'amount_paid' => $patient_invoice_bill,
'unpaid_balance' => 0,
'paid' => 1
]);
$invoice_amount_after_one_patient_bill_reduction = $invoice_amount_after_one_patient_bill_reduction - $patient_invoice_bill;
} elseif (($invoice_amount_after_one_patient_bill_reduction < $patient_invoice_bill) && ($invoice_amount_after_one_patient_bill_reduction > 0)) {
# if there is sm money left on payemnt after deduction but less that the whole bill of patient pay some items
$balance_remaining = $patient_invoice_bill - $invoice_amount_after_one_patient_bill_reduction;
\Streamline\Models\DependantsConsumption::where('id', $dependant_consumption->id)->update([
'amount_paid' => $invoice_amount_after_one_patient_bill_reduction,
'unpaid_balance' => $balance_remaining
]);
$invoice_amount_after_one_patient_bill_reduction = 0;
break;
}
}
}
}
}
function mother_of_patient($patient_id)
{
$mother_id = null;
$patient = Patient::withTrashed()->find($patient_id);
if ($patient) {
$mother_id = $patient->parent_id;
}
return $mother_id;
}
function children_of_patient($patient_id)
{
$children_ids = null;
$patients = Patient::where('parent_id', $patient_id)->get();
if (count($patients) > 0) {
foreach ($patients as $patient) {
$children_ids[] = $patient->id;
}
}
return $children_ids;
}
function can_receipt_be_cancelled($receipt_number): bool {
// check for patient debts
$debts = DB::table('debtors')
->where('receipt_number', $receipt_number)
->whereNotNull('amount_paid_off')
->count();
if ($debts > 0) {
return false;
}
// check the debt plan
$debt_plan = DB::table('debt_plan')
->where('receipt_number', $receipt_number)
->whereNotNull('amount_paid_off')
->count();
if ($debt_plan > 0) {
return false;
}
return true;
}
function can_central_billing_be_cancelled($receipt_number): bool {
$deposit_details = DB::table('central_billing_deposits')
->where('receipt_number', $receipt_number)
->get();
// first make sure that none of the money was collected
foreach ($deposit_details as $deposit_detail) {
if ($deposit_detail->tag_id == 2) {
$result = DB::table('investigation_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->get();
} else if ($deposit_detail->tag_id == 3) {
$result = DB::table('treatment_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->get();
} else if ($deposit_detail->tag_id == 4) {
$result = DB::table('procedure_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->get();
} else if ($deposit_detail->tag_id == 5) {
$result = DB::table('sundries_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->get();
} else if ($deposit_detail->tag_id == 8) {
$result = DB::table('service_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->get();
}
$invoices_result = DB::table('patient_category_invoices')
->where('receipt_number', $receipt_number)
->where('invoice_generated', 1)
->get();
if (count($result) > 0 || count($invoices_result) > 0) {
return false;
}
}
// check for patient debts
$debts = DB::table('debtors')
->where('receipt_number', $receipt_number)
->whereNotNull('amount_paid_off')
->count();
if ($debts > 0) {
return false;
}
// check the debt plan
$debt_plan = DB::table('debt_plan')
->where('receipt_number', $receipt_number)
->whereNotNull('amount_paid_off')
->count();
if ($debt_plan > 0) {
return false;
}
return true;
}
function batch_tracking_method()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->batch_tracking_method;
}
function last_item_dispensation_to_ward($item_id, $item_type, $ward_id)
{
$last_quantity_taken = 0;
$dispensation_date = null;
$last_dispensation_details_array = [];
$ward_item_request_record = \Streamline\Models\WardItemRequest::where(['ward_id' => $ward_id, 'item_type' => $item_type, 'dispensation_status' => 1])->whereRaw('FIND_IN_SET('. $item_id .',item_ids)')->orderBY('id', 'desc')->first();
if ($ward_item_request_record) {
$items_ids_array = explode(",", $ward_item_request_record->item_ids);
$items_quantities_array = explode(",", $ward_item_request_record->quantity_issued_out);
for ($i=0; $i < count($items_ids_array) ; $i++) {
if ($item_id == $items_ids_array[$i]) {
$last_quantity_taken = $items_quantities_array[$i];
$dispensation_date = $ward_item_request_record->dispensation_date;
}
}
}
$last_dispensation_details_array = [$last_quantity_taken, $dispensation_date];
return $last_dispensation_details_array;
}
function record_patient_accounts_consumption($patient_id, $episode_id, $amount_consumed, $tag_id, $receipt_number) {
$patient_account_consumption = new PatientAccountConsumption;
$patient_account_consumption->patient_id = $patient_id;
$patient_account_consumption->episode_id = $episode_id;
$patient_account_consumption->amount_consumed = $amount_consumed;
$patient_account_consumption->tag_id = $tag_id;
$patient_account_consumption->receipt_number = $receipt_number;
$patient_account_consumption->created_by = auth()->user()->id;
if ($patient_account_consumption->save()) {
// reduce the patient's current balance by deleted amount
$patient_to_update = Patient::find($patient_id);
$patient_to_update->patient_account_balance = (int)$patient_to_update->patient_account_balance - (int)$amount_consumed;
$patient_to_update->update();
$patient_account_balance_id = get_name("patient_account_balance", "slug", "id", "chart_of_accounts");
if (is_numeric($patient_account_balance_id)) {
// decrease the balance on chart of accounts called "patient account deposit"
$chart_of_account = ChartOfAccount::find($patient_account_balance_id);
$chart_of_account->balance = $chart_of_account->balance - (int)$amount_consumed;
$chart_of_account->update();
} else {
flash('A chart of accounts is missing. Please contact Stre@mline support immediately!')->error();
}
}
}
function reverse_patient_account_consumption_record($receipt_number, $amount_to_refund, $is_full_refund)
{
$patient_account_consumption = DB::table('patient_account_consumptions')
->where('receipt_number', $receipt_number)
->first();
if ($patient_account_consumption) {
// begin DB transaction
DB::transaction(function () use ($patient_account_consumption, $amount_to_refund, $is_full_refund, $receipt_number) {
$patient_id = $patient_account_consumption->patient_id;
$amount_consumed = $patient_account_consumption->amount_consumed;
$new_amount_consumed = $amount_consumed - $amount_to_refund;
$new_amount_consumed = ($new_amount_consumed > 0) ? $new_amount_consumed : 0;
if ($is_full_refund) {
DB::table('patient_account_consumptions')
->where('receipt_number', $receipt_number)
->delete();
$amount_to_refund = $patient_account_consumption->amount_consumed;
} else {
$patient_account_consumption = PatientAccountConsumption::find($patient_account_consumption->id);
$patient_account_consumption->amount_consumed = $new_amount_consumed;
$patient_account_consumption->updated_by = auth()->user()->id;
$patient_account_consumption->save();
}
// increase the patient's current balance by deleted amount
$patient_to_update = Patient::find($patient_id);
$patient_to_update->patient_account_balance = (int)$patient_to_update->patient_account_balance + $amount_to_refund;
$patient_to_update->update();
$patient_account_balance_id = get_name("patient_account_balance", "slug", "id", "chart_of_accounts");
if (is_numeric($patient_account_balance_id)) {
// increase the balance on chart of accounts called "patient account deposit"
$chart_of_account = ChartOfAccount::find($patient_account_balance_id);
$chart_of_account->balance = $chart_of_account->balance - $amount_to_refund;
$chart_of_account->update();
} else {
flash('A chart of accounts is missing. Please contact Stre@mline support immediately!')->error();
}
});
}
}
function does_investigation_have_template($id, $is_variable) {
$templates = DB::table('investigation_result_templates')
->whereIn('investigation_id', [$id, 0])
->where('is_specialised_variable', $is_variable)
->whereNull('deleted_at')
->get();
return count($templates) > 0;
}
function is_patient_accounts_enabled(): bool {
$general_settings = GeneralSettings::find(1);
return $general_settings->patient_accounts_enabled == 1;
}
function is_family_consumption_allowed($this_patient_to_pay, $this_family_account_balance, $family_account_credit_limit): bool {
if (($this_patient_to_pay > $this_family_account_balance) && !can_family_accounts_consume_more_than_balance()) {
// check for credit limit for the family
if ($family_account_credit_limit == 0) {
//over family consumption message
flash('Family account balance is less than the current bill.')->error();
return false;
} else {
// add amount to the current balance and turn everything into +ve for stress relief
$potential_family_account_balance = $this_family_account_balance - $this_patient_to_pay;
if($potential_family_account_balance < $family_account_credit_limit){
session()->put('credit_limit_message', 'Bill is beyond credit limit by '. ugandan_shillings(-($potential_family_account_balance - $family_account_credit_limit)));
return false;
}
}
}
return true;
}
function get_investigation_billing_mode()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->investigation_billing_mode;
}
function get_doctor_who_completed_episode_consultation($episode_id)
{
$consultation_details = Consultation::where('episode_id', $episode_id)->first();
if (!is_null($consultation_details)) {
if (!is_null($consultation_details->consultation_done_by)) {
return $consultation_details->consultation_done_by;
} else {
return $consultation_details->created_by;
}
}
return null;
}
function get_ward_investigation_pricing($patient_id, $episode_id, $investigation_id, $order_id) {
$ward_investigation = \Streamline\Models\WardInvestigationPricing::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'investigation_id' => $investigation_id, 'order_id' => $order_id])->orderBy('id', 'desc')->first();
if ($ward_investigation) {
return $ward_investigation->price;
} else {
return "N/A";
}
}
function get_ward_investigation_chi_pricing($patient_id, $episode_id, $investigation_id, $order_id) {
$ward_investigation = \Streamline\Models\WardInvestigationPricing::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'investigation_id' => $investigation_id, 'order_id' => $order_id])->orderBy('id', 'desc')->first();
return $ward_investigation ? $ward_investigation->chi_price : 'N/A';
}
function create_anc_registration_record_from_previous_visit($patient_id, $previous_episode_id, $episode_id)
{
$previous_anc_registration = AnteNatalClinicRegistration::where(['patient_id' => $patient_id, 'episode_id' => $previous_episode_id])->first();
$pregnancy_registration_copy = $previous_anc_registration->replicate();
$pregnancy_registration_copy->episode_id = $episode_id;
$pregnancy_registration_copy->created_at = Carbon::now();
$pregnancy_registration_copy->save();
}
function is_tuberculosis_screening_enabled()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->enable_tuberculosis_screening == 1) {
return true;
} else {
return false;
}
}
function is_hiv_and_gbv_screening_tool_enabled(): bool
{
$general_settings = GeneralSettings::find(1);
return $general_settings->enable_hiv_and_gbv_screening_tool === 1;
}
function array_group_by_key($values, $key): array {
$return_array = [];
foreach ($values as $value) {
if ($value instanceof stdClass) {
$return_array[$value->$key][] = $value;
} elseif (is_array($value)) {
$return_array[$value[$key]][] = $value;
}
}
return $return_array;
}
function get_item_average_monthly_consumption($item_type, $item_id, $period_span)
{
$total_quantity = 0;
$sub_months = Carbon::now()->subMonth($period_span);
//dd($sub_months);
if ($item_type == 1) {
//opd
$patient_dispensings = \Streamline\Models\PatientDispensing::whereDate('created_at', '>', $sub_months)->whereRaw('FIND_IN_SET('. $item_id .',drugs)')->get();
if (count($patient_dispensings) > 0) {
foreach ($patient_dispensings as $record) {
$drug_ids_array = explode(",", $record->drugs);
$quantities_array = explode(",", $record->quantity_dispensed);
$purchased_elsewhere_array = explode(",", $record->purchased_elsewhere);
for ($i = 0; $i < count($drug_ids_array); $i++) {
if (isset($purchased_elsewhere_array[$i]) && $purchased_elsewhere_array[$i] == 0) {
$clean_qty = is_numeric($quantities_array[$i]) ? $quantities_array[$i] : 0;
$total_quantity += $clean_qty;
}
}
}
}
//ward treatment using ward_prescription model
$ward_dispensations = \Streamline\Models\WardTreatmentDispensation::whereDate('created_at', '>', $sub_months)->where('drug_id', $item_id)->get();
if (count($ward_dispensations) > 0) {
foreach ($ward_dispensations as $ward_record) {
$total_quantity += $ward_record->quantity_given;
}
}
//ward treatment using ward_pricing model
$ward_pricing_factors = \Streamline\Models\InpatientInfo::whereDate('created_at', '>', $sub_months)->whereNotNull('ward_treatments')->get();
if (count($ward_pricing_factors) > 0) {
foreach ($ward_pricing_factors as $ward_record) {
$inpatient_ward_treatment = unserialize($ward_record->ward_treatments);
$drugs = isset($inpatient_ward_treatment['drugs']) ? $inpatient_ward_treatment['drugs'] : 0;
$days = isset($inpatient_ward_treatment['days']) ? $inpatient_ward_treatment['days'] : 0;
if (is_array($drugs)) {
for($i = 0; $i < count($drugs); $i++){
$consumed_drug = \Streamline\Models\Drug::withTrashed()->find($drugs[$i]);
if ($consumed_drug) {
$today = date("Y-m-d");
$dob = get_name($ward_record->patient_id, "id", "date_of_birth", "patients");
$difference = days_months_years($dob, $today);
$years = $difference[2];
$age_bracket = "";
if (between($years, 0, 5)){
$age_bracket = __('inpatient.infant');
} elseif (between($years, 6, 12)){
$age_bracket = __('inpatient.child');
} elseif ($years > 12){
$age_bracket = __('inpatient.adult');
}
if ($age_bracket == __('inpatient.infant')){
$quantity = $consumed_drug->pricing_factor_infant * $days[$i];
} elseif ($age_bracket == __('inpatient.child')){
$quantity = $consumed_drug->pricing_factor_children * $days[$i];
} elseif ($age_bracket == __('inpatient.adult')){
$quantity = $consumed_drug->pricing_factor_adult * $days[$i];
}
$total_quantity += $quantity;
}
}
}
}
}
}
if ($item_type == 2) {
//opd sundries
$opd_used_sundries = \Streamline\Models\OrderedSundry::whereDate('created_at', '>', $sub_months)->whereRaw('FIND_IN_SET('. $item_id .',sundries_id)')->get();
if (count($opd_used_sundries) > 0) {
foreach ($opd_used_sundries as $record) {
$sundries_ids_array = explode(",", $record->sundries_id);
$quantities_array = explode(",", $record->quantity);
for ($i = 0; $i < count($sundries_ids_array); $i++) {
$total_quantity += $quantities_array[$i];
}
}
}
//ward sundries
$ward_dispensations = \Streamline\Models\WardSundryDispensation::whereDate('dispensation_date', '>', $sub_months)->where('sundry_id', $item_id)->get();
if (count($ward_dispensations) > 0) {
foreach ($ward_dispensations as $ward_record) {
$total_quantity += $ward_record->quantity_given;
}
}
}
if ($item_type == 5) {
# code...
}
if ($item_type == 6) {
# code...
}
//calculate the average
if ($total_quantity != 0) {
return round($total_quantity/$period_span);
}
return "N/A";
}
function register_chronic_patient($patient_id, $episode_id, $drug_id) {
$already_registered = ChronicPatient::where(['patient_id' => $patient_id, 'drug_id' => $drug_id])->first();
if (!$already_registered) {
$chronic_patient = new ChronicPatient();
$chronic_patient->patient_id = $patient_id;
$chronic_patient->episode_id = $episode_id;
$chronic_patient->drug_id = $drug_id;
$chronic_patient->created_by = Auth::id();
$chronic_patient->save();
}
}
function is_drug_chronic($drug_id) {
$result = DB::table("drugs")->where("id", $drug_id)->first();
if (!$result) {
$chronic_status = 0;
} else {
$chronic_status = $result->long_term;
}
return $chronic_status == 1;
}
function is_investigation_chronic($drug_id) {
$result = DB::table("investigations")->where("id", $drug_id)->first();
return $result && ($result->is_chronic == 1);
}
function register_chronic_investigation($patient_id, $episode_id, $inv_id) {
$already_registered = ChronicPatient::where(['patient_id' => $patient_id, 'investigation_id' => $inv_id])->first();
if (!$already_registered) {
$chronic_patient = new ChronicPatient();
$chronic_patient->patient_id = $patient_id;
$chronic_patient->episode_id = $episode_id;
$chronic_patient->investigation_id = $inv_id;
$chronic_patient->created_by = Auth::id();
$chronic_patient->save();
}
}
function save_new_stock_level($item_id, $item_type) {
$today = date('Y-m-d');
$ward_stock = get_item_ward_stock($item_id, $item_type);
$stock_watcher_drug = DB::table('stock_watcher')->where('item_id', $item_id)->where('item_type', $item_type)->first();
if ($stock_watcher_drug) {
$details_arr = json_decode($stock_watcher_drug->details, true);
$update_stock_watcher = StockWatcher::find($stock_watcher_drug->id);
} else {
$details_arr = [];
$update_stock_watcher = new StockWatcher;
$update_stock_watcher->item_type = $item_type;
$update_stock_watcher->item_id = $item_id;
}
if ($item_type == 1) {
// drugs
$drug = DB::table('drugs')->where('id', $item_id)->first();
if ($drug) {
$details_arr[$today] = [
"pharmacy_stock" => $drug->pharmacy_stock,
"store_stock" => $drug->store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $drug->cost_price,
"selling_price" => $drug->non_insured_price,
"inventory_account_id" => $drug->inventory_account,
"cost_of_goods_account_id" => $drug->cost_of_goods_account
];
} else {
return;
}
} elseif ($item_type == 2) {
// sundries
$sundry = DB::table('sundries')->where('id', $item_id)->first();
if ($sundry) {
$details_arr[$today] = [
"pharmacy_stock" => $sundry->pharmacy_stock,
"store_stock" => $sundry->store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $sundry->cost_price,
"selling_price" => $sundry->non_insured_price,
"inventory_account_id" => $sundry->inventory_account,
"cost_of_goods_account_id" => $sundry->cost_of_goods_account
];
} else {
return;
}
} elseif ($item_type == 3) {
// dental
$dental = DB::table('dentals')->where('id', $item_id)->first();
if ($dental) {
$details_arr[$today] = [
"pharmacy_stock" => $dental->pharmacy_stock,
"store_stock" => $dental->store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $dental->buying_price,
"selling_price" => $dental->non_insured_price,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
} elseif ($item_type == 4) {
// radiology
$radiology = DB::table('radiologies')->where('id', $item_id)->first();
if ($radiology) {
$details_arr[$today] = [
"pharmacy_stock" => $radiology->pharmacy_stock,
"store_stock" => $radiology->store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $radiology->cost_price,
"selling_price" => $radiology->non_insured_price,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
} elseif ($item_type == 5) {
// labs
$lab = DB::table('labs')->where('id', $item_id)->first();
if ($lab) {
$details_arr[$today] = [
"pharmacy_stock" => $lab->laboratory_stock,
"store_stock" => $lab->store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $lab->cost_price,
"selling_price" => $lab->non_insured_price,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
} elseif ($item_type == 6) {
// general items
$item = DB::table('general_items')->where('id', $item_id)->first();
if ($item) {
$details_arr[$today] = [
"pharmacy_stock" => 0,
"store_stock" => $item->store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $item->cost_price,
"selling_price" => 0,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
}
$update_stock_watcher->details = json_encode($details_arr);
$update_stock_watcher->save();
}
function format_key($value){
$val = str_replace('_', ' ', $value);
return ucwords($val);
}
function format_id($value){
$val = str_replace('id', ' ', $value);
return ucwords($val);
}
function get_inventory_reduction_point()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->point_of_inventory_reduction;
}
function view_procedure_price_on_order()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->view_procedure_price_on_order;
}
function view_prescription_price_on_order()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->view_prescription_price_on_order;
}
function view_investigation_price_on_order()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->view_investigation_price_on_order;
}
function view_sundry_price_on_order()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->view_sundry_price_on_order;
}
function view_service_price_on_order()
{
$general_settings = GeneralSettings::find(1);
return $general_settings->view_service_price_on_order;
}
function save_inpatient_bill($inpatient_info_id) {
$inpatient_info = InpatientInfo::find($inpatient_info_id);
$patient_id = $inpatient_info->patient_id;
$episode_id = $inpatient_info->episode_id;
$patient = Patient::find($patient_id);
if (!$patient) {return;}
$total_deposits_paid = $insurance_investigations = $insurance_treatments = $insurance_sundries = 0;
$insurance_services = $insurance_procedures = $insurance_tta = $investigation_amount_total = $insurance_opd_treatment = 0;
$opd_procedure_insurance_amount_total = $opd_unpaid_treatment_total = $opd_procedure_amount_total = 0;
$investigations_item_ids = $investigations_tariff_ids = $investigations_benefit_ids = $investigation_insurance_amount = [];
$prescription_treatment_item_prices = $drug_unit_insurance_amount = $ward_drug_quantity = $prescription_treatment_item_ids = [];
$prescription_treatment_tariff_ids = $prescription_treatment_benefit_ids = $drug_subtotal = $drug_insurance_amount = [];
$pf_treatment_item_ids = $investigation_order_ids = $pf_treatment_item_prices = [];
$price_list_id = is_patient_category_attached_to_price_list($patient_id);
$patient_insurance_status = (patient_insurance_status($patient_id) == 1);
if ($inpatient_info->discharged == 1) {
$end_date = new DateTime($inpatient_info->discharged_on);
} else {
$end_date = new DateTime(date('Y-m-d'));
}
$start_date = new DateTime($inpatient_info->admitted_on);
$days_spent_in_ward = ($end_date->diff($start_date)->format('%a'));
$services_with_users_array = InpatientController::configured_users_with_their_services_array();
$service_deposits = ServiceDeposit::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->get();
$ward_bed_stays = WardBedStay::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->get();
$ward_bed_admission_total_cost = $ward_bed_admission_chi_total_cost = 0;
foreach($ward_bed_stays as $bed_record) {
$chi_accommodation_cost = $chi_bed_rate_id = 0;
if ($patient_insurance_status) {
$bed_prices = get_inpatient_admission_cost_insurance($bed_record->duration, $bed_record->bed_category, $bed_record->bed_fee_rate, $patient_id);
$accommodation_cost = $bed_prices[0];
$chi_accommodation_cost = $bed_prices[1];
$chi_bed_rate_id = $bed_prices[2];
} else {
$accommodation_cost = get_inpatient_admission_cost($bed_record->duration, $bed_record->bed_category, $bed_record->bed_fee_rate);
}
$ward_bed_admission_total_cost += $accommodation_cost;
$ward_bed_admission_chi_total_cost += $chi_accommodation_cost;
$bed_record->bed_fee_total = $accommodation_cost;
$bed_record->chi_bed_fee_total = $chi_accommodation_cost;
$bed_record->chi_bed_rate_id = $chi_bed_rate_id;
$bed_record->save();
}
$ordered_ward_investigations = OrderedInvestigation::where(['episode_id' => $episode_id, 'payment_status' => '0'])->get();
if(count($ordered_ward_investigations) > 0) {
// ids of the ordered investigations
$investigation_amount = $investigation_ids = $all_order_ids_array = [];
foreach($ordered_ward_investigations as $ordered_investigation){
if (get_investigation_billing_mode() == 1 && $ordered_investigation->investigation_status == 0) {continue;}
$investigation_ids = array_merge($investigation_ids, explode(",", $ordered_investigation->investigation_id));
$single_order_investigations = explode(",",$ordered_investigation->investigation_id);
for ($w=0; $w < count($single_order_investigations) ; $w++) {
$investigation_order_ids[] = $ordered_investigation->id;
$all_order_ids_array[] = $ordered_investigation->id;
}
}
for ($i = 0; $i < count($investigation_ids); $i++) {
$tariff_id = 0;
$benefit_id = 0;
$investigation_amount_insurance = 0;
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $investigation_ids[$i], 3, true);
$investigation_item_amount = $item_insurance_details[2];
$investigation_amount_insurance = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
} else {
if ($price_list_id) {
$investigation_item_amount = get_price_list_category_price($price_list_id, 2, $investigation_ids[$i]);
} else {
$investigation_item_amount = get_name($investigation_ids[$i], "id", "non_insured_price", "investigations");
}
}
//check if there is a saved record in ward investigation pricing
$saved_ward_price = get_ward_investigation_pricing($patient_id, $episode_id, $investigation_ids[$i], $all_order_ids_array[$i]);
//if the inv exists in ward pricing table use that price else use default
if($saved_ward_price != "N/A"){
$investigation_item_amount = $saved_ward_price;
}
$saved_ward_chi_price = get_ward_investigation_chi_pricing($patient_id, $episode_id, $investigation_ids[$i], $all_order_ids_array[$i]);
$investigation_amount_insurance = $saved_ward_chi_price == 'N/A' ? $investigation_amount_insurance : $saved_ward_chi_price;
$investigation_amount_total += $investigation_item_amount;
$insurance_investigations += $investigation_amount_insurance;
$investigations_item_ids[] = $investigation_ids[$i];
$investigations_tariff_ids[] = $tariff_id;
$investigations_benefit_ids[] = $benefit_id;
$investigation_amount[] = $investigation_item_amount;
$investigation_insurance_amount[] = $investigation_amount_insurance;
}
}
$investigation_cost = $investigation_amount_total;
$insurance_investigation_cost = $insurance_investigations;
$this_drug_sp = 0;
$insurance_treatment_to_pay = 0;
$treatment_total_cost = 0;
if(get_ward_prescription_model() == 1 || $patient_insurance_status) {
if (!empty($dispensed_drug_quantity_given_array)) {
foreach ($dispensed_drug_quantity_given_array as $drug_id => $quantity_given) {
$tariff_id = 0;
$benefit_id = 0;
if ($patient_insurance_status) {
$item_insurance_details = get_item_insurance_pricing($patient_id, $drug_id, 4, true);
$insurance_treatment_to_pay = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
}
//get actual total costs in case the price of item changed after dispensation to allow retro billing
$this_drug_total_price = 0;
$per_ward_drug_given_rows = DB::table('ward_treatment_dispensations')->whereNull('deleted_at')->where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'drug_id' => $drug_id])->get();
foreach ($per_ward_drug_given_rows as $drug_ward_record) {
$this_drug_sp = $drug_ward_record->price;
$this_drug_sp = is_numeric($this_drug_sp) ? $this_drug_sp : 0;
$this_drug_total_price += ($this_drug_sp * $drug_ward_record->quantity_given);
$insurance_treatment_to_pay = $drug_ward_record->chi_price;
}
$treatment_total_cost += $this_drug_total_price;
$insurance_treatments += ($insurance_treatment_to_pay * $quantity_given);
$prescription_treatment_item_prices[] = $this_drug_sp;
$drug_unit_insurance_amount[] = $insurance_treatment_to_pay;
$ward_drug_quantity[] = $quantity_given;
$prescription_treatment_item_ids[] = $drug_id;
$prescription_treatment_tariff_ids[] = $tariff_id;
$prescription_treatment_benefit_ids[] = $benefit_id;
$drug_subtotal[] = $this_drug_total_price;
$drug_insurance_amount[] = $insurance_treatment_to_pay * $quantity_given;
}
}
} elseif(get_ward_prescription_model() == 2) {
$inpatient_ward_treatment = unserialize($inpatient_info->ward_treatments);
$dob = get_name($patient_id, "id", "date_of_birth", "patients");
$difference = days_months_years($dob, date("Y-m-d"));
$years = $difference[2];
$age_bracket = "";
if (between($years, 0, 5)){
$age_bracket = __('inpatient.infant');
} elseif (between($years, 6, 12)){
$age_bracket = __('inpatient.child');
} elseif ($years > 12){
$age_bracket = __('inpatient.adult');
}
if($inpatient_ward_treatment) {
// for old streamline system records which were using a weird naming convention
$drugs = $inpatient_ward_treatment['drugs'] ?? $inpatient_ward_treatment['Drugs'];
$days = $inpatient_ward_treatment['days'] ?? $inpatient_ward_treatment['Days'];
for($i = 0; $i < count($drugs); $i++) {
$daily_cost = 0;
if ($age_bracket == __('inpatient.infant')){
$daily_cost = get_name($drugs[$i], 'id', 'ip_daily_cost_infant', 'drugs');
} elseif ($age_bracket == __('inpatient.child')){
$daily_cost = get_name($drugs[$i], 'id', 'ip_daily_cost_children', 'drugs');
} elseif ($age_bracket == __('inpatient.adult')){
$daily_cost = get_name($drugs[$i], 'id', 'ip_daily_cost_adult', 'drugs');
}
if (!is_numeric($daily_cost)){
$daily_cost = 0;
}
$pf_treatment_item_ids[] = $drugs[$i];
$pf_treatment_item_prices[] = $daily_cost;
$treatment_total_cost += $daily_cost * $days[$i];
}
}
}
$treatment_cost = $treatment_total_cost;
$insurance_treatment_cost = $insurance_treatments;
$opd_unpaid_treatments = Treatment::where(['patient_id' => $patient_id, 'episode_id' => $episode_id,'payment_status' => 0, 'tta' => 0])->get();
$opd_treatment_amount = $opd_treatment_insurance_amount = $opd_treatment_subtotal = [];
$opd_treatment_quantity = $opd_treatment_insurance_unit_amount = $opd_treatment_item = [];
$opd_treatment_tariff = $opd_treatment_benefit = $opd_treatment_id = [];
if (count($opd_unpaid_treatments) > 0) {
foreach($opd_unpaid_treatments as $opd_treatment) {
if(!(is_incoming_prescriptions_feature_enabled() && $opd_treatment->confirmation_status == 0)) {
$opd_drug_ids = explode(",", $opd_treatment->drugs);
$drug_quantities = explode(",", $opd_treatment->quantities_dispensed);
$purchased_elsewhere = explode(",", $opd_treatment->purchased_elsewhere);
$unit_selling_prices_array = is_null($opd_treatment->unit_selling_prices) ? [] : explode(",", $opd_treatment->unit_selling_prices);
for ($i = 0; $i < count($opd_drug_ids); $i++) {
if(get_name($opd_drug_ids[$i], "id", "name", "drugs") != "N/A") {
$opd_treatment_item_insurance_amount = 0;
$tariff_id = 0;
$benefit_id = 0;
// check if drug and patient is eligible for insurance
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $opd_drug_ids[$i], 4, true);
$opd_item_treatment_amount = $item_insurance_details[2];
$opd_treatment_item_insurance_amount = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
} else {
if (isset($unit_selling_prices_array[$i]) && !is_null($unit_selling_prices_array[$i])) {
$opd_item_treatment_amount = is_numeric($unit_selling_prices_array[$i]) ? $unit_selling_prices_array[$i] : 0;
} else {
if ($price_list_id) {
$opd_item_treatment_amount = get_price_list_category_price($price_list_id, 3, $opd_drug_ids[$i]);
} else {
$opd_item_treatment_amount = get_name($opd_drug_ids[$i], "id", "non_insured_price", "drugs");
}
}
}
// get money saved from the inpatient bill table
$opd_item_treatment_amount = $saved_drug_prices[$opd_drug_ids[$i]] ?? $opd_item_treatment_amount;
$opd_treatment_item_insurance_amount = $saved_chi_drug_prices[$opd_drug_ids[$i]] ?? $opd_treatment_item_insurance_amount;
if(isset($drug_quantities[$i]) && $drug_quantities[$i] != ""){
$opd_item_treatment_subtotal = $drug_quantities[$i] * $opd_item_treatment_amount;
$opd_treatment_insurance_subtotal = $drug_quantities[$i] * $opd_treatment_item_insurance_amount;
} else {
$opd_item_treatment_subtotal = 0;
$opd_treatment_insurance_subtotal = 0;
}
// add amounts to totals
$opd_unpaid_treatment_total += $opd_item_treatment_subtotal;
$insurance_opd_treatment += $opd_treatment_insurance_subtotal;
if (!(count($purchased_elsewhere) > 0 && isset($purchased_elsewhere[$i]) && $purchased_elsewhere[$i] == 1)) {
$opd_treatment_quantity[] = $drug_quantities[$i];
$opd_treatment_amount[] = $opd_item_treatment_amount;
$opd_treatment_insurance_unit_amount[] = $opd_treatment_item_insurance_amount;
$opd_treatment_subtotal[] = $opd_item_treatment_subtotal;
$opd_treatment_insurance_amount[] = $opd_treatment_insurance_subtotal;
$opd_treatment_item[] = $opd_drug_ids[$i];
$opd_treatment_tariff[] = $tariff_id;
$opd_treatment_benefit[] = $benefit_id;
$opd_treatment_id[] = $opd_treatment->id;
}
}
}
}
}
$opd_treatment_cost = $opd_unpaid_treatment_total;
}
$sundries_total_cost = 0;
$ward_sundry_quantities_given = DB::table('ward_sundry_dispensations')->whereNull('deleted_at')->where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->groupBy('sundry_id')->selectRaw('*, sum(quantity_given) as quantity_given')->get();
$sundries_item_ids = $sundries_benefit_ids = $sundries_tariff_ids = $sundries_item_prices = [];
$sundry_unit_insurance_amount = $sundry_quantity_given = $sundry_subtotal = $sundry_insurance_amount = [];
if(count($ward_sundry_quantities_given) > 0) {
foreach($ward_sundry_quantities_given as $sundry_record) {
$this_sundry_sp = 0;
$tariff_id = 0;
$benefit_id = 0;
$insurance_sundry_amount = 0;
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $sundry_record->sundry_id, 5, true);
$sundries_cost = $item_insurance_details[2];
$insurance_sundry_amount = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
} else {
if ($price_list_id) {
$sundries_cost = get_price_list_category_price($price_list_id, 5, $sundry_record->sundry_id);
} else {
$sundries_cost = get_name($sundry_record->sundry_id, "id", "non_insured_price", "sundries");
}
}
//get actual total costs incase the price of item changed after dispensation to allow retro billing
$this_sundry_total_price = 0;
$per_ward_sundry_given_rows = DB::table('ward_sundry_dispensations')->whereNull('deleted_at')->where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'sundry_id' => $sundry_record->sundry_id])->get();
if (count($per_ward_sundry_given_rows) > 0) {
foreach ($per_ward_sundry_given_rows as $sundry_ward_record) {
$this_sundry_sp = ($sundry_ward_record->price != 0) ? $sundry_ward_record->price : $sundries_cost;
$this_sundry_total_price += ($this_sundry_sp * $sundry_ward_record->quantity_given);
$insurance_sundry_amount = $sundry_ward_record->chi_price;
}
} else {
$this_sundry_total_price = $sundry_record->quantity_given * $sundries_cost;
}
$sundries_total_cost += $this_sundry_total_price;
$insurance_sundries += ($sundry_record->quantity_given * $insurance_sundry_amount);
$sundries_item_ids[] = $sundry_record->sundry_id;
$sundries_benefit_ids[] = $benefit_id;
$sundries_tariff_ids[] = $tariff_id;
$sundries_item_prices[] = $this_sundry_sp;
$sundry_unit_insurance_amount[] = $insurance_sundry_amount;
$sundry_quantity_given[] = $sundry_record->quantity_given;
$sundry_subtotal[] = $this_sundry_total_price;
$sundry_insurance_amount[] = $sundry_record->quantity_given * $insurance_sundry_amount;
}
}
$sundries_cost = $sundries_total_cost;
$insurance_sundries_cost = $insurance_sundries;
$opd_sundries_ids_request = $opd_sundry_amount_request = $opd_sundry_subtotal_request = $opd_sundries_benefit_ids = [];
$opd_sundries_tariff_ids = $opd_sundry_insurance_unit = $opd_sundry_quantity = $opd_sundry_insurance_amount = [];
$opd_unpaid_sundries = OrderedSundry::where(['patient_id' => $patient_id, 'episode_id' => $episode_id,'payment_status' => 0])->get();
$opd_sundries_total_cost = $opd_insurance_sundries = 0;
if (count($opd_unpaid_sundries) > 0) {
$opd_sundries_ids = [];
$opd_sundries_quantity = [];
$opd_sundry_order_ids = [];
$opd_sundries_orders_amounts = [];
$opd_unit_sundries_selling_prices_array = [];
foreach($opd_unpaid_sundries as $opd_ordered_sundry){
$opd_sundries_ids = array_merge($opd_sundries_ids, explode(",", $opd_ordered_sundry->sundries_id));
$opd_sundries_quantity = array_merge($opd_sundries_quantity, explode(",",$opd_ordered_sundry->quantity));
$opd_unit_sundries_selling_prices_array = array_merge($opd_unit_sundries_selling_prices_array, explode(",",$opd_ordered_sundry->sundries_amount));// is_null($treatment->sundries_amount) ? [] : explode(",", $treatment->unit_selling_prices);
$opd_sundry_order_ids[] = $opd_ordered_sundry->id;
//if amounts are put at the time of ordering
$opd_sundries_orders_amounts = is_null($opd_ordered_sundry->sundries_amount) ? array_merge($opd_sundries_orders_amounts, []) : array_merge($opd_sundries_orders_amounts, explode(",", $opd_ordered_sundry->sundries_amount));
}
$orders_count = 0;
for ($i = 0; $i < count($opd_sundries_ids); $i++) {
$tariff_id = 0;
$benefit_id = 0;
$opd_sund_insurance_amount = 0;
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $opd_sundries_ids[$i], 5, true);
$opd_sundry_amount = $item_insurance_details[2];
$opd_sund_insurance_amount = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
} else {
if (isset($opd_unit_sundries_selling_prices_array[$i]) && is_numeric($opd_unit_sundries_selling_prices_array[$i])) {
$opd_sundry_amount = $opd_unit_sundries_selling_prices_array[$i];
} else {
// check if the patient category is attached to a price list
if ($price_list_id) {
$opd_sundry_amount = get_price_list_category_price($price_list_id, 5, $opd_sundries_ids[$i]);
} else {
$opd_sundry_amount = $opd_sundries_orders_amounts[$i] ?? get_name($opd_sundries_ids[$i], "id", "non_insured_price", "sundries");
}
}
}
$opd_sundry_amount = $saved_sundry_prices[$opd_sundries_ids[$i]] ?? $opd_sundry_amount;
$opd_sund_insurance_amount = $saved_chi_sundry_prices[$opd_sundries_ids[$i]] ?? $opd_sund_insurance_amount;
// get the subtotal for this sundry
$opd_sundry_subtotal = $opd_sundries_quantity[$orders_count] * $opd_sundry_amount;
$opd_sundry_insurance_subtotal = $opd_sundries_quantity[$orders_count] * $opd_sund_insurance_amount;
$opd_sundries_ids_request[] = $opd_sundries_ids[$i];
$opd_sundries_benefit_ids[] = $benefit_id;
$opd_sundries_tariff_ids[] = $tariff_id;
$opd_sundry_amount_request[] = $opd_sundry_amount;
$opd_sundry_insurance_unit[] = $opd_sund_insurance_amount;
$opd_sundry_quantity[] = $opd_sundries_quantity[$orders_count];
$opd_sundry_subtotal_request[] = $opd_sundry_subtotal;
$opd_sundry_insurance_amount[] = $opd_sundry_insurance_subtotal;
$orders_count++;
$opd_sundries_total_cost += $opd_sundry_subtotal;
$opd_insurance_sundries += $opd_sundry_insurance_subtotal;
}
$opd_sundries_cost = $opd_sundries_total_cost;
$insurance_opd_sundries_cost = $opd_insurance_sundries;
}
$services_total_cost = 0;
$ward_services_quantities_given = DB::table('ward_consultations_and_services')->whereNull('deleted_at')->where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->get();
$service_benefit_ids = $service_tariff_ids = $services_item_ids = $services_item_prices = [];
$service_insurance_unit = $service_quantity = $service_total_cost = $service_insurance_amount = [];
if(count($ward_services_quantities_given) > 0) {
foreach($ward_services_quantities_given as $record) {
$tariff_id = 0;
$benefit_id = 0;
if(array_key_exists($record->service_id, $services_with_users_array)){
$services_user_key = explode("__", $record->service_id);
$service_id = $services_user_key[0];
} else {
$service_id = $record->service_id;
}
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $service_id, 1, true);
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
}
$services_cost = $record->unit_price;
$service_amount_insurance = $record->chi_price;
$services_total_cost += ($services_cost * $record->quantity_given);
$insurance_services += ($record->quantity_given * $service_amount_insurance);
$service_benefit_ids[] = $benefit_id;
$service_tariff_ids[] = $tariff_id;
$services_item_ids[] = $service_id;
$services_item_prices[] = $services_cost;
$service_insurance_unit[] = $service_amount_insurance;
$service_quantity[] = $record->quantity_given;
$service_total_cost[] = $services_cost * $record->quantity_given;
$service_insurance_amount[] = $record->quantity_given * $service_amount_insurance;
}
}
$insurance_services_cost = $insurance_services;
$opd_unpaid_services = OrderedService::where(['patient_id' => $patient_id, 'episode_id' => $episode_id,'payment_status' => 0])->get();
$opd_services_amount_total = $opd_services_insurance_amount_total = 0;
$opd_service_id = $opd_service_benefit_ids = $opd_service_tariff_ids = $opd_service_unit_cost = [];
$opd_service_insurance_unit = $opd_service_quantity = $opd_service_amount = $opd_service_insurance_amount = [];
if (count($opd_unpaid_services) > 0) {
foreach($opd_unpaid_services as $used_service) {
$service_ids = explode(",", $used_service->service_id);
$service_quantity = explode(",", $used_service->quantity);
$ordered_services_amounts = (is_null($used_service->service_amount) || $used_service->service_amount == '') ? []: explode(",", $used_service->service_amount);
$opd_service_order_id[] = $used_service->id;
for($i = 0; $i < count($service_ids); $i++) {
$tariff_id = 0;
$benefit_id = 0;
$opd_service_insurance = 0;
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $service_ids[$i], 1, true);
$service_cost = $item_insurance_details[2];
$opd_service_insurance = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
} else {
if($price_list_id){
$service_cost = get_price_list_category_price($price_list_id, 6, $service_ids[$i]);
} else {
$pre_order = Services::withTrashed()->find($service_ids[$i]);
//if amount was set at time of ordering
$service_cost = $ordered_services_amounts[$i] ?? $pre_order->non_insured_price;
}
}
$service_cost = $saved_services_prices[$service_ids[$i]] ?? $service_cost;
$opd_service_insurance = $saved_chi_services_prices[$service_ids[$i]] ?? $opd_service_insurance;
$opd_service_id[] = $service_ids[$i];
$opd_service_benefit_ids[] = $benefit_id;
$opd_service_tariff_ids[] = $tariff_id;
$opd_service_unit_cost[] = $service_cost;
$opd_service_insurance_unit[] = $opd_service_insurance;
$opd_service_quantity[] = $service_quantity[$i];
$opd_service_amount[] = $service_cost * $service_quantity[$i];
$opd_service_insurance_amount[] = $opd_service_insurance * $service_quantity[$i];
$opd_services_amount_total += ($service_cost * $service_quantity[$i]);
$opd_services_insurance_amount_total += ($opd_service_insurance * $service_quantity[$i]);
}
}
$opd_services_cost = $opd_services_amount_total;
$insurance_opd_services_cost = $opd_services_insurance_amount_total;
}
$ward_procedures = DB::table('ward_procedures')->whereNull('deleted_at')->where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->get();
$procedures_total_cost = 0;
$ipd_procedure_benefit_ids = $ipd_procedure_tariff_ids = $ipd_procedure_order_ids = $ipd_procedure_amount = $procedures_item_ids = $ipd_procedure_insurance_amount = [];
foreach($ward_procedures as $ward_procedure) {
$tariff_id = 0;
$benefit_id = 0;
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $ward_procedure->procedure_id, 2, true);
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
}
$procedure_price = $ward_procedure->hospital_fee;
$procedure_amount_insurance = $ward_procedure->chi_price;
$procedures_total_cost += ($procedure_price + $ward_procedure->staff_fee);
$insurance_procedures += $procedure_amount_insurance;
$ipd_procedure_benefit_ids[] = $benefit_id;
$ipd_procedure_tariff_ids[] = $tariff_id;
$ipd_procedure_amount[] = $procedure_price;
$procedures_item_ids[] = $ward_procedure->procedure_id;
$ipd_procedure_order_ids[] = $ward_procedure->id;
$ipd_procedure_insurance_amount[] = $procedure_amount_insurance;
}
$opd_unpaid_procedures = OrderedProcedure::where(['patient_id' => $patient_id, 'episode_id' => $episode_id,'payment_status' => 0])->get();
$opd_procedure_amount_request = $opd_procedure_benefit_ids = $opd_procedure_tariff_ids = $opd_procedure_insurance_amount = [];
if (count($opd_unpaid_procedures) > 0) {
$opd_procedure_ids = array();
$opd_procedure_order_ids = array();
$opd_procedures_orders_amounts = [];
foreach($opd_unpaid_procedures as $opd_ordered_procedure){
$opd_procedure_ids = array_merge($opd_procedure_ids, explode(",", $opd_ordered_procedure->procedure_id));
$opd_procedure_order_ids[] = $opd_ordered_procedure->id;
$opd_procedures_orders_amounts = is_null($opd_ordered_procedure->procedure_amount) ? array_merge($opd_procedures_orders_amounts, []) : array_merge($opd_procedures_orders_amounts, explode(",", $opd_ordered_procedure->procedure_amount));
}
for ($i = 0; $i < count($opd_procedure_ids); $i++) {
$opd_insurance_amount = 0;
$tariff_id = 0;
$benefit_id = 0;
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $opd_procedure_ids[$i], 2, true);
$opd_procedure_amount = $item_insurance_details[2];
$opd_insurance_amount = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
} else {
// check if the patient category is attached to a price list
if ($price_list_id) {
$opd_procedure_amount = get_price_list_category_price($price_list_id, 4, $opd_procedure_ids[$i]);
} else {
//if amount was set at time of ordering
if (isset($opd_procedures_orders_amounts[$i]) && !is_null($opd_procedures_orders_amounts[$i])) {
$opd_procedure_amount = $opd_procedures_orders_amounts[$i];
} else{
$opd_procedure_amount = get_name($opd_procedure_ids[$i], "id", "non_insured_price", "procedures");
}
}
}
$opd_procedure_amount = $saved_procedures_prices[$opd_procedure_ids[$i]] ?? $opd_procedure_amount;
$opd_insurance_amount = $saved_chi_procedures_prices[$opd_procedure_ids[$i]] ?? $opd_insurance_amount;
// add amounts to totals
$opd_procedure_amount_total += $opd_procedure_amount;
$opd_procedure_insurance_amount_total += $opd_insurance_amount;
$opd_procedure_benefit_ids[] = $benefit_id;
$opd_procedure_tariff_ids[] = $tariff_id;
$opd_procedure_amount_request[] = $opd_procedure_amount;
$opd_procedure_insurance_amount[] = $opd_insurance_amount;
}
$opd_procedures_cost = $opd_procedure_amount_total;
$insurance_opd_procedures_cost = $opd_procedure_insurance_amount_total;
}
$drugs_given_anae_cost_total = 0;
$anaesthesia = DB::table('anaesthesias')->where('episode_id', $episode_id)->select('other_drugs_given', 'other_drugs_cost', 'other_drugs_bill')->first();
if ($anaesthesia) {
$drugs_given_anae = @unserialize($anaesthesia->other_drugs_given);
$drugs_given_anae_cost = @unserialize($anaesthesia->other_drugs_cost);
$do_not_bill_other_drugs = explode(",", $anaesthesia->other_drugs_bill);
$drugs_given_anae = is_array($drugs_given_anae) ? $drugs_given_anae : [];
$drugs = DB::table('drugs')->whereNull('deleted_at')->pluck('name', 'id');
if (count($drugs_given_anae) > 0) {
foreach ($drugs_given_anae as $key => $value) {
if (isset($drugs[$value['id']]) && !in_array($value['id'], $do_not_bill_other_drugs)) {
$cost = isset($drugs_given_anae_cost[$key]) ? trim($drugs_given_anae_cost[$key]) : 0;
$drugs_given_anae_cost_total += $cost;
}
}
}
}
$tta_total_cost = 0;
$treatment_to_take_away = Treatment::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'tta' => 1])->get();
$tta_insurance_amount_arr = $tta_drugs_array_request = $tta_treatment_id = $tta_tariff_ids = $tta_benefit_ids = $tta_unit_cost = [];
$tta_insurance_unit = $tta_quantity = $tta_amount = [];
if(count($treatment_to_take_away) > 0) {
foreach($treatment_to_take_away as $treatment) {
$tta_drugs_array = explode(",", $treatment->drugs);
$tta_dispensed_array = explode(",", $treatment->quantities_dispensed);
$tta_unit_selling_prices_array = is_null($treatment->unit_selling_prices) ? [] : explode(",", $treatment->unit_selling_prices);
for($x = 0; $x < count($tta_drugs_array); $x++) {
$tariff_id = 0;
$benefit_id = 0;
$tta_insurance_amount = 0;
if($patient_insurance_status){
$item_insurance_details = get_item_insurance_pricing($patient_id, $tta_drugs_array[$x], 4, true);
$drugs_cost = $item_insurance_details[2];
$tta_insurance_amount = $item_insurance_details[1];
$tariff_id = $item_insurance_details[3];
$benefit_id = $item_insurance_details[4];
} else {
if (isset($tta_unit_selling_prices_array[$x])) {
$drugs_cost = is_numeric($tta_unit_selling_prices_array[$x]) ? $tta_unit_selling_prices_array[$x] : 0;
} else {
if ($price_list_id) {
$drugs_cost = get_price_list_category_price($price_list_id, 3, $tta_drugs_array[$x]);
} else {
$drugs_cost = get_name($tta_drugs_array[$x], "id", "non_insured_price", "drugs");
}
}
}
$drugs_cost = $saved_tta_prices[$tta_drugs_array[$x]] ?? $drugs_cost;
$tta_insurance_amount = $saved_chi_tta_prices[$tta_drugs_array[$x]] ?? $tta_insurance_amount;
$insurance_tta += $tta_dispensed_array[$x] * $tta_insurance_amount;
$tta_drugs_array_request[] = $tta_drugs_array[$x];
$tta_tariff_ids[] = $tariff_id;
$tta_benefit_ids[] = $benefit_id;
$tta_unit_cost[] = $drugs_cost;
$tta_insurance_unit[] = $tta_insurance_amount;
$tta_quantity[] = $tta_dispensed_array[$x];
$tta_total_cost += $drugs_cost * $tta_dispensed_array[$x];
$tta_amount[] = $drugs_cost * $tta_dispensed_array[$x];
$tta_insurance_amount_arr[] = $tta_dispensed_array[$x] * $tta_insurance_amount;
}
$tta_treatment_id[] = $treatment->id;
}
}
$insurance_tta_cost = $insurance_tta;
$extras_total_cost = 0;
$ward_extras_given = DB::table('ward_extras')->whereNull('deleted_at')->where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->get();
if(count($ward_extras_given) > 0) {
foreach($ward_extras_given as $extras_record) {
$extras_total_cost += $extras_record->extra_cost;
}
}
$extras_cost = $extras_total_cost;
$unpaid_opd_grand_total = $opd_unpaid_treatment_total + $opd_sundries_total_cost + $opd_services_amount_total + $opd_procedure_amount_total;
$amount_to_pay = $extras_total_cost + $tta_total_cost + $procedures_total_cost + $sundries_total_cost + $treatment_total_cost + $ward_bed_admission_total_cost + $investigation_amount_total + $services_total_cost + $drugs_given_anae_cost_total + $unpaid_opd_grand_total;
if(count($service_deposits) > 0) {
foreach($service_deposits as $service_deposit) {
if(($service_deposit->service_type == "Inpatient_Deposit") && ($service_deposit->patient_id == $patient_id) && ($service_deposit->episode_id == $episode_id)) {
$total_deposits_paid += $service_deposit->patient_amount_paid;
}
}
}
$original_amount_owed = $amount_to_pay;
$ward_discount_records = InpatientWardDiscounts::where(['inpatient_info_id' => $inpatient_info->id])->get();
$ward_discount_total = 0;
foreach($ward_discount_records as $ward_discount) {
$ward_discount_total += $ward_discount->amount;
}
$category_to_pay_deposits = 0;
$patient_category_invoices_record = PatientCategoryInvoice::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'patient_category' => $patient->category_id])->get();
if(count($patient_category_invoices_record) > 0) {
foreach($patient_category_invoices_record as $invoice_record) {
if($invoice_record->tag_id == 9 || $invoice_record->tag_id == 10) {
$category_to_pay_deposits += $invoice_record->patient_amount;
}
}
}
$invoices_amount = $category_to_pay_deposits;
$dependant_consumptions_total = 0;
$dependant_consumptions = DependantsConsumption::where(['dependant_patient_id' => $patient_id, 'episode_id' => $episode_id])->get();
if(count($dependant_consumptions) > 0) {
foreach($dependant_consumptions as $dependant_consumption_record) {
if($dependant_consumption_record->items_ids == "Inpatient-deposit") {
$dependant_consumptions_total += $dependant_consumption_record->amount_consumed;
}
}
}
$debt_plan_total = 0;
$debt_plan_payments = DebtPlan::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'tag_id' => 10])->get();
foreach($debt_plan_payments as $debt_plan_payment) {
$debt_plan_total += $debt_plan_payment->staff_guarantor_to_pay;
}
$deposits_made = $total_deposits_paid;
$amount_owed = $amount_to_pay - $total_deposits_paid - $category_to_pay_deposits - $ward_discount_total - $debt_plan_total - $dependant_consumptions_total;
/** Save the inpatient bill now */
$insurance_claims = [];
// generate receipt number
$receipt_number = generateReceiptNumberFromDB();
// store ward investigations and there dynamic prices
$ward_investigations_array = $investigations_item_ids ?? [];
$ward_investigations_amounts_array = $investigation_amount ?? [];
$ward_investigations_insurance_amounts_array = $investigation_insurance_amount ?? [];
$ward_investigation_order_ids = $investigation_order_ids ?? [];
$investigations_tariff_ids = $investigations_tariff_ids ?? [];
$investigations_benefit_ids = $investigations_benefit_ids ?? [];
for ($i=0; $i < count($ward_investigations_array) ; $i++) {
$ward_inv_pricing = WardInvestigationPricing::firstOrNew(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'investigation_id' => $ward_investigations_array[$i]]);
$ward_inv_pricing->patient_id = $patient_id;
$ward_inv_pricing->episode_id = $episode_id;
$ward_inv_pricing->investigation_id = $ward_investigations_array[$i];
$ward_inv_pricing->price = $ward_investigations_amounts_array[$i];
$ward_inv_pricing->chi_price = $ward_investigations_insurance_amounts_array[$i];
$ward_inv_pricing->order_id = $ward_investigation_order_ids[$i] ?? null;
$ward_inv_pricing->ward_id = get_name($inpatient_info_id, "id", "ward_id", "inpatient_info");
$ward_inv_pricing->current_chart_of_account = get_name($ward_investigations_array[$i], "id", "account_id", "investigations");
$ward_inv_pricing->created_by = auth()->user()->id;
$ward_inv_pricing->save();
// check if benefit is valid and save item
if ($investigations_benefit_ids[$i] != 0) {
$insurance_claims[3]["benefit_ids"][] = $investigations_benefit_ids[$i];
$insurance_claims[3]["item_ids"][] = $ward_investigations_array[$i];
$insurance_claims[3]["item_quantities"][] = 1;
$insurance_claims[3]["tariff_ids"][] = $investigations_tariff_ids[$i];
$insurance_claims[3]["tariff_amounts"][] = $ward_investigations_insurance_amounts_array[$i];
$insurance_claims[3]["co_payment_amounts"][] = $ward_investigations_amounts_array[$i];
$insurance_claims[3]["item_cash_amounts"][] = $ward_investigations_insurance_amounts_array[$i] + $ward_investigations_amounts_array[$i];
}
}
// ward treatments
$ward_treatments_ids = $prescription_treatment_item_ids ?? [];
$ward_treatment_amounts = $prescription_treatment_item_prices ?? [];
$ward_treatment_insurance = $drug_unit_insurance_amount ?? [];
$ward_treatment_tariff_ids = $prescription_treatment_tariff_ids ?? [];
$ward_treatment_benefit_ids = $prescription_treatment_benefit_ids ?? [];
$ward_treatment_quantities = $ward_drug_quantity ?? [];
$ward_treatment_subtotal = $drug_subtotal ?? [];
$ward_treatment_subtotal_insurance = $drug_insurance_amount ?? [];
for ($i=0; $i < count($ward_treatments_ids); $i++) {
$ward_treatment = WardTreatmentDispensation::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'drug_id' => $ward_treatments_ids[$i]])->first();
if ($ward_treatment) {
$ward_treatment->price = $ward_treatment_amounts[$i] ?? 0;
$ward_treatment->chi_price = $ward_treatment_insurance[$i] ?? 0;
$ward_treatment->update();
// check if benefit is valid and save item
if ($ward_treatment_benefit_ids[$i] != 0) {
$insurance_claims[4]["benefit_ids"][] = $ward_treatment_benefit_ids[$i];
$insurance_claims[4]["item_ids"][] = $ward_treatments_ids[$i];
$insurance_claims[4]["item_quantities"][] = $ward_treatment_quantities[$i];
$insurance_claims[4]["tariff_ids"][] = $ward_treatment_tariff_ids[$i];
$insurance_claims[4]["tariff_amounts"][] = $ward_treatment_subtotal_insurance[$i];
$insurance_claims[4]["co_payment_amounts"][] = $ward_treatment_subtotal[$i];
$insurance_claims[4]["item_cash_amounts"][] = $ward_treatment_subtotal_insurance[$i] + $ward_treatment_subtotal[$i];
}
}
}
// ward services
$ward_service_ids = $services_item_ids ?? [];
$ward_service_amounts = $services_item_prices ?? [];
$ward_service_insurance = $service_insurance_unit ?? [];
$ward_service_benefit_ids = $service_benefit_ids ?? [];
$ward_service_tariff_ids = $service_tariff_ids ?? [];
$ward_service_quantity = $service_quantity ?? [];
$ward_service_total_cost = $service_total_cost ?? [];
$ward_service_total_insurance = $service_insurance_amount ?? [];
for ($i=0; $i < count($ward_service_ids); $i++) {
$ward_service = WardConsultationsAndService::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'service_id' => $ward_service_ids[$i]])->first();
if ($ward_service) {
$ward_service->unit_price = $ward_service_amounts[$i] ?? 0;
$ward_service->chi_price = $ward_service_insurance[$i] ?? 0;
$ward_service->update();
// check if benefit is valid and save item
if ($ward_service_benefit_ids[$i] != 0) {
$insurance_claims[1]["benefit_ids"][] = $ward_service_benefit_ids[$i];
$insurance_claims[1]["item_ids"][] = $ward_service_ids[$i];
$insurance_claims[1]["item_quantities"][] = $ward_service_quantity[$i];
$insurance_claims[1]["tariff_ids"][] = $ward_service_tariff_ids[$i];
$insurance_claims[1]["tariff_amounts"][] = $ward_service_total_insurance[$i];
$insurance_claims[1]["co_payment_amounts"][] = $ward_service_total_cost[$i];
$insurance_claims[1]["item_cash_amounts"][] = $ward_service_total_insurance[$i] + $ward_service_total_cost[$i];
}
}
}
// ward sundries
$ward_sundry_ids = $sundries_item_ids ?? [];
$ward_sundry_amounts = $sundries_item_prices ?? [];
$ward_sundry_insurance = $sundry_unit_insurance_amount ?? [];
$ward_sundry_tariff_ids = $sundries_tariff_ids ?? [];
$ward_sundry_benefit_ids = $sundries_benefit_ids ?? [];
$ward_sundry_quantity = $sundry_quantity_given ?? [];
$ward_sundry_subtotal = $sundry_subtotal ?? [];
$ward_sundry_subtotal_insurance = $sundry_insurance_amount ?? [];
for ($i=0; $i < count($ward_sundry_ids); $i++) {
$ward_sundry = WardSundryDispensation::where(['patient_id' => $patient_id, 'episode_id' => $episode_id, 'sundry_id' => $ward_sundry_ids[$i]])->first();
if ($ward_sundry) {
$ward_sundry->price = $ward_sundry_amounts[$i] ?? 0;
$ward_sundry->chi_price = $ward_sundry_insurance[$i] ?? 0;
$ward_sundry->update();
// check if benefit is valid and save item
if ($ward_sundry_benefit_ids[$i] != 0) {
$insurance_claims[5]["benefit_ids"][] = $ward_sundry_benefit_ids[$i];
$insurance_claims[5]["item_ids"][] = $ward_sundry_ids[$i];
$insurance_claims[5]["item_quantities"][] = $ward_sundry_quantity[$i];
$insurance_claims[5]["tariff_ids"][] = $ward_sundry_tariff_ids[$i];
$insurance_claims[5]["tariff_amounts"][] = $ward_sundry_subtotal_insurance[$i];
$insurance_claims[5]["co_payment_amounts"][] = $ward_sundry_subtotal[$i];
$insurance_claims[5]["item_cash_amounts"][] = $ward_sundry_subtotal_insurance[$i] + $ward_sundry_subtotal[$i];
}
}
}
// ward procedures
$ward_procedure_ids = $procedures_item_ids ?? [];
$ward_procedure_amounts = $ipd_procedure_amount ?? [];
$ward_procedure_insurance = $ipd_procedure_insurance_amount ?? [];
$ward_procedure_benefit_ids = $ipd_procedure_benefit_ids ?? [];
$ward_procedure_tariff_ids = $ipd_procedure_tariff_ids ?? [];
for ($i=0; $i < count($ward_procedure_ids); $i++) {
$ward_procedure = WardProcedure::where('id', $ipd_procedure_order_ids[$i])->first();
if ($ward_procedure) {
$ward_procedure->hospital_fee = $ward_procedure_amounts[$i] ?? 0;
$ward_procedure->chi_price = $ward_procedure_insurance[$i] ?? 0;
$ward_procedure->update();
// check if benefit is valid and save item
if ($ward_procedure_benefit_ids[$i] != 0) {
$insurance_claims[2]["benefit_ids"][] = $ward_procedure_benefit_ids[$i];
$insurance_claims[2]["item_ids"][] = $ward_procedure_ids[$i];
$insurance_claims[2]["item_quantities"][] = 1;
$insurance_claims[2]["tariff_ids"][] = $ward_procedure_tariff_ids[$i];
$insurance_claims[2]["tariff_amounts"][] = $ward_procedure_insurance[$i];
$insurance_claims[2]["co_payment_amounts"][] = $ward_procedure_amounts[$i];
$insurance_claims[2]["item_cash_amounts"][] = $ward_procedure_insurance[$i] + $ward_procedure_amounts[$i];
}
}
}
// make claims for items if insured
if ($patient_insurance_status == 1) {
$opd_treatment_item = $opd_treatment_item ?? [];
$opd_treatment_tariff = $opd_treatment_tariff ?? [];
$opd_treatment_benefit = $opd_treatment_benefit ?? [];
$opd_treatment_quantity = $opd_treatment_quantity ?? [];
$opd_treatment_subtotal = $opd_treatment_subtotal ?? [];
$opd_treatment_insurance_amount = $opd_treatment_insurance_amount ?? [];
for ($i=0; $i < count($opd_treatment_item); $i++) {
if ($opd_treatment_benefit[$i] != 0) {
$insurance_claims[4]["benefit_ids"][] = $opd_treatment_benefit[$i];
$insurance_claims[4]["item_ids"][] = $opd_treatment_item[$i];
$insurance_claims[4]["item_quantities"][] = $opd_treatment_quantity[$i];
$insurance_claims[4]["tariff_ids"][] = $opd_treatment_tariff[$i];
$insurance_claims[4]["tariff_amounts"][] = $opd_treatment_insurance_amount[$i];
$insurance_claims[4]["co_payment_amounts"][] = $opd_treatment_subtotal[$i];
$insurance_claims[4]["item_cash_amounts"][] = $opd_treatment_insurance_amount[$i] + $opd_treatment_subtotal[$i];
}
}
$tta_drugs_array_request = $tta_drugs_array_request ?? [];
$tta_tariff_ids = $tta_tariff_ids ?? [];
$tta_benefit_ids = $tta_benefit_ids ?? [];
$tta_quantity = $tta_quantity ?? [];
$tta_amount = $tta_amount ?? [];
$tta_insurance_amount_arr = $tta_insurance_amount_arr ?? [];
for ($i=0; $i < count($tta_drugs_array_request); $i++) {
if ($tta_benefit_ids[$i] != 0) {
$insurance_claims[4]["benefit_ids"][] = $tta_benefit_ids[$i];
$insurance_claims[4]["item_ids"][] = $tta_drugs_array_request[$i];
$insurance_claims[4]["item_quantities"][] = $tta_quantity[$i];
$insurance_claims[4]["tariff_ids"][] = $tta_tariff_ids[$i];
$insurance_claims[4]["tariff_amounts"][] = $tta_amount[$i];
$insurance_claims[4]["co_payment_amounts"][] = $tta_insurance_amount_arr[$i];
$insurance_claims[4]["item_cash_amounts"][] = $tta_amount[$i] + $tta_insurance_amount_arr[$i];
}
}
$opd_service_id = $opd_service_id ?? [];
$opd_service_benefit_ids = $opd_service_benefit_ids ?? [];
$opd_service_tariff_ids = $opd_service_tariff_ids ?? [];
$opd_service_quantity = $opd_service_quantity ?? [];
$opd_service_amount = $opd_service_amount ?? [];
$opd_service_insurance_amount = $opd_service_insurance_amount ?? [];
for ($i=0; $i < count($opd_service_id); $i++) {
if ($opd_service_benefit_ids[$i] != 0) {
$insurance_claims[1]["benefit_ids"][] = $opd_service_benefit_ids[$i];
$insurance_claims[1]["item_ids"][] = $opd_service_id[$i];
$insurance_claims[1]["item_quantities"][] = $opd_service_quantity[$i];
$insurance_claims[1]["tariff_ids"][] = $opd_service_tariff_ids[$i];
$insurance_claims[1]["tariff_amounts"][] = $opd_service_insurance_amount[$i];
$insurance_claims[1]["co_payment_amounts"][] = $opd_service_amount[$i];
$insurance_claims[1]["item_cash_amounts"][] = $opd_service_insurance_amount[$i] + $opd_service_amount[$i];
}
}
$opd_sundries_ids_request = $opd_sundries_ids_request ?? [];
$opd_sundries_benefit_ids = $opd_sundries_benefit_ids ?? [];
$opd_sundries_tariff_ids = $opd_sundries_tariff_ids ?? [];
$opd_sundry_quantity = $opd_sundry_quantity ?? [];
$opd_sundry_subtotal_request = $opd_sundry_subtotal_request ?? [];
$opd_sundry_insurance_amount = $opd_sundry_insurance_amount ?? [];
for ($i=0; $i < count($opd_sundries_ids_request); $i++) {
if ($opd_sundries_benefit_ids[$i] != 0) {
$insurance_claims[5]["benefit_ids"][] = $opd_sundries_benefit_ids[$i];
$insurance_claims[5]["item_ids"][] = $opd_sundries_ids_request[$i];
$insurance_claims[5]["item_quantities"][] = $opd_sundry_quantity[$i];
$insurance_claims[5]["tariff_ids"][] = $opd_sundries_tariff_ids[$i];
$insurance_claims[5]["tariff_amounts"][] = $opd_sundry_subtotal_request[$i];
$insurance_claims[5]["co_payment_amounts"][] = $opd_sundry_insurance_amount[$i];
$insurance_claims[5]["item_cash_amounts"][] = $opd_sundry_subtotal_request[$i] + $opd_sundry_insurance_amount[$i];
}
}
$opd_procedure_ids = $opd_procedure_ids ?? [];
$opd_procedure_benefit_ids = $opd_procedure_benefit_ids ?? [];
$opd_procedure_tariff_ids = $opd_procedure_tariff_ids ?? [];
$opd_procedure_amount_request = $opd_procedure_amount_request ?? [];
$opd_procedure_insurance_amount = $opd_procedure_insurance_amount ?? [];
for ($i=0; $i < count($opd_procedure_ids); $i++) {
if ($opd_procedure_benefit_ids[$i] != 0) {
$insurance_claims[2]["benefit_ids"][] = $opd_procedure_benefit_ids[$i];
$insurance_claims[2]["item_ids"][] = $opd_procedure_ids[$i];
$insurance_claims[2]["item_quantities"][] = 1;
$insurance_claims[2]["tariff_ids"][] = $opd_procedure_tariff_ids[$i];
$insurance_claims[2]["tariff_amounts"][] = $opd_procedure_insurance_amount[$i];
$insurance_claims[2]["co_payment_amounts"][] = $opd_procedure_amount_request[$i];
$insurance_claims[2]["item_cash_amounts"][] = $opd_procedure_insurance_amount[$i] + $opd_procedure_amount_request[$i];
}
}
$ward_bed_stays = WardBedStay::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->whereNotIn('chi_bed_rate_id', [0])->get();
foreach ($ward_bed_stays as $stay) {
$rate_info = DB::table('insurance_inpatient_accommodation_rates')->where('id', $stay->chi_bed_rate_id)->first();
if($rate_info) {
$insurance_claims[6]["benefit_ids"][] = $rate_info->benefit_id;
$insurance_claims[6]["item_ids"][] = $rate_info->id;
$insurance_claims[6]["item_quantities"][] = $stay->duration;
$insurance_claims[6]["tariff_ids"][] = 0;
$insurance_claims[6]["tariff_amounts"][] = $stay->chi_bed_fee_total;
$insurance_claims[6]["co_payment_amounts"][] = $stay->bed_fee_total;
$insurance_claims[6]["item_cash_amounts"][] = $stay->chi_bed_fee_total + $stay->bed_fee_total;
}
}
}
// check if any investigations are available
$investigation_ids = $investigation_ids ?? false;
$investigation_order_ids = $investigation_order_ids ?? [];
if ($investigation_ids) {
$inpatient_info = InpatientInfo::find($inpatient_info_id);
$inpatient_info->investigation_ids = $investigation_ids;
$inpatient_info->update();
$order_ids_array = $investigation_order_ids;
// update the ordered_investigation table to show it has been paid
for ($i = 0; $i < count($order_ids_array); $i++) {
OrderedInvestigation::where(['id' => $order_ids_array[$i]])->update(['inpatient_bill_generated' => 1]);
remove_insurance_claim_by_order($order_ids_array[$i], 3);
}
}
$opd_treatment_id = $opd_treatment_id ?? [];
for ($i=0; $i < count($opd_treatment_id) ; $i++) {
Treatment::where(['id' => $opd_treatment_id[$i]])->update(['inpatient_bill_generated' => 1]);
remove_insurance_claim_by_order($opd_treatment_id[$i], 4);
}
$tta_treatment_id = $tta_treatment_id ?? [];
for ($i=0; $i < count($tta_treatment_id) ; $i++) {
Treatment::where(['id' => $tta_treatment_id[$i]])->update(['inpatient_bill_generated' => 1]);
remove_insurance_claim_by_order($tta_treatment_id[$i], 4);
}
$opd_sundry_order_ids = $opd_sundry_order_ids ?? [];
for ($i=0; $i < count($opd_sundry_order_ids) ; $i++) {
OrderedSundry::where(['id' => $opd_sundry_order_ids[$i]])->update(['inpatient_bill_generated' => 1]);
remove_insurance_claim_by_order($opd_sundry_order_ids[$i], 5);
}
$opd_service_order_id = $opd_service_order_id ?? [];
for ($i=0; $i < count($opd_service_order_id) ; $i++) {
OrderedService::where(['id' => $opd_service_order_id[$i]])->update(['inpatient_bill_generated' => 1]);
remove_insurance_claim_by_order($opd_service_order_id[$i], 1);
}
$opd_procedure_order_ids = $opd_procedure_order_ids ?? [];
for ($i=0; $i < count($opd_procedure_order_ids) ; $i++) {
OrderedProcedure::where(['id' => $opd_procedure_order_ids[$i]])->update(['inpatient_bill_generated' => 1]);
remove_insurance_claim_by_order($opd_procedure_order_ids[$i], 2);
}
$inpatient_bill = InpatientBill::where(['patient_id'=>$patient_id, 'episode_id'=>$episode_id])->first();
if (is_null($inpatient_bill)) {
// create new record
$inpatient_bill = new InpatientBill;
$inpatient_bill->patient_id = $patient_id;
$inpatient_bill->episode_id = $episode_id;
$inpatient_bill->created_by = Auth::id();
} else {
$inpatient_bill->updated_by = Auth::id();
}
$inpatient_bill->duration = $days_spent_in_ward;
$inpatient_bill->receipt_number = $receipt_number;
$inpatient_bill->inpatient_info_id = $inpatient_info_id;
$inpatient_bill->treatment_cost = ($treatment_cost ?? 0) + ($opd_treatment_cost ?? 0);
$inpatient_bill->sundries_cost = ($sundries_cost ?? 0) + ($opd_sundries_cost ?? 0);
$inpatient_bill->services_cost = ($services_total_cost ?? 0) + ($opd_services_cost ?? 0);
$inpatient_bill->procedures_cost = ($procedures_total_cost ?? 0) + ($opd_procedures_cost ?? 0);
$inpatient_bill->extras_cost = $extras_cost;
$inpatient_bill->tta_cost = $tta_total_cost;
$inpatient_bill->investigation_cost = $investigation_cost ?? 0;
$inpatient_bill->insurance_hospital_stay_cost = $ward_bed_admission_chi_total_cost ?? 0;
$inpatient_bill->hospital_stay_cost = $ward_bed_admission_total_cost ?? 0;
$inpatient_bill->insurance_investigation_cost = $insurance_investigation_cost ?? 0;
$inpatient_bill->insurance_treatment_cost = ($insurance_treatment_cost ?? 0) + ($insurance_opd_treatment ?? 0);
$inpatient_bill->insurance_sundries_cost = ($insurance_sundries_cost ?? 0) + ($insurance_opd_sundries_cost ?? 0);
$inpatient_bill->insurance_services_cost = ($insurance_services_cost ?? 0) + ($insurance_opd_services_cost ?? 0);
$inpatient_bill->insurance_procedures_cost = ($insurance_procedures ?? 0) + ($insurance_opd_procedures_cost ?? 0);
$inpatient_bill->insurance_tta_cost = $insurance_tta_cost;
$inpatient_bill->amount_to_pay = $amount_owed;
$inpatient_bill->original_bill = $original_amount_owed;
$inpatient_bill->amount_paid = $deposits_made;
$inpatient_bill->invoices_amount = $invoices_amount + $ward_discount_total;
$investigation_amount = $investigation_amount ?? [];
$opd_sundry_amount_request = $opd_sundry_amount_request ?? [];
$opd_treatment_amount = $opd_treatment_amount ?? [];
$pf_treatment_item_prices = $pf_treatment_item_prices ?? [];
$opd_procedure_amount_request = $opd_procedure_amount_request ?? [];
$opd_service_unit_cost = $opd_service_unit_cost ?? [];
$tta_unit_cost = $tta_unit_cost ?? [];
$investigation_insurance_amount = $investigation_insurance_amount ?? [];
$opd_sundry_insurance_unit = $opd_sundry_insurance_unit ?? [];
$opd_treatment_insurance_unit_amount = $opd_treatment_insurance_unit_amount ?? [];
$opd_procedure_insurance_amount = $opd_procedure_insurance_amount ?? [];
$opd_service_insurance_unit = $opd_service_insurance_unit ?? [];
$tta_insurance_unit = $tta_insurance_unit ?? [];
$opd_service_id = $opd_service_id ?? [];
$opd_procedure_ids = $opd_procedure_ids ?? [];
$pf_treatment_item_ids = $pf_treatment_item_ids ?? [];
$opd_treatment_item = $opd_treatment_item ?? [];
$opd_sundries_ids_request = $opd_sundries_ids_request ?? [];
$investigations_item_ids = $investigations_item_ids ?? [];
$tta_drugs_array_request = $tta_drugs_array_request ?? [];
// save items and prices for OPD items since IPD have their own tables 'cept for investigations
$inpatient_bill->investigations_item_prices = implode(",",$investigation_amount);
$inpatient_bill->sundries_item_prices = implode(",",$opd_sundry_amount_request);
$inpatient_bill->prescription_treatment_item_prices = implode(",",$opd_treatment_amount);
$inpatient_bill->pf_treatment_item_prices = implode(",",$pf_treatment_item_prices);
$inpatient_bill->procedures_item_prices = implode(",",$opd_procedure_amount_request);
$inpatient_bill->services_item_prices = implode(",",$opd_service_unit_cost);
$inpatient_bill->tta_item_prices = implode(",",$tta_unit_cost);
$inpatient_bill->investigations_item_chi_prices = implode(",",$investigation_insurance_amount);
$inpatient_bill->sundries_item_chi_prices = implode(",",$opd_sundry_insurance_unit);
$inpatient_bill->prescription_treatment_item_chi_prices = implode(",",$opd_treatment_insurance_unit_amount);
$inpatient_bill->procedures_item_chi_prices = implode(",",$opd_procedure_insurance_amount);
$inpatient_bill->services_item_chi_prices = implode(",",$opd_service_insurance_unit);
$inpatient_bill->tta_item_chi_prices = implode(",",$tta_insurance_unit);
$inpatient_bill->investigations_item_ids = implode(",",$investigations_item_ids);
$inpatient_bill->sundries_item_ids = implode(",",$opd_sundries_ids_request);
$inpatient_bill->prescription_treatment_item_ids = implode(",",$opd_treatment_item);
$inpatient_bill->pf_treatment_item_ids = implode(",",$pf_treatment_item_ids);
$inpatient_bill->procedures_item_ids = implode(",",$opd_procedure_ids);
$inpatient_bill->services_item_ids = implode(",",$opd_service_id);
$inpatient_bill->tta_item_ids = implode(",",$tta_drugs_array_request);
$saved_bill_savers_array = is_null($inpatient_bill->bill_saved_by) ? [] : explode(",", $inpatient_bill->bill_saved_by);
$saved_bill_savers_array[] = Auth::id();
$inpatient_bill->bill_saved_by = implode(",", $saved_bill_savers_array);
$bill_saved_at_array = is_null($inpatient_bill->bill_saved_at) ? [] : explode(",", $inpatient_bill->bill_saved_at);
$bill_saved_at_array[] = Carbon::now();
$inpatient_bill->bill_saved_at = implode(",", $bill_saved_at_array);
$inpatient_bill->save();
// generate the insurance claims
if ($patient_insurance_status == 1) {
create_inpatient_claims($insurance_claims, $patient_id, $episode_id, $inpatient_bill->id);
}
}
/**
* Get all stock amounts of an item that is in the different wards
*
* @param int $item_id - the id of the item from its respective item
* @param int $item_type - type of item e.g drug, sundry etc
* @return int
*/
function get_item_ward_stock($item_id, $item_type)
{
$total_stock_amount = 0;
//item_type = 1-drugs, 2-sundries, 3-dentals, 4-radiologies, 5-Labs
$ward_stock_records = \Streamline\Models\WardStock::where(['item_type' => $item_type, 'item_id' => $item_id])->get();
if (count($ward_stock_records) > 0) {
foreach ($ward_stock_records as $stock_record) {
$total_stock_amount += $stock_record->ward_item_stock;
}
}
return $total_stock_amount;
}
function is_payment_of_greater_expense_allowed()
{
$general_settings = GeneralSettings::find(1);
if ($general_settings->payments_from_banks_with_lesser_balance == 1) {
return 1;
} else {
return 0;
}
}
function get_personal_language_setting(){
$personal_settting = User::find(auth()->user()->id);
if ($personal_settting) {
$system_language = is_null($personal_settting->system_language) ? 1 : $personal_settting->system_language;
return $system_language;
}
return 1;
}
function is_smart_triage_enabled(): bool {
$general_settings = GeneralSettings::find(1);
return $general_settings->smart_triage_feature == 1;
}
function apply_triage_grade(): bool {
$general_settings = GeneralSettings::find(1);
return $general_settings->apply_triage_grade == 1;
}
function get_patient_and_their_dependants($patient_id)
{
$patient_ids_array = [];
$patient_dependants = \Streamline\Models\CategoryPatientDependant::where('main_patient_id', $patient_id)->get();
if (count($patient_dependants) > 0) {
foreach ($patient_dependants as $dependants_record) {
$patient_ids_array = explode(",", $dependants_record->dependant_patient_ids);
}
}
//add the original patient in the array if they are not there
if (!in_array($patient_id, $patient_ids_array)) {
$patient_ids_array[] = $patient_id;
}
return $patient_ids_array;
}
function reverse_dependant_consumption_record($receipt_number, $amount_to_refund, $is_full_refund)
{
$dependant_consumption = DB::table('dependants_consumptions')
->where('receipt_number', $receipt_number)
->first();
if ($dependant_consumption) {
// begin DB transaction
DB::transaction(function () use ($dependant_consumption, $amount_to_refund, $is_full_refund, $receipt_number) {
$dependant_consumption_id = $dependant_consumption->id;
$amount_consumed = $dependant_consumption->amount_consumed;
$new_amount_consumed = $amount_consumed - $amount_to_refund;
$new_amount_consumed = ($new_amount_consumed > 0) ? $new_amount_consumed : 0;
if ($is_full_refund) {
\Streamline\Models\DependantsConsumption::where('receipt_number', $receipt_number)->delete();
\Streamline\Models\PatientCategoryInvoice::where(['receipt_number' => $receipt_number, 'patient_id' => $dependant_consumption->dependant_patient_id])->delete();
$amount_to_refund = $dependant_consumption->amount_consumed;
\Streamline\Models\Discount::where('receipt_number', $receipt_number)->delete();
} else {
$dependant_consumption = \Streamline\Models\DependantsConsumption::find($dependant_consumption->id);
$dependant_consumption->amount_consumed = $new_amount_consumed;
if ($amount_to_refund > $dependant_consumption->unpaid_balance) {
$dependant_consumption->unpaid_balance = 0;
} else{
$dependant_consumption->unpaid_balance = $dependant_consumption->unpaid_balance - $amount_to_refund;
}
$dependant_consumption->updated_by = auth()->user()->id;
$dependant_consumption->save();
//update the discounts
$discount_record = \Streamline\Models\Discount::where('receipt_number', $receipt_number)->first;
$discount_record->discount_amount = $new_amount_consumed;
$discount_record->save();
}
});
}
}
function get_closest_element_in_array($array, $target) {
$array_length = count($array);
// cater for the edge cases
if ($target <= $array[0]) {
return $array[0];
}
// cater for the edge cases
if ($target >= $array[$array_length - 1]) {
return $array[$array_length - 1];
}
$i = 0;
$j = $array_length;
$mid = 0;
while ($i < $j) {
$mid = ($i + $j) / 2;
if ($array[$mid] == $target) {
return $array[$mid];
}
// if target is less than array element then search in left, else right
if ($target < $array[$mid]) {
if ($mid > 0 && $target > $array[$mid - 1]) {
return $array[$mid - 1];
}
// repeat for left half
$j = $mid;
} else {
if ($mid < $array_length - 1 && $target < $array[$mid + 1]) {
return $array[$mid];
}
// repeat for right half
$i = $mid + 1;
}
}
return $array[$mid];
}
function get_post_discharge_mortality_risk($patient_id) {
// confirm that the person is in the desired age bracket
$date_of_birth = get_name($patient_id, 'id', 'date_of_birth', 'patients');
if (DateTime::createFromFormat('Y-m-d', $date_of_birth) == false){
return "Invalid Date of Birth";
}
$dob = new Carbon($date_of_birth);
$gender = get_name($patient_id, 'id', 'gender', 'patients');
$age_diff_months = $dob->diffInMonths(Carbon::now());
if ($age_diff_months < 61) {
// get the latest episode
$patient_episode = DB::table('patient_episodes')
->where('patient_id', $patient_id)
->orderBy('id', 'desc')
->first();
if ($patient_episode) {
// check if record exists in the discharge_mortality table
$discharge_mortality = DB::table('discharge_mortality_risk')->where('patient_id', $patient_id)
->where('episode_id', $patient_episode->id)
->first();
if ($discharge_mortality) {
// check to see if the inpatient is filled in
if (is_null($discharge_mortality->inpatient_id) && is_patient_currently_admitted($patient_id)) {
$inpatient = DB::table('inpatient_info')->where('episode_id', $patient_episode->id)->first();
DB::table('discharge_mortality_risk')
->where('id', $discharge_mortality->id)
->update(['inpatient_id' => $inpatient->id]);
}
// for z score
$l_weight = 0;
$m_weight = 0;
$s_weight = 0;
if ($age_diff_months < 6) {
if (!(is_null($discharge_mortality->tone_normal_6mo) || is_null($discharge_mortality->illness_duration_at_admission_below_6) || is_null($discharge_mortality->muac_below_6))) {
$illness_duration_at_admission_below_6 = $discharge_mortality->illness_duration_at_admission_below_6;
$muac_below_6 = $discharge_mortality->muac_below_6;
$tone_normal_6mo = ($discharge_mortality->tone_normal_6mo == 2 ? 1 : 0);
// center and scale the value
$illness_duration_at_admission_below_6 = ($illness_duration_at_admission_below_6 - 1.838461538) / 0.6597083667;
$muac_below_6 = ($muac_below_6 - 113.5153846) / 17.41973336;
$tone_normal_6mo = ($tone_normal_6mo - 0.9064777328) / 0.2912218894;
// multiple value by coefficient
$illness_duration_at_admission_below_6 = $illness_duration_at_admission_below_6 * 0.006608349806;
$tone_normal_6mo = $tone_normal_6mo * -0.03326141445;
$muac_below_6 = $muac_below_6 * -0.04547998344;
// sum all the values and add the y-intercept
$value = ($illness_duration_at_admission_below_6 + $muac_below_6 + $tone_normal_6mo) + -2.388092672;
$probability = 1 / (1 + exp(-$value));
$probability = $probability * 100;
$probability = round($probability, 2);
DischargeMortalityRisk::where('id', $discharge_mortality->id)
->update(['score_model_used' => 0, 'post_discharge_mortality_risk' => $probability]);
if ($probability <= 8.0) {
return "<b style='color: green'>Moderate Risk</b>";
} elseif ($probability <= 9.15) {
return "<b style='color: orangered'>High Risk</b>";
} else {
return "<b style='color: red'>Very High Risk</b>";
}
} else {
return "Pending";
}
} else {
if (!(is_null($discharge_mortality->last_hospitalization) && is_null($discharge_mortality->water_source) &&
is_null($discharge_mortality->filter_water) && is_null($discharge_mortality->child_mosquito_net) &&
is_null($discharge_mortality->mother_education_level) && is_null($discharge_mortality->hospital_travel_duration) &&
is_null($discharge_mortality->child_hiv) && is_null($discharge_mortality->muac) && is_null($discharge_mortality->weight) &&
is_null($discharge_mortality->temperature) && is_null($discharge_mortality->oxy_saturation) &&
is_null($discharge_mortality->bcs) && is_null($discharge_mortality->hiv_mom_positive))) {
if ($gender == 1) {
// boys
if ($age_diff_months < 7){ $l_weight = 0.1257; $m_weight = 7.934; $s_weight = 0.10958;}
elseif ($age_diff_months < 8){$l_weight = 0.1134; $m_weight = 8.297; $s_weight = 0.10902;}
elseif ($age_diff_months < 9){$l_weight = 0.1021; $m_weight = 8.6151; $s_weight = 0.10882;}
elseif ($age_diff_months < 10){$l_weight = 0.0917; $m_weight = 8.9014; $s_weight = 0.10881;}
elseif ($age_diff_months < 11){$l_weight = 0.082; $m_weight = 9.1649; $s_weight = 0.10891;}
elseif ($age_diff_months < 12){$l_weight = 0.073; $m_weight = 9.4122; $s_weight = 0.10906;}
elseif ($age_diff_months < 13){$l_weight = 0.0644; $m_weight = 9.6479; $s_weight = 0.10925;}
elseif ($age_diff_months < 14){$l_weight = 0.0563; $m_weight = 9.8749; $s_weight = 0.10949;}
elseif ($age_diff_months < 15){$l_weight = 0.0487; $m_weight = 10.0953; $s_weight = 0.10976;}
elseif ($age_diff_months < 16){$l_weight = 0.0413; $m_weight = 10.3108; $s_weight = 0.11007;}
elseif ($age_diff_months < 17){$l_weight = 0.0343; $m_weight = 10.5228; $s_weight = 0.11041;}
elseif ($age_diff_months < 18){$l_weight = 0.0275; $m_weight = 10.7319; $s_weight = 0.11079;}
elseif ($age_diff_months < 19){$l_weight = 0.0211; $m_weight = 10.9385; $s_weight = 0.11119;}
elseif ($age_diff_months < 20){$l_weight = 0.0148; $m_weight = 11.143; $s_weight = 0.11164;}
elseif ($age_diff_months < 21){$l_weight = 0.0087; $m_weight = 11.3462; $s_weight = 0.11211;}
elseif ($age_diff_months < 22){$l_weight = 0.0029; $m_weight = 11.5486; $s_weight = 0.11261;}
elseif ($age_diff_months < 23){$l_weight = -0.0028; $m_weight = 11.7504; $s_weight = 0.11314;}
elseif ($age_diff_months < 24){$l_weight = -0.0083; $m_weight = 11.9514; $s_weight = 0.11369;}
elseif ($age_diff_months < 25){$l_weight = -0.0137; $m_weight = 12.1515; $s_weight = 0.11426;}
elseif ($age_diff_months < 26){$l_weight = -0.0189; $m_weight = 12.3502; $s_weight = 0.11485;}
elseif ($age_diff_months < 27){$l_weight = -0.024; $m_weight = 12.5466; $s_weight = 0.11544;}
elseif ($age_diff_months < 28){$l_weight = -0.0289; $m_weight = 12.7401; $s_weight = 0.11604;}
elseif ($age_diff_months < 29){$l_weight = -0.0337; $m_weight = 12.9303; $s_weight = 0.11664;}
elseif ($age_diff_months < 30){$l_weight = -0.0385; $m_weight = 13.1169; $s_weight = 0.11723;}
elseif ($age_diff_months < 31){$l_weight = -0.0431; $m_weight = 13.3; $s_weight = 0.11781;}
elseif ($age_diff_months < 32){$l_weight = -0.0476; $m_weight = 13.4798; $s_weight = 0.11839;}
elseif ($age_diff_months < 33){$l_weight = -0.052; $m_weight = 13.6567; $s_weight = 0.11896;}
elseif ($age_diff_months < 34){$l_weight = -0.0564; $m_weight = 13.8309; $s_weight = 0.11953;}
elseif ($age_diff_months < 35){$l_weight = -0.0606; $m_weight = 14.0031; $s_weight = 0.12008;}
elseif ($age_diff_months < 36){$l_weight = -0.0648; $m_weight = 14.1736; $s_weight = 0.12062;}
elseif ($age_diff_months < 37){$l_weight = -0.0689; $m_weight = 14.3429; $s_weight = 0.12116;}
elseif ($age_diff_months < 38){$l_weight = -0.0729; $m_weight = 14.5113; $s_weight = 0.12168;}
elseif ($age_diff_months < 39){$l_weight = -0.0769; $m_weight = 14.6791; $s_weight = 0.1222;}
elseif ($age_diff_months < 40){$l_weight = -0.0808; $m_weight = 14.8466; $s_weight = 0.12271;}
elseif ($age_diff_months < 41){$l_weight = -0.0846; $m_weight = 15.014; $s_weight = 0.12322;}
elseif ($age_diff_months < 42){$l_weight = -0.0883; $m_weight = 15.1813; $s_weight = 0.12373;}
elseif ($age_diff_months < 43){$l_weight = -0.092; $m_weight = 15.3486; $s_weight = 0.12425;}
elseif ($age_diff_months < 44){$l_weight = -0.0957; $m_weight = 15.5158; $s_weight = 0.12478;}
elseif ($age_diff_months < 45){$l_weight = -0.0993; $m_weight = 15.6828; $s_weight = 0.12531;}
elseif ($age_diff_months < 46){$l_weight = -0.1028; $m_weight = 15.8497; $s_weight = 0.12586;}
elseif ($age_diff_months < 47){$l_weight = -0.1063; $m_weight = 16.0163; $s_weight = 0.12643;}
elseif ($age_diff_months < 48){$l_weight = -0.1097; $m_weight = 16.1827; $s_weight = 0.127;}
elseif ($age_diff_months < 49){$l_weight = -0.1131; $m_weight = 16.3489; $s_weight = 0.12759;}
elseif ($age_diff_months < 50){$l_weight = -0.1165; $m_weight = 16.515; $s_weight = 0.12819;}
elseif ($age_diff_months < 51){$l_weight = -0.1198; $m_weight = 16.6811; $s_weight = 0.1288;}
elseif ($age_diff_months < 52){$l_weight = -0.123; $m_weight = 16.8471; $s_weight = 0.12943;}
elseif ($age_diff_months < 53){$l_weight = -0.1262; $m_weight = 17.0132; $s_weight = 0.13005;}
elseif ($age_diff_months < 54){$l_weight = -0.1294; $m_weight = 17.1792; $s_weight = 0.13069;}
elseif ($age_diff_months < 55){$l_weight = -0.1325; $m_weight = 17.3452; $s_weight = 0.13133;}
elseif ($age_diff_months < 56){$l_weight = -0.1356; $m_weight = 17.5111; $s_weight = 0.13197;}
elseif ($age_diff_months < 57){$l_weight = -0.1387; $m_weight = 17.6768; $s_weight = 0.13261;}
elseif ($age_diff_months < 58){$l_weight = -0.1417; $m_weight = 17.8422; $s_weight = 0.13325;}
elseif ($age_diff_months < 59){$l_weight = -0.1447; $m_weight = 18.0073; $s_weight = 0.13389;}
elseif ($age_diff_months < 60){$l_weight = -0.1477; $m_weight = 18.1722; $s_weight = 0.13453;}
elseif ($age_diff_months < 61){$l_weight = -0.1506; $m_weight = 18.3366; $s_weight = 0.13517;}
} else {
// girls
if ($age_diff_months < 7){$l_weight = -0.0756; $m_weight = 7.297; $s_weight = 0.12204;}
elseif ($age_diff_months < 8){$l_weight = -0.1039; $m_weight = 7.6422; $s_weight = 0.12178;}
elseif ($age_diff_months < 9){$l_weight = -0.1288; $m_weight = 7.9487; $s_weight = 0.12181;}
elseif ($age_diff_months < 10){$l_weight = -0.1507; $m_weight = 8.2254; $s_weight = 0.12199;}
elseif ($age_diff_months < 11){$l_weight = -0.17; $m_weight = 8.48; $s_weight = 0.12223;}
elseif ($age_diff_months < 12){$l_weight = -0.1872; $m_weight = 8.7192; $s_weight = 0.12247;}
elseif ($age_diff_months < 13){$l_weight = -0.2024; $m_weight = 8.9481; $s_weight = 0.12268;}
elseif ($age_diff_months < 14){$l_weight = -0.2158; $m_weight = 9.1699; $s_weight = 0.12283;}
elseif ($age_diff_months < 15){$l_weight = -0.2278; $m_weight = 9.387; $s_weight = 0.12294;}
elseif ($age_diff_months < 16){$l_weight = -0.2384; $m_weight = 9.6008; $s_weight = 0.12299;}
elseif ($age_diff_months < 17){$l_weight = -0.2478; $m_weight = 9.8124; $s_weight = 0.12303;}
elseif ($age_diff_months < 18){$l_weight = -0.2562; $m_weight = 10.0226; $s_weight = 0.12306;}
elseif ($age_diff_months < 19){$l_weight = -0.2637; $m_weight = 10.2315; $s_weight = 0.12309;}
elseif ($age_diff_months < 20){$l_weight = -0.2703; $m_weight = 10.4393; $s_weight = 0.12315;}
elseif ($age_diff_months < 21){$l_weight = -0.2762; $m_weight = 10.6464; $s_weight = 0.12323;}
elseif ($age_diff_months < 22){$l_weight = -0.2815; $m_weight = 10.8534; $s_weight = 0.12335;}
elseif ($age_diff_months < 23){$l_weight = -0.2862; $m_weight = 11.0608; $s_weight = 0.1235;}
elseif ($age_diff_months < 24){$l_weight = -0.2903; $m_weight = 11.2688; $s_weight = 0.12369;}
elseif ($age_diff_months < 25){$l_weight = -0.2941; $m_weight = 11.4775; $s_weight = 0.1239;}
elseif ($age_diff_months < 26){$l_weight = -0.2975; $m_weight = 11.6864; $s_weight = 0.12414;}
elseif ($age_diff_months < 27){$l_weight = -0.3005; $m_weight = 11.8947; $s_weight = 0.12441;}
elseif ($age_diff_months < 28){$l_weight = -0.3032; $m_weight = 12.1015; $s_weight = 0.12472;}
elseif ($age_diff_months < 29){$l_weight = -0.3057; $m_weight = 12.3059; $s_weight = 0.12506;}
elseif ($age_diff_months < 30){$l_weight = -0.308; $m_weight = 12.5073; $s_weight = 0.12545;}
elseif ($age_diff_months < 31){$l_weight = -0.3101; $m_weight = 12.7055; $s_weight = 0.12587;}
elseif ($age_diff_months < 32){$l_weight = -0.312; $m_weight = 12.9006; $s_weight = 0.12633;}
elseif ($age_diff_months < 33){$l_weight = -0.3138; $m_weight = 13.093; $s_weight = 0.12683;}
elseif ($age_diff_months < 34){$l_weight = -0.3155; $m_weight = 13.2837; $s_weight = 0.12737;}
elseif ($age_diff_months < 35){$l_weight = -0.3171; $m_weight = 13.4731; $s_weight = 0.12794;}
elseif ($age_diff_months < 36){$l_weight = -0.3186; $m_weight = 13.6618; $s_weight = 0.12855;}
elseif ($age_diff_months < 37){$l_weight = -0.3201; $m_weight = 13.8503; $s_weight = 0.12919;}
elseif ($age_diff_months < 38){$l_weight = -0.3216; $m_weight = 14.0385; $s_weight = 0.12988;}
elseif ($age_diff_months < 39){$l_weight = -0.323; $m_weight = 14.2265; $s_weight = 0.13059;}
elseif ($age_diff_months < 40){$l_weight = -0.3243; $m_weight = 14.414; $s_weight = 0.13135;}
elseif ($age_diff_months < 41){$l_weight = -0.3257; $m_weight = 14.601; $s_weight = 0.13213;}
elseif ($age_diff_months < 42){$l_weight = -0.327; $m_weight = 14.7873; $s_weight = 0.13293;}
elseif ($age_diff_months < 43){$l_weight = -0.3283; $m_weight = 14.9727; $s_weight = 0.13376;}
elseif ($age_diff_months < 44){$l_weight = -0.3296; $m_weight = 15.1573; $s_weight = 0.1346;}
elseif ($age_diff_months < 45){$l_weight = -0.3309; $m_weight = 15.341; $s_weight = 0.13545;}
elseif ($age_diff_months < 46){$l_weight = -0.3322; $m_weight = 15.524; $s_weight = 0.1363;}
elseif ($age_diff_months < 47){$l_weight = -0.3335; $m_weight = 15.7064; $s_weight = 0.13716;}
elseif ($age_diff_months < 48){$l_weight = -0.3348; $m_weight = 15.8882; $s_weight = 0.138;}
elseif ($age_diff_months < 49){$l_weight = -0.3361; $m_weight = 16.0697; $s_weight = 0.13884;}
elseif ($age_diff_months < 50){$l_weight = -0.3374; $m_weight = 16.2511; $s_weight = 0.13968;}
elseif ($age_diff_months < 51){$l_weight = -0.3387; $m_weight = 16.4322; $s_weight = 0.14051;}
elseif ($age_diff_months < 52){$l_weight = -0.34; $m_weight = 16.6133; $s_weight = 0.14132;}
elseif ($age_diff_months < 53){$l_weight = -0.3414; $m_weight = 16.7942; $s_weight = 0.14213;}
elseif ($age_diff_months < 54){$l_weight = -0.3427; $m_weight = 16.9748; $s_weight = 0.14293;}
elseif ($age_diff_months < 55){$l_weight = -0.344; $m_weight = 17.1551; $s_weight = 0.14371;}
elseif ($age_diff_months < 56){$l_weight = -0.3453; $m_weight = 17.3347; $s_weight = 0.14448;}
elseif ($age_diff_months < 57){$l_weight = -0.3466; $m_weight = 17.5136; $s_weight = 0.14525;}
elseif ($age_diff_months < 58){$l_weight = -0.3479; $m_weight = 17.6916; $s_weight = 0.146;}
elseif ($age_diff_months < 59){$l_weight = -0.3492; $m_weight = 17.8686; $s_weight = 0.14675;}
elseif ($age_diff_months < 60){$l_weight = -0.3505; $m_weight = 18.0445; $s_weight = 0.14748;}
elseif ($age_diff_months < 61){$l_weight = -0.3518; $m_weight = 18.2193; $s_weight = 0.14821;}
}
$last_hospitalization = $discharge_mortality->last_hospitalization;
$water_source = ($discharge_mortality->water_source == 2 ? 1 : 0);
$filter_water = $discharge_mortality->filter_water;
$child_mosquito_net = $discharge_mortality->child_mosquito_net;
$mother_education_level = $discharge_mortality->mother_education_level;
$hospital_travel_duration = $discharge_mortality->hospital_travel_duration;
$child_hiv = $discharge_mortality->child_hiv;
$muac = $discharge_mortality->muac;
$weight = $discharge_mortality->weight;
$temperature = $discharge_mortality->temperature * $discharge_mortality->temperature;
$oxy_saturation = $discharge_mortality->oxy_saturation;
$bcs = $discharge_mortality->bcs;
$hiv_mom_positive = $discharge_mortality->hiv_mom_positive;
$hiv_mom_unknown = $discharge_mortality->hiv_mom_unknown;
$malaria_test = $discharge_mortality->malaria_test;
$maternal_age = $discharge_mortality->maternal_age;
$gender = ($gender != 1) ? 0 : $gender;
$weight_zscore = (pow(($weight / $m_weight), $l_weight) - 1) / ($l_weight * $s_weight);
// center and scale the value
$waz = ($weight_zscore - -1.175595455) / 1.733614018;
$last_hospitalization = ($last_hospitalization - 3.972675522) / 1.239386626;
$water_source = ($water_source - 0.176470588) / 0.381292399;
$filter_water = ($filter_water - 0.708918406) / 0.45434727;
$child_mosquito_net = ($child_mosquito_net - 2.533586338) / 0.752565243;
$hospital_travel_duration = ($hospital_travel_duration - 2.264895636) / 0.825997211;
$mother_education_level = ($mother_education_level - 2.803795066) / 1.13171342;
$child_hiv = ($child_hiv - 0.037191651) / 0.189267078;
$muac = ($muac - 140.4573055) / 16.75147685;
$temperature = ($temperature - 1447.743492) / 98.20992618;
$oxy_saturation = ($oxy_saturation - 93.23795066) / 6.802892684;
$bcs = ($bcs - 0.094497154) / 0.292574653;
$hiv_mom_positive = ($hiv_mom_positive - 0.1041376104) / 0.3054744826;
$hiv_mom_unknown = ($hiv_mom_unknown - 0.121062619) / 0.326261947;
$age_diff_months = ($age_diff_months - 21.75753152) / 13.86769278;
$gender = ($gender - 0.55160390516039) / 0.497387719831987;
$malaria_test = ($malaria_test - 0.305904230590423) / 0.460842922425563;
$maternal_age = ($maternal_age - 27.9365411436541) / 6.49535587374389;
// multiple value by coefficient according to available variables
if (!(is_null($waz) || is_null($last_hospitalization) || is_null($water_source) || is_null($filter_water) ||
is_null($child_mosquito_net) || is_null($mother_education_level) ||
is_null($hospital_travel_duration) || is_null($child_hiv) || is_null($muac) ||
is_null($temperature) || is_null($oxy_saturation) || is_null($bcs) || is_null($hiv_mom_unknown))) {
// original formula
$score_model = 1;
$waz = $waz * -0.225603341;
$last_hospitalization = $last_hospitalization * -0.116558307;
$water_source = $water_source * 0.170080257;
$filter_water = $filter_water * -0.019881807;
$child_mosquito_net = $child_mosquito_net * -0.014920737;
$mother_education_level = $mother_education_level * -0.032607766;
$hospital_travel_duration = $hospital_travel_duration * 0.134578194;
$child_hiv = $child_hiv * 0.153679396;
$muac = $muac * -0.252396925;
$temperature = $temperature * -0.086806429;
$oxy_saturation = $oxy_saturation * -0.211672495;
$bcs = $bcs * 0.128376701;
$hiv_mom_unknown = $hiv_mom_unknown * 0.041557107;
// sum all the values and add the y-intercept
$value = ($waz + $last_hospitalization + $water_source
+ $filter_water + $child_mosquito_net + $hospital_travel_duration
+ $child_hiv + $muac + $temperature + $bcs + $mother_education_level
+ $oxy_saturation + $hiv_mom_unknown) + -3.214063319;
} else if (!(is_null($last_hospitalization) || is_null($hospital_travel_duration) || is_null($child_hiv) || is_null($muac) ||
is_null($temperature) || is_null($oxy_saturation) || is_null($bcs))) {
// alternate formula #1
$score_model = 2;
$last_hospitalization = $last_hospitalization * -0.21797566522041;
$hospital_travel_duration = $hospital_travel_duration * 0.185628115861501;
$child_hiv = $child_hiv * 0.12579252862453;
$muac = $muac * -0.429880439456127;
$temperature = $temperature * -0.116757889445837;
$oxy_saturation = $oxy_saturation * -0.220344754894439;
$bcs = $bcs * 0.139550062988723;
$hiv_mom_unknown = $hiv_mom_unknown * 0.0664980735044757;
$hiv_mom_positive = $hiv_mom_positive * 0.051716877214218;
$age_diff_months = $age_diff_months * -0.0942893527085892;
$gender = $gender * -0.0397219636250871;
$malaria_test = $malaria_test * -0.0428340362512068;
$maternal_age = $maternal_age * -0.0316370208792521;
// sum all the values and add the y-intercept
$value = ($last_hospitalization + $hospital_travel_duration + $malaria_test
+ $child_hiv + $muac + $temperature + $bcs + $age_diff_months + $gender
+ $oxy_saturation + $hiv_mom_unknown + $hiv_mom_positive + $maternal_age) + -3.20014357797846;
} else if (!(is_null($last_hospitalization) || is_null($child_hiv) || is_null($muac) ||
is_null($temperature) || is_null($bcs) || is_null($hiv_mom_unknown))) {
// alternate formula #2
$score_model = 3;
$last_hospitalization = $last_hospitalization * 0.0870327300391114;
$child_hiv = $child_hiv * 0.143399157343558;
$muac = $muac * -0.521711763106214;
$temperature = $temperature * -0.0825553722819837;
$bcs = $bcs * 0.153175250332773;
$hiv_mom_unknown = $hiv_mom_unknown * 0.0484939458465363;
$age_diff_months = $age_diff_months * 0.0802088003235002;
// sum all the values and add the y-intercept
$value = ($last_hospitalization + $child_hiv + $muac + $temperature + $bcs
+ $age_diff_months + $hiv_mom_unknown) + -3.13079507371701;
} else {
return "Pending";
}
$probability = 1 / (1 + exp(-$value));
$probability = $probability * 100;
$probability = round($probability, 2);
DischargeMortalityRisk::where('id', $discharge_mortality->id)
->update(['weight_for_age_zscore' => $weight_zscore,
'score_model_used' => $score_model,
'post_discharge_mortality_risk' => $probability]);
if ($probability <= 4.0) {
return "<b style='color: green'>Low Risk</b>";
} else {
return "<b style='color: red'>High Risk</b>";
}
} else {
return "Pending";
}
}
} else {
$discharge_mortality = new DischargeMortalityRisk();
$discharge_mortality->patient_id = $patient_id;
$discharge_mortality->episode_id = $patient_episode->id;
$discharge_mortality->gender = $gender;
$discharge_mortality->date_of_birth = $date_of_birth;
$discharge_mortality->age_in_months = $age_diff_months;
$discharge_mortality->save();
return "Pending";
}
} else {
return "No episodes available";
}
} else {
return "N/A";
}
}
/**
* similar to the get_post_discharge_mortality_risk function but assumes the risk score is already calculated
* @param $discharge_score
* @return string
*/
function get_post_discharge_mortality_risk_score_display($discharge_score, $date_of_birth): string {
// confirm that the person is in the desired age bracket
$dob = new Carbon($date_of_birth);
$age_diff_months = $dob->diffInMonths(Carbon::now());
if (!is_null($discharge_score)) {
if ($age_diff_months < 6) {
if ($discharge_score <= 8.0) {
return "<b style='color: green'>Moderate Risk</b>";
} elseif ($discharge_score <= 9.15) {
return "<b style='color: orangered'>High Risk</b>";
} else {
return "<b style='color: red'>Very High Risk</b>";
}
} else {
if ($discharge_score <= 4.0) {
return "<b style='color: green'>Low Risk</b>";
} else {
return "<b style='color: red'>High Risk</b>";
}
}
} else {
return "Pending";
}
}
function is_patient_at_post_discharge_high_risk($discharge_score, $date_of_birth): bool {
// confirm that the person is in the desired age bracket
$dob = new Carbon($date_of_birth);
$age_diff_months = $dob->diffInMonths(Carbon::now());
if (!is_null($discharge_score)) {
if ($age_diff_months < 6) {
if ($discharge_score <= 8.0) {
return false;
} elseif ($discharge_score <= 9.15) {
return true;
} else {
return true;
}
} else {
if ($discharge_score <= 4.0) {
return false;
} else {
return true;
}
}
} else {
return false;
}
}
/**
* Check if the vht discharge form should be generated based on the risk score
* @param $discharge_score
* @return bool
*/
function should_vht_form_be_generated($discharge_score, $date_of_birth): bool {
// confirm that the person is in the desired age bracket
$dob = new Carbon($date_of_birth);
$age_diff_months = $dob->diffInMonths(Carbon::now());
if (!is_null($discharge_score)) {
if ($age_diff_months < 6) {
if ($discharge_score <= 8.0) {
return false;
} elseif ($discharge_score <= 9.15) {
return true;
} else {
return true;
}
} else {
if ($discharge_score <= 4.0) {
return false;
} else {
return true;
}
}
} else {
return false;
}
}
function perform_post_discharge_actions($patient_id, $discharge_mortality_id) {
$discharge_mortality = DB::table('discharge_mortality_risk')->where('id', $discharge_mortality_id)->first();
// check if the score has been calculated
if ($discharge_mortality->post_discharge_mortality_risk && $discharge_mortality->child_with_proven_infection == 1) {
send_data_to_redcap($discharge_mortality_id);
$date_of_birth = get_name($patient_id, 'id', 'date_of_birth', 'patients');
$dob = new Carbon($date_of_birth);
$age_diff_months = $dob->diffInMonths(Carbon::now());
if ($age_diff_months < 6) {
if ($discharge_mortality->post_discharge_mortality_risk < 8.0) {
//
} elseif ($discharge_mortality->post_discharge_mortality_risk <= 9.15) {
send_message_to_vht_about_discharge_risk($patient_id, $discharge_mortality->id);
} else {
send_message_to_vht_about_discharge_risk($patient_id, $discharge_mortality->id);
}
} else {
if ($discharge_mortality->post_discharge_mortality_risk > 4.0) {
send_message_to_vht_about_discharge_risk($patient_id, $discharge_mortality->id);
}
}
}
}
function send_message_to_insurance_lead_about_discharge_risk($patient_id) {
if (get_name($patient_id, 'id', 'insurance_status', 'patients') == 1) {
$group_id = get_name($patient_id, 'patient_id', 'group_id', 'insurance_members');
$insurance_group = DB::table('insurance_groups')->where('id', $group_id)->first();
$group_name = $insurance_group->name;
$lead_name = $insurance_group->contact_name;
$lead_contact = str_replace(' ', '', $insurance_group->contact_number);
if (strlen($lead_contact) == 10 && in_array(str_split($lead_contact, 3)[0], ["077", "070", "075", "078"])){
$formatted_contact = "+256" . substr($lead_contact, 1);
$text = "Hello " . $lead_name . ". " . get_full_name($patient_id, 'id', 'first_name', 'last_name', 'patients') .
", a patient in your insurance group, has a high post discharge risk of mortality. Please ensure to check on them constantly to monitor their health progress";
// $sid = "AC7689a73aba0d6b51e13b783cf4c6717d";
// $token = "23cbc58b6a3687b7d6cd667ddf6e68f7";
// $twilio = new Twilio\Rest\Client($sid, $token);
// $message = $twilio->messages
// ->create($formatted_contact, // to
// [
// "body" => $text,
// "from" => "+17786541291"
// ]
// );
send_smart_discharge_sms($formatted_contact, $text);
}
}
}
function send_message_to_vht_about_discharge_risk($patient_id, $discharge_id) {
$inpatient_id = get_name($discharge_id, 'id', 'inpatient_id', 'discharge_mortality_risk');
if (get_name($discharge_id, 'id', 'is_vht_alerted', 'discharge_mortality_risk') == 0 && get_patient_discharge_date($inpatient_id)) {
$discharge_date = get_patient_discharge_date($inpatient_id);
$discharge_date_carbon = new Carbon($discharge_date);
$first_followup_date = $discharge_date_carbon->copy()->addDays(2);
$second_followup_date = $discharge_date_carbon->copy()->addDays(7);
$third_followup_date = $discharge_date_carbon->copy()->addDays(14);
$inpatient_info = DB::table('inpatient_info')
->where('id', get_name($discharge_id, 'id', 'inpatient_id', 'discharge_mortality_risk'))
->first();
if (get_name($patient_id, 'id', 'village_id', 'patients') != 'N/A') {
$vht = DB::table('vht_contacts')
->where('village', get_name($patient_id, 'id', 'village_id', 'patients'))
->orWhere('village', get_name(get_name($patient_id, 'id', 'village_id', 'patients'), 'id', 'name', 'villages'))
->first();
if ($vht) {
/*if (strlen($vht->contact) == 10 && in_array(str_split($vht->contact, 3)[0], ["077", "070", "075", "078"])){
//
} else {
// send a message to the insurance head
send_message_to_insurance_lead_about_discharge_risk($patient_id);
}*/
// create a new record for phone followup
DB::table('phone_followup_patients')
->insert(['patient_id' => $patient_id, 'created_at' => date('Y-m-d H:i:s'), 'vht_id' => $vht->id,
'episode_id' => $inpatient_info->episode_id, 'inpatient_id' => $inpatient_info->id, 'discharge_mortality_risk_id' => $discharge_id,
'follow_up_date' => $first_followup_date, 'discharge_date' => $discharge_date]);
DB::table('phone_followup_patients')
->insert(['patient_id' => $patient_id, 'created_at' => date('Y-m-d H:i:s'), 'vht_id' => $vht->id,
'episode_id' => $inpatient_info->episode_id, 'inpatient_id' => $inpatient_info->id, 'discharge_mortality_risk_id' => $discharge_id,
'follow_up_date' => $second_followup_date, 'discharge_date' => $discharge_date]);
DB::table('phone_followup_patients')
->insert(['patient_id' => $patient_id, 'created_at' => date('Y-m-d H:i:s'), 'vht_id' => $vht->id,
'episode_id' => $inpatient_info->episode_id, 'inpatient_id' => $inpatient_info->id, 'discharge_mortality_risk_id' => $discharge_id,
'follow_up_date' => $third_followup_date, 'discharge_date' => $discharge_date]);
$patient = DB::table('patients')->where('id', $patient_id)->first();
$message = "Dear VHT,\nA child from your area was discharged today. Please complete 3 follow-up visits to assess recovery.\n\nDetails:\n";
$message .= "Child: " . $patient->first_name . " " . $patient->last_name . ",";
$message .= " " . (($patient->gender == 1) ? "Boy" : "Girl") . "\n";
$message .= " Age:" . get_patients_age($patient->date_of_birth) . "\n";
$message .= " Village:" . get_name($patient->village_id, 'id', 'name', 'villages') . "\n";
$message .= "From: Kisiizi Hospital\n";
if ($patient->parent_id) {
$message .= "Parent: " . get_full_name($patient->parent_id, 'id', 'first_name', 'last_name', 'patients') . ", " . get_name($patient->parent_id, 'id', 'phone', 'patients') . "\n";
} elseif ($patient->hospital_contact) {
$message .= "Parent: " . $patient->hospital_contact_name . ", " . $patient->hospital_contact . "\n";
} elseif ($patient->next_of_kin) {
$message .= "Parent: " . $patient->next_of_kin . ", " . $patient->phone_of_next_of_kin . "\n";
}
$number = "+256" . $vht->contact . "\n";
$message .= "Follow-ups: " . $first_followup_date->format('D j M') . ", " . $second_followup_date->format('D j M') . ", " . $third_followup_date->format('D j M');
send_smart_discharge_sms($number, $message);
DB::table('discharge_mortality_risk')
->where('id', $discharge_id)
->update(['is_vht_alerted' => 1]);
flash("A message has been sent to the child's village VHT about their follow ups")->success();
} else {
// send a message to the insurance head
send_message_to_insurance_lead_about_discharge_risk($patient_id);
}
} else {
// send a message to the insurance head
send_message_to_insurance_lead_about_discharge_risk($patient_id);
}
}
}
function send_data_to_redcap($id) {
if (get_name($id, 'id', 'is_data_sent_to_redcap', 'discharge_mortality_risk') == 0) {
// get the latest score calculation
$para = DB::table('discharge_mortality_risk')
->where('id', $id)
->first();
if ($para->age_in_months < 6) {
$less_than_six = 1;
$travel_dist = $para->hospital_travel_duration_below_6;
$dpi_para = $para->illness_duration_at_admission_below_6;
$muac_mm_para = $para->muac_below_6;
$waz_zscore_para = $para->weight_for_age_zscore_below_6;
} else {
$less_than_six = 0;
$travel_dist = $para->hospital_travel_duration;
$dpi_para = null;
$muac_mm_para = $para->muac;
$waz_zscore_para = $para->weight_for_age_zscore;
}
$patient = DB::table('patients')->find($para->patient_id);
$caregiver_phone = "";
$caregiver_name = "None";
$vht_name = "None";
$vht_number = "";
if ($patient->insurance_status == 1) {
$group_id = get_name($patient->id, 'patient_id', 'group_id', 'insurance_members');
$insurance_group = DB::table('insurance_groups')->where('id', $group_id)->first();
$caregiver_name = $insurance_group->contact_name;
$lead_contact = str_replace(' ', '', $insurance_group->contact_number);
if (strlen($lead_contact) == 10 && in_array(str_split($lead_contact, 3)[0], ["077", "070", "075", "078"])){
$caregiver_phone = "+256" . substr($lead_contact, 1);
}
}
$vht = DB::table('vht_contacts')
->where('village', get_name($patient->id, 'id', 'village_id', 'patients'))
->orWhere('village', get_name(get_name($patient->id, 'id', 'village_id', 'patients'), 'id', 'name', 'villages'))
->first();
if ($vht) {
$vht_name = $vht->name;
$vht_number = "+256" . $vht->contact;
}
if ($caregiver_name == "None") {
$caregiver_name = $patient->next_of_kin;
if ($patient->phone_of_next_of_kin != "" && !is_null($patient->phone_of_next_of_kin)) {
$caregiver_phone = $patient->phone_of_next_of_kin;
} else {
$caregiver_phone = $patient->phone;
}
}
$discharge_date_carbon = new Carbon(get_patient_discharge_date($para->inpatient_id));
$first_followup_date = $discharge_date_carbon->copy()->addDays(2);
$second_followup_date = $discharge_date_carbon->copy()->addDays(7);
$third_followup_date = $discharge_date_carbon->copy()->addDays(14);
$maternal_hiv = 3;
if ($para->maternal_hiv == 2) {
$maternal_hiv = 1;
} elseif ($para->maternal_hiv == 1) {
$maternal_hiv = 2;
}
$record = ['studyid_adm' => get_name($para->patient_id, 'id', 'number', 'patients'),
'redcap_event_name' => 'hospitalization_an_arm_1',
'date_para' => date_format(date_create($para->created_at), 'Y-m-d'),
'site_para' => "Kisiizi Hospital",
'sixmonths_adm_para' => $less_than_six,
'sex_para' => $para->gender,
'agecalc_yrs_tab_para' => get_patients_age_decimals($para->date_of_birth),
'priorhosp_para' => $para->last_hospitalization,
'watersource_para' => ($para->water_source == 0 ? 4 : $para->water_source),
'waterpure_para' => $para->filter_water,
'bednet_para' => $para->child_mosquito_net,
'momage_para' => $para->maternal_age,
'momedu_para' => $para->mother_education_level,
'traveldist_para' => $travel_dist,
'dpi_para' => $dpi_para,
'district_para' => 2,
'height_cm_para' => null,
'weight_kg_para' => $para->weight,
'muac_mm_para' => $muac_mm_para,
'temp_c_para' => $para->temperature,
'waz_zscore_para' => $waz_zscore_para,
'bmi_kgm2_para' => $para->bmi_below_6,
'bmiaz_zscore_para' => $para->bmi_zscore_below_6,
'muscletone_para' => $para->tone_normal_6mo,
'spo2_pc_oxi_para' => null,
'hr_bpm_oxi_para' => null,
'hr_bpm_manual_para' => null,
'spo2other_para' => $para->oxy_saturation,
'bcseye_para' => $para->bcs_eye_movement,
'bcsmotor_para' => $para->bcs_best_mortal,
'bcsverbal_para' => $para->bcs_best_verbal,
'momhiv_para' => $maternal_hiv,
'hiv_para' => ($para->child_hiv == 0 ? 2 : 1),
'malaria_para' => $para->malaria_test,
'scorevar_para' => $para->score_model_used,
'pdscore_para' => $para->post_discharge_mortality_risk,
'disdate_para' => get_patient_discharge_date($para->inpatient_id),
'caregiver_para' => $caregiver_name,
'parish_para' => get_name(get_name($para->patient_id, 'id', 'parish_id', 'patients'), 'id', 'name', 'parishes'),
'subvillage_para' => get_name(get_name($para->patient_id, 'id', 'village_id', 'patients'), 'id', 'name', 'villages'),
'phone_para' => $caregiver_phone,
'vht_para' => $vht_name,
'vhtnumber_para' => $vht_number,
'ref1date_para' => date_format(date_create($first_followup_date), 'Y-m-d'),
'ref2date_para' => date_format(date_create($second_followup_date), 'Y-m-d'),
'ref3date_para' => date_format(date_create($third_followup_date), 'Y-m-d'),
];
$data = json_encode([$record]);
$client = new Client();
try {
$res = $client->request('POST', 'https://rc.bcchr.ca/redcap/api/', [
'form_params' => [
'token' => "A8D82E0C6FE06546201918A3D650DF1B",
'content' => 'record',
'format' => 'json',
'type' => 'flat',
'data' => $data,
]
]);
DB::table('failed_smart_discharge_redcap')
->insert(['study_id' => $id, "error_text" => $res->getStatusCode(), 'created_at' => Carbon::now()]);
if ($res->getStatusCode() == 200) {
DB::table('discharge_mortality_risk')
->where('id', $id)
->update(['is_data_sent_to_redcap' => 1]);
} else {
DB::table('failed_smart_discharge_redcap')
->insert(['study_id' => $id, 'created_at' => Carbon::now()]);
}
} catch (Exception $exception) {
DB::table('failed_smart_discharge_redcap')
->insert(['study_id' => $id, "error_text" => $exception->getMessage() . " - " . $exception->getLine(), 'created_at' => Carbon::now()]);
}
}
}
function get_patients_age_decimals($date_of_birth): float {
$dob = new Carbon($date_of_birth);
return round(($dob->diffInMonths(Carbon::now()) / 12), 2);
}
function get_patient_discharge_date($inpatient_id) {
$inpatient_info = DB::table('inpatient_info')
->where('id', $inpatient_id)
->first();
if($inpatient_info) {
return $inpatient_info->discharged_on;
} else {
return null;
}
}
function send_smart_discharge_sms($number, $message) {
$username = 'streamline';
$apiKey = '829ee2fcf4ea9fd2b6930687bb274f6e5c8f722bb6770f95b778a9d5485d38e8';
$AT = new AfricasTalking($username, $apiKey);
// Get one of the services
$sms = $AT->sms();
try {
// Use the service
$result = $sms->send([
'to' => $number, // +256705003878
'message' => $message
]);
} catch (Exception $exception) {
// log that the message could not be sent somewhere
DB::table('failed_smart_discharge_messages')
->insert(['number_to_send_to' => $number, 'message' => $message]);
}
}
function is_patient_currently_admitted($patient_id): bool {
// get latest episode
$episode = DB::table('patient_episodes')->where('patient_id', $patient_id)->orderBy('id', 'desc')->first();
if ($episode) {
$inpatient = DB::table('inpatient_info')->where('episode_id', $episode->id)->first();
return (bool)$inpatient;
} else {
return false;
}
}
function is_smart_discharge_enabled(): bool {
$general_settings = GeneralSettings::find(1);
return $general_settings->smart_discharge_feature == 1;
}
function get_quarters($start_date, $end_date){
$quarters = array();
$start_month = date( 'm', strtotime($start_date) );
$start_year = date( 'Y', strtotime($start_date) );
$end_month = date( 'm', strtotime($end_date) );
$end_year = date( 'Y', strtotime($end_date) );
$start_quarter = ceil($start_month/3);
$end_quarter = ceil($end_month/3);
$quarter = $start_quarter; // variable to track current quarter
// Loop over years and quarters to create array
for( $y = $start_year; $y <= $end_year; $y++ ){
if($y == $end_year)
$max_qtr = $end_quarter;
else
$max_qtr = 4;
for($q=$quarter; $q<=$max_qtr; $q++){
$current_quarter = new stdClass();
$end_month_num = zero_pad($q * 3);
$start_month_num = ($end_month_num - 2);
$q_start_month = month_name($start_month_num);
$q_end_month = month_name($end_month_num);
// $current_quarter->period = "Qtr $q ($q_start_month - $q_end_month) $y";
$current_quarter->period = "Quarter $q - $y";
$current_quarter->period_start = "$y-$start_month_num-01"; // yyyy-mm-dd
$current_quarter->period_end = "$y-$end_month_num-" . month_end_date($y, $end_month_num);
$quarters[] = $current_quarter;
unset($current_quarter);
}
$quarter = 1; // reset to 1 for next year
}
return $quarters;
}
// return two digit month or day, e.g. 04 - April
function zero_pad($number){
if($number < 10)
return "0$number";
return "$number";
}
// get month name from number
function month_name($month_number){
return date('F', mktime(0, 0, 0, $month_number, 10));
}
// get get last date of given month (of year)
function month_end_date($year, $month_number){
return date("t", strtotime("$year-$month_number-1"));
}
function is_fingerprint_enabled(): bool {
$general_settings = GeneralSettings::find(1);
return $general_settings->enable_fingerprint == 1;
}
function get_item_insurance_details($item_id, $item_type, $benefit_id) {
switch ($item_type) {
case 1:
$item_details = DB::table('services')->where('id', $item_id)->select('insurance_benefit_details', 'non_insured_price')->first();
break;
case 2:
$item_details = DB::table('procedures')->where('id', $item_id)->select('insurance_benefit_details', 'non_insured_price')->first();
break;
case 3:
$item_details = DB::table('investigations')->where('id', $item_id)->select('insurance_benefit_details', 'non_insured_price')->first();
break;
case 4:
$item_details = DB::table('drugs')->where('id', $item_id)->select('insurance_benefit_details', 'non_insured_price')->first();
break;
case 5:
$item_details = DB::table('sundries')->where('id', $item_id)->select('insurance_benefit_details', 'non_insured_price')->first();
break;
default:
return [];
}
$decoded_json = json_decode($item_details->insurance_benefit_details, true);
if ($decoded_json && is_array($decoded_json)) {
$insurance_item_details = $decoded_json[$benefit_id] ?? false;
} else {
$insurance_item_details = false;
}
if ($insurance_item_details) {
$insurance_item_details["cash_price"] = $item_details->non_insured_price;
}
return $insurance_item_details;
}
function getStringBetweenCharacters($string, $start = "", $end = ""){
if (strpos($string, $start)) { // required if $start not exist in $string
$startCharCount = strpos($string, $start) + strlen($start);
$firstSubStr = substr($string, $startCharCount, strlen($string));
$endCharCount = strpos($firstSubStr, $end);
if ($endCharCount == 0) {
$endCharCount = strlen($firstSubStr);
}
return substr($firstSubStr, 0, $endCharCount);
} else {
return '';
}
}
function allocate_insurance_member_account_number($insurance_member_id, $insurance_member_group)
{
$prefix = DB::table('hospital_information')->where('id', 1)->value('patient_number_abbr');
$new_id = quadLimit($insurance_member_id);
$year = date('Y');
$chi_member_acc_number = $prefix . "/" . $year . "/" . $insurance_member_group. "/" . $new_id;
return $chi_member_acc_number;
}
function are_patient_receipts_full_detail() {
$general_settings = GeneralSettings::find(1);
return $general_settings->full_detail_receipt_print == 1;
}
function get_fingerprint_key() {
return "w43CiMOtw40KKsOOw6oOD8KOw6jChmrCrsOpwqlqD0xoL8OJKGjDicOpDydmS8OGZk0OacONLsOIworDpsOpKMOOTg8Pw6Zmw4oLwo4rw67DiGZqw6hNw6rCrMKmbcOKwqbDiMOIK8KIw4xtw4lJS8OJSsKKwo7DicKmbG4Owqpuwo5NTi3CqW4swqxlw40qw60LL8ONZihmw6zCqkttSMOGTAvDiMKIw6puRk3DjsOlD8KIB8KmTcKuwqzDrCvDqAfCiS3DrmllDcKqTcOqDcKOwq3DrMOqw6hLBsKMLcOuw4jDrMKuw4zCqmpuw4onw6bCiEYuw61tJ8KNJwnDiChpaCwvw60OSsKGJkbDjcOJJi5lTi/DqMOMwo3DqWrCisOtw6bCiA5sSgctw6nDisKpwowtSsKuw6YJTcOlwq4HaMOqw44nbivDrS/DrS/DjMKuwo3DjcOuCSwrJwkNw67CjApNCSfChsKIK8OIaA3DiC/DqglJLMOIw4oGwo1mw4pGRgnCqUvDqEsJT01uDkoHbsOMak7CiMKmDUbDjMKNZcOuwqbCqCdGBgYswqYmS03ChsKGwoZJT8OlaMOMD2zCicKMwqjCicKpSsOJw4bDhirDqsOsTSjCqmnDqG3DicONDsKKZcOIBsOoSMKMw65lSMKmw4YOTWrCpsONwqoJC2wsT0jCrMKMwq4qLcKtTGYoamjDrizChsKGLAbCrMKuTkzCiMOowqwHDU0mCypuw6XCiMOISMKqTMKGRi7DpgfCqSsHZcOJB24HSMKmw67DpcOqTyZObCgHw47DisKJKm5Iw4zDrcKNTcOsLgvCicOlw6nDicKJw43ChgYtSUbCrSnCrMKtKQfCqsOMKMKtJsKtSmplSgnCrg3CqkZGD07DrCzDqG4LCg4rw4kvw60tw41LD8OowoZpKMKGw6xOSUwuDcKIw6pOw64PaQbCqmjCqQ9uwq3CqMOqTsOtw6lNKcKowq7CqsOISMONKsOJTgZlwokvaWgqTEjDiklsTsOqw65sRmnCqG5Mw6zCiQtlakxLw4zCqEnCiMKowqxGw4llwqYmwqYoK04GC8ONDsOlK8KmLQ0mwo4mw6rCicOmLkbCqQ1Nw4jCjGpLw6xuJ21MJkbDqcKMD8OoKsOqSCfDqCwOw6lOLcKqw4jDjGULSWwGDWrDjWUowq0NwqjCjsKsB8KqwqnDqCzCisOsDcKMbUxsKcKpwo5PaWzCiMKmw44HD8OlCsOuJyoqwqfCp07CiQ1MwozChmxqDcKOacKNBsOmSCYNKsOuw4zDrMOswqfCp0wDQUFZTQ==";
}
function is_inpatient_sheet_with_detailed_notes_enabled() {
$general_settings = GeneralSettings::find(1);
if ($general_settings->inpatient_sheet_with_detailed_notes == 1) {
return true;
} else {
return false;
}
}
function get_item_insurance_co_payment($patient_id, $item_id, $item_type, $is_inpatient): int {
$member_details = DB::table('insurance_members')->join('insurance_benefit_items', 'insurance_benefit_items.plan_id', '=', 'insurance_members.chi_plan')
->where('insurance_members.patient_id', $patient_id)
->whereNull('insurance_benefit_items.deleted_at')
->where('insurance_benefit_items.item_type', $item_type)->whereRaw('FIND_IN_SET(' . $item_id . ',insurance_benefit_items.item_id)')
->select('insurance_members.chi_plan', 'insurance_benefit_items.benefit_id')->first();
if ($item_type == 1) {
$item = Services::find($item_id);
} elseif ($item_type == 2) {
$item = Procedure::find($item_id);
} elseif ($item_type == 3) {
$item = Investigation::find($item_id);
} elseif ($item_type == 4) {
$item = Drug::find($item_id);
} elseif ($item_type == 5) {
$item = Sundry::find($item_id);
} else {
return 0;
}
if ($member_details) {
$insurance_item_details = json_decode($item->insurance_benefit_details, true) ?? [];
$insurance_benefit_details = DB::table('insurance_benefits')
->where('id', $member_details->benefit_id)->first();
if ($is_inpatient) {
$apply_ipd_percentage = $insurance_item_details[$member_details->benefit_id]['apply_ipd_percentage'] ?? false;
if(isset($apply_ipd_percentage) && $apply_ipd_percentage == 1) {
return (($insurance_benefit_details->ipd_percentage / 100) * $item->non_insured_price);
} else {
return $insurance_item_details[$member_details->benefit_id]['ipd_co_payment'] ?? 0;
}
} else {
$apply_opd_percentage = $insurance_item_details[$member_details->benefit_id]['apply_opd_percentage'] ?? false;
if(isset($apply_opd_percentage) && $apply_opd_percentage == 1) {
return (($insurance_benefit_details->opd_percentage / 100) * $item->non_insured_price);
} else {
return $insurance_item_details[$member_details->benefit_id]['co_payment'] ?? 0;
}
}
}
return $item->non_insured_price;
}
function get_item_insurance_pricing($patient_id, $item_id, $item_type, $is_inpatient): array {
$insurance_price = 0;
$insurance_status = 0;
$tariff_id = 0;
$benefit_id = 0;
if ($item_type == 1) {
$item = Services::find($item_id);
} elseif ($item_type == 2) {
$item = Procedure::find($item_id);
} elseif ($item_type == 3) {
$item = Investigation::find($item_id);
} elseif ($item_type == 4) {
$item = Drug::find($item_id);
} elseif ($item_type == 5) {
$item = Sundry::find($item_id);
} else {
return [0, 0, 0, 0];
}
$co_payment = $item->non_insured_price;
$member_details = DB::table('insurance_members')->join('insurance_benefit_items', 'insurance_benefit_items.plan_id', '=', 'insurance_members.chi_plan')
->join('patients', 'patients.id', '=', 'insurance_members.patient_id')
->where('insurance_members.patient_id', $patient_id)
->whereNull('insurance_benefit_items.deleted_at')
->where('insurance_benefit_items.item_type', $item_type)->whereRaw('FIND_IN_SET(' . $item_id . ',insurance_benefit_items.item_id)')
->select('insurance_members.chi_plan', 'insurance_benefit_items.benefit_id', 'patients.date_of_birth', 'patients.gender')->first();
if ($member_details) {
$age_diff_days = Carbon::createFromFormat('Y-m-d', $member_details->date_of_birth)->diffInDays(Carbon::now());
$benefit_id = $member_details->benefit_id;
$insurance_item_details = json_decode($item->insurance_benefit_details, true) ?? [];
$insurance_benefit_details = DB::table('insurance_benefits')
->where('id', $benefit_id)->first();
if ($is_inpatient) {
$apply_ipd_percentage = $insurance_item_details[$benefit_id]['apply_ipd_percentage'] ?? false;
if(isset($apply_ipd_percentage) && $apply_ipd_percentage == 1) {
$co_payment = (int)(($insurance_benefit_details->ipd_percentage / 100) * $item->non_insured_price);
} else {
$co_payment = $insurance_item_details[$benefit_id]['ipd_co_payment'] ?? 0;
}
} else {
$apply_opd_percentage = $insurance_item_details[$benefit_id]['apply_opd_percentage'] ?? false;
if(isset($apply_opd_percentage) && $apply_opd_percentage == 1) {
$co_payment = (int)(($insurance_benefit_details->opd_percentage / 100) * $item->non_insured_price);
} else {
$co_payment = $insurance_item_details[$benefit_id]['co_payment'] ?? 0;
}
}
$insurance_status = 1;
// get the insurance amount
$opposite_gender = $member_details->gender == 1 ? 2 : 1;
// get the tariffs for the item
$tariffs = DB::table('insurance_tariffs')->where('item_id', $item_id)->where('item_type', $item_type)
->where('benefit_id', $benefit_id)->whereNotIn('gender', [$opposite_gender])
->whereNull('deleted_at')->get();
foreach ($tariffs as $tariff) {
// check for the age that it is a valid tariff
$age_array = explode(",", $tariff->age_limit);
if ($tariff->age_type == 0) {
// days
$first_day = $age_array[0];
$last_day = $age_array[1];
} elseif ($tariff->age_type == 1) {
// months
$first_day = $age_array[0] * 30;
$last_day = $age_array[1] * 30;
} else {
// years
$first_day = $age_array[0] * 365;
$last_day = $age_array[1] * 365;
}
if (between($age_diff_days, $first_day, $last_day)) {
$tariff_id = $tariff->id;
$insurance_price = $is_inpatient ? $tariff->ipd_tariff_price : $tariff->tariff_price;
break;
}
}
if ($tariff_id == 0) {
$insurance_price = $item->non_insured_price - $co_payment;
}
}
return [$insurance_status, $insurance_price, $co_payment, $tariff_id, $benefit_id];
}
function generate_insurance_claim($order_id, $item_type): bool{
$user_id = Auth::id();
if ($item_type == 1) {
$ordered_item = OrderedService::find($order_id);
$item_ids = explode(",", $ordered_item->service_id);
$item_qtys = explode(",", $ordered_item->quantity);
$episode_id = $ordered_item->episode_id;
$patient_id = $ordered_item->patient_id;
} elseif ($item_type == 2) {
$ordered_item = OrderedProcedure::find($order_id);
$item_ids = explode(",", $ordered_item->procedure_id);
$item_qtys = array_fill(0, count($item_ids), 1);
$episode_id = $ordered_item->episode_id;
$patient_id = $ordered_item->patient_id;
} elseif ($item_type == 3) {
$ordered_item = OrderedInvestigation::find($order_id);
$item_ids = explode(",", $ordered_item->investigation_id);
$item_qtys = array_fill(0, count($item_ids), 1);
$episode_id = $ordered_item->episode_id;
$patient_id = $ordered_item->patient_id;
} elseif ($item_type == 4) {
$ordered_item = Treatment::find($order_id);
$item_ids = explode(",", $ordered_item->drugs);
$item_qtys = explode(",", $ordered_item->quantities_dispensed);
$episode_id = $ordered_item->episode_id;
$patient_id = $ordered_item->patient_id;
} elseif ($item_type == 5) {
$ordered_item = OrderedSundry::find($order_id);
$item_ids = explode(",", $ordered_item->sundries_id);
$item_qtys = explode(",", $ordered_item->quantity);
$episode_id = $ordered_item->episode_id;
$patient_id = $ordered_item->patient_id;
} else {
return false;
}
$patient_details = DB::table('insurance_members')->join('patients', 'insurance_members.patient_id', '=', 'patients.id')
->join('community_health_insurance_plans', 'insurance_members.chi_plan', '=', 'community_health_insurance_plans.id')
->where('insurance_members.patient_id', $patient_id)
->select('insurance_members.chi_plan', 'insurance_members.family_id', 'insurance_members.membership_start_date', 'patients.date_of_birth', 'patients.gender', 'community_health_insurance_plans.is_authorized_required')->first();
$age_diff_days = Carbon::createFromFormat('Y-m-d', $patient_details->date_of_birth)->diffInDays(Carbon::now());
$membership_diff_days = $patient_details->membership_start_date ? Carbon::createFromFormat('Y-m-d', $patient_details->membership_start_date)->diffInDays(Carbon::now()) : 0;
$plan_id = $patient_details->chi_plan;
// check if plan is still valid
$plan_details = DB::table('community_health_insurance_plans')->whereNull('deleted_at')->where('id', $plan_id)->first();
$claim = InsuranceClaim::where('order_id', $order_id)->where('item_type', $item_type)->first();
// check if plan has been deleted and remove any claim that exists
if (!$plan_details) {
if ($claim) {
// if claim was already registered then delete it
$claim->delete();
}
return true;
}
$plan_start_date = Carbon::createFromFormat('Y-m-d',$plan_details->plan_start_date);
$plan_end_date = Carbon::createFromFormat('Y-m-d',$plan_details->plan_end_date);
$plan_validity_error = Carbon::now()->between($plan_start_date,$plan_end_date) ? 0 : 1;
// get the consumption details so far for the patient
$consumption_details = get_insurance_member_plan_yearly_consumption_details ($patient_id, $patient_details->family_id, $plan_id, date('Y'));
// check for plan limits
$plan_member_usage = $consumption_details["member_plan_usage"] ?? 0;
$plan_family_usage = $consumption_details["family_plan_usage"] ?? 0;
$plan_member_limit = $plan_details->member_annual_limit;
$plan_family_limit = $plan_details->family_annual_limit;
$benefit_member_usage = [];
$benefit_family_usage = [];
$item_member_usage = [];
$item_family_usage = [];
$benefit_ids = [];
$item_authorisation = [];
$item_cash_amounts = [];
$co_payment_amounts = [];
$tariff_ids = [];
$tariff_amounts = [];
$claim_total = 0;
$chart_account_array = [];
$benefit_waiting_period_error = [];
$plan_limit_error = [];
$benefit_limit_error = [];
$item_limit_error = [];
for ($i = 0; $i < count($item_ids); $i++) {
if ($item_type == 1) {
$item = Services::find($item_ids[$i]);
} elseif ($item_type == 2) {
$item = Procedure::find($item_ids[$i]);
} elseif ($item_type == 3) {
$item = Investigation::find($item_ids[$i]);
} elseif ($item_type == 4) {
$item = Drug::find($item_ids[$i]);
} elseif ($item_type == 5) {
$item = Sundry::find($item_ids[$i]);
}
$is_item_authorisation_required = 0;
$tariff_id = 0;
$tariff_amount = 0;
$item_details = DB::table('insurance_benefit_items')->join('insurance_benefits', 'insurance_benefit_items.benefit_id', '=', 'insurance_benefits.id')
->where('insurance_benefit_items.plan_id', $plan_id)
->whereNull('insurance_benefit_items.deleted_at')
->whereNull('insurance_benefits.deleted_at')
->where('insurance_benefit_items.item_type', $item_type)->whereRaw('FIND_IN_SET(' . $item_ids[$i] . ',insurance_benefit_items.item_id)')
->select('insurance_benefit_items.benefit_id', 'insurance_benefits.waiting_period', 'insurance_benefits.annual_member_limit', 'insurance_benefits.annual_family_limit')->first();
if ($item_details) {
$insurance_item_details = json_decode($item->insurance_benefit_details, true) ?? [];
$benefit_ids[] = $item_details->benefit_id;
$insurance_benefit_details = DB::table('insurance_benefits')->where('id', $item_details->benefit_id)->first();
$apply_opd_percentage = $insurance_item_details[$item_details->benefit_id]['apply_opd_percentage'] ?? false;
if(isset($apply_opd_percentage) && $apply_opd_percentage == 1) {
$co_payment_amount = (int)(($insurance_benefit_details->opd_percentage / 100) * $item->non_insured_price);
} else {
$co_payment_amount = $insurance_item_details[$item_details->benefit_id]['co_payment'] ?? 0;
}
if ($insurance_item_details[$item_details->benefit_id]['authorisation'] == 1) {
$is_item_authorisation_required = 1;
}
// flip the gender for the tariffs to include the all option
$opposite_gender = $patient_details->gender == 1 ? 2 : 1;
// get the tariffs for the item
$tariffs = DB::table('insurance_tariffs')->where('item_id', $item_ids[$i])->where('item_type', $item_type)
->where('benefit_id', $item_details->benefit_id)->whereNotIn('gender', [$opposite_gender])
->whereNull('deleted_at')->get();
foreach ($tariffs as $tariff) {
// check for the age that it is a valid tariff
$age_array = explode(",", $tariff->age_limit);
if ($tariff->age_type == 0) {
// days
$first_day = $age_array[0];
$last_day = $age_array[1];
} elseif ($tariff->age_type == 1) {
// months
$first_day = $age_array[0] * 30;
$last_day = $age_array[1] * 30;
} else {
// years
$first_day = $age_array[0] * 365;
$last_day = $age_array[1] * 365;
}
if (between($age_diff_days, $first_day, $last_day)) {
$tariff_id = $tariff->id;
$tariff_amount = $tariff->tariff_price;
if ($tariff->authorisation_required == 1) {
$is_item_authorisation_required = 1;
}
break;
}
}
// if no tariff, get to pay from the non-insured
if ($tariff_id == 0) {
$tariff_amount = $item->non_insured_price - $co_payment_amount;
}
// check if the benefit waiting period is complete
$benefit_waiting_period_error[] = ($membership_diff_days >= $item_details->waiting_period) ? 0 : 1;
$tariff_amount = $tariff_amount * $item_qtys[$i];
// confirm the plan limits
$plan_member_usage += $tariff_amount;
$plan_family_usage += $tariff_amount;
// if any of family or member limit is exceeded, add flag and remove the amount from temp total
if (($plan_member_usage > $plan_member_limit && $plan_member_limit > 0) || ($plan_family_usage > $plan_family_limit && $plan_family_limit > 0)) {
$plan_limit_error[] = 1;
$plan_member_usage -= $tariff_amount;
$plan_family_usage -= $tariff_amount;
} else {
$plan_limit_error[] = 0;
}
// confirm the benefit limits
if (!isset($benefit_member_usage[$item_details->benefit_id])) {
$benefit_member_usage[$item_details->benefit_id] = $consumption_details["benefits"][$item_details->benefit_id]["member_plan_usage"] ?? 0;
$benefit_family_usage[$item_details->benefit_id] = $consumption_details["benefits"][$item_details->benefit_id]["family_plan_usage"] ?? 0;
}
$benefit_member_usage[$item_details->benefit_id] += $tariff_amount;
$benefit_family_usage[$item_details->benefit_id] += $tariff_amount;
if (($benefit_member_usage[$item_details->benefit_id] > $item_details->annual_member_limit && $item_details->annual_member_limit > 0) || ($benefit_family_usage[$item_details->benefit_id] > $item_details->annual_family_limit && $item_details->annual_family_limit > 0)) {
$benefit_limit_error[] = 1;
$benefit_member_usage[$item_details->benefit_id] -= $tariff_amount;
$benefit_family_usage[$item_details->benefit_id] -= $tariff_amount;
} else {
$benefit_limit_error[] = 0;
}
// confirm the item limits
$item_key = $item_ids[$i] . ',' . $item_type;
if (!isset($item_member_usage[$item_key])) {
$item_member_usage[$item_key] = $consumption_details["benefits"][$item_details->benefit_id]["items"][$item_key]["member_plan_usage"] ?? 0;
$item_family_usage[$item_key] = $consumption_details["benefits"][$item_details->benefit_id]["items"][$item_key]["family_plan_usage"] ?? 0;
}
$item_member_usage[$item_key] += $tariff_amount;
$item_family_usage[$item_key] += $tariff_amount;
if (($item_member_usage[$item_key] > $insurance_item_details[$item_details->benefit_id]["annual_member_limit"] && $insurance_item_details[$item_details->benefit_id]["annual_member_limit"] > 0) || ($item_family_usage[$item_key] > $insurance_item_details[$item_details->benefit_id]["annual_family_limit"] && $insurance_item_details[$item_details->benefit_id]["annual_family_limit"] > 0)) {
$item_limit_error[] = 1;
$item_member_usage[$item_key] -= $tariff_amount;
$item_family_usage[$item_key] -= $tariff_amount;
} else {
$item_limit_error[] = 0;
}
} else {
$benefit_ids[] = 0;
$co_payment_amount = $item->non_insured_price;
$plan_limit_error[] = 0;
$benefit_waiting_period_error[] = 0;
$benefit_limit_error[] = 0;
$item_limit_error[] = 0;
}
$item_authorisation[] = $is_item_authorisation_required;
$item_cash_amounts[] = $item->non_insured_price * $item_qtys[$i];
$co_payment_amounts[] = $co_payment_amount * $item_qtys[$i];
$tariff_ids[] = $tariff_id;
$tariff_amounts[] = $tariff_amount;
$claim_total += $tariff_amount;
$chart_account_array[] = $item->account_id;
}
// check if claim has any money else ignore
if ($claim_total < 1) {
if ($claim) {
// if claim was already registered then delete it
$claim->delete();
}
return true;
}
if (!$claim) {
$claim = new InsuranceClaim();
$claim->patient_id = $patient_id;
$claim->episode_id = $episode_id;
$claim->plan_id = $plan_id;
$claim->inpatient_outpatient = 0;
$claim->order_id = $order_id;
$claim->created_by = $user_id;
}
$claim->claim_status = 1;
$claim->benefit_ids = implode(",", $benefit_ids);
$claim->primary_plan_claim_total = $claim_total;
$claim->item_type = $item_type;
$claim->item_ids = implode(",", $item_ids);
$claim->item_quantities = implode(",", $item_qtys);
$claim->tariff_ids = implode(",", $tariff_ids);
$claim->tariff_amounts = implode(",", $tariff_amounts);
$claim->co_payment_amounts = implode(",", $co_payment_amounts);
$claim->item_cash_amounts = implode(",", $item_cash_amounts);
$claim->is_item_authorisation_required = implode(",", $item_authorisation);
$claim->current_chart_of_accounts = implode(",", $chart_account_array);
$claim->is_authorisation_required = $patient_details->is_authorized_required;
$claim->plan_validity_error = $plan_validity_error;
$claim->benefit_waiting_period_error = implode(",", $benefit_waiting_period_error);
$claim->plan_limit_error = implode(",", $plan_limit_error);
$claim->benefit_limit_error = implode(",", $benefit_limit_error);
$claim->item_limit_error = implode(",", $item_limit_error);
$claim->updated_by = $user_id;
try {
$claim->save();
} catch (ErrorException $exception) {}
return true;
}
function is_patient_item_covered($patient_id, $item_id, $item_type): int {
$member_details = DB::table('insurance_members')->join('insurance_benefit_items', 'insurance_benefit_items.plan_id', '=', 'insurance_members.chi_plan')
->where('insurance_members.patient_id', $patient_id)
->whereNull('insurance_benefit_items.deleted_at')
->where('insurance_benefit_items.item_type', $item_type)->whereRaw('FIND_IN_SET(' . $item_id . ',insurance_benefit_items.item_id)')
->select('insurance_members.chi_plan')->first();
return $member_details == true;
}
function register_insurance_item_consumption($patient_id, $family_id, $group_id, $plan_id, $benefit_id, $item_id, $item_type, $amount_consumed) {
$consumption_year = date('Y');
$consumption = InsuranceMemberConsumption::where('consumption_year', $consumption_year)->where('patient_id', $patient_id)
->where('family_id', $family_id)->where('item_type', $item_type)
->where('item_id', $item_id)->where('benefit_id', $benefit_id)->first();
if (!$consumption) {
$consumption = new InsuranceMemberConsumption();
$consumption->patient_id = $patient_id;
$consumption->family_id = $family_id;
$consumption->group_id = $group_id;
$consumption->plan_id = $plan_id;
$consumption->benefit_id = $benefit_id;
$consumption->item_id = $item_id;
$consumption->item_type = $item_type;
$consumption->amount_consumed = $amount_consumed;
$consumption->consumption_year = $consumption_year;
$consumption->created_by = Auth::id();
} else {
$current_amount_consumed = $consumption->amount_consumed;
$consumption->amount_consumed = $current_amount_consumed + $amount_consumed;
$consumption->updated_by = Auth::id();
}
$consumption->save();
}
function get_insurance_member_plan_yearly_consumption_details ($patient_id, $family_id, $plan_id, $year): array {
$return_arr = [];
$consumptions = DB::table('insurance_member_consumptions')
->where('plan_id', $plan_id)->where('consumption_year', $year)
->where('family_id', $family_id)->get();
foreach ($consumptions as $consumption) {
$return_arr["member_plan_usage"] = ($return_arr["member_plan_usage"] ?? 0) + (($consumption->patient_id == $patient_id) ? $consumption->amount_consumed : 0);
$return_arr["family_plan_usage"] = ($return_arr["family_plan_usage"] ?? 0) + $consumption->amount_consumed;
// get the benefits
$return_arr["benefits"][$consumption->benefit_id]["member_plan_usage"] =
($return_arr["benefits"][$consumption->benefit_id]["member_plan_usage"] ?? 0) + (($consumption->patient_id == $patient_id) ? $consumption->amount_consumed : 0);
$return_arr["benefits"][$consumption->benefit_id]["family_plan_usage"] =
($return_arr["benefits"][$consumption->benefit_id]["family_plan_usage"] ?? 0) + $consumption->amount_consumed;
// then the items
// use combination of item id and type to avoid confusion
$item_key = $consumption->item_id . ',' . $consumption->item_type;
$return_arr["benefits"][$consumption->benefit_id]["items"][$item_key]["member_plan_usage"] =
($return_arr["benefits"][$consumption->benefit_id]["items"][$item_key]["member_plan_usage"] ?? 0) + (($consumption->patient_id == $patient_id) ? $consumption->amount_consumed : 0);
$return_arr["benefits"][$consumption->benefit_id]["items"][$item_key]["family_plan_usage"] =
($return_arr["benefits"][$consumption->benefit_id]["items"][$item_key]["family_plan_usage"] ?? 0) + $consumption->amount_consumed;
}
return $return_arr;
}
function are_item_type_claims_available($episode_id, $item_type): bool {
if ($item_type == 0) {
$claims = DB::table('insurance_claims')->whereNull('deleted_at')->where('episode_id', $episode_id)->where('claim_status', 1)->count();
} else {
$claims = DB::table('insurance_claims')->whereNull('deleted_at')->where('episode_id', $episode_id)->where('item_type', $item_type)->where('claim_status', 1)->count();
}
return $claims > 0;
}
function can_chi_deposit_be_cancelled($receipt_number): bool {
$deposit_details = DB::table('chi_deposits')
->where('receipt_number', $receipt_number)
->get();
// first make sure that none of the money was collected
foreach ($deposit_details as $deposit_detail) {
if ($deposit_detail->tag_id == 2) {
$result = DB::table('investigation_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->count();
$item_type = 3;
} else if ($deposit_detail->tag_id == 3) {
$result = DB::table('treatment_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->count();
$item_type = 4;
} else if ($deposit_detail->tag_id == 4) {
$result = DB::table('procedure_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->count();
$item_type = 2;
} else if ($deposit_detail->tag_id == 5) {
$result = DB::table('sundries_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->count();
$item_type = 5;
} else if ($deposit_detail->tag_id == 8) {
$result = DB::table('service_deposits')
->where('receipt_number', $receipt_number)
->whereNotNull('received')
->count();
$item_type = 1;
} else {
return false;
}
if ($result > 0) {
return false;
}
$orders = explode(",", $deposit_detail->order_ids);
foreach ($orders as $order) {
$claim_result = DB::table('insurance_claims')
->where('order_id', $order)
->where('item_type', $item_type)
->where('claim_status', '!=', 2)
->count();
if ($claim_result > 0) {
return false;
}
}
}
// check for patient debts
$debts = DB::table('debtors')
->where('receipt_number', $receipt_number)
->whereNotNull('amount_paid_off')
->count();
if ($debts > 0) {
return false;
}
// check the debt plan
$debt_plan = DB::table('debt_plan')
->where('receipt_number', $receipt_number)
->whereNotNull('amount_paid_off')
->count();
if ($debt_plan > 0) {
return false;
}
return true;
}
function remove_insurance_item_consumption($patient_id, $family_id, $benefit_id, $item_id, $item_type, $amount_consumed) {
$consumption_year = date('Y');
$consumption = InsuranceMemberConsumption::where('consumption_year', $consumption_year)->where('patient_id', $patient_id)
->where('family_id', $family_id)->where('item_type', $item_type)
->where('item_id', $item_id)->where('benefit_id', $benefit_id)->first();
if ($consumption) {
$current_amount_consumed = $consumption->amount_consumed;
$consumption->amount_consumed = $current_amount_consumed - $amount_consumed;
$consumption->updated_by = Auth::id();
$consumption->save();
}
}
function update_insurance_heads_of_family_record($family_head_id, $insurance_member_id, $insurance_member_premium)
{
$insurance_heads_of_family = \Streamline\Models\HeadOfFamily::withTrashed()->find($family_head_id);
if ($insurance_heads_of_family) {
$members_array = is_null($insurance_heads_of_family->family_members_ids) ? [] : explode(",", $insurance_heads_of_family->family_members_ids);
if (!in_array($insurance_member_id,$members_array)) {
$members_array[] = $insurance_member_id;
$premiums_array = is_null($insurance_heads_of_family->family_member_premiums) ? [] : explode(",", $insurance_heads_of_family->family_member_premiums);
$premiums_array[] = $insurance_member_premium;
$insurance_heads_of_family->family_members_ids = implode(",", $members_array);
$insurance_heads_of_family->family_member_premiums = implode(",", $premiums_array);
$insurance_heads_of_family->update();
}
}
}
function patient_duration_on_chi_sheme($patient_id)
{
$insurance_member = DB::table('insurance_members')->where('patient_id', $patient_id)->orderBy('id', 'desc')->first();
if ($insurance_member) {
if (!is_null($insurance_member->membership_start_date)) {
return Carbon::parse($insurance_member->membership_start_date)->diffForHumans();
} else{
return Carbon::parse($insurance_member->created_at)->diffForHumans();
}
}
}
function create_inpatient_claims($insurance_claim_items, $patient_id, $episode_id, $inpatient_bill_id){
$user_id = Auth::id();
$patient_details = DB::table('insurance_members')->join('patients', 'insurance_members.patient_id', '=', 'patients.id')
->join('community_health_insurance_plans', 'insurance_members.chi_plan', '=', 'community_health_insurance_plans.id')
->where('insurance_members.patient_id', $patient_id)
->select('insurance_members.chi_plan', 'insurance_members.family_id', 'insurance_members.membership_start_date', 'community_health_insurance_plans.is_authorized_required')->first();
if ($patient_details) {
$membership_diff_days = $patient_details->membership_start_date ? Carbon::createFromFormat('Y-m-d', $patient_details->membership_start_date)->diffInDays(Carbon::now()) : 0;
$plan_id = $patient_details->chi_plan;
// check if plan is still valid
$plan_details = DB::table('community_health_insurance_plans')->whereNull('deleted_at')->where('id', $plan_id)->first();
$plan_start_date = Carbon::createFromFormat('Y-m-d',$plan_details->plan_start_date);
$plan_end_date = Carbon::createFromFormat('Y-m-d',$plan_details->plan_end_date);
$plan_validity_error = Carbon::now()->between($plan_start_date,$plan_end_date) ? 0 : 1;
// get the consumption details so far for the patient
$consumption_details = get_insurance_member_plan_yearly_consumption_details ($patient_id, $patient_details->family_id, $plan_id, date('Y'));
// check for plan limits
$plan_member_usage = $consumption_details["member_plan_usage"] ?? 0;
$plan_family_usage = $consumption_details["family_plan_usage"] ?? 0;
$plan_member_limit = $plan_details->member_annual_limit;
$plan_family_limit = $plan_details->family_annual_limit;
$benefit_member_usage = [];
$benefit_family_usage = [];
$item_member_usage = [];
$item_family_usage = [];
foreach ($insurance_claim_items as $item_type => $insurance_claim_item) {
$claim = InsuranceClaim::where('order_id', $inpatient_bill_id)->where('item_type', $item_type)->first();
// check if plan has been deleted and remove any claim that exists
if (!$plan_details) {
if ($claim) {
// if claim was already registered then delete it
$claim->delete();
}
continue;
}
$item_authorisation = [];
$claim_total = 0;
$chart_account_array = [];
$benefit_waiting_period_error = [];
$plan_limit_error = [];
$benefit_limit_error = [];
$item_limit_error = [];
$benefit_ids = $insurance_claim_item['benefit_ids'];
$item_ids = $insurance_claim_item['item_ids'];
$item_quantities = $insurance_claim_item['item_quantities'];
$tariff_ids = $insurance_claim_item['tariff_ids'];
$tariff_amounts = $insurance_claim_item['tariff_amounts'];
$co_payment_amounts = $insurance_claim_item['co_payment_amounts'];
$item_cash_amounts = $insurance_claim_item['item_cash_amounts'];
for ($i = 0; $i < count($item_ids); $i++) {
if ($item_type == 1) {
$item = Services::find($item_ids[$i]);
} elseif ($item_type == 2) {
$item = Procedure::find($item_ids[$i]);
} elseif ($item_type == 3) {
$item = Investigation::find($item_ids[$i]);
} elseif ($item_type == 4) {
$item = Drug::find($item_ids[$i]);
} elseif ($item_type == 5) {
$item = Sundry::find($item_ids[$i]);
} elseif ($item_type == 6) {
// do the adjudication for the bed stays here
$tariff_amount = $tariff_amounts[$i];
$rate_info = DB::table('insurance_inpatient_accommodation_rates')->where('id', $item_ids[$i])->first();
if($rate_info) {
$benefit_details = DB::table('insurance_benefits')
->where('id', $rate_info->benefit_id)
->whereNull('insurance_benefits.deleted_at')
->select('waiting_period', 'annual_member_limit', 'annual_family_limit', 'id')->first();
// check if the benefit waiting period is complete
$benefit_waiting_period_error[] = ($membership_diff_days >= $benefit_details->waiting_period) ? 0 : 1;
// confirm the plan limits
$plan_member_usage += $tariff_amount;
$plan_family_usage += $tariff_amount;
// if any of family or member limit is exceeded, add flag and remove the amount from temp total
if (($plan_member_usage > $plan_member_limit && $plan_member_limit > 0) || ($plan_family_usage > $plan_family_limit && $plan_family_limit > 0)) {
$plan_limit_error[] = 1;
$plan_member_usage -= $tariff_amount;
$plan_family_usage -= $tariff_amount;
} else {
$plan_limit_error[] = 0;
}
// confirm the benefit limits
if (!isset($benefit_member_usage[$benefit_details->id])) {
$benefit_member_usage[$benefit_details->id] = $consumption_details["benefits"][$benefit_details->id]["member_plan_usage"] ?? 0;
$benefit_family_usage[$benefit_details->id] = $consumption_details["benefits"][$benefit_details->id]["family_plan_usage"] ?? 0;
}
$benefit_member_usage[$benefit_details->id] += $tariff_amount;
$benefit_family_usage[$benefit_details->id] += $tariff_amount;
if (($benefit_member_usage[$benefit_details->id] > $benefit_details->annual_member_limit && $benefit_details->annual_member_limit > 0) || ($benefit_family_usage[$benefit_details->id] > $benefit_details->annual_family_limit && $benefit_details->annual_family_limit > 0)) {
$benefit_limit_error[] = 1;
$benefit_member_usage[$benefit_details->id] -= $tariff_amount;
$benefit_family_usage[$benefit_details->id] -= $tariff_amount;
} else {
$benefit_limit_error[] = 0;
}
// confirm the item limits
$item_key = $item_ids[$i] . ',' . $item_type;
if (!isset($item_member_usage[$item_key])) {
$item_member_usage[$item_key] = $consumption_details["benefits"][$benefit_details->id]["items"][$item_key]["member_plan_usage"] ?? 0;
$item_family_usage[$item_key] = $consumption_details["benefits"][$benefit_details->id]["items"][$item_key]["family_plan_usage"] ?? 0;
}
$item_member_usage[$item_key] += $tariff_amount;
$item_family_usage[$item_key] += $tariff_amount;
if (($item_member_usage[$item_key] > $rate_info->annual_member_limit && $rate_info->annual_member_limit > 0) || ($item_family_usage[$item_key] > $rate_info->annual_family_limit && $rate_info->annual_family_limit > 0)) {
$item_limit_error[] = 1;
$item_member_usage[$item_key] -= $tariff_amount;
$item_family_usage[$item_key] -= $tariff_amount;
} else {
$item_limit_error[] = 0;
}
$item_authorisation[] = $rate_info->authorisation_required;
$claim_total += $tariff_amount;
$chart_account_array[] = get_name($rate_info->bed_category_id, 'id', 'income_account', 'inpatient_bed_categories');
}
continue;
} else {
break;
}
$is_item_authorisation_required = 0;
$tariff_id = $tariff_ids[$i];
$tariff_amount = $tariff_amounts[$i];
$item_details = DB::table('insurance_benefit_items')->join('insurance_benefits', 'insurance_benefit_items.benefit_id', '=', 'insurance_benefits.id')
->where('insurance_benefit_items.plan_id', $plan_id)
->whereNull('insurance_benefit_items.deleted_at')
->whereNull('insurance_benefits.deleted_at')
->where('insurance_benefit_items.item_type', $item_type)->whereRaw('FIND_IN_SET(' . $item_ids[$i] . ',insurance_benefit_items.item_id)')
->select('insurance_benefit_items.benefit_id', 'insurance_benefits.waiting_period', 'insurance_benefits.annual_member_limit', 'insurance_benefits.annual_family_limit')->first();
if ($item_details) {
$insurance_item_details = json_decode($item->insurance_benefit_details, true) ?? [];
// get the tariff for the item
$tariff = DB::table('insurance_tariffs')->where('id', $tariff_id)->whereNull('deleted_at')->first();
if (($tariff && $tariff->authorisation_required == 1) || $insurance_item_details[$item_details->benefit_id]['authorisation'] == 1) {
$is_item_authorisation_required = 1;
}
// check if the benefit waiting period is complete
$benefit_waiting_period_error[] = ($membership_diff_days >= $item_details->waiting_period) ? 0 : 1;
// confirm the plan limits
$plan_member_usage += $tariff_amount;
$plan_family_usage += $tariff_amount;
// if any of family or member limit is exceeded, add flag and remove the amount from temp total
if (($plan_member_usage > $plan_member_limit && $plan_member_limit > 0) || ($plan_family_usage > $plan_family_limit && $plan_family_limit > 0)) {
$plan_limit_error[] = 1;
$plan_member_usage -= $tariff_amount;
$plan_family_usage -= $tariff_amount;
} else {
$plan_limit_error[] = 0;
}
// confirm the benefit limits
if (!isset($benefit_member_usage[$item_details->benefit_id])) {
$benefit_member_usage[$item_details->benefit_id] = $consumption_details["benefits"][$item_details->benefit_id]["member_plan_usage"] ?? 0;
$benefit_family_usage[$item_details->benefit_id] = $consumption_details["benefits"][$item_details->benefit_id]["family_plan_usage"] ?? 0;
}
$benefit_member_usage[$item_details->benefit_id] += $tariff_amount;
$benefit_family_usage[$item_details->benefit_id] += $tariff_amount;
if (($benefit_member_usage[$item_details->benefit_id] > $item_details->annual_member_limit && $item_details->annual_member_limit > 0) || ($benefit_family_usage[$item_details->benefit_id] > $item_details->annual_family_limit && $item_details->annual_family_limit > 0)) {
$benefit_limit_error[] = 1;
$benefit_member_usage[$item_details->benefit_id] -= $tariff_amount;
$benefit_family_usage[$item_details->benefit_id] -= $tariff_amount;
} else {
$benefit_limit_error[] = 0;
}
// confirm the item limits
$item_key = $item_ids[$i] . ',' . $item_type;
if (!isset($item_member_usage[$item_key])) {
$item_member_usage[$item_key] = $consumption_details["benefits"][$item_details->benefit_id]["items"][$item_key]["member_plan_usage"] ?? 0;
$item_family_usage[$item_key] = $consumption_details["benefits"][$item_details->benefit_id]["items"][$item_key]["family_plan_usage"] ?? 0;
}
$item_member_usage[$item_key] += $tariff_amount;
$item_family_usage[$item_key] += $tariff_amount;
if (($item_member_usage[$item_key] > $insurance_item_details[$item_details->benefit_id]["annual_member_limit"] && $insurance_item_details[$item_details->benefit_id]["annual_member_limit"] > 0) || ($item_family_usage[$item_key] > $insurance_item_details[$item_details->benefit_id]["annual_family_limit"] && $insurance_item_details[$item_details->benefit_id]["annual_family_limit"] > 0)) {
$item_limit_error[] = 1;
$item_member_usage[$item_key] -= $tariff_amount;
$item_family_usage[$item_key] -= $tariff_amount;
} else {
$item_limit_error[] = 0;
}
} else {
$plan_limit_error[] = 0;
$benefit_waiting_period_error[] = 0;
$benefit_limit_error[] = 0;
$item_limit_error[] = 0;
}
$item_authorisation[] = $is_item_authorisation_required;
$chart_account_array[] = $item->account_id;
$claim_total += $tariff_amount;
}
if (!$claim) {
$claim = new InsuranceClaim();
$claim->patient_id = $patient_id;
$claim->episode_id = $episode_id;
$claim->plan_id = $plan_id;
$claim->inpatient_outpatient = 1;
$claim->order_id = $inpatient_bill_id;
$claim->created_by = $user_id;
}
$claim->claim_status = 1;
$claim->benefit_ids = implode(",", $benefit_ids);
$claim->primary_plan_claim_total = $claim_total;
$claim->item_type = $item_type;
$claim->item_ids = implode(",", $item_ids);
$claim->item_quantities = implode(",", $item_quantities);
$claim->tariff_ids = implode(",", $tariff_ids);
$claim->tariff_amounts = implode(",", $tariff_amounts);
$claim->co_payment_amounts = implode(",", $co_payment_amounts);
$claim->item_cash_amounts = implode(",", $item_cash_amounts);
$claim->is_item_authorisation_required = implode(",", $item_authorisation);
$claim->current_chart_of_accounts = implode(",", $chart_account_array);
$claim->is_authorisation_required = $patient_details->is_authorized_required;
$claim->plan_validity_error = $plan_validity_error;
$claim->benefit_waiting_period_error = implode(",", $benefit_waiting_period_error);
$claim->plan_limit_error = implode(",", $plan_limit_error);
$claim->benefit_limit_error = implode(",", $benefit_limit_error);
$claim->item_limit_error = implode(",", $item_limit_error);
$claim->updated_by = $user_id;
try {
$claim->save();
} catch (ErrorException $exception) {}
}
}
}
/**
* Remove insurance claims from OPD orders
*
* @param $order_id
* @param $item_type
* @return void
*/
function remove_insurance_claim_by_order($order_id, $item_type) {
// check if claim exists in table and delete it
$claim = InsuranceClaim::where('order_id', $order_id)->where('item_type', $item_type)->first();
if ($claim) {
$claim->delete();
}
}
function get_insurance_bed_rate($patient_id, $bed_category_id) {
$inpatient_bed_category = InpatientBedCategory::withTrashed()->find($bed_category_id);
$patient = DB::table('patients')->join('insurance_members', 'insurance_members.patient_id', '=', 'patients.id')
->where('patients.id', $patient_id)
->select(['insurance_members.chi_plan', 'patients.gender', 'patients.date_of_birth'])->first();
if ($patient) {
$insurance_bed_categories = DB::table('insurance_inpatient_accommodation_rates')->where('plan_id', $patient->chi_plan)
->where('bed_category_id', $bed_category_id)->whereIn('gender', [0, $patient->gender])->get();
$age_diff_days = Carbon::createFromFormat('Y-m-d', $patient->date_of_birth)->diffInDays(Carbon::now());
foreach ($insurance_bed_categories as $category) {
$age_array = explode(",", $category->age_limit);
if ($category->age_type == 0) {
// days
$first_day = $age_array[0];
$last_day = $age_array[1];
} elseif ($category->age_type == 1) {
// months
$first_day = $age_array[0] * 30;
$last_day = $age_array[1] * 30;
} else {
// years
$first_day = $age_array[0] * 365;
$last_day = $age_array[1] * 365;
}
if (between($age_diff_days, $first_day, $last_day)) {
return ($category->cost_type == 1) ? $category->cost_per_night : $category->cost_first_night;
}
}
}
return ($inpatient_bed_category->cost_type == 1) ? $inpatient_bed_category->cost_per_night : $inpatient_bed_category->cost_first_night;
}
function get_inpatient_admission_cost($days, $id, $edited_cost) {
//get bed category details for patient
$bed_category = InpatientBedCategory::withTrashed()->find($id);
if($bed_category){
if ($bed_category->cost_type == 1) {
$cost = (($edited_cost > -1) ? $edited_cost : $bed_category->cost_per_night) * $days;
} else {
// get cost for the first night
$cost = ($edited_cost > -1) ? $edited_cost : $bed_category->cost_first_night;
$last_night_in_range = $bed_category->to_night;
// run from the first night to the last one separating for the range and thereafter
for ($i = 2; $i <= $days; $i++) {
if ($i > $last_night_in_range) {
$cost += $bed_category->cost_after;
} else {
$cost += $bed_category->cost_range;
}
}
}
return $cost;
}
return 0;
}
function get_inpatient_admission_cost_insurance($days, $id, $edited_cost, $patient_id): array {
//get bed category details for patient
$bed_category = InpatientBedCategory::withTrashed()->find($id);
$patient = DB::table('patients')->join('insurance_members', 'insurance_members.patient_id', '=', 'patients.id')
->where('patients.id', $patient_id)
->select(['insurance_members.chi_plan', 'patients.gender', 'patients.date_of_birth'])->first();
if ($patient) {
$insurance_bed_categories = DB::table('insurance_inpatient_accommodation_rates')->where('plan_id', $patient->chi_plan)
->where('bed_category_id', $id)->whereIn('gender', [0, $patient->gender])->get();
$age_diff_days = Carbon::createFromFormat('Y-m-d', $patient->date_of_birth)->diffInDays(Carbon::now());
foreach ($insurance_bed_categories as $category) {
$age_array = explode(",", $category->age_limit);
if ($category->age_type == 0) {
// days
$first_day = $age_array[0];
$last_day = $age_array[1];
} elseif ($category->age_type == 1) {
// months
$first_day = $age_array[0] * 30;
$last_day = $age_array[1] * 30;
} else {
// years
$first_day = $age_array[0] * 365;
$last_day = $age_array[1] * 365;
}
if (between($age_diff_days, $first_day, $last_day)) {
if ($category->cost_type == 1) {
$patient_to_pay = (($edited_cost > -1) ? $edited_cost : $category->cost_per_night) * $days;
$chi_to_pay = $category->chi_cost_per_night * $days;
} else {
// get cost for the first night
$patient_to_pay = ($edited_cost > -1) ? $edited_cost : $category->cost_first_night;
$chi_to_pay = $category->chi_cost_first_night;
$last_night_in_range = $bed_category->to_night;
// run from the first night to the last one separating for the range and thereafter
for ($i = 2; $i <= $days; $i++) {
if ($i > $last_night_in_range) {
$patient_to_pay += $category->cost_after;
$chi_to_pay += $category->chi_cost_after;
} else {
$patient_to_pay += $category->cost_range;
$chi_to_pay += $category->chi_cost_range;
}
}
}
return [$patient_to_pay, $chi_to_pay, $category->id];
}
}
}
return [get_inpatient_admission_cost($days, $id, $edited_cost), 0, 0];
}
function are_symptoms_on_consultation() {
$general_settings = GeneralSettings::find(1);
return $general_settings->show_symptoms_on_consultation == 1;
}
function create_batch_watcher_record($item_id, $item_category_id, $cost_price, $batch_number, $store_stock, $pharmacy_stock, $expiry_date)
{
$item_batch_watcher = new \Streamline\Models\ItemBatchWatcher;
$item_batch_watcher->item_id = $item_id;
$item_batch_watcher->item_type = $item_category_id;
$item_batch_watcher->cost_price = $cost_price;
$item_batch_watcher->batch_number = $batch_number;
$item_batch_watcher->store_stock = $store_stock;
$item_batch_watcher->pharmacy_stock = $pharmacy_stock;
$item_batch_watcher->expiry_date = $expiry_date;
$item_batch_watcher->save();
}
function move_batch_item_from_store_to_pharmacy($item_type, $item_id, $batch_number, $quantity_to_move, $requisition_id)
{
$item_name = "";
if ($item_type == 1) {
$item_name = get_name($item_id, "id", "name", "drugs");
} elseif ($item_type == 2) {
$item_name = get_name($item_id, "id", "name", "sundries");
}
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id, 'batch_number' => $batch_number])->first();
if ($item_batch_watcher ) {
$item_batch_watcher->store_stock = $item_batch_watcher->store_stock - $quantity_to_move;
$item_batch_watcher->pharmacy_stock = $item_batch_watcher->pharmacy_stock + $quantity_to_move;
$item_batch_watcher->save();
flash("Moved ".$quantity_to_move." units of ".$item_name." from Batch: ".$batch_number." from store to pharmacy");
} else{
//reduce the next one in line that has enough store stock.
$random_batch_next = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id])->where('store_stock','>',0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if ($random_batch_next) {
$random_batch_next->store_stock = $random_batch_next->store_stock - $quantity_to_move;
$random_batch_next->pharmacy_stock = $random_batch_next->pharmacy_stock + $quantity_to_move;
$random_batch_next->save();
flash("Moved ".$quantity_to_move." units of ".$item_name." from Batch: ".$random_batch_next->batch_number." from store to pharmacy");
}
}
record_store_stock_movement($item_type, $item_id, $batch_number, $quantity_to_move, "pharmacy", $requisition_id);
}
function move_batch_item_from_store_to_ward($item_type, $item_id, $batch_number, $quantity_to_move, $ward_id, $ward_request_id)
{
$item_name = "";
if ($item_type == 1) {
$item_name = get_name($item_id, "id", "name", "drugs");
} elseif ($item_type == 2) {
$item_name = get_name($item_id, "id", "name", "sundries");
}
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id, 'batch_number' => $batch_number])->first();
if ($item_batch_watcher ) {
$item_batch_watcher->store_stock = $item_batch_watcher->store_stock - $quantity_to_move;
$item_batch_watcher->ward_stock = $item_batch_watcher->ward_stock + $quantity_to_move;
$item_batch_watcher->ward_id = $ward_id;
$item_batch_watcher->save();
flash("Moved ".$quantity_to_move." units of ".$item_name." from Batch: ".$batch_number." from store to ward");
} else{
//reduce the next one in line that has enough store stock.
$random_batch_next = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id])->where('store_stock','>',0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if ($random_batch_next) {
$random_batch_next->store_stock = $random_batch_next->store_stock - $quantity_to_move;
$random_batch_next->ward_stock = $random_batch_next->ward_stock + $quantity_to_move;
$random_batch_next->ward_id = $ward_id;
$random_batch_next->save();
flash("Moved ".$quantity_to_move." units of ".$item_name." from Batch: ".$random_batch_next->batch_number." from store to ward");
}
}
record_store_stock_movement($item_type, $item_id, $batch_number, $quantity_to_move, "ward", $ward_request_id);
}
function move_batch_item_from_pharmacy_to_ward($item_type, $item_id, $batch_number, $quantity_to_move, $ward_id)
{
$item_name = "";
if ($item_type == 1) {
$item_name = get_name($item_id, "id", "name", "drugs");
} elseif ($item_type == 2) {
$item_name = get_name($item_id, "id", "name", "sundries");
}
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id, 'batch_number' => $batch_number])->first();
if ($item_batch_watcher ) {
$item_batch_watcher->pharmacy_stock = $item_batch_watcher->pharmacy_stock - $quantity_to_move;
$item_batch_watcher->ward_stock = $item_batch_watcher->ward_stock + $quantity_to_move;
$item_batch_watcher->ward_id = $ward_id;
$item_batch_watcher->save();
flash("Moved ".$quantity_to_move." units of ".$item_name." from Batch: ".$batch_number." from pharmacy to ward");
} else{
//reduce the next one in line that has enough store stock.
$random_batch_next = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id])->where('pharmacy_stock','>',0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if ($random_batch_next) {
$random_batch_next->pharmacy_stock = $random_batch_next->pharmacy_stock - $quantity_to_move;
$random_batch_next->ward_stock = $random_batch_next->ward_stock + $quantity_to_move;
$random_batch_next->ward_id = $ward_id;
$random_batch_next->save();
flash("Moved ".$quantity_to_move." units of ".$item_name." from Batch: ".$random_batch_next->batch_number." from pharmacy to ward");
}
}
}
function reduce_batch_item_from_pharmacy($item_type, $item_id, $batch_number, $quantity_to_reduce, $reduction_table, $reduction_table_id, $patient_id)
{
$item_name = "";
if ($item_type == 1) {
$item_name = get_name($item_id, "id", "name", "drugs");
} elseif ($item_type == 2) {
$item_name = get_name($item_id, "id", "name", "sundries");
}
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id, 'batch_number' => $batch_number])->first();
if ($item_batch_watcher ) {
$item_batch_watcher->pharmacy_stock = $item_batch_watcher->pharmacy_stock - $quantity_to_reduce;
$item_batch_watcher->save();
record_batch_consumption(1, $item_id, $batch_number, $quantity_to_reduce, $reduction_table, $reduction_table_id, $patient_id);
flash("Reduced ".$quantity_to_reduce." units of ".$item_name." of Batch: ".$batch_number. " from pharmacy");
} else{
//reduce the next one in line that has enough store stock.
$random_batch_next = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id])->where('pharmacy_stock','>',0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if ($random_batch_next) {
$random_batch_next->pharmacy_stock = $random_batch_next->pharmacy_stock - $quantity_to_reduce;
$random_batch_next->save();
record_batch_consumption(1, $item_id, $random_batch_next->batch_number, $quantity_to_reduce, $reduction_table, $reduction_table_id, $patient_id);
flash("Reduced ".$quantity_to_reduce." units of ".$item_name." of Batch: ".$random_batch_next->batch_number. " from pharmacy");
}
}
}
function reduce_batch_item_from_store($item_type, $item_id, $batch_number, $quantity_to_reduce)
{
$item_name = "";
if ($item_type == 1) {
$item_name = get_name($item_id, "id", "name", "drugs");
} elseif ($item_type == 2) {
$item_name = get_name($item_id, "id", "name", "sundries");
}
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id, 'batch_number' => $batch_number])->first();
if ($item_batch_watcher ) {
$item_batch_watcher->store_stock = $item_batch_watcher->store_stock - $quantity_to_reduce;
$item_batch_watcher->save();
flash("Reduced ".$quantity_to_reduce." units of ".$item_name." of Batch: ".$batch_number. " from store");
} else{
//reduce the next one in line that has enough store stock.
$random_batch_next = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id])->where('store_stock','>',0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if ($random_batch_next) {
$random_batch_next->store_stock = $random_batch_next->store_stock - $quantity_to_reduce;
$random_batch_next->save();
flash("Reduced ".$quantity_to_reduce." units of ".$item_name." of Batch: ".$random_batch_next->batch_number. " from store");
}
}
}
function update_batch_stock_watcher_table($item_batch_watcher_id){
$today = date('Y-m-d');
//get for this batches' details
$item_batch_watcher_record = \Streamline\Models\ItemBatchWatcher::withTrashed()->find($item_batch_watcher_id);
$item_type = $item_batch_watcher_record->item_type;
$item_id = $item_batch_watcher_record->item_id;
$item_cost_price = $item_batch_watcher_record->cost_price;
$pharmacy_stock = $item_batch_watcher_record->pharmacy_stock;
$store_stock = $item_batch_watcher_record->store_stock;
$ward_stock = $item_batch_watcher_record->ward_stock;
//first check if this batch has a record that is being tracked by the batch_stock_watcher table
$batch_stock_watcher = DB::table('batch_stock_watcher')->where('item_batch_watcher_id', $item_batch_watcher_id)->first();
if ($batch_stock_watcher) {
$details_arr = json_decode($batch_stock_watcher->details, true);
$update_stock_watcher = BatchStockWatcher::find($batch_stock_watcher->id);
} else {
$details_arr = [];
$update_stock_watcher = new BatchStockWatcher;
$update_stock_watcher->item_type = $item_type;
$update_stock_watcher->item_id = $item_id;
$update_stock_watcher->item_batch_watcher_id = $item_batch_watcher_id;
}
if ($item_type == 1) {
// drugs
$drug = DB::table('drugs')->where('id', $item_id)->first();
if ($drug) {
$details_arr[$today] = [
"pharmacy_stock" => $pharmacy_stock,
"store_stock" => $store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $item_cost_price,
"selling_price" => $drug->non_insured_price,
"inventory_account_id" => $drug->inventory_account,
"cost_of_goods_account_id" => $drug->cost_of_goods_account
];
} else {
return;
}
} elseif ($item_type == 2) {
// sundries
$sundry = DB::table('sundries')->where('id', $item_id)->first();
if ($sundry) {
$details_arr[$today] = [
"pharmacy_stock" => $pharmacy_stock,
"store_stock" => $store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $item_cost_price,
"selling_price" => $sundry->non_insured_price,
"inventory_account_id" => $sundry->inventory_account,
"cost_of_goods_account_id" => $sundry->cost_of_goods_account
];
} else {
return;
}
} elseif ($item_type == 3) {
// dental
$dental = DB::table('dentals')->where('id', $item_id)->first();
if ($dental) {
$details_arr[$today] = [
"pharmacy_stock" => $pharmacy_stock,
"store_stock" => $store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $item_cost_price,
"selling_price" => $dental->non_insured_price,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
} elseif ($item_type == 4) {
// radiology
$radiology = DB::table('radiologies')->where('id', $item_id)->first();
if ($radiology) {
$details_arr[$today] = [
"pharmacy_stock" => $pharmacy_stock,
"store_stock" => $store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $item_cost_price,
"selling_price" => $radiology->non_insured_price,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
} elseif ($item_type == 5) {
// labs
$lab = DB::table('labs')->where('id', $item_id)->first();
if ($lab) {
$details_arr[$today] = [
"pharmacy_stock" => $pharmacy_stock,
"store_stock" => $store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $item_cost_price,
"selling_price" => $lab->non_insured_price,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
} elseif ($item_type == 6) {
// general items
$item = DB::table('general_items')->where('id', $item_id)->first();
if ($item) {
$details_arr[$today] = [
"pharmacy_stock" => 0,
"store_stock" => $store_stock,
"ward_stock" => $ward_stock,
"buying_price" => $item_cost_price,
"selling_price" => 0,
"inventory_account_id" => 0,
"cost_of_goods_account_id" => 0
];
} else {
return;
}
}
$update_stock_watcher->details = json_encode($details_arr);
$update_stock_watcher->save();
}
function get_select_clinic_order_type() {
$general_settings = GeneralSettings::find(1);
return $general_settings->select_clinic_order_type;
}
function get_pharmacy_batches_to_use_based_on_needed_quantity($item_id, $item_type, $needed_quantity){
$item_batch_watcher = null;
if (batch_tracking_method() == "FIFO") {
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type])->where('pharmacy_stock', '>', 0)->orderBy('id', 'asc')->first();
} elseif (batch_tracking_method() == "FEFO") {
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type])->where('pharmacy_stock', '>', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
}
$batch_quantity_assoc_array = [];
$batched_only_array = [];
if ($item_batch_watcher) {
//if the needed qty is more than what is available in this batch, get balance from next batch
if ($needed_quantity > $item_batch_watcher->pharmacy_stock) {
$batch_quantity_assoc_array[$item_batch_watcher->batch_number] = $item_batch_watcher->pharmacy_stock;
$batched_only_array[] = $item_batch_watcher->batch_number;
$extra_needed_quantity = $needed_quantity - $item_batch_watcher->pharmacy_stock;
//now get the other batches to use
$result = needed_pharmacy_batches_recursive_helper($batched_only_array, $extra_needed_quantity, $item_id, $item_type);
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $result[0]);
} else{
$batch_quantity_assoc_array[$item_batch_watcher->batch_number] = $needed_quantity;
}
}
return $batch_quantity_assoc_array;
}
function needed_pharmacy_batches_recursive_helper($batches_to_exclude, $needed_quantity, $item_id, $item_type)
{
$needed_item_batch_watcher = null;
if (batch_tracking_method() == "FIFO") {
$needed_item_batch_watcher = \Streamline\Models\ItemBatchWatcher::whereNotIn('batch_number', $batches_to_exclude)->where(['item_id' => $item_id, 'item_type' => $item_type])->where('pharmacy_stock', '>', 0)->orderBy('id', 'asc')->first();
} elseif (batch_tracking_method() == "FEFO") {
$needed_item_batch_watcher = \Streamline\Models\ItemBatchWatcher::whereNotIn('batch_number', $batches_to_exclude)->where(['item_id' => $item_id, 'item_type' => $item_type])->where('pharmacy_stock', '>', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
}
$extra_needed_quantity = null;
$batch_quantity_assoc_array = [];
if ($needed_item_batch_watcher) {
if ($needed_quantity > $needed_item_batch_watcher->pharmacy_stock) {
$local_assoc_array[$needed_item_batch_watcher->batch_number] = $needed_item_batch_watcher->pharmacy_stock;
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $local_assoc_array);
$batches_to_exclude[] = $needed_item_batch_watcher->batch_number;
$extra_needed_quantity = $needed_quantity - $needed_item_batch_watcher->pharmacy_stock;
$result = needed_pharmacy_batches_recursive_helper($batches_to_exclude, $extra_needed_quantity, $item_id, $item_type);
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $result[0]);
} else{
$local_assoc_array[$needed_item_batch_watcher->batch_number] = $needed_quantity;
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $local_assoc_array);
}
}
return [$batch_quantity_assoc_array, $batches_to_exclude, $extra_needed_quantity];
}
function get_stores_batches_to_use_based_on_needed_quantity($item_id, $item_type, $needed_quantity){
$item_batch_watcher = null;
if (batch_tracking_method() == "FIFO") {
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type])->where('store_stock', '>', 0)->orderBy('id', 'asc')->first();
} elseif (batch_tracking_method() == "FEFO") {
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type])->where('store_stock', '>', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
}
$batch_quantity_assoc_array = [];
$batched_only_array = [];
if ($item_batch_watcher) {
//if the needed qty is more than what is available in this batch, get balance from next batch
if ($needed_quantity > $item_batch_watcher->store_stock) {
$batch_quantity_assoc_array[$item_batch_watcher->batch_number] = $item_batch_watcher->store_stock;
$batched_only_array[] = $item_batch_watcher->batch_number;
$extra_needed_quantity = $needed_quantity - $item_batch_watcher->store_stock;
//now get the other batches to use
$result = needed_stores_batches_recursive_helper($batched_only_array, $extra_needed_quantity, $item_id, $item_type);
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $result[0]);
} else{
$batch_quantity_assoc_array[$item_batch_watcher->batch_number] = $needed_quantity;
}
}
return $batch_quantity_assoc_array;
}
function needed_stores_batches_recursive_helper($batches_to_exclude, $needed_quantity, $item_id, $item_type)
{
$needed_item_batch_watcher = null;
if (batch_tracking_method() == "FIFO") {
$needed_item_batch_watcher = \Streamline\Models\ItemBatchWatcher::whereNotIn('batch_number', $batches_to_exclude)->where(['item_id' => $item_id, 'item_type' => $item_type])->where('store_stock', '>', 0)->orderBy('id', 'asc')->first();
} elseif (batch_tracking_method() == "FEFO") {
$needed_item_batch_watcher = \Streamline\Models\ItemBatchWatcher::whereNotIn('batch_number', $batches_to_exclude)->where(['item_id' => $item_id, 'item_type' => $item_type])->where('store_stock', '>', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
}
$extra_needed_quantity = null;
$batch_quantity_assoc_array = [];
if ($needed_item_batch_watcher) {
if ($needed_quantity > $needed_item_batch_watcher->store_stock) {
$local_assoc_array[$needed_item_batch_watcher->batch_number] = $needed_item_batch_watcher->store_stock;
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $local_assoc_array);
$batches_to_exclude[] = $needed_item_batch_watcher->batch_number;
$extra_needed_quantity = $needed_quantity - $needed_item_batch_watcher->store_stock;
$result = needed_stores_batches_recursive_helper($batches_to_exclude, $extra_needed_quantity, $item_id, $item_type);
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $result[0]);
} else{
$local_assoc_array[$needed_item_batch_watcher->batch_number] = $needed_quantity;
$batch_quantity_assoc_array = array_merge($batch_quantity_assoc_array, $local_assoc_array);
}
}
return [$batch_quantity_assoc_array, $batches_to_exclude, $extra_needed_quantity];
}
function reduce_batch_items_from_ward($item_type, $item_id, $consumed_quantity, $ward_id, $patient_id, $episode_id, $reduction_table, $reduction_table_id)
{
$item_batch_watcher = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type, 'ward_id' => $ward_id])->where('ward_stock', '>', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if ($item_batch_watcher) {
//if the needed qty is more than what is available in this batch, get balance from next batch
if ($consumed_quantity > $item_batch_watcher->ward_stock) {
$batch_ward_stock = $item_batch_watcher->ward_stock;
$extra_needed_quantity = $consumed_quantity - $item_batch_watcher->ward_stock;
record_batch_consumption($item_type, $item_id, $item_batch_watcher->batch_number, $item_batch_watcher->ward_stock, $reduction_table, $reduction_table_id, $patient_id);
$item_batch_watcher->ward_stock = 0;
$item_batch_watcher->update();
//now get the other batches to use
reduce_batch_items_from_ward($item_type, $item_id, $extra_needed_quantity, $ward_id, $patient_id, $episode_id, $reduction_table, $reduction_table_id);
} else{
$item_batch_watcher->ward_stock = $item_batch_watcher->ward_stock - $consumed_quantity;
$item_batch_watcher->update();
record_batch_consumption($item_type, $item_id, $item_batch_watcher->batch_number, $consumed_quantity, $reduction_table, $reduction_table_id, $patient_id);
}
}
}
function reconcile_batches($item_type, $item_id, $batch_number, $batch_quantity, $batch_expiry_date, $store_or_pharmacy)
{
$batch_record = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id, 'batch_number' => $batch_number])->first();
if ($batch_record) {
$item_batch_watcher = $batch_record;
} else{
$item_batch_watcher = new \Streamline\Models\ItemBatchWatcher;
$item_batch_watcher->item_id = $item_id;
$item_batch_watcher->item_type = $item_type;
$item_batch_watcher->batch_number = $batch_number;
}
$item_batch_watcher->batch_number = $batch_number;
if ($store_or_pharmacy == "store") {
$item_batch_watcher->store_stock = $batch_quantity;
}
if ($store_or_pharmacy == "pharmacy") {
$item_batch_watcher->pharmacy_stock = $batch_quantity;
}
$item_batch_watcher->expiry_date = $batch_expiry_date;
$item_batch_watcher->save();
}
function account_for_batch_reconciliations_difference($item_type, $item_id, $affected_account_id, $batch_number, $new_batch_balance, $reconciliation_date, $reconciliation_point)
{
//get batch details to get actual cost price and the difference
$batch_record = \Streamline\Models\ItemBatchWatcher::where(['item_type' => $item_type, 'item_id' => $item_id, 'batch_number' => $batch_number])->first();
if ($batch_record) {
$item_batch_watcher = $batch_record;
} else{
$item_batch_watcher = new \Streamline\Models\ItemBatchWatcher;
$item_batch_watcher->item_id = $item_id;
$item_batch_watcher->item_type = $item_type;
$item_batch_watcher->batch_number = $batch_number;
}
$cost_price = $item_batch_watcher->cost_price ?: 0;
if ($reconciliation_point == "store") {
$difference = $new_batch_balance - $item_batch_watcher->store_stock;
}
if ($reconciliation_point == "pharmacy") {
$difference = $new_batch_balance - $item_batch_watcher->pharmacy_stock;
}
//finance double entry
if ($item_type == 1) {
$item = \Streamline\Models\Drug::withTrashed()->find($item_id);
$item_name = $item ? $item->name : "N/A";
} elseif($item_type == 2){
$item = \Streamline\Models\Sundry::withTrashed()->find($item_id);
$item_name = $item ? $item->name : "N/A";
}
$track_receipt = new TrackReceipt;
$track_receipt->reason = "Stock reconciliation";
$track_receipt->created_by = Auth::id();
$track_receipt->save();
$receipt_number = sprintf("%04u", $track_receipt->id);
$account_slug = get_name($affected_account_id, "id", "slug", "chart_of_accounts");
$difference_amount = $difference * $cost_price;
if ($account_slug != "opening_inventory" && $difference != 0) {
$other_income = new \Streamline\Models\OtherIncome;
$other_income->income_account = $affected_account_id;
$other_income->deposit_amount = $difference_amount;
$other_income->banked_amount = $difference_amount;
$other_income->deposit_date = $reconciliation_date;
$other_income->deposit_memo = "Stock reconciliation for ".$item_name;
$other_income->trans_id = $receipt_number;
$other_income->received = 1;
$other_income->created_by = Auth::id();
$other_income->save();
}
}
function record_batch_consumption($item_type, $item_id, $batch_number, $quantity_reduced, $reduction_table, $reduction_table_id, $patient_id)
{
$batch_consumption = new \Streamline\Models\BatchConsumptionTracking;
$batch_consumption->item_type = $item_type;
$batch_consumption->item_id = $item_id;
$batch_consumption->batch_number = $batch_number;
$batch_consumption->quantity_reduced = $quantity_reduced;
$batch_consumption->reduction_table = $reduction_table;
$batch_consumption->reduction_table_id = $reduction_table_id;
$batch_consumption->patient_id = $patient_id;
$batch_consumption->created_by = auth()->user()->id;
$batch_consumption->save();
}
function reverse_dispensed_item_batches($item_type, $item_id, $quantity_to_reverse, $patient_id, $reduction_table, $reduction_table_id)
{
if ($patient_id) {
# look for this patient record in the batch tracking table
if($reduction_table_id){
$batch_tracking_records = \Streamline\Models\BatchConsumptionTracking::where(['patient_id' => $patient_id, 'item_id' => $item_id, 'item_type' => $item_type, 'reduction_table' => $reduction_table, 'reduction_table_id' => $reduction_table_id])->orderBy('created_at','desc')->get();
} else{
$batch_tracking_records = \Streamline\Models\BatchConsumptionTracking::where(['patient_id' => $patient_id, 'item_id' => $item_id, 'item_type' => $item_type, 'reduction_table' => $reduction_table])->orderBy('created_at','desc')->get();
}
if (count($batch_tracking_records) > 0) {
foreach ($batch_tracking_records as $batch_tracking_record) {
$exact_batch_watcher_record = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type, 'batch_number' => $batch_tracking_record->batch_number])->first();
if ($exact_batch_watcher_record) {
$exact_batch_watcher_record->pharmacy_stock = $exact_batch_watcher_record->pharmacy_stock + $batch_tracking_record->quantity_reduced;
$exact_batch_watcher_record->update();
}
$batch_tracking_record->delete();
}
}
} else{
/*
$nearest_batch_record_with_quantity = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type])->where('pharmacy_stock', '>', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first(); //the one that is expiring soonest
if ($nearest_batch_record_with_quantity) {
$nearest_batch_record_with_quantity->pharmacy_stock = $nearest_batch_record_with_quantity->pharmacy_stock + $quantity_returned;
$nearest_batch_record_with_quantity->update();
} else{
//if there is no batch record with quantity, get the latest record with 0 pharmacy stock
$batch_record = \Streamline\Models\ItemBatchWatcher::where(['item_id' => $item_id, 'item_type' => $item_type])->where('pharmacy_stock', 0)->orderBy(DB::raw('ABS(DATEDIFF(expiry_date, NOW()))'))->first();
if ($batch_record) {
$batch_record->pharmacy_stock = $batch_record->pharmacy_stock + $quantity_returned;
$batch_record->update();
}
}
*/
}
}
function record_store_stock_movement($item_type, $item_id, $batch_number, $quantity_to_move, $moved_to, $requisition_id){
$recording = new \Streamline\Models\BatchIssuedTracking;
$recording->batch_number = $batch_number;
$recording->quantity_moved = $quantity_to_move;
$recording->item_id = $item_id;
$recording->item_type = $item_type;
$recording->requisition_id = $requisition_id;
$recording->moved_to = $moved_to;
$recording->created_by = auth()->user()->id;
$recording->save();
}