Investigation Profile Master: CRUD and consult integration
This commit is contained in:
parent
d06fe77f03
commit
94e1253e40
|
|
@ -601,6 +601,12 @@ $routes->get('Opd_prescription/opd_invest_master_get/(:num)', 'Opd_prescription:
|
|||
$routes->post('Opd_prescription/opd_invest_master_save', 'Opd_prescription::opd_invest_master_save');
|
||||
$routes->post('Opd_prescription/opd_invest_master_remove/(:num)', 'Opd_prescription::opd_invest_master_remove/$1');
|
||||
$routes->post('Opd_prescription/opd_invest_master_toggle_fav/(:num)', 'Opd_prescription::opd_invest_master_toggle_fav/$1');
|
||||
$routes->get('Opd_prescription/opd_invest_profile_master', 'Opd_prescription::opd_invest_profile_master', ['filter' => 'permission:doctor_work.medicine.manage,doctor_work.access']);
|
||||
$routes->get('Opd_prescription/opd_invest_profile_master_list', 'Opd_prescription::opd_invest_profile_master_list');
|
||||
$routes->get('Opd_prescription/opd_invest_profile_master_data', 'Opd_prescription::opd_invest_profile_master_data');
|
||||
$routes->get('Opd_prescription/opd_invest_profile_master_get/(:num)', 'Opd_prescription::opd_invest_profile_master_get/$1');
|
||||
$routes->post('Opd_prescription/opd_invest_profile_master_save', 'Opd_prescription::opd_invest_profile_master_save');
|
||||
$routes->post('Opd_prescription/opd_invest_profile_master_remove/(:num)', 'Opd_prescription::opd_invest_profile_master_remove/$1');
|
||||
|
||||
$routes->get('Opd_prescription/medicine_search', 'Opd_prescription::medicine_search');
|
||||
$routes->get('Opd_prescription/medicine_substitutes', 'Opd_prescription::medicine_substitutes');
|
||||
|
|
|
|||
|
|
@ -3286,6 +3286,218 @@ class Opd_prescription extends BaseController
|
|||
]);
|
||||
}
|
||||
|
||||
public function opd_invest_profile_master()
|
||||
{
|
||||
return view('billing/opd_invest_profile_master_workspace');
|
||||
}
|
||||
|
||||
public function opd_invest_profile_master_list()
|
||||
{
|
||||
if (! $this->db->tableExists('invprofiles') || ! $this->db->tableExists('invtprofiles') || ! $this->db->tableExists('investigation')) {
|
||||
return $this->response->setJSON(['rows' => []]);
|
||||
}
|
||||
|
||||
$pFields = $this->db->getFieldNames('invprofiles');
|
||||
$jFields = $this->db->getFieldNames('invtprofiles');
|
||||
$iFields = $this->db->getFieldNames('investigation');
|
||||
|
||||
$pCode = $this->resolveFirstField($pFields, ['Code', 'code', 'id']);
|
||||
$pName = $this->resolveFirstField($pFields, ['Name', 'name']);
|
||||
$jProfileCode = $this->resolveFirstField($jFields, ['ProfileCode', 'profile_code']);
|
||||
$jInvestCode = $this->resolveFirstField($jFields, ['InvestigationCode', 'investigation_code']);
|
||||
$jPrintOrder = $this->resolveFirstField($jFields, ['printOrder', 'print_order', 'id']);
|
||||
$iCode = $this->resolveFirstField($iFields, ['Code', 'code']);
|
||||
$iName = $this->resolveFirstField($iFields, ['Name', 'name']);
|
||||
|
||||
if ($pCode === null || $pName === null || $jProfileCode === null || $jInvestCode === null || $iCode === null || $iName === null) {
|
||||
return $this->response->setJSON(['rows' => []]);
|
||||
}
|
||||
|
||||
$filter = trim((string) $this->request->getGet('filter'));
|
||||
|
||||
$sql = 'SELECT '
|
||||
. 'p.`' . $pCode . '` AS profile_code, '
|
||||
. 'p.`' . $pName . '` AS profile_name, '
|
||||
. 'i.`' . $iCode . '` AS investigation_code, '
|
||||
. 'i.`' . $iName . '` AS investigation_name '
|
||||
. 'FROM `invprofiles` p '
|
||||
. 'LEFT JOIN `invtprofiles` j ON p.`' . $pCode . '` = j.`' . $jProfileCode . '` '
|
||||
. 'LEFT JOIN `investigation` i ON i.`' . $iCode . '` = j.`' . $jInvestCode . '` ';
|
||||
|
||||
$params = [];
|
||||
if ($filter !== '') {
|
||||
$sql .= 'WHERE p.`' . $pName . '` LIKE ? OR i.`' . $iName . '` LIKE ? ';
|
||||
$params[] = '%' . $filter . '%';
|
||||
$params[] = '%' . $filter . '%';
|
||||
}
|
||||
$sql .= 'ORDER BY p.`' . $pName . '` ASC';
|
||||
if ($jPrintOrder !== null) {
|
||||
$sql .= ', j.`' . $jPrintOrder . '` ASC';
|
||||
}
|
||||
|
||||
$rows = $this->db->query($sql, $params)->getResultArray();
|
||||
$map = [];
|
||||
foreach ($rows as $row) {
|
||||
$profileCode = (int) ($row['profile_code'] ?? 0);
|
||||
$profileName = trim((string) ($row['profile_name'] ?? ''));
|
||||
if ($profileCode <= 0 || $profileName === '') {
|
||||
continue;
|
||||
}
|
||||
if (! isset($map[$profileCode])) {
|
||||
$map[$profileCode] = [
|
||||
'profile_code' => $profileCode,
|
||||
'profile_name' => $profileName,
|
||||
'tests' => [],
|
||||
];
|
||||
}
|
||||
$testCode = trim((string) ($row['investigation_code'] ?? ''));
|
||||
$testName = trim((string) ($row['investigation_name'] ?? ''));
|
||||
if ($testCode !== '' && $testName !== '') {
|
||||
$map[$profileCode]['tests'][] = [
|
||||
'code' => $testCode,
|
||||
'name' => $testName,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->response->setJSON(['rows' => array_values($map)]);
|
||||
}
|
||||
|
||||
public function opd_invest_profile_master_data()
|
||||
{
|
||||
$rows = $this->opd_invest_profile_master_list()->getJSON(true);
|
||||
$list = $rows['rows'] ?? [];
|
||||
$draw = (int) $this->request->getGet('draw');
|
||||
$start = max(0, (int) $this->request->getGet('start'));
|
||||
$length = (int) $this->request->getGet('length');
|
||||
if ($length <= 0) {
|
||||
$length = 25;
|
||||
}
|
||||
|
||||
$paged = array_slice($list, $start, $length);
|
||||
foreach ($paged as &$row) {
|
||||
$row['test_count'] = count($row['tests'] ?? []);
|
||||
$row['test_names'] = implode(', ', array_map(static function ($item) {
|
||||
return (string) ($item['name'] ?? '');
|
||||
}, $row['tests'] ?? []));
|
||||
}
|
||||
unset($row);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'draw' => $draw,
|
||||
'recordsTotal' => count($list),
|
||||
'recordsFiltered' => count($list),
|
||||
'data' => $paged,
|
||||
]);
|
||||
}
|
||||
|
||||
public function opd_invest_profile_master_get(int $profileCode)
|
||||
{
|
||||
$response = $this->opd_invest_profile_master_list()->getJSON(true);
|
||||
$rows = $response['rows'] ?? [];
|
||||
foreach ($rows as $row) {
|
||||
if ((int) ($row['profile_code'] ?? 0) === $profileCode) {
|
||||
return $this->response->setJSON([
|
||||
'update' => 1,
|
||||
'row' => $row,
|
||||
'csrfName' => csrf_token(),
|
||||
'csrfHash' => csrf_hash(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->response->setJSON(['update' => 0, 'error_text' => 'Profile not found']);
|
||||
}
|
||||
|
||||
public function opd_invest_profile_master_save()
|
||||
{
|
||||
if (! $this->request->isAJAX()) {
|
||||
return $this->response->setStatusCode(400)->setJSON(['update' => 0]);
|
||||
}
|
||||
if (! $this->db->tableExists('invprofiles') || ! $this->db->tableExists('invtprofiles') || ! $this->db->tableExists('investigation')) {
|
||||
return $this->response->setJSON(['update' => 0, 'error_text' => 'Profile tables not found']);
|
||||
}
|
||||
|
||||
$profileCode = (int) $this->request->getPost('profile_code');
|
||||
$profileName = trim((string) $this->request->getPost('profile_name'));
|
||||
$investigationCodes = array_values(array_filter(array_map('intval', explode(',', (string) $this->request->getPost('investigation_codes')))));
|
||||
|
||||
if ($profileName === '') {
|
||||
return $this->response->setJSON(['update' => 0, 'error_text' => 'Profile name is required']);
|
||||
}
|
||||
if (empty($investigationCodes)) {
|
||||
return $this->response->setJSON(['update' => 0, 'error_text' => 'Select at least one investigation']);
|
||||
}
|
||||
|
||||
$pFields = $this->db->getFieldNames('invprofiles');
|
||||
$jFields = $this->db->getFieldNames('invtprofiles');
|
||||
$pCode = $this->resolveFirstField($pFields, ['Code', 'code', 'id']);
|
||||
$pName = $this->resolveFirstField($pFields, ['Name', 'name']);
|
||||
$jProfileCode = $this->resolveFirstField($jFields, ['ProfileCode', 'profile_code']);
|
||||
$jInvestCode = $this->resolveFirstField($jFields, ['InvestigationCode', 'investigation_code']);
|
||||
$jPrintOrder = $this->resolveFirstField($jFields, ['printOrder', 'print_order', 'id']);
|
||||
if ($pCode === null || $pName === null || $jProfileCode === null || $jInvestCode === null) {
|
||||
return $this->response->setJSON(['update' => 0, 'error_text' => 'Invalid profile table structure']);
|
||||
}
|
||||
|
||||
if ($profileCode > 0) {
|
||||
$this->db->table('invprofiles')->where($pCode, $profileCode)->update([$pName => $profileName]);
|
||||
$savedCode = $profileCode;
|
||||
$this->db->table('invtprofiles')->where($jProfileCode, $savedCode)->delete();
|
||||
} else {
|
||||
$this->db->table('invprofiles')->insert([$pName => $profileName]);
|
||||
$savedCode = (int) $this->db->insertID();
|
||||
}
|
||||
|
||||
$order = 1;
|
||||
foreach ($investigationCodes as $code) {
|
||||
$joinRow = [
|
||||
$jProfileCode => $savedCode,
|
||||
$jInvestCode => $code,
|
||||
];
|
||||
if ($jPrintOrder !== null) {
|
||||
$joinRow[$jPrintOrder] = $order;
|
||||
}
|
||||
$this->db->table('invtprofiles')->insert($joinRow);
|
||||
$order++;
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'update' => 1,
|
||||
'insertid' => $savedCode,
|
||||
'error_text' => $profileCode > 0 ? 'Profile updated' : 'Profile added',
|
||||
'csrfName' => csrf_token(),
|
||||
'csrfHash' => csrf_hash(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function opd_invest_profile_master_remove(int $profileCode)
|
||||
{
|
||||
if (! $this->request->isAJAX()) {
|
||||
return $this->response->setStatusCode(400)->setJSON(['update' => 0]);
|
||||
}
|
||||
if (! $this->db->tableExists('invprofiles') || ! $this->db->tableExists('invtprofiles')) {
|
||||
return $this->response->setJSON(['update' => 0, 'error_text' => 'Profile tables not found']);
|
||||
}
|
||||
|
||||
$pFields = $this->db->getFieldNames('invprofiles');
|
||||
$jFields = $this->db->getFieldNames('invtprofiles');
|
||||
$pCode = $this->resolveFirstField($pFields, ['Code', 'code', 'id']);
|
||||
$jProfileCode = $this->resolveFirstField($jFields, ['ProfileCode', 'profile_code']);
|
||||
if ($pCode === null || $jProfileCode === null) {
|
||||
return $this->response->setJSON(['update' => 0, 'error_text' => 'Invalid profile table structure']);
|
||||
}
|
||||
|
||||
$this->db->table('invtprofiles')->where($jProfileCode, $profileCode)->delete();
|
||||
$this->db->table('invprofiles')->where($pCode, $profileCode)->delete();
|
||||
return $this->response->setJSON([
|
||||
'update' => 1,
|
||||
'error_text' => 'Profile deleted',
|
||||
'csrfName' => csrf_token(),
|
||||
'csrfHash' => csrf_hash(),
|
||||
]);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
public function opd_medicince_duplicate_report()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class CreateInvestigationProfileTables extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (! $this->db->tableExists('invprofiles')) {
|
||||
$this->forge->addField([
|
||||
'Code' => [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'unsigned' => false,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'Name' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 150,
|
||||
'null' => false,
|
||||
],
|
||||
]);
|
||||
$this->forge->addKey('Code', true);
|
||||
$this->forge->addUniqueKey('Name');
|
||||
$this->forge->createTable('invprofiles', true);
|
||||
}
|
||||
|
||||
if (! $this->db->tableExists('invtprofiles')) {
|
||||
$this->forge->addField([
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'ProfileCode' => [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'null' => false,
|
||||
],
|
||||
'InvestigationCode' => [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'null' => false,
|
||||
],
|
||||
'printOrder' => [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'default' => 0,
|
||||
],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->addKey(['ProfileCode', 'InvestigationCode']);
|
||||
$this->forge->createTable('invtprofiles', true);
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if ($this->db->tableExists('invtprofiles')) {
|
||||
$this->forge->dropTable('invtprofiles', true);
|
||||
}
|
||||
if ($this->db->tableExists('invprofiles')) {
|
||||
$this->forge->dropTable('invprofiles', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
299
app/Views/billing/opd_invest_profile_master_workspace.php
Normal file
299
app/Views/billing/opd_invest_profile_master_workspace.php
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
<section class="container-fluid py-3">
|
||||
<div class="d-flex align-items-center gap-2 mb-3">
|
||||
<h5 class="mb-0"><i class="bi bi-collection me-1"></i> Investigation Profile Master</h5>
|
||||
<span class="badge bg-secondary" id="inv_profile_total_badge">—</span>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex flex-wrap gap-2 align-items-center">
|
||||
<input type="text" id="inv_profile_filter_text" class="form-control form-control-sm" style="max-width:260px;" placeholder="Search profile / test...">
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table id="tbl_inv_profile_master" class="table table-bordered table-sm table-hover mb-0" style="width:100%;">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Profile</th>
|
||||
<th width="80">Code</th>
|
||||
<th width="80">Tests</th>
|
||||
<th>Investigation Names</th>
|
||||
<th width="100">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr><td colspan="5" class="text-center text-muted py-3">Loading...</td></tr></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header"><strong id="inv_profile_form_title">New Profile</strong></div>
|
||||
<div class="card-body">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" id="inv_profile_code" value="0">
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Profile Name</label>
|
||||
<input type="text" id="inv_profile_name_master" class="form-control form-control-sm" placeholder="e.g. Fever Panel, Pre-Op Panel">
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Investigations</label>
|
||||
<select id="inv_profile_tests_select" class="form-select form-select-sm" multiple="multiple" style="width:100%;"></select>
|
||||
<div class="small text-muted mt-1">Search and select multiple investigations.</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="btn_inv_profile_save">Save</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" id="btn_inv_profile_reset">Reset</button>
|
||||
</div>
|
||||
|
||||
<div class="small mt-2 text-muted" id="inv_profile_msg">Ready.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var profileTable = null;
|
||||
var filterTimer = null;
|
||||
|
||||
function getCsrfPair() {
|
||||
var input = document.querySelector('input[name="<?= csrf_token() ?>"]');
|
||||
return input
|
||||
? { name: input.getAttribute('name'), value: input.value }
|
||||
: { name: '<?= csrf_token() ?>', value: '<?= csrf_hash() ?>' };
|
||||
}
|
||||
|
||||
function updateCsrf(data) {
|
||||
if (!data || !data.csrfName || !data.csrfHash) {
|
||||
return;
|
||||
}
|
||||
var input = document.querySelector('input[name="' + data.csrfName + '"]');
|
||||
if (input) {
|
||||
input.value = data.csrfHash;
|
||||
}
|
||||
}
|
||||
|
||||
function apiPost(url, payload, cb) {
|
||||
var csrf = getCsrfPair();
|
||||
payload = payload || {};
|
||||
payload[csrf.name] = csrf.value;
|
||||
$.post(url, payload, function(data) {
|
||||
updateCsrf(data);
|
||||
cb(data || {});
|
||||
}, 'json');
|
||||
}
|
||||
|
||||
function apiGet(url, cb) {
|
||||
$.get(url, function(data) { cb(data || {}); }, 'json');
|
||||
}
|
||||
|
||||
function setMsg(type, text) {
|
||||
var $msg = $('#inv_profile_msg');
|
||||
$msg.removeClass('text-success text-danger text-muted');
|
||||
if (type === 'ok') {
|
||||
$msg.addClass('text-success');
|
||||
} else if (type === 'err') {
|
||||
$msg.addClass('text-danger');
|
||||
} else {
|
||||
$msg.addClass('text-muted');
|
||||
}
|
||||
$msg.text(text || '');
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
$('#inv_profile_code').val('0');
|
||||
$('#inv_profile_name_master').val('');
|
||||
$('#inv_profile_tests_select').val(null).trigger('change');
|
||||
$('#inv_profile_form_title').text('New Profile');
|
||||
setMsg('normal', 'Ready.');
|
||||
}
|
||||
|
||||
function fillForm(row) {
|
||||
row = row || {};
|
||||
$('#inv_profile_code').val(row.profile_code || 0);
|
||||
$('#inv_profile_name_master').val(row.profile_name || '');
|
||||
var values = [];
|
||||
(row.tests || []).forEach(function(test) {
|
||||
var code = (test.code || '').toString();
|
||||
var name = (test.name || '').toString();
|
||||
if (!code || !name) {
|
||||
return;
|
||||
}
|
||||
if (!$('#inv_profile_tests_select option[value="' + code + '"]').length) {
|
||||
$('#inv_profile_tests_select').append(new Option(name + ' [' + code + ']', code, true, true));
|
||||
}
|
||||
values.push(code);
|
||||
});
|
||||
$('#inv_profile_tests_select').val(values).trigger('change');
|
||||
$('#inv_profile_form_title').text('Edit: ' + (row.profile_name || ''));
|
||||
}
|
||||
|
||||
function buildPayload() {
|
||||
return {
|
||||
profile_code: parseInt($('#inv_profile_code').val() || '0', 10),
|
||||
profile_name: ($('#inv_profile_name_master').val() || '').trim(),
|
||||
investigation_codes: ($('#inv_profile_tests_select').val() || []).join(',')
|
||||
};
|
||||
}
|
||||
|
||||
function initInvestigationMultiSelect() {
|
||||
var $select = $('#inv_profile_tests_select');
|
||||
if (!$.fn || !$.fn.select2 || !$select.length) {
|
||||
return;
|
||||
}
|
||||
$select.select2({
|
||||
width: '100%',
|
||||
placeholder: 'Search investigation...',
|
||||
ajax: {
|
||||
delay: 250,
|
||||
transport: function(params, success, failure) {
|
||||
var term = (params.data && params.data.term) ? params.data.term : '';
|
||||
$.ajax({
|
||||
url: '<?= base_url('Opd_prescription/investigation_search') ?>',
|
||||
dataType: 'json',
|
||||
data: { q: term },
|
||||
success: success,
|
||||
error: failure
|
||||
});
|
||||
},
|
||||
processResults: function(data) {
|
||||
var rows = (data && data.rows) ? data.rows : [];
|
||||
return {
|
||||
results: rows.map(function(row) {
|
||||
var name = (row.name || '').toString();
|
||||
var code = (row.code || '').toString();
|
||||
return {
|
||||
id: code,
|
||||
text: name + (code ? ' [' + code + ']' : '')
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initTable() {
|
||||
if (profileTable || !$.fn || typeof $.fn.DataTable !== 'function') {
|
||||
return;
|
||||
}
|
||||
profileTable = $('#tbl_inv_profile_master').DataTable({
|
||||
serverSide: true,
|
||||
processing: true,
|
||||
searching: false,
|
||||
paging: true,
|
||||
pageLength: 25,
|
||||
lengthChange: false,
|
||||
ajax: {
|
||||
url: '<?= base_url('Opd_prescription/opd_invest_profile_master_data') ?>',
|
||||
type: 'GET',
|
||||
data: function(d) {
|
||||
d.filter = ($('#inv_profile_filter_text').val() || '').trim();
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{ data: 'profile_name' },
|
||||
{ data: 'profile_code' },
|
||||
{ data: 'test_count', orderable: false },
|
||||
{ data: 'test_names', orderable: false },
|
||||
{
|
||||
data: 'profile_code', orderable: false,
|
||||
render: function(code) {
|
||||
return '<button type="button" class="btn btn-outline-primary btn-sm btn-inv-profile-edit" data-code="' + code + '">Edit</button> '
|
||||
+ '<button type="button" class="btn btn-outline-danger btn-sm btn-inv-profile-del" data-code="' + code + '">Del</button>';
|
||||
}
|
||||
}
|
||||
],
|
||||
drawCallback: function(settings) {
|
||||
var json = settings.json || {};
|
||||
$('#inv_profile_total_badge').text((json.recordsTotal || 0) + ' total');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
if (profileTable) {
|
||||
profileTable.ajax.reload(null, true);
|
||||
}
|
||||
}
|
||||
|
||||
$('#btn_inv_profile_save').on('click', function() {
|
||||
var payload = buildPayload();
|
||||
if (!payload.profile_name) {
|
||||
setMsg('err', 'Profile name is required.');
|
||||
return;
|
||||
}
|
||||
if (!payload.investigation_codes) {
|
||||
setMsg('err', 'Select at least one investigation.');
|
||||
return;
|
||||
}
|
||||
apiPost('<?= base_url('Opd_prescription/opd_invest_profile_master_save') ?>', payload, function(data) {
|
||||
if ((data.update || 0) != 1) {
|
||||
setMsg('err', data.error_text || 'Unable to save profile');
|
||||
return;
|
||||
}
|
||||
$('#inv_profile_code').val(data.insertid || 0);
|
||||
setMsg('ok', data.error_text || 'Saved');
|
||||
reloadTable();
|
||||
});
|
||||
});
|
||||
|
||||
$('#btn_inv_profile_reset').on('click', function() {
|
||||
clearForm();
|
||||
});
|
||||
|
||||
$('#inv_profile_filter_text').on('input', function() {
|
||||
clearTimeout(filterTimer);
|
||||
filterTimer = setTimeout(reloadTable, 250);
|
||||
});
|
||||
|
||||
$(document).on('click', '.btn-inv-profile-edit', function() {
|
||||
var code = parseInt($(this).data('code') || '0', 10);
|
||||
if (code <= 0) {
|
||||
return;
|
||||
}
|
||||
apiGet('<?= base_url('Opd_prescription/opd_invest_profile_master_get') ?>/' + code, function(data) {
|
||||
if ((data.update || 0) != 1) {
|
||||
setMsg('err', data.error_text || 'Unable to load profile');
|
||||
return;
|
||||
}
|
||||
fillForm(data.row || {});
|
||||
setMsg('normal', 'Profile loaded for edit.');
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.btn-inv-profile-del', function() {
|
||||
var code = parseInt($(this).data('code') || '0', 10);
|
||||
if (code <= 0) {
|
||||
return;
|
||||
}
|
||||
if (!confirm('Delete this profile?')) {
|
||||
return;
|
||||
}
|
||||
apiPost('<?= base_url('Opd_prescription/opd_invest_profile_master_remove') ?>/' + code, {}, function(data) {
|
||||
if ((data.update || 0) != 1) {
|
||||
setMsg('err', data.error_text || 'Unable to delete profile');
|
||||
return;
|
||||
}
|
||||
setMsg('ok', data.error_text || 'Deleted');
|
||||
reloadTable();
|
||||
if (parseInt($('#inv_profile_code').val() || '0', 10) === code) {
|
||||
clearForm();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(function() {
|
||||
initInvestigationMultiSelect();
|
||||
initTable();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
|
@ -711,9 +711,9 @@
|
|||
<div class="d-flex flex-wrap gap-2 align-items-center" id="inv_profile_chip_wrap">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm inv-profile-chip" data-profile="cardiac">Cardiac Profile</button>
|
||||
<button type="button" class="btn btn-outline-success btn-sm inv-profile-chip" data-profile="viral_infection">Viral Infection</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" id="btn_create_inv_profile">Create Profile</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" id="btn_create_inv_profile">Profile Master</button>
|
||||
<select class="form-select form-select-sm" id="inv_custom_profile_select" style="max-width:260px;">
|
||||
<option value="">Load custom profile...</option>
|
||||
<option value="">Load profile...</option>
|
||||
</select>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" id="btn_apply_custom_inv_profile">Apply</button>
|
||||
</div>
|
||||
|
|
@ -1876,37 +1876,25 @@
|
|||
}
|
||||
|
||||
function refreshCustomProfileSelect() {
|
||||
var rows = getCustomInvestigationProfiles();
|
||||
var $sel = $('#inv_custom_profile_select');
|
||||
if (!$sel.length) {
|
||||
return;
|
||||
}
|
||||
$sel.html('<option value="">Load profile...</option>');
|
||||
|
||||
if (legacyInvestigationProfileList.length) {
|
||||
$sel.append('<optgroup label="Old HMS Profiles"></optgroup>');
|
||||
var $legacyGroup = $sel.find('optgroup[label="Old HMS Profiles"]');
|
||||
legacyInvestigationProfileList.forEach(function(row) {
|
||||
var key = (row && row.key) ? row.key : '';
|
||||
var name = (row && row.name) ? row.name : '';
|
||||
if (!key || !name) {
|
||||
return;
|
||||
}
|
||||
$legacyGroup.append('<option value="legacy:' + $('<div>').text(key).html() + '">' + $('<div>').text(name).html() + '</option>');
|
||||
});
|
||||
}
|
||||
|
||||
if (rows.length) {
|
||||
$sel.append('<optgroup label="Custom Profiles"></optgroup>');
|
||||
var $customGroup = $sel.find('optgroup[label="Custom Profiles"]');
|
||||
rows.forEach(function(row, idx) {
|
||||
$customGroup.append('<option value="custom:' + idx + '">' + $('<div>').text(row.name || ('Profile ' + (idx + 1))).html() + '</option>');
|
||||
});
|
||||
if (!legacyInvestigationProfileList.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
rows.forEach(function(row, idx) {
|
||||
$sel.append('<option value="custom:' + idx + '">' + $('<div>').text(row.name || ('Profile ' + (idx + 1))).html() + '</option>');
|
||||
$sel.append('<optgroup label="Master Profiles"></optgroup>');
|
||||
var $group = $sel.find('optgroup[label="Master Profiles"]');
|
||||
legacyInvestigationProfileList.forEach(function(row) {
|
||||
var key = (row && row.key) ? row.key : '';
|
||||
var name = (row && row.name) ? row.name : '';
|
||||
if (!key || !name) {
|
||||
return;
|
||||
}
|
||||
$group.append('<option value="legacy:' + $('<div>').text(key).html() + '">' + $('<div>').text(name).html() + '</option>');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -4052,13 +4040,11 @@
|
|||
});
|
||||
|
||||
$('#btn_create_inv_profile').on('click', function() {
|
||||
$('#inv_profile_name').val('');
|
||||
$('#inv_profile_tests').val('');
|
||||
if (window.bootstrap && window.bootstrap.Modal) {
|
||||
window.bootstrap.Modal.getOrCreateInstance(document.getElementById('invProfileModal')).show();
|
||||
} else {
|
||||
$('#invProfileModal').show();
|
||||
if (typeof window.load_form === 'function') {
|
||||
window.load_form('<?= base_url('Opd_prescription/opd_invest_profile_master') ?>', 'Investigation Profile Master');
|
||||
return;
|
||||
}
|
||||
window.location.href = '<?= base_url('Opd_prescription/opd_invest_profile_master') ?>';
|
||||
});
|
||||
|
||||
$('#btn_save_inv_profile').on('click', function() {
|
||||
|
|
@ -4095,25 +4081,14 @@
|
|||
var legacyKey = selected.substring(7);
|
||||
var legacyRows = legacyInvestigationProfiles[legacyKey] || [];
|
||||
if (!legacyRows.length) {
|
||||
$('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Selected old HMS profile has no tests.');
|
||||
$('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Selected profile has no tests.');
|
||||
return;
|
||||
}
|
||||
batchAddInvestigationRows(legacyRows);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected.indexOf('custom:') !== 0) {
|
||||
$('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Invalid profile selection.');
|
||||
return;
|
||||
}
|
||||
|
||||
var idx = parseInt(selected.substring(7), 10);
|
||||
var rows = getCustomInvestigationProfiles();
|
||||
if (isNaN(idx) || idx < 0 || idx >= rows.length) {
|
||||
$('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Selected custom profile is not available.');
|
||||
return;
|
||||
}
|
||||
batchAddInvestigations(rows[idx].tests || []);
|
||||
$('.jsError').removeClass('text-success text-muted').addClass('text-danger').text('Invalid profile selection.');
|
||||
});
|
||||
|
||||
$('#advise_investigation_notes').on('input', function() {
|
||||
|
|
|
|||
|
|
@ -238,15 +238,20 @@ if (! $canDiagnosis && $user && method_exists($user, 'inGroup')) {
|
|||
<span>OPD Medicine</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link collapsed" href="javascript:load_form('<?= base_url('Opd_prescription/opd_invest_master') ?>','Investigation Master')">
|
||||
<i class="bi bi-clipboard2-pulse"></i>
|
||||
<span>Investigation Master</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link collapsed" href="javascript:load_form('<?= base_url('Opd_prescription/opd_invest_profile_master') ?>','Investigation Profile Master')">
|
||||
<i class="bi bi-collection"></i>
|
||||
<span>Investigation Profile Master</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link collapsed" href="javascript:load_form('<?= base_url('Opd_prescription/opd_advice') ?>','OPD Advice Master')">
|
||||
<a class="nav-link collapsed" href="javascript:load_form('<?= base_url('Opd_prescription/opd_invest_master') ?>','Investigation Master')">
|
||||
<i class="bi bi-clipboard2-pulse"></i>
|
||||
<span>Investigation Master</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link collapsed" href="javascript:load_form('<?= base_url('Opd_prescription/opd_advice') ?>','OPD Advice Master')">
|
||||
<i class="bi bi-chat-left-text"></i>
|
||||
<span>OPD Advice Master</span>
|
||||
</a>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user