devsofttech_hms_ci4/app/Models/OpdModel.php

170 lines
5.0 KiB
PHP

<?php
namespace App\Models;
use CodeIgniter\Database\BaseConnection;
class OpdModel
{
private BaseConnection $db;
public function __construct()
{
$this->db = db_connect();
}
public function insertOpd(array $data): int
{
$pId = (int) ($data['p_id'] ?? 0);
$docId = (int) ($data['doc_id'] ?? 0);
$todayStart = date('Y-m-d') . ' 00:00:00';
$tomorrowStart = date('Y-m-d', strtotime('+1 day')) . ' 00:00:00';
if ($pId <= 0 || $docId <= 0) {
return 0;
}
$duplicate = $this->db->table('opd_master')
->where('apointment_date >=', $todayStart)
->where('apointment_date <', $tomorrowStart)
->where('p_id', $pId)
->where('doc_id', $docId)
->groupStart()
->where('payment_status', 0)
->orWhere('opd_status', 1)
->groupEnd()
->countAllResults();
if ($duplicate > 0) {
return 0;
}
$this->db->table('opd_master')->insert($data);
$insertId = (int) $this->db->insertID();
if ($insertId <= 0) {
return 0;
}
$opdNoRow = $this->db->table('opd_master')
->select('count(*) as no_max')
->where('apointment_date >=', $todayStart)
->where('apointment_date <', $tomorrowStart)
->where('doc_id', $docId)
->get()
->getRow();
$opdNo = (int) ($opdNoRow->no_max ?? 1);
if ($opdNo <= 0) {
$opdNo = 1;
}
$pidSuffix = str_pad(substr((string) $insertId, -7, 7), 7, '0', STR_PAD_LEFT);
$opdCode = 'D' . date('ym') . $pidSuffix;
$runningOpd = 0;
$lastOpdId = 0;
$isZeroValueRunning = ((int) ($data['opd_fee_type'] ?? 0) === 3)
|| ((float) ($data['opd_fee_amount'] ?? 0) <= 0);
if ((int) ($data['opd_fee_type'] ?? 0) === 3) {
$runningOpd = 1;
$lastOpdRow = $this->db->table('opd_master')
->select('max(opd_id) as last_opd_id')
->where('apointment_date >=', $this->resolveRunningLookupDate($docId) . ' 00:00:00')
->where('apointment_date <', $tomorrowStart)
->where('running_opd', 0)
->where('opd_fee_type <>', 3)
->where('coalesce(opd_fee_amount,0) >', 0, false)
->where('doc_id', $docId)
->where('p_id', $pId)
->get()
->getRow();
$lastOpdId = (int) ($lastOpdRow->last_opd_id ?? 0);
}
$opdTimesBuilder = $this->db->table('opd_master')
->select('count(*) as xtimes')
->where('opd_id <=', $insertId)
->where('p_id', $pId);
if ($isZeroValueRunning && $lastOpdId > 0) {
// For zero-value running OPD, keep visit count within the same paid OPD validity cycle.
$opdTimesBuilder
->where('opd_id >=', $lastOpdId)
->where('doc_id', $docId);
}
$opdTimesRow = $opdTimesBuilder->get()->getRow();
$opdTimes = (int) ($opdTimesRow->xtimes ?? 0);
$update = [
'opd_code' => $opdCode,
'no_visit' => $opdTimes,
'running_opd' => $runningOpd,
'running_opd_id' => $lastOpdId,
'opd_no' => $opdNo,
];
$this->db->table('opd_master')
->where('opd_id', $insertId)
->update($update);
return $insertId;
}
private function resolveRunningLookupDate(int $docId): string
{
$docRow = $this->db->table('doctor_master')
->select('opd_valid_no_days')
->where('id', $docId)
->get()
->getRow();
$validDays = (int) ($docRow->opd_valid_no_days ?? 0);
if ($validDays <= 0) {
$validDays = $this->getHospitalDefaultOpdValidityDays();
}
$spanDays = max(0, $validDays - 1);
return date('Y-m-d', strtotime('-' . $spanDays . ' days'));
}
private function getHospitalDefaultOpdValidityDays(): int
{
if (! $this->db->tableExists('hospital_setting')) {
return 5;
}
$keys = [
'OPD_VALID_NO_DAYS',
'OPD_VALIDITY_DAYS',
'DEFAULT_OPD_VALID_NO_DAYS',
'DEFAULT_OPD_VALIDITY_DAYS',
];
$rows = $this->db->table('hospital_setting')
->select('s_name,s_value')
->whereIn('s_name', $keys)
->get()
->getResultArray();
$map = [];
foreach ($rows as $row) {
$name = strtoupper(trim((string) ($row['s_name'] ?? '')));
if ($name === '') {
continue;
}
$map[$name] = (string) ($row['s_value'] ?? '');
}
foreach ($keys as $key) {
$value = (int) ($map[$key] ?? 0);
if ($value > 0) {
return min(365, $value);
}
}
return 5;
}
}