devsofttech_hms_ci4/app/Models/OpdModel.php
DevSoftTech Server 21ddeefe40 fix: Running OPD zero-value validity, update_doc_field HTTP 500, PDF Unicode font (Devanagari)
- Opd.php showfee(): exclude zero-amount OPD from validity window query
- Opd.php confirm_opd(): anchor last_opdvisit_date to most recent paid OPD for zero-value running
- Opd.php buildOpdLetterPrintData(): use paid OPD start date for expiry on zero-value entries
- OpdModel.php insertOpd(): exclude fee_type=3/zero-amount from running_opd_id lookup; anchor visit count to paid OPD start when isZeroValueRunning
- DoctorDocument.php update_doc_field(): wrap in try/catch, schema-safe payload via filterPayloadByExistingColumns, structured JSON errors
- DoctorDocument.php create_final(): configure mPDF with FreeSans/FreeSerif (GNU FreeFont), useOTL=0xFF, autoScriptToLang=true for Devanagari/Hindi rendering
- doc_letterhead_print.php: add body/p/td/th font-family freesans for PDF Unicode output
2026-04-10 12:30:15 +05:30

112 lines
3.2 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);
if ($pId <= 0 || $docId <= 0) {
return 0;
}
$duplicate = $this->db->table('opd_master')
->where('apointment_date', date('Y-m-d'))
->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', date('Y-m-d'))
->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 >=', date('Y-m-d', strtotime('-4 days')))
->where('apointment_date <=', date('Y-m-d'))
->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;
}
}