devsofttech_hms_ci4/app/Controllers/Billing/Charges.php

1021 lines
42 KiB
PHP

<?php
namespace App\Controllers\Billing;
use App\Controllers\BaseController;
use App\Models\InvoiceModel;
class Charges extends BaseController
{
private function requirePermission(string $permission)
{
$user = auth()->user();
if (!$user || !$user->can($permission)) {
if ($this->request->isAJAX()) {
return $this->response->setStatusCode(403)->setJSON([
'update' => 0,
'error_text' => 'Permission denied',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
return $this->response->setStatusCode(403)->setBody('Forbidden');
}
return null;
}
public function add(int $pno, int $insId = 0, int $opdId = 0)
{
if ($resp = $this->requirePermission('billing.charges.edit')) {
return $resp;
}
$sql = "select *,if(gender=1,'Male','Female') as xgender from patient_master where id='" . (int) $pno . "'";
$query = $this->db->query($sql);
$data['person_info'] = $query->getResult();
if (!empty($data['person_info'])) {
$row = $data['person_info'][0];
$row->age = get_age_1($row->dob ?? null, $row->age ?? '', $row->age_in_month ?? '', $row->estimate_dob ?? '');
}
if ($opdId > 0) {
$sql = "select * from opd_master where p_id='" . (int) $pno . "' and opd_id=" . (int) $opdId . " order by opd_id desc limit 1";
} else {
$sql = "select * from opd_master where p_id='" . (int) $pno . "' order by opd_id desc limit 1";
}
$query = $this->db->query($sql);
$data['opd_master'] = $query->getResult();
$selectDoc = 0;
$opdCode = '';
if (count($data['opd_master']) > 0) {
$selectDoc = (int) $data['opd_master'][0]->doc_id;
$opdCode = $data['opd_master'][0]->opd_code;
}
$sql = "select l.doc_id from ipd_master p join ipd_master_doc_list l on p.id=l.ipd_id
where p.ipd_status=0 and p.p_id=" . (int) $pno;
$query = $this->db->query($sql);
$data['ipd_master_docid'] = $query->getResult();
if (count($data['ipd_master_docid']) > 0) {
$selectDoc = (int) $data['ipd_master_docid'][0]->doc_id;
}
$insCompId = 0;
if ($insId > 0) {
$sql = "select * from hc_item_type order by group_desc";
} else {
$sql = "select * from hc_item_type where itype_id<>33 order by group_desc";
}
$query = $this->db->query($sql);
$data['labitemtype'] = $query->getResult();
if ($insId > 0) {
$sql = "select * from hc_insurance_card where id=" . (int) $insId;
$query = $this->db->query($sql);
$data['hc_insurance_card'] = $query->getResult();
if (!empty($data['hc_insurance_card'])) {
$insCompId = (int) $data['hc_insurance_card'][0]->insurance_id;
}
$sql = "select * from hc_insurance where id=" . $insCompId;
$query = $this->db->query($sql);
$data['insurance'] = $query->getResult();
if (!empty($data['insurance'])) {
$pathCash = (int) $data['insurance'][0]->path_cash;
$pathCredit = (int) $data['insurance'][0]->path_credit;
}
}
$pathCash = $pathCash ?? 1;
$pathCredit = $pathCredit ?? 1;
$data['pdata'] = $insCompId;
$sql = "select * from doctor_master where active=1 order by p_fname";
$query = $this->db->query($sql);
$data['doclist'] = $query->getResult();
if ($insCompId < 2) {
$sql = "select id,Concat(idesc,' : {',amount,'}') as sdesc from hc_items where itype=1 order by idesc";
} else {
$sql = "select m.id,m.itype,m.idesc,m.amount,t.itype_id,t.is_ipd_opd,t.group_desc,
i.hc_insurance_id,if(i.hc_insurance_id is null,m.amount,i.amount1) as amount1,
Concat(m.idesc,'{',if(i.hc_insurance_id is null,m.amount,i.amount1),'}',if(i.id is null,'',concat('[',i.code,']'))) as sdesc
from (hc_items m join hc_item_type t on m.itype=t.itype_id)
left join (select * from hc_items_insurance where hc_insurance_id=" . $insCompId . " and isdelete=0) as i
on m.id=i.hc_items_id
where itype_id=1 order by m.idesc";
}
$query = $this->db->query($sql);
$data['labitem'] = $query->getResult();
$invoiceModel = new InvoiceModel();
if ($insId > 0) {
$sql = "select * from invoice_master where invoice_status=0 and insurance_card_id>0 and attach_id=" . (int) $pno;
} else {
$sql = "select * from invoice_master where invoice_status=0 and insurance_card_id=0 and attach_id=" . (int) $pno;
}
$query = $this->db->query($sql);
$data['chk_draft_invoice'] = $query->getResult();
if (count($data['chk_draft_invoice']) < 1) {
$data['insert_invoice'] = [
'attach_type' => '0',
'opd_code' => $opdCode,
'attach_id' => $pno,
'refer_by_id' => $selectDoc,
'inv_date' => date('Y-m-d H:i:s'),
'inv_name' => $data['person_info'][0]->p_fname ?? '',
'insurance_id' => $insCompId,
'insurance_card_id' => $insId,
'insurance_cash' => $pathCash,
'insurance_credit' => $pathCredit,
'inv_a_code' => $data['person_info'][0]->p_code ?? '',
];
$insertId = $invoiceModel->createInvoice($data['insert_invoice']);
} else {
$today = new \DateTime(date('Y-m-d'));
$invDate = new \DateTime($data['chk_draft_invoice'][0]->inv_date);
if ($invDate < $today) {
$data['insert_invoice'] = [
'attach_type' => '0',
'attach_id' => $pno,
'opd_code' => $opdCode,
'refer_by_id' => $selectDoc,
'inv_date' => date('Y-m-d H:i:s'),
'inv_name' => $data['person_info'][0]->p_fname ?? '',
'insurance_id' => $insCompId,
'insurance_card_id' => $insId,
'insurance_cash' => $pathCash,
'insurance_credit' => $pathCredit,
'inv_a_code' => $data['person_info'][0]->p_code ?? '',
];
$insertId = $invoiceModel->createInvoice($data['insert_invoice']);
} else {
$insertId = (int) $data['chk_draft_invoice'][0]->id;
}
}
if ($insertId) {
$sql = "select * from invoice_master where id=" . $insertId;
$query = $this->db->query($sql);
$data['invoiceMaster'] = $query->getResult();
$sql = "select i.*,t.group_desc from invoice_item i join hc_item_type t on i.item_type=t.itype_id where i.inv_master_id=" . $insertId;
$query = $this->db->query($sql);
$data['invoiceDetails'] = $query->getResult();
$sql = "select sum(item_amount) as Gtotal from invoice_item where inv_master_id=" . $insertId;
$query = $this->db->query($sql);
$data['invoiceGtotal'] = $query->getResult();
}
$sql = "select *,if(ipd_status=0,DATEDIFF(sysdate(),register_date),DATEDIFF(discharge_date,register_date)) as no_days
from ipd_master where ipd_status=0 and p_id=" . (int) ($data['invoiceMaster'][0]->attach_id ?? 0);
$query = $this->db->query($sql);
$data['ipd_master'] = $query->getResult();
$data['show_ipd_credit'] = false;
if (!empty($data['ipd_master']) && !empty($data['invoiceMaster'])) {
$insuranceCaseId = (int) ($data['invoiceMaster'][0]->insurance_case_id ?? 0);
$invoiceIpdId = (int) ($data['invoiceMaster'][0]->ipd_id ?? 0);
$data['show_ipd_credit'] = ($insuranceCaseId === 0 && $invoiceIpdId === 0);
}
return view('billing/charges/charges_invoice_edit', $data);
}
public function edit(int $invoiceId)
{
if ($resp = $this->requirePermission('billing.charges.edit')) {
return $resp;
}
$invoiceMasterRow = $this->db->table('invoice_master')->where('id', $invoiceId)->get()->getRow();
if (empty($invoiceMasterRow)) {
return $this->response->setStatusCode(404)->setBody('Invoice not found');
}
$pno = (int) ($invoiceMasterRow->attach_id ?? 0);
$insId = (int) ($invoiceMasterRow->insurance_card_id ?? 0);
$insCompId = (int) ($invoiceMasterRow->insurance_id ?? 0);
$sql = "select *,if(gender=1,'Male','Female') as xgender from patient_master where id='" . (int) $pno . "'";
$query = $this->db->query($sql);
$data['person_info'] = $query->getResult();
if (!empty($data['person_info'])) {
$row = $data['person_info'][0];
$row->age = get_age_1($row->dob ?? null, $row->age ?? '', $row->age_in_month ?? '', $row->estimate_dob ?? '');
}
if ($insId > 0) {
$sql = "select * from hc_item_type order by group_desc";
} else {
$sql = "select * from hc_item_type where itype_id<>33 order by group_desc";
}
$query = $this->db->query($sql);
$data['labitemtype'] = $query->getResult();
$sql = "select * from doctor_master where active=1 order by p_fname";
$query = $this->db->query($sql);
$data['doclist'] = $query->getResult();
if ($insCompId < 2) {
$sql = "select id,Concat(idesc,' : {',amount,'}') as sdesc from hc_items where itype=1 order by idesc";
} else {
$sql = "select m.id,m.itype,m.idesc,m.amount,t.itype_id,t.is_ipd_opd,t.group_desc,
i.hc_insurance_id,if(i.hc_insurance_id is null,m.amount,i.amount1) as amount1,
Concat(m.idesc,'{',if(i.hc_insurance_id is null,m.amount,i.amount1),'}',if(i.id is null,'',concat('[',i.code,']'))) as sdesc
from (hc_items m join hc_item_type t on m.itype=t.itype_id)
left join (select * from hc_items_insurance where hc_insurance_id=" . $insCompId . " and isdelete=0) as i
on m.id=i.hc_items_id
where itype_id=1 order by m.idesc";
}
$query = $this->db->query($sql);
$data['labitem'] = $query->getResult();
$data['pdata'] = $insCompId;
$sql = "select * from invoice_master where id=" . (int) $invoiceId;
$query = $this->db->query($sql);
$data['invoiceMaster'] = $query->getResult();
$sql = "select i.*,t.group_desc from invoice_item i join hc_item_type t on i.item_type=t.itype_id where i.inv_master_id=" . (int) $invoiceId;
$query = $this->db->query($sql);
$data['invoiceDetails'] = $query->getResult();
$sql = "select sum(item_amount) as Gtotal from invoice_item where inv_master_id=" . (int) $invoiceId;
$query = $this->db->query($sql);
$data['invoiceGtotal'] = $query->getResult();
$sql = "select *,if(ipd_status=0,DATEDIFF(sysdate(),register_date),DATEDIFF(discharge_date,register_date)) as no_days
from ipd_master where ipd_status=0 and p_id=" . (int) ($data['invoiceMaster'][0]->attach_id ?? 0);
$query = $this->db->query($sql);
$data['ipd_master'] = $query->getResult();
return view('billing/charges/charges_invoice_edit', $data);
}
public function listByType()
{
if ($resp = $this->requirePermission('billing.charges.edit')) {
return $resp;
}
$tid = (int) $this->request->getPost('itype_idv');
$insId = (int) $this->request->getPost('ins_id');
if ($insId > 1) {
$sql = "select m.id,m.itype,m.idesc,m.amount,t.itype_id,t.is_ipd_opd,t.group_desc,
i.hc_insurance_id ,if(i.hc_insurance_id is null,m.amount,i.amount1) as amount1,
Concat(m.idesc,'{',if(i.hc_insurance_id is null,m.amount,i.amount1),'}',if(i.id is null,'',concat('[',i.code,']'))) as sdesc
from (hc_items m join hc_item_type t on m.itype=t.itype_id)
left join (select * from hc_items_insurance where hc_insurance_id=" . $insId . " and isdelete=0) as i
on m.id=i.hc_items_id
where itype_id=" . $tid . " order by m.idesc";
} else {
$sql = "select id,Concat(idesc,' : [',amount,']') as sdesc from hc_items where itype=" . $tid . " order by idesc";
}
$query = $this->db->query($sql);
$labitem = $query->getResult();
echo '<div class="form-group">';
echo '<label>Charge Name</label>';
echo '<select class="form-control input-sm select2" id="itype_name_id" name="itype_name_id">';
foreach ($labitem as $row) {
echo '<option value=' . $row->id . '>' . $row->sdesc . '</option>';
}
echo '</select></div>';
}
public function updateReferDoc()
{
if ($resp = $this->requirePermission('billing.charges.edit')) {
return $resp;
}
$invoiceId = (int) $this->request->getPost('inv_id');
$docId = (int) $this->request->getPost('doc_id');
$rawDate = (string) $this->request->getPost('inv_date');
$invDate = str_to_MysqlDate($rawDate);
if (strpos($rawDate, '-') !== false && strlen($rawDate) === 10) {
$invDate = $rawDate;
}
$user = auth()->user();
$canEditDate = is_object($user) && method_exists($user, 'can') ? $user->can('billing.charges.date-edit') : false;
if (!$canEditDate) {
$existing = $this->db->table('invoice_master')->select('inv_date')->where('id', $invoiceId)->get()->getRowArray();
if (!empty($existing['inv_date'])) {
$invDate = $existing['inv_date'];
}
}
if ($docId < 1) {
$referName = (string) $this->request->getPost('refername');
} else {
$sql = "select * from doctor_master where id=" . $docId;
$query = $this->db->query($sql);
$docMaster = $query->getResult();
$referName = $docMaster[0]->p_fname ?? '';
}
$dataUpdate = [
'refer_by_id' => $docId,
'inv_date' => $invDate,
'refer_by_other' => $referName,
'invoice_status' => '1',
];
$invoiceModel = new InvoiceModel();
$invoiceModel->updateInvoice($dataUpdate, $invoiceId);
}
public function item(int $type)
{
if ($resp = $this->requirePermission('billing.charges.edit')) {
return $resp;
}
$invoiceModel = new InvoiceModel();
if ($type === 1) {
$insId = (int) $this->request->getPost('ins_id');
$itemId = (int) $this->request->getPost('itype_name_id');
if ($insId > 1) {
$sql = "select m.id,m.itype,m.idesc as sdesc,m.amount,t.itype_id,t.is_ipd_opd,t.group_desc,i.isdelete,
if(i.hc_insurance_id is null,0,i.hc_insurance_id) as hc_insurance_id,
if(i.hc_insurance_id is null,m.amount,i.amount1) as amount1,
if(i.hc_insurance_id is null,'',i.code) as org_code
from (hc_items m left join hc_items_insurance i on m.id=i.hc_items_id and i.isdelete=0 and i.hc_insurance_id=" . $insId . ")
join hc_item_type t on m.itype=t.itype_id where m.id=" . $itemId;
$query = $this->db->query($sql);
$itemlist = $query->getResult();
$itemRate = $itemlist[0]->amount1 ?? 0;
$orgCode = $itemlist[0]->org_code ?? '';
$customRate = (float) $this->request->getPost('input_rate');
if ($customRate > 0) {
$itemRate = $customRate;
}
$amountValue = (float) $this->request->getPost('input_qty') * $itemRate;
} else {
$sql = "select id,idesc as sdesc,amount from hc_items where id=" . $itemId;
$query = $this->db->query($sql);
$itemlist = $query->getResult();
$itemRate = $itemlist[0]->amount ?? 0;
$orgCode = '';
$customRate = (float) $this->request->getPost('input_rate');
if ($customRate > 0) {
$itemRate = $customRate;
}
$amountValue = (float) $this->request->getPost('input_qty') * $itemRate;
}
$insertInvoiceItem = [
'inv_master_id' => (int) $this->request->getPost('lab_invoice_id'),
'item_type' => (int) $this->request->getPost('itype_idv'),
'item_id' => $itemId,
'item_name' => $itemlist[0]->sdesc ?? '',
'item_rate' => $itemRate,
'item_added_date' => str_to_MysqlDate(date('d/m/Y')),
'item_qty' => (float) $this->request->getPost('input_qty'),
'item_amount' => $amountValue,
'ins_id' => $insId,
'org_code' => $orgCode,
];
$sql = "select * from invoice_item where inv_master_id=" . (int) $this->request->getPost('lab_invoice_id') . " and item_id=" . $itemId;
$query = $this->db->query($sql);
$itemCheck = $query->getResult();
if (count($itemCheck) < 1) {
$invoiceModel->addInvoiceItem($insertInvoiceItem);
}
} elseif ($type === 2) {
$amountValue = (float) $this->request->getPost('update_qty') * (float) $this->request->getPost('item_rate');
$updateInvoiceItem = [
'item_added_date' => str_to_MysqlDate(date('d/m/Y')),
'item_qty' => (float) $this->request->getPost('update_qty'),
'item_amount' => $amountValue,
];
$invoiceModel->updateItem($updateInvoiceItem, (int) $this->request->getPost('itemid'));
} else {
$invoiceModel->deleteInvoiceItem((int) $this->request->getPost('itemid'));
}
$invoiceId = (int) $this->request->getPost('lab_invoice_id');
$sql = "select i.*,t.group_desc from invoice_item i join hc_item_type t on i.item_type=t.itype_id where i.inv_master_id=" . $invoiceId . " Order by i.id";
$query = $this->db->query($sql);
$invoiceDetails = $query->getResult();
$sql = "select * from invoice_master where id=" . $invoiceId;
$query = $this->db->query($sql);
$invoiceMaster = $query->getResult();
$sql = "select sum(item_amount) as Gtotal from invoice_item where inv_master_id=" . $invoiceId;
$query = $this->db->query($sql);
$invoiceGtotal = $query->getResult();
$totalAmount = (float) ($invoiceGtotal[0]->Gtotal ?? 0);
$discountAmount = (float) ($invoiceMaster[0]->discount_amount ?? 0);
$netAmount = $totalAmount - $discountAmount;
$invoiceModel->updateInvoice([
'total_amount' => $totalAmount,
'net_amount' => $netAmount,
], $invoiceId);
echo '<table class="table table-striped ">
<tr>
<th style="width: 10px">#</th>
<th>Charge Type</th>
<th>Charge Name</th>
<th>Rate</th>
<th>Qty</th>
<th>Updated Qty</th>
<th>Amount</th>
<th></th>
</tr>';
$srno = 0;
foreach ($invoiceDetails as $row) {
$srno++;
echo '<tr>';
echo '<td>' . $srno . '</td>';
echo '<td>' . $row->group_desc . '</td>';
echo '<td>' . $row->item_name . '</td>';
if (in_array((int) $row->item_type, [1, 2, 3, 4, 5], true)) {
echo '<td>' . $row->item_rate . '</td>';
echo '<td>' . $row->item_qty . '</td>';
echo '<td>' . $row->item_amount . '</td>';
echo '<td>';
} else {
echo '<td><input type=hidden name="hidden_rate_' . $row->id . '" id="hidden_rate_' . $row->id . '" value="' . $row->item_rate . '" >' . $row->item_rate . '</td>';
echo '<td><input class="form-control" style="width:100px" name="input_qty_' . $row->id . '" id="input_qty_' . $row->id . '" value="' . $row->item_qty . '" type="number" /></td>';
echo '<td>' . $row->item_amount . '</td>';
echo '<td>';
echo '<button type="button" class="btn btn-primary" id="btn_update" onclick="update_qty(' . $row->id . ')">Update</button>';
}
$sql = "select * from lab_request where charge_item_id=" . $row->id;
$query = $this->db->query($sql);
$labRequest = $query->getResult();
if (count($labRequest) < 1) {
echo '<td><button type="button" class="btn btn-danger" id="btn_add_fee" onclick="remove_item_invoice(' . $row->id . ')">-Remove</button>';
}
echo '</tr>';
}
echo '<input type="hidden" id="srno" name="srno" value="' . count($invoiceDetails) . '" />';
echo '<tr>
<th style="width: 10px">#</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th>Gross Total</th>
<th>' . ($invoiceGtotal[0]->Gtotal ?? 0) . '</th>
<th></th>
</tr>
</table>';
}
public function show(int $invoiceId)
{
if ($resp = $this->requirePermission('billing.charges.view')) {
return $resp;
}
$invoiceModel = new InvoiceModel();
$invoiceModel->updateInvoiceFinal($invoiceId);
$sql = "select i.*,t.group_desc from invoice_item i join hc_item_type t on i.item_type=t.itype_id
where i.inv_master_id=" . (int) $invoiceId;
$query = $this->db->query($sql);
$data['invoiceDetails'] = $query->getResult();
$sql = "select *,
(case payment_mode when 1 then 'Cash' when 2 then 'Bank Card/Online' when 3 then 'IPD Credit' when 4 then 'Org. Credit' else 'Pending' end) as Payment_type_str
from invoice_master where id=" . (int) $invoiceId;
$query = $this->db->query($sql);
$data['invoice_master'] = $query->getResult();
$insCompId = (int) ($data['invoice_master'][0]->insurance_id ?? 0);
$insId = (int) ($data['invoice_master'][0]->insurance_card_id ?? 0);
$sql = "select * from hc_insurance_card where id=" . $insId;
$query = $this->db->query($sql);
$data['hc_insurance_card'] = $query->getResult();
$sql = "select * from hc_insurance where id=" . $insCompId;
$query = $this->db->query($sql);
$data['insurance'] = $query->getResult();
$sql = "select p.*,f.full_path as profile_picture
from patient_master p
left join file_upload_data f on p.profile_file_id=f.id
where p.id=" . (int) ($data['invoice_master'][0]->attach_id ?? 0);
$query = $this->db->query($sql);
$data['patient_master'] = $query->getResult();
if (!empty($data['patient_master'])) {
$row = $data['patient_master'][0];
$row->age = get_age_1($row->dob ?? null, $row->age ?? '', $row->age_in_month ?? '', $row->estimate_dob ?? '');
$row->xgender = ($row->gender ?? 0) == 1 ? 'Male' : 'Female';
}
$sql = "select * from ipd_master where ipd_status=0 and p_id=" . (int) ($data['invoice_master'][0]->attach_id ?? 0);
if (($data['invoice_master'][0]->ipd_id ?? 0) > 0) {
$sql = "select * from ipd_master where id=" . (int) $data['invoice_master'][0]->ipd_id;
}
$query = $this->db->query($sql);
$data['ipd_master'] = $query->getResult();
$data['show_ipd_credit'] = false;
if (! empty($data['ipd_master'])) {
$insuranceCaseId = (int) ($data['invoice_master'][0]->insurance_case_id ?? 0);
$invoiceIpdId = (int) ($data['invoice_master'][0]->ipd_id ?? 0);
$data['show_ipd_credit'] = ($insuranceCaseId === 0 && $invoiceIpdId === 0);
}
$sql = "select * from invoice_item i join hc_item_type t on i.item_type=t.itype_id
where t.is_ipd_opd=2 and i.inv_master_id=" . (int) $invoiceId;
$query = $this->db->query($sql);
$ipdCredit = $query->getResult();
$data['IPD_Credit'] = count($ipdCredit) > 0 ? '1' : '0';
$sql = "select * from organization_case_master where case_type=0 and status=0 and p_id=" . (int) ($data['invoice_master'][0]->attach_id ?? 0);
if (($data['invoice_master'][0]->insurance_case_id ?? 0) > 0) {
$sql = "select * from organization_case_master where case_type=0 and id=" . (int) $data['invoice_master'][0]->insurance_case_id;
} elseif (count($data['ipd_master']) > 0) {
if (($data['ipd_master'][0]->case_id ?? 0) > 0) {
$sql = "select * from organization_case_master where case_type=0 and id=" . (int) $data['ipd_master'][0]->case_id;
}
}
$query = $this->db->query($sql);
$data['case_master'] = $query->getResult();
$sql = "select s.id,s.pay_type,m.bank_name from hospital_bank m join hospital_bank_payment_source s on m.id=s.bank_id";
$query = $this->db->query($sql);
$data['bank_data'] = $query->getResult();
$sql = "select sum(if(credit_debit=0,amount,amount*-1)) as paid_amount
from payment_history where payof_type=2 and payof_id=" . (int) $invoiceId;
$query = $this->db->query($sql);
$data['payment_history'] = $query->getResult();
$paidAmount = 0;
if (!empty($data['payment_history']) && $data['payment_history'][0]->paid_amount) {
$paidAmount = (float) $data['payment_history'][0]->paid_amount;
}
$data['paid_amount'] = $paidAmount;
$netAmount = (float) ($data['invoice_master'][0]->net_amount ?? 0);
$paymentMode = (int) ($data['invoice_master'][0]->payment_mode ?? 0);
$data['pending_amount'] = ($paymentMode === 3 || $paymentMode === 4) ? 0 : ($netAmount - $paidAmount);
return view('billing/charges/charges_invoice_show', $data);
}
public function confirm_payment()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'update' => 0,
'error_text' => 'Invalid request',
]);
}
if ($resp = $this->requirePermission('billing.charges.pay')) {
return $resp;
}
$mode = (int) $this->request->getPost('mode');
$invId = (int) $this->request->getPost('inv_id');
$spid = (string) $this->request->getPost('spid');
$receivedAmountInput = (float) $this->request->getPost('received_amount');
if ($invId <= 0) {
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Invalid invoice ID',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
$invoice = $this->db->table('invoice_master')->where('id', $invId)->get()->getRowArray();
if (empty($invoice)) {
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Invoice not found',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
$sql = "select coalesce(sum(if(credit_debit=0,amount,amount*-1)),0) as paid_amount
from payment_history where payof_type=2 and payof_id=" . (int) $invId;
$query = $this->db->query($sql);
$paidRow = $query->getResult();
$paidAmount = (float) ($paidRow[0]->paid_amount ?? 0);
$netAmount = (float) ($invoice['net_amount'] ?? 0);
$pendingAmt = $netAmount - $paidAmount;
$payRemark = '';
if (!empty($invoice['discount_amount']) && (float) $invoice['discount_amount'] > 0) {
$payRemark = 'Dis.Amt.:' . ($invoice['discount_desc'] ?? '') . ' /Amount: ' . $invoice['discount_amount'];
}
$user = auth()->user();
$userLabel = $user ? ($user->username ?? $user->email ?? 'User') : 'User';
$userId = $user->id ?? 0;
$userNameInfo = $userLabel . '[' . date('d-m-Y H:i:s') . ']';
$paymentModel = new \App\Models\PaymentModel();
$invoiceModel = new InvoiceModel();
if ($mode === 0) {
if ($pendingAmt > 0) {
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Zero amount allowed only when pending is zero.',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
$paydata = [
'payment_mode' => '0',
'payof_type' => '2',
'payof_id' => $invId,
'payof_code' => $invoice['invoice_code'] ?? '',
'credit_debit' => '0',
'amount' => $netAmount,
'payment_date' => date('Y-m-d H:i:s'),
'remark' => $payRemark,
'update_by' => $userNameInfo . ' [' . $userId . ']',
'update_by_id' => $userId,
'insert_code' => $spid,
];
$paymentModel->insertPayment($paydata);
$this->db->table('invoice_master')->where('id', $invId)->update([
'payment_mode' => '0',
'payment_status' => '1',
]);
$invoiceModel->updateInvoiceFinal($invId);
return $this->response->setJSON([
'update' => 1,
'showcontent' => 'Zero Amount',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
if ($mode === 1 && $pendingAmt > 0) {
$receivedAmount = $receivedAmountInput > 0 ? $receivedAmountInput : $pendingAmt;
if ($receivedAmount <= 0 || $receivedAmount > $pendingAmt) {
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Received amount must be between 0 and pending amount.',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
$paydata = [
'payment_mode' => '1',
'payof_type' => '2',
'payof_id' => $invId,
'payof_code' => $invoice['invoice_code'] ?? '',
'credit_debit' => '0',
'amount' => $receivedAmount,
'payment_date' => date('Y-m-d H:i:s'),
'remark' => $payRemark,
'update_by' => $userNameInfo . ' [' . $userId . ']',
'update_by_id' => $userId,
'insert_code' => $spid,
];
$paymentModel->insertPayment($paydata);
$newPending = $pendingAmt - $receivedAmount;
$this->db->table('invoice_master')->where('id', $invId)->update([
'payment_mode' => '1',
'payment_status' => $newPending <= 0 ? '1' : '0',
]);
$invoiceModel->updateInvoiceFinal($invId);
return $this->response->setJSON([
'update' => 1,
'showcontent' => 'Cash',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
if ($mode === 2 && $pendingAmt > 0) {
$cardTran = trim((string) $this->request->getPost('input_card_tran'));
if ($cardTran === '' || strlen($cardTran) < 3 || strlen($cardTran) > 20) {
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Card Transaction ID is required (3-20 chars).',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
$receivedAmount = $receivedAmountInput > 0 ? $receivedAmountInput : $pendingAmt;
if ($receivedAmount <= 0 || $receivedAmount > $pendingAmt) {
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Received amount must be between 0 and pending amount.',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
$paydata = [
'payment_mode' => '2',
'payof_type' => '2',
'payof_id' => $invId,
'payof_code' => $invoice['invoice_code'] ?? '',
'credit_debit' => '0',
'amount' => $receivedAmount,
'payment_date' => date('Y-m-d H:i:s'),
'remark' => $payRemark,
'update_by' => $userNameInfo . ' [' . $userId . ']',
'pay_bank_id' => (int) $this->request->getPost('cbo_pay_type'),
'card_tran_id' => $cardTran,
'update_by_id' => $userId,
];
$paymentModel->insertPayment($paydata);
$newPending = $pendingAmt - $receivedAmount;
$this->db->table('invoice_master')->where('id', $invId)->update([
'payment_mode' => '2',
'payment_status' => $newPending <= 0 ? '1' : '0',
]);
$invoiceModel->updateInvoiceFinal($invId);
return $this->response->setJSON([
'update' => 1,
'showcontent' => 'Bank/Online',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
if ($mode === 3) {
$ipdId = (int) $this->request->getPost('ipd_id');
if ($ipdId <= 0) {
$ipdRow = $this->db->table('ipd_master')
->select('id')
->where('ipd_status', 0)
->where('p_id', (int) ($invoice['attach_id'] ?? 0))
->orderBy('id', 'DESC')
->get()
->getRowArray();
$ipdId = (int) ($ipdRow['id'] ?? 0);
}
if ($ipdId <= 0) {
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Active IPD admission not found.',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
$this->db->table('invoice_master')->where('id', $invId)->update([
'payment_mode' => '3',
'payment_status' => '1',
'ipd_id' => $ipdId,
'ipd_include' => $ipdId > 0 ? 1 : 0,
]);
$invoiceModel->updateInvoiceFinal($invId);
return $this->response->setJSON([
'update' => 1,
'showcontent' => 'IPD Credit',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
if ($mode === 4) {
$this->db->table('invoice_master')->where('id', $invId)->update([
'payment_mode' => '4',
'payment_status' => '1',
'insurance_case_id' => (int) $this->request->getPost('case_id'),
]);
$invoiceModel->updateInvoiceFinal($invId);
return $this->response->setJSON([
'update' => 1,
'showcontent' => 'Org. Case Credit',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
return $this->response->setJSON([
'update' => 0,
'error_text' => 'Invalid payment request',
'csrfName' => csrf_token(),
'csrfHash' => csrf_hash(),
]);
}
public function delete()
{
if ($resp = $this->requirePermission('billing.charges.edit')) {
return $resp;
}
$invId = (int) $this->request->getPost('inv_id');
if ($invId <= 0) {
return $this->response->setStatusCode(400)->setJSON(['update' => 0, 'error_text' => 'Invalid invoice ID']);
}
$this->db->table('invoice_master')->where('id', $invId)->delete();
$this->db->table('invoice_item')->where('inv_master_id', $invId)->delete();
return $this->response->setJSON(['update' => 1]);
}
public function updateDiscount()
{
if ($resp = $this->requirePermission('billing.charges.edit')) {
return $resp;
}
$invId = (int) $this->request->getPost('inv_id');
$discountDesc = (string) $this->request->getPost('discount_desc');
$discountAmount = (float) $this->request->getPost('discount_amount');
if ($invId <= 0) {
return $this->response->setStatusCode(400)->setJSON(['update' => 0, 'error_text' => 'Invalid invoice ID']);
}
$row = $this->db->table('invoice_master')->where('id', $invId)->get()->getRowArray();
if (empty($row)) {
return $this->response->setStatusCode(404)->setJSON(['update' => 0, 'error_text' => 'Invoice not found']);
}
$totalAmount = (float) ($row['total_amount'] ?? 0);
$netAmount = $totalAmount - $discountAmount;
$updated = (bool) $this->db->table('invoice_master')
->where('id', $invId)
->update([
'discount_desc' => $discountDesc,
'discount_amount' => $discountAmount,
'net_amount' => $netAmount,
]);
return $this->response->setJSON([
'update' => $updated ? 1 : 0,
'net_amount' => $netAmount,
]);
}
public function cancel_invoice(int $invId)
{
if ($resp = $this->requirePermission('billing.charges.cancel')) {
return $resp;
}
$invoice = $this->db->table('invoice_master')->where('id', $invId)->get()->getRowArray();
if (empty($invoice)) {
return $this->response->setJSON(['update' => 0, 'error_text' => 'Invoice not found']);
}
$sql = "select sum(if(credit_debit>0,amount*-1,amount)) as paid_amount
from payment_history where payof_type=2 and payof_id=" . (int) $invId;
$query = $this->db->query($sql);
$paymentHistory = $query->getResult();
$paidAmount = (float) ($paymentHistory[0]->paid_amount ?? 0);
if ($paidAmount > 0 && ($invoice['invoice_status'] ?? 0) == 1 && $this->db->tableExists('refund_order')) {
$user = auth()->user();
$userId = $user->id ?? 0;
$userName = ($user->username ?? $user->email ?? 'User') . '[' . $userId . ']:T-' . date('d-m-Y H:i:s');
$refundRequest = [
'refund_type' => 2,
'refund_type_id' => $invId,
'refund_type_code' => $invoice['invoice_code'] ?? '',
'refund_type_reason' => 'Cancel Invoice',
'approved_by_id' => $userId,
'approved_by' => $userName,
'refund_amount' => $paidAmount,
'patient_id' => $invoice['attach_id'] ?? 0,
'patient_name' => strtoupper((string) ($invoice['inv_name'] ?? '')),
];
$this->db->table('refund_order')->insert($refundRequest);
}
$this->db->table('invoice_master')->where('id', $invId)->update([
'payment_id' => 0,
'invoice_status' => 2,
]);
return $this->response->setJSON(['update' => 1]);
}
public function update_correction_charges()
{
if ($resp = $this->requirePermission('billing.charges.correct')) {
return $resp;
}
$invoiceId = (int) $this->request->getPost('invoice_id');
$corrDesc = (string) $this->request->getPost('input_corr_desc');
$corrAmount = (float) $this->request->getPost('input_corr_amt');
$corrCrdr = (int) $this->request->getPost('optionsRadios_crdr');
$invoice = $this->db->table('invoice_master')->where('id', $invoiceId)->get()->getRowArray();
if (empty($invoice)) {
return $this->response->setJSON(['update' => 0, 'error_text' => 'Invoice not found']);
}
if ($corrAmount <= 0) {
return $this->response->setJSON(['update' => 0, 'error_text' => 'Correction amount must be greater than 0']);
}
$netAmount = (float) ($invoice['net_amount'] ?? 0);
if ($corrCrdr === 1 && $netAmount < $corrAmount) {
return $this->response->setJSON(['update' => 0, 'error_text' => 'Correction amount cannot exceed net amount']);
}
$correctionNetAmount = $corrCrdr === 1 ? ($netAmount - $corrAmount) : ($netAmount + $corrAmount);
$user = auth()->user();
$userName = $user ? ($user->username ?? $user->email ?? 'User') : 'User';
$update = [];
if ($this->db->fieldExists('correction_amount', 'invoice_master')) {
$update['correction_amount'] = $corrAmount;
}
if ($this->db->fieldExists('correction_remark', 'invoice_master')) {
$update['correction_remark'] = $corrDesc;
}
if ($this->db->fieldExists('correction_user', 'invoice_master')) {
$update['correction_user'] = $userName;
}
if ($this->db->fieldExists('correction_crdr', 'invoice_master')) {
$update['correction_crdr'] = $corrCrdr;
}
if ($this->db->fieldExists('correction_datetime', 'invoice_master')) {
$update['correction_datetime'] = date('Y-m-d H:i:s');
}
if ($this->db->fieldExists('correction_net_amount', 'invoice_master')) {
$update['correction_net_amount'] = $correctionNetAmount;
}
$update['invoice_status'] = 3;
$this->db->table('invoice_master')->where('id', $invoiceId)->update($update);
$paydata = [
'payment_mode' => '3',
'payof_type' => '2',
'payof_id' => $invoiceId,
'payof_code' => $invoice['invoice_code'] ?? '',
'credit_debit' => $corrCrdr === 1 ? 1 : 0,
'amount' => $corrAmount,
'payment_date' => date('Y-m-d H:i:s'),
'remark' => $corrDesc,
'update_by' => $userName . '[' . ($user->id ?? 0) . ']',
'update_by_id' => $user->id ?? 0,
];
$paymentModel = new \App\Models\PaymentModel();
$paymentModel->insertPayment($paydata);
return $this->response->setJSON(['update' => 1]);
}
}