170 lines
5.0 KiB
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;
|
|
}
|
|
}
|