Restore finance medical credit workflow and update help

This commit is contained in:
DevSoftTech Server 2026-08-12 16:17:25 +05:30
parent 870fed5dcd
commit d10f49c482
3 changed files with 667 additions and 97 deletions

View File

@ -322,6 +322,15 @@ $routes->get('Finance/scroll_items_table', 'Finance::scrollItemsTable');
$routes->get('Finance/bank_deposits', 'Finance::bankDeposits');
$routes->get('Finance/bank_deposits_table', 'Finance::bankDepositsTable');
$routes->get('Finance/bank_audit', 'Finance::bankAudit');
$routes->get('Finance/medical_store_credit_account', 'Finance::medicalStoreCreditAccount');
$routes->get('Finance/medical_store_requests_table', 'Finance::medicalStoreRequestsTable');
$routes->get('Finance/medical_store_dashboard_card', 'Finance::medicalStoreDashboardCard');
$routes->get('Finance/medical_store_request_detail/(:num)', 'Finance::medicalStoreRequestDetail/$1');
$routes->get('Finance/medical_store_request_lines_table', 'Finance::medicalStoreRequestLinesTable');
$routes->post('Finance/medical_store_request_review', 'Finance::medicalStoreRequestReview');
$routes->post('Finance/medical_store_request_approve', 'Finance::medicalStoreRequestApprove');
$routes->post('Finance/medical_store_request_reject', 'Finance::medicalStoreRequestReject');
$routes->post('Finance/medical_store_payment_create', 'Finance::medicalStorePaymentCreate');
$routes->get('Finance/payout/opd-consult', 'Finance::payoutOpdConsult');
$routes->get('Finance/payout/opd-consult-summary', 'Finance::payoutOpdConsultSummary');
$routes->get('Finance/payout/opd-consult-drafts-table', 'Finance::payoutOpdConsultDraftsTable');

View File

@ -19,6 +19,11 @@ use App\Models\FinanceScrollSubmissionItemModel;
use App\Models\FinanceScrollSubmissionModel;
use App\Models\FinanceVendorInvoiceModel;
use App\Models\FinancePharmacyBillModel;
use App\Models\FinancePayoutRequestAuditModel;
use App\Models\FinancePayoutRequestLineModel;
use App\Models\FinancePayoutRequestModel;
use App\Models\FinanceOutgoingPaymentAllocationModel;
use App\Models\FinanceOutgoingPaymentHistoryModel;
use App\Models\FinanceVendorModel;
class Finance extends BaseController
@ -40,6 +45,11 @@ class Finance extends BaseController
private FinanceDoctorAgreementModel $doctorAgreementModel;
private FinanceDoctorPayoutModel $doctorPayoutModel;
private FinancePharmacyBillModel $pharmBillModel;
private FinancePayoutRequestModel $payoutRequestModel;
private FinancePayoutRequestLineModel $payoutRequestLineModel;
private FinanceOutgoingPaymentHistoryModel $outgoingPaymentHistoryModel;
private FinanceOutgoingPaymentAllocationModel $outgoingPaymentAllocationModel;
private FinancePayoutRequestAuditModel $payoutRequestAuditModel;
public function __construct()
{
@ -60,6 +70,11 @@ class Finance extends BaseController
$this->doctorAgreementModel = new FinanceDoctorAgreementModel();
$this->doctorPayoutModel = new FinanceDoctorPayoutModel();
$this->pharmBillModel = new FinancePharmacyBillModel();
$this->payoutRequestModel = new FinancePayoutRequestModel();
$this->payoutRequestLineModel = new FinancePayoutRequestLineModel();
$this->outgoingPaymentHistoryModel = new FinanceOutgoingPaymentHistoryModel();
$this->outgoingPaymentAllocationModel = new FinanceOutgoingPaymentAllocationModel();
$this->payoutRequestAuditModel = new FinancePayoutRequestAuditModel();
}
public function bankDeposits()
@ -3487,6 +3502,16 @@ class Finance extends BaseController
return trim((string) ($user->username ?? 'System'));
}
private function currentUserId(): ?int
{
$user = function_exists('auth') ? auth()->user() : null;
if (! $user || ! isset($user->id)) {
return null;
}
return (int) $user->id;
}
private function fetchCashTransactions(): array
{
return $this->cashTxnModel->orderBy('id', 'DESC')->findAll(15);
@ -3587,6 +3612,399 @@ class Finance extends BaseController
];
}
public function medicalStoreCreditAccount()
{
if (! $this->canFinanceAny(['finance.workflow.view', 'finance.cash.accounts.accept', 'finance.cash.accounts.verify', 'finance.doctor_payout.manage'])) {
return $this->response->setStatusCode(403)->setBody('Access denied');
}
$summary = [
'total_requested' => 0.0,
'total_paid' => 0.0,
'total_pending' => 0.0,
'open_requests' => 0,
];
$rows = [];
if ($this->db->tableExists('finance_payout_requests')) {
$summaryRow = $this->db->table('finance_payout_requests')
->select('COALESCE(SUM(requested_amount),0) AS total_requested, COALESCE(SUM(paid_amount),0) AS total_paid, COALESCE(SUM(pending_amount),0) AS total_pending', false)
->where('request_type', 'medical_store_credit')
->get()->getRowArray();
$summary['total_requested'] = (float) ($summaryRow['total_requested'] ?? 0);
$summary['total_paid'] = (float) ($summaryRow['total_paid'] ?? 0);
$summary['total_pending'] = (float) ($summaryRow['total_pending'] ?? 0);
$summary['open_requests'] = $this->db->table('finance_payout_requests')
->where('request_type', 'medical_store_credit')
->whereIn('status', ['submitted', 'finance_review', 'approved', 'partially_paid'])
->countAllResults();
$rows = $this->payoutRequestModel
->where('request_type', 'medical_store_credit')
->orderBy('id', 'DESC')
->findAll(60);
}
return view('finance/medical_store_credit_account', [
'summary' => $summary,
'rows' => $rows,
]);
}
public function medicalStoreRequestsTable()
{
if (! $this->canFinanceAny(['finance.workflow.view', 'finance.cash.accounts.accept', 'finance.cash.accounts.verify', 'finance.doctor_payout.manage'])) {
return $this->response->setStatusCode(403)->setBody('Access denied');
}
$status = trim((string) ($this->request->getGet('status') ?? ''));
$rows = [];
if ($this->db->tableExists('finance_payout_requests')) {
$builder = $this->payoutRequestModel
->where('request_type', 'medical_store_credit')
->orderBy('id', 'DESC');
if ($status !== '') {
$builder->where('status', $status);
}
$rows = $builder->findAll(200);
}
return view('finance/partials/medical_store_requests_table', ['rows' => $rows]);
}
public function medicalStoreRequestLinesTable()
{
if (! $this->canFinanceAny(['finance.workflow.view', 'finance.cash.accounts.accept', 'finance.cash.accounts.verify', 'finance.doctor_payout.manage'])) {
return $this->response->setStatusCode(403)->setBody('Access denied');
}
$requestId = (int) ($this->request->getGet('request_id') ?? 0);
if ($requestId <= 0) {
return view('finance/partials/medical_store_request_lines_table', [
'request' => null,
'lines' => [],
'payments' => [],
]);
}
$request = $this->payoutRequestModel->find($requestId);
$lines = $this->db->tableExists('finance_payout_request_lines')
? $this->payoutRequestLineModel->where('request_id', $requestId)->orderBy('line_order', 'ASC')->orderBy('id', 'ASC')->findAll()
: [];
$payments = $this->db->tableExists('finance_outgoing_payment_history')
? $this->outgoingPaymentHistoryModel->where('request_id', $requestId)->orderBy('id', 'DESC')->findAll()
: [];
return view('finance/partials/medical_store_request_lines_table', [
'request' => $request,
'lines' => $lines,
'payments' => $payments,
]);
}
public function medicalStoreRequestDetail($requestId = 0)
{
if (! $this->canFinanceAny(['finance.workflow.view', 'finance.cash.accounts.accept', 'finance.cash.accounts.verify', 'finance.doctor_payout.manage'])) {
return $this->response->setStatusCode(403)->setJSON(['status' => 0, 'message' => 'Access denied']);
}
$requestId = (int) $requestId;
if ($requestId <= 0) {
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Request ID required']);
}
$request = $this->payoutRequestModel->find($requestId);
if (! is_array($request)) {
return $this->response->setStatusCode(404)->setJSON(['status' => 0, 'message' => 'Request not found']);
}
$lines = $this->db->tableExists('finance_payout_request_lines')
? $this->payoutRequestLineModel->where('request_id', $requestId)->orderBy('line_order', 'ASC')->orderBy('id', 'ASC')->findAll()
: [];
$payments = $this->db->tableExists('finance_outgoing_payment_history')
? $this->outgoingPaymentHistoryModel->where('request_id', $requestId)->orderBy('id', 'DESC')->findAll()
: [];
return $this->response->setJSON([
'status' => 1,
'request' => $request,
'lines' => $lines,
'payments' => $payments,
]);
}
public function medicalStoreRequestReview()
{
return $this->transitionMedicalStoreRequestStatus('finance_review', ['submitted']);
}
public function medicalStoreRequestApprove()
{
return $this->transitionMedicalStoreRequestStatus('approved', ['finance_review']);
}
public function medicalStoreRequestReject()
{
return $this->transitionMedicalStoreRequestStatus('rejected', ['finance_review', 'submitted']);
}
public function medicalStorePaymentCreate()
{
if (! $this->canFinanceAny(['finance.cash.accounts.accept', 'finance.cash.accounts.verify', 'finance.doctor_payout.manage'])) {
return $this->response->setStatusCode(403)->setJSON(['status' => 0, 'message' => 'Access denied']);
}
$requestId = (int) ($this->request->getPost('request_id') ?? 0);
$amount = round((float) ($this->request->getPost('amount') ?? 0), 2);
$paymentMode = (int) ($this->request->getPost('payment_mode') ?? 1);
$remark = trim((string) ($this->request->getPost('remark') ?? ''));
if ($requestId <= 0 || $amount <= 0) {
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Request and amount are required.']);
}
$request = $this->payoutRequestModel->find($requestId);
if (! is_array($request)) {
return $this->response->setStatusCode(404)->setJSON(['status' => 0, 'message' => 'Request not found.']);
}
$status = (string) ($request['status'] ?? '');
if (! in_array($status, ['approved', 'partially_paid'], true)) {
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Only approved or partially paid requests can be paid.']);
}
$pending = round((float) ($request['pending_amount'] ?? 0), 2);
if ($pending <= 0) {
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Request has no pending amount.']);
}
if ($amount > $pending) {
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Payment amount exceeds pending amount.']);
}
$userId = $this->currentUserId();
$userName = $this->currentUserName();
$now = date('Y-m-d H:i:s');
$paymentNo = 'MSP-' . date('YmdHis') . '-' . random_int(1000, 9999);
$this->db->transStart();
$this->outgoingPaymentHistoryModel->insert([
'payment_no' => $paymentNo,
'payout_type' => 'medical_store',
'payee_label' => 'Medical Store Credit Settlement',
'request_id' => $requestId,
'payment_date' => $now,
'amount' => $amount,
'payment_mode' => $paymentMode,
'pay_bank_id' => (int) ($this->request->getPost('pay_bank_id') ?? 0),
'card_bank' => trim((string) ($this->request->getPost('card_bank') ?? '')),
'card_remark' => trim((string) ($this->request->getPost('card_remark') ?? '')),
'cust_card' => trim((string) ($this->request->getPost('cust_card') ?? '')),
'card_tran_id' => trim((string) ($this->request->getPost('card_tran_id') ?? '')),
'bankcard_machine' => trim((string) ($this->request->getPost('bankcard_machine') ?? '')),
'insert_code' => trim((string) ($this->request->getPost('insert_code') ?? '')),
'credit_debit' => 0,
'remark' => $remark,
'status' => 'paid',
'created_by' => $userName,
'created_by_id' => $userId,
'created_at' => $now,
'updated_at' => $now,
]);
$paymentId = (int) $this->outgoingPaymentHistoryModel->getInsertID();
$openLines = $this->payoutRequestLineModel
->where('request_id', $requestId)
->where('pending_amount >', 0)
->orderBy('line_order', 'ASC')
->orderBy('id', 'ASC')
->findAll();
$remaining = $amount;
$allocOrder = 1;
foreach ($openLines as $line) {
$lineId = (int) ($line['id'] ?? 0);
$linePending = round((float) ($line['pending_amount'] ?? 0), 2);
if ($lineId <= 0 || $linePending <= 0 || $remaining <= 0) {
continue;
}
$alloc = round(min($linePending, $remaining), 2);
$this->outgoingPaymentAllocationModel->insert([
'payment_id' => $paymentId,
'request_id' => $requestId,
'request_line_id' => $lineId,
'allocated_amount' => $alloc,
'allocation_order' => $allocOrder,
'allocation_note' => 'Auto FIFO allocation',
'created_by' => $userName,
'created_by_id' => $userId,
'created_at' => $now,
]);
$newAllocated = round((float) ($line['allocated_amount'] ?? 0) + $alloc, 2);
$newPending = round(max(0, (float) ($line['line_amount'] ?? 0) - $newAllocated), 2);
$newLineStatus = $newPending <= 0 ? 'closed' : ($newAllocated > 0 ? 'partial' : 'open');
$this->payoutRequestLineModel->update($lineId, [
'allocated_amount' => $newAllocated,
'pending_amount' => $newPending,
'line_status' => $newLineStatus,
'updated_at' => $now,
]);
$remaining = round($remaining - $alloc, 2);
$allocOrder++;
}
if ($remaining > 0) {
$this->db->transRollback();
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Payment exceeds open line capacity.']);
}
$this->recalculateMedicalStoreRequestTotals($requestId, $userId, $userName);
$this->logPayoutRequestAudit($requestId, 'payment_create', $status, null, 'Payment #' . $paymentNo . ' amount: ' . number_format($amount, 2, '.', ''));
$this->db->transComplete();
if (! $this->db->transStatus()) {
return $this->response->setStatusCode(500)->setJSON(['status' => 0, 'message' => 'Failed to save payout payment.']);
}
return $this->response->setJSON([
'status' => 1,
'message' => 'Payment saved and allocated successfully.',
'payment_id' => $paymentId,
'payment_no' => $paymentNo,
]);
}
public function medicalStoreDashboardCard()
{
if (! $this->canFinanceAny(['finance.workflow.view', 'finance.cash.accounts.accept', 'finance.cash.accounts.verify', 'finance.doctor_payout.manage'])) {
return $this->response->setStatusCode(403)->setJSON(['status' => 0, 'message' => 'Access denied']);
}
if (! $this->db->tableExists('finance_payout_requests')) {
return $this->response->setJSON([
'status' => 1,
'summary' => ['total_requested' => 0, 'total_paid' => 0, 'total_pending' => 0, 'open_requests' => 0],
]);
}
$summaryRow = $this->db->table('finance_payout_requests')
->select('COALESCE(SUM(requested_amount),0) AS total_requested, COALESCE(SUM(paid_amount),0) AS total_paid, COALESCE(SUM(pending_amount),0) AS total_pending', false)
->where('request_type', 'medical_store_credit')
->get()->getRowArray();
$openRequests = $this->db->table('finance_payout_requests')
->where('request_type', 'medical_store_credit')
->whereIn('status', ['submitted', 'finance_review', 'approved', 'partially_paid'])
->countAllResults();
return $this->response->setJSON([
'status' => 1,
'summary' => [
'total_requested' => (float) ($summaryRow['total_requested'] ?? 0),
'total_paid' => (float) ($summaryRow['total_paid'] ?? 0),
'total_pending' => (float) ($summaryRow['total_pending'] ?? 0),
'open_requests' => $openRequests,
],
]);
}
private function transitionMedicalStoreRequestStatus(string $newStatus, array $allowedFrom)
{
if (! $this->canFinanceAny(['finance.workflow.view', 'finance.cash.accounts.accept', 'finance.cash.accounts.verify', 'finance.doctor_payout.manage'])) {
return $this->response->setStatusCode(403)->setJSON(['status' => 0, 'message' => 'Access denied']);
}
$requestId = (int) ($this->request->getPost('request_id') ?? 0);
$remark = trim((string) ($this->request->getPost('remark') ?? ''));
if ($requestId <= 0) {
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Request ID required.']);
}
$request = $this->payoutRequestModel->find($requestId);
if (! is_array($request)) {
return $this->response->setStatusCode(404)->setJSON(['status' => 0, 'message' => 'Request not found.']);
}
$oldStatus = (string) ($request['status'] ?? '');
if (! in_array($oldStatus, $allowedFrom, true)) {
return $this->response->setStatusCode(422)->setJSON(['status' => 0, 'message' => 'Invalid status transition from ' . $oldStatus . ' to ' . $newStatus . '.']);
}
$now = date('Y-m-d H:i:s');
$update = [
'status' => $newStatus,
'updated_at' => $now,
'updated_by' => $this->currentUserName(),
'updated_by_id' => $this->currentUserId(),
];
if ($newStatus === 'finance_review') {
$update['finance_reviewed_at'] = $now;
}
if ($newStatus === 'approved') {
$update['approved_at'] = $now;
if ((float) ($request['approved_amount'] ?? 0) <= 0) {
$update['approved_amount'] = (float) ($request['requested_amount'] ?? 0);
}
}
$this->payoutRequestModel->update($requestId, $update);
$this->logPayoutRequestAudit($requestId, 'status_change', $oldStatus, $newStatus, $remark);
return $this->response->setJSON(['status' => 1, 'message' => 'Request status updated to ' . $newStatus . '.']);
}
private function recalculateMedicalStoreRequestTotals(int $requestId, ?int $userId = null, ?string $userName = null): void
{
$sumLines = $this->db->table('finance_payout_request_lines')
->select('COALESCE(SUM(line_amount),0) AS line_total, COALESCE(SUM(allocated_amount),0) AS allocated_total, COALESCE(SUM(pending_amount),0) AS pending_total', false)
->where('request_id', $requestId)
->get()->getRowArray();
$requested = round((float) ($sumLines['line_total'] ?? 0), 2);
$paid = round((float) ($sumLines['allocated_total'] ?? 0), 2);
$pending = round((float) ($sumLines['pending_total'] ?? 0), 2);
$newStatus = $paid <= 0 ? 'approved' : ($pending > 0 ? 'partially_paid' : 'paid');
$update = [
'requested_amount' => $requested,
'paid_amount' => $paid,
'pending_amount' => $pending,
'status' => $newStatus,
'updated_at' => date('Y-m-d H:i:s'),
];
if ($userName !== null) {
$update['updated_by'] = $userName;
}
if ($userId !== null) {
$update['updated_by_id'] = $userId;
}
if ($newStatus === 'paid') {
$update['closed_at'] = date('Y-m-d H:i:s');
}
$this->payoutRequestModel->update($requestId, $update);
}
private function logPayoutRequestAudit(int $requestId, string $actionType, ?string $oldStatus, ?string $newStatus, string $note = ''): void
{
if (! $this->db->tableExists('finance_payout_request_audit')) {
return;
}
$this->payoutRequestAuditModel->insert([
'request_id' => $requestId,
'action_type' => $actionType,
'old_status' => $oldStatus,
'new_status' => $newStatus,
'action_note' => $note !== '' ? $note : null,
'action_by' => $this->currentUserName(),
'action_by_id' => $this->currentUserId(),
'action_at' => date('Y-m-d H:i:s'),
]);
}
private function fetchCollectorOptions(): array
{
if (! method_exists($this->db, 'tableExists') || ! $this->db->tableExists('payment_history')) {

View File

@ -3,121 +3,264 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HMS Software Help Guide</title>
<meta name="description" content="Detailed user and operations guide for E-Atria Hospital Management System.">
<title>E-Atria HMS Help &amp; Operations Guide</title>
<link href="assets/img/logo.ico" rel="icon" type="image/x-icon">
<link href="assets/img/favicon.png" rel="alternate icon" type="image/png">
<link href="assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/vendor/bootstrap-icons/bootstrap-icons.css" rel="stylesheet">
<style>
body { background: #f5f7fb; color: #1f2937; }
.wrap { max-width: 980px; margin: 24px auto; }
.card { border: 1px solid #dbe3ee; }
h1, h2 { color: #0f3d7a; }
.toc a { text-decoration: none; }
.toc a:hover { text-decoration: underline; }
:root { --ink:#172238; --muted:#617087; --navy:#123765; --teal:#087f75; --amber:#b96710; --red:#b43c47; --paper:#fff; --canvas:#edf2f7; --line:#d6dee9; --soft-blue:#eaf2fb; --soft-teal:#e7f5f2; --soft-amber:#fff3df; }
html { scroll-behavior:smooth; }
body { background-color:var(--canvas); background-image:linear-gradient(rgba(18,55,101,.035) 1px,transparent 1px),linear-gradient(90deg,rgba(18,55,101,.035) 1px,transparent 1px); background-size:28px 28px; color:var(--ink); font-family:"Segoe UI",Tahoma,sans-serif; letter-spacing:0; }
h1,h2,h3 { font-family:Georgia,"Times New Roman",serif; letter-spacing:0; }
a { color:var(--navy); } code { color:var(--red); }
.page-shell { max-width:1440px; margin:0 auto; }
.guide-header { background:var(--navy); color:#fff; border-bottom:5px solid var(--teal); }
.brand-mark { width:48px; height:48px; object-fit:contain; background:#fff; padding:4px; border-radius:6px; }
.guide-title { font-size:clamp(1.65rem,3vw,2.45rem); margin:0; }
.version-label { color:#dce8f6; }
.search-wrap { position:relative; max-width:520px; }
.search-wrap i { position:absolute; left:14px; top:11px; color:#68778d; }
.search-wrap input { padding-left:40px; border:0; border-radius:6px; min-height:44px; }
.layout { display:grid; grid-template-columns:290px minmax(0,1fr); gap:24px; align-items:start; }
.toc-panel { position:sticky; top:16px; max-height:calc(100vh - 32px); overflow:auto; background:var(--paper); border:1px solid var(--line); border-radius:6px; }
.toc-panel h2 { font:700 1rem "Segoe UI",Tahoma,sans-serif; }
.toc-panel a { display:block; padding:7px 14px; color:#3f4c60; text-decoration:none; border-left:3px solid transparent; font-size:.9rem; }
.toc-panel a:hover,.toc-panel a:focus { background:var(--soft-blue); border-left-color:var(--navy); color:var(--navy); }
.guide-content { min-width:0; }
.guide-section { background:var(--paper); border:1px solid var(--line); border-radius:6px; margin-bottom:18px; padding:clamp(20px,3vw,34px); scroll-margin-top:16px; }
.guide-section>h2 { color:var(--navy); font-size:1.55rem; border-bottom:2px solid var(--line); padding-bottom:12px; margin-bottom:20px; }
.guide-section h3 { color:#274e72; font-size:1.12rem; margin-top:22px; }
.section-number { color:var(--teal); font:800 1rem "Segoe UI",Tahoma,sans-serif; margin-right:7px; }
.quick-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; }
.quick-item { border:1px solid var(--line); border-top:4px solid var(--teal); padding:16px; background:#fbfdff; }
.quick-item strong { display:block; color:var(--navy); margin-bottom:5px; }
.update-item { border-left:4px solid var(--teal); background:var(--soft-teal); padding:14px 16px; margin-bottom:10px; }
.update-item.finance { border-left-color:var(--amber); background:var(--soft-amber); }
.update-item.security { border-left-color:var(--red); background:#fcedef; }
.status-chip { display:inline-block; background:var(--navy); color:#fff; border-radius:4px; padding:2px 7px; font-size:.75rem; font-weight:700; }
.workflow { counter-reset:workflow; list-style:none; padding:0; }
.workflow li { counter-increment:workflow; position:relative; padding:0 0 16px 46px; min-height:38px; }
.workflow li::before { content:counter(workflow); position:absolute; left:0; top:0; width:30px; height:30px; display:grid; place-items:center; background:var(--navy); color:#fff; border-radius:50%; font-weight:700; }
.workflow li:not(:last-child)::after { content:""; position:absolute; left:14px; top:31px; bottom:1px; border-left:2px solid var(--line); }
.note,.warning,.safety { padding:13px 15px; margin:16px 0; border-left:4px solid var(--navy); background:var(--soft-blue); }
.warning { border-left-color:var(--amber); background:var(--soft-amber); }
.safety { border-left-color:var(--red); background:#fcedef; }
.table-guide th { background:var(--navy); color:#fff; font-weight:600; }
.table-guide td,.table-guide th { vertical-align:top; }
.search-hidden { display:none!important; }
.no-results { display:none; background:var(--soft-amber); border:1px solid #eccb91; padding:18px; border-radius:6px; }
.back-top { text-align:right; margin-top:18px; font-size:.85rem; }
footer { color:var(--muted); }
@media (max-width:991.98px) { .layout{grid-template-columns:1fr}.toc-panel{position:static;max-height:none}.toc-links{columns:2}.quick-grid{grid-template-columns:1fr 1fr} }
@media (max-width:575.98px) { .toc-links{columns:1}.quick-grid{grid-template-columns:1fr}.guide-section{border-radius:0;margin-left:-12px;margin-right:-12px}.guide-title{font-size:1.45rem} }
@media print { body{background:#fff}.guide-header,.toc-panel,.back-top,.no-print{display:none!important}.layout{display:block}.guide-section{border:0;break-inside:avoid;padding:12px 0} }
</style>
</head>
<body>
<div class="container wrap">
<div class="card shadow-sm">
<div class="card-body p-4 p-md-5">
<h1 class="mb-3">HMS Software Help Guide</h1>
<p class="text-muted">Version 1.0 | Last updated: 2026-04-02</p>
<body id="top">
<header class="guide-header">
<div class="page-shell px-3 px-lg-4 py-4">
<div class="d-flex align-items-center gap-3 mb-3">
<img class="brand-mark" src="assets/img/logo.png" alt="E-Atria logo">
<div><h1 class="guide-title">E-Atria HMS Help &amp; Operations Guide</h1><div class="version-label">Version 2.0 &nbsp;|&nbsp; Updated 12 August 2026</div></div>
</div>
<div class="search-wrap no-print"><i class="bi bi-search" aria-hidden="true"></i><label class="visually-hidden" for="guide-search">Search this guide</label><input id="guide-search" class="form-control" type="search" placeholder="Search modules, workflows, errors, or updates"></div>
</div>
</header>
<h2 class="h4 mt-4">Contents</h2>
<ul class="toc">
<li><a href="#getting-started">Getting Started</a></li>
<li><a href="#roles">User Roles and Access</a></li>
<li><a href="#daily-flow">Daily Operation Flow</a></li>
<li><a href="#billing">Billing and Cash Flow</a></li>
<li><a href="#diagnosis">Diagnosis and Reports</a></li>
<li><a href="#stock">Hospital Stock Module</a></li>
<li><a href="#admin">Admin and Configuration</a></li>
<li><a href="#security">Security and Compliance</a></li>
<li><a href="#backup">Backup and Maintenance</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
</ul>
<main class="page-shell px-3 px-lg-4 py-4">
<div id="no-results" class="no-results mb-3" role="status">No guide section matches your search.</div>
<div class="layout">
<aside class="toc-panel no-print" aria-label="Guide contents">
<div class="p-3 border-bottom"><h2 class="mb-0">Contents</h2></div>
<nav class="toc-links py-2">
<a href="#recent-updates">Recent Updates</a><a href="#getting-started">Getting Started</a><a href="#roles-access">Roles &amp; Access</a><a href="#patient-management">Patient Management</a><a href="#opd">OPD Workflow</a><a href="#ipd">IPD &amp; Nursing</a><a href="#ot-management">OT Management</a><a href="#diagnosis">Diagnosis &amp; Imaging</a><a href="#pharmacy">Pharmacy</a><a href="#billing">Billing &amp; Payments</a><a href="#finance">Finance</a><a href="#insurance">Insurance &amp; ORG Cases</a><a href="#abdm">ABDM &amp; ABHA</a><a href="#stock">Hospital Stock</a><a href="#reports">Reports &amp; Dashboards</a><a href="#admin">Admin &amp; System Operations</a><a href="#security">Security &amp; Compliance</a><a href="#backup">Backup &amp; Maintenance</a><a href="#troubleshooting">Troubleshooting</a>
</nav>
</aside>
<h2 id="getting-started" class="h4 mt-4">1. Getting Started</h2>
<ol>
<li>Login with your assigned user ID.</li>
<li>Use the left sidebar to open modules.</li>
<li>Use Dashboard for daily status.</li>
<li>Use My Profile to verify your name and login details.</li>
</ol>
<div class="guide-content">
<section id="recent-updates" class="guide-section searchable-section">
<h2><span class="section-number">01</span>Recent Updates</h2>
<p>These functions were added or strengthened after the previous help guide was published.</p>
<div class="update-item"><strong>OT Management Phase 1 <span class="status-chip ms-1">NEW</span></strong><div>Surgery requests, OT queue, scheduling, patient call status, pre-operative safety checks, WHO sign-in, operation progress, immutable event history, and signed post-operative assessment are now integrated with IPD Nursing.</div></div>
<div class="update-item"><strong>Department-specific pre-operative forms</strong><div>Specialty forms can appear according to the admitted patient's department. Ophthalmology pre-operative examination is available with completed-record edit reasons and audit history.</div></div>
<div class="update-item"><strong>IPD Nursing and discharge controls</strong><div>Dedicated nursing access, clinical workspace improvements, configurable discharge content, diagnosis masters, and more reliable HTML/PDF template rendering are available.</div></div>
<div class="update-item finance"><strong>Controlled Payment Edit</strong><div>Authorized finance users can correct payment mode, amount, and recorded user. Zero-value corrections are supported; negative values remain blocked.</div></div>
<div class="update-item finance"><strong>Pharmacy credit payout workflow</strong><div>Pharmacy can review the eligible medical-store credit pool, create payout requests, submit them to Finance, and monitor submitted, approved, partially paid, paid, or rejected status.</div></div>
<div class="update-item security"><strong>Stronger session and permission controls</strong><div>Single-active-session protection, clearer access-denied pages, streamlined permission management, and dedicated permissions for payment editing, nursing, discharge, and OT actions are active.</div></div>
<div class="update-item"><strong>Clinical drill-down dashboards</strong><div>Management dashboards support navigation from summary indicators to underlying operational and clinical records.</div></div>
<div class="update-item"><strong>Pharmacy usability fixes</strong><div>Credit payout routes, Medicine Return labels, and the Org. Credit Invoice empty-grid behavior have been corrected.</div></div>
<div class="note"><strong>Deployment note:</strong> New database-backed features require their migrations and permissions to be applied by the system administrator.</div>
</section>
<h2 id="roles" class="h4 mt-4">2. User Roles and Access</h2>
<p>Access is permission-based. Typical groups include Admin, Billing users, Diagnosis users, and Stock roles (Stock Manager, Department Head, Storekeeper). If you see "Access denied", contact administrator to assign correct permission.</p>
<section id="getting-started" class="guide-section searchable-section">
<h2><span class="section-number">02</span>Getting Started</h2>
<div class="quick-grid">
<div class="quick-item"><strong>1. Sign in</strong>Use only your assigned account. Shared accounts weaken clinical and financial audit records.</div>
<div class="quick-item"><strong>2. Select a module</strong>Use the sidebar for Patient, OPD, IPD, Diagnosis, Pharmacy, Finance, Stock, Reports, or Settings.</div>
<div class="quick-item"><strong>3. Search first</strong>Search by patient code, name, mobile, ABHA, invoice, IPD, or case code before creating a duplicate.</div>
<div class="quick-item"><strong>4. Verify context</strong>Confirm patient, encounter, department, payer, and date before saving clinical or billing data.</div>
<div class="quick-item"><strong>5. Complete the workflow</strong>Draft, verify, approve, print, or submit as required. A draft is not always final.</div>
<div class="quick-item"><strong>6. Sign out</strong>Use the profile menu, especially on shared workstations.</div>
</div>
<h3>Common screen behavior</h3>
<ul><li>Most pages open inside the main workspace without a full browser refresh.</li><li>Filters affect the current list. Clear them before concluding a record is missing.</li><li>PDF/print buttons may open a new tab; allow pop-ups for the HMS domain.</li><li>Red actions may cancel, delete, refund, reject, or finalize and require extra care.</li></ul>
<div class="warning"><strong>Before finalization:</strong> Recheck identifiers, dates, amounts, medicine batches, clinical findings, and print template. Final records may require permission and an edit reason to change.</div>
</section>
<h2 id="daily-flow" class="h4 mt-4">3. Daily Operation Flow</h2>
<ol>
<li>Patient registration and OPD/IPD workflow.</li>
<li>Charge posting and invoice generation.</li>
<li>Payment collection and receipt.</li>
<li>Lab/radiology processing and report verification.</li>
<li>Inventory issue/receipt for consumables and medicines.</li>
</ol>
<section id="roles-access" class="guide-section searchable-section">
<h2><span class="section-number">03</span>User Roles &amp; Access</h2>
<p>Menus and actions are permission-based. Two users may open the same patient but see different buttons.</p>
<div class="table-responsive"><table class="table table-bordered table-guide"><thead><tr><th>Role area</th><th>Typical responsibility</th><th>Restricted actions</th></tr></thead><tbody>
<tr><td>Registration</td><td>Patient search, registration, appointment, token, admission support</td><td>Clinical verification and financial correction</td></tr>
<tr><td>Doctor / Clinical</td><td>Consultation, diagnosis, prescription, orders, discharge</td><td>Finance approval and stock administration</td></tr>
<tr><td>Nursing / OT</td><td>Nursing workspace, bedside care, safety checks, OT status, handover</td><td>Scheduling or signed assessment unless assigned</td></tr>
<tr><td>Diagnosis</td><td>Sample workflow, findings, imaging, verification, report printing</td><td>Verified-report edits without reason/permission</td></tr>
<tr><td>Pharmacy</td><td>Dispensing, returns, inventory, purchasing, supplier and credit workflows</td><td>Finance payout approval</td></tr>
<tr><td>Billing / Finance</td><td>Invoices, collections, refunds, reconciliation, payouts</td><td>Payment edits without <code>finance.payment.edit</code></td></tr>
<tr><td>Administrator</td><td>Users, permissions, masters, templates, integrations, operations</td><td>Infrastructure actions still require confirmation</td></tr>
</tbody></table></div>
<p>For <strong>Access denied</strong>, note the module and action and ask an administrator to review the role. Never use another person's login.</p>
</section>
<h2 id="billing" class="h4 mt-4">4. Billing and Cash Flow</h2>
<ul>
<li>Use Billing -> Patient List for patient-level work.</li>
<li>Use OPD Invoice and Charges Invoice to post/collect payments.</li>
<li>Use IPD Billing for admitted patients, package and discharge flow.</li>
<li>Use Payment Request and Refund Request for controlled approvals.</li>
<li>Use report screens for daily reconciliation.</li>
</ul>
<section id="patient-management" class="guide-section searchable-section">
<h2><span class="section-number">04</span>Patient Management</h2>
<ol class="workflow"><li><strong>Search first.</strong> Use UHID/patient code, name, phone, Aadhaar reference, old UHID, or ABHA.</li><li><strong>Review matches.</strong> Compare DOB, gender, guardian, address, and contact number.</li><li><strong>Create or update.</strong> Enter demographics, identity documents, photo, guardian/family data, and attachments.</li><li><strong>Open the profile.</strong> Use it for OPD, IPD, billing, diagnosis, documents, and health-record history.</li><li><strong>Link ABHA.</strong> Verify that the ABHA profile belongs to the same patient first.</li></ol>
<div class="safety"><strong>Duplicate prevention:</strong> Try alternate spelling, phone, old code, and family details before creating a new patient.</div>
</section>
<h2 id="diagnosis" class="h4 mt-4">5. Diagnosis and Reports</h2>
<ul>
<li>Diagnosis module supports pathology and imaging workflows.</li>
<li>Draft findings before final verification.</li>
<li>Use print templates for standardized report output.</li>
<li>Use audit trails and verification states for NABH-style controls.</li>
</ul>
<section id="opd" class="guide-section searchable-section">
<h2><span class="section-number">05</span>OPD Workflow</h2>
<h3>Appointment and check-in</h3>
<ol class="workflow"><li>Select patient, doctor, date/slot, or walk-in.</li><li>Confirm department, referral, consultation type, and organization/insurance case.</li><li>Generate the visit/token. Scan &amp; Share patients may arrive through the facility QR.</li><li>Collect or confirm consultation payment according to policy.</li></ol>
<h3>Clinical consultation</h3>
<ul><li>Record vitals, complaints, history, examination, allergies/ADR, medications, diagnosis, advice, and follow-up.</li><li>Add medicines with dosage, frequency, route, duration, and instructions.</li><li>Order pathology or imaging investigations and review previous visits.</li><li>Generate referral letters, prescription PDFs, and FHIR e-Prescription records when required.</li></ul>
<div class="note"><strong>AI assistance:</strong> AI can draft complaints, prescriptions, or extract report values where configured. A clinician must review all generated content.</div>
</section>
<h2 id="stock" class="h4 mt-4">6. Hospital Stock Module</h2>
<ol>
<li>Item Masters: category, item, supplier setup.</li>
<li>Indent & Issue: departments raise request, approver approves, storekeeper issues.</li>
<li>Purchase: create PO and receive stock.</li>
<li>Dashboard: expiry risk, short stock, new requests, daily-use status.</li>
<li>Reports: consumption, monthly issue, near-expiry, low/reorder alerts.</li>
</ol>
<p>Key item fields: purchase unit, issue unit, issue-per-purchase ratio, min/reorder levels, expiry date, and store location.</p>
<section id="ipd" class="guide-section searchable-section">
<h2><span class="section-number">06</span>IPD Admission, Nursing &amp; Discharge</h2>
<h3>Admission and beds</h3>
<ol class="workflow"><li>Create admission with department, doctor, date/time, and reason.</li><li>Assign an available Department → Ward → Category → Bed.</li><li>Record HPI/admission history and treating doctors.</li><li>Use bed transfer instead of overwriting the bed to preserve history.</li></ol>
<h3>Nursing</h3>
<ul><li>Document shift notes and observations against the correct admission.</li><li>Post bedside consumables, nursing items, and doctor visits promptly.</li><li>Scan paper forms and use Surgery/OT for operative patients.</li><li>Check the patient/IPD banner before every entry.</li></ul>
<h3>Discharge</h3>
<ul><li>Complete diagnosis, course, procedures, condition, medication, advice, diet, and follow-up.</li><li>Select and preview the approved discharge template.</li><li>Reconcile pending charges, returns, package adjustments, and balance.</li><li>Verify PDF page breaks, placeholders, dates, letterhead mode, and signatures.</li><li>Generate/share the ABDM discharge summary when requirements are met.</li></ul>
</section>
<h2 id="admin" class="h4 mt-4">7. Admin and Configuration</h2>
<ul>
<li>User management, password reset, and permission mapping.</li>
<li>Doctor/refer/master settings.</li>
<li>Template management for reports and print formats.</li>
<li>Bed management and hospital stock settings.</li>
</ul>
<section id="ot-management" class="guide-section searchable-section">
<h2><span class="section-number">07</span>OT Management</h2>
<p>Available from IPD Nursing and OT Surgery Queue. Request, scheduling, examination, status, and post-operative actions have separate permissions.</p>
<ol class="workflow"><li><strong>Create request.</strong> Enter procedure, surgeon, priority, indication, and requested schedule.</li><li><strong>Complete pre-op examination.</strong> Use the department-specific form; revisions to completed forms require a reason.</li><li><strong>Schedule.</strong> Authorized OT staff assign date/time and coordination details.</li><li><strong>Call patient.</strong> Update the case when preparation begins.</li><li><strong>Complete safety gates.</strong> Confirm pre-op checks and WHO sign-in before starting.</li><li><strong>Record progress.</strong> Move through requested, scheduled, called, in progress, and completed; give reasons for cancellation or major changes.</li><li><strong>Sign post-op assessment.</strong> Record observations, outcome, instructions, and handover.</li></ol>
<div class="safety"><strong>Clinical integrity:</strong> OT actions create event history and use version checks. Refresh if another user changed the case.</div>
</section>
<h2 id="security" class="h4 mt-4">8. Security and Compliance</h2>
<ul>
<li>Use personal login only; do not share credentials.</li>
<li>Keep audit remarks clear for financial and clinical edits.</li>
<li>Follow organization policy for health data privacy.</li>
</ul>
<section id="diagnosis" class="guide-section searchable-section">
<h2><span class="section-number">08</span>Diagnosis, Laboratory &amp; Imaging</h2>
<p>Supported workflows include Pathology, Biopsy, X-Ray, Ultrasound, MRI, CT, and Echo.</p>
<h3>Laboratory</h3><ol class="workflow"><li>Receive the OPD, IPD, or walk-in request and confirm patient/tests.</li><li>Record sample collection and lab number.</li><li>Enter values; review units, reference ranges, flags, and comments.</li><li>Save draft, then verify/sign according to policy.</li><li>Print individual or compiled reports using the correct template.</li></ol>
<h3>Imaging</h3><ul><li>Upload images, scans, or DICOM studies against the report.</li><li>Use the viewer/gallery and draft findings/impression.</li><li>Complete doctor verification; AI suggestions require radiologist review.</li></ul>
<div class="warning"><strong>Verified reports:</strong> Authorized edits require a meaningful reason retained in the audit trail.</div>
</section>
<h2 id="backup" class="h4 mt-4">9. Backup and Maintenance</h2>
<ul>
<li>Take scheduled database backups.</li>
<li>Archive monthly reports.</li>
<li>Apply migrations in controlled deployment steps.</li>
<li>Validate writable folder permissions after server changes.</li>
</ul>
<section id="pharmacy" class="guide-section searchable-section">
<h2><span class="section-number">09</span>Pharmacy / Medical Store</h2>
<h3>Dispensing</h3><ul><li>Create counter, OPD, IPD, or organization-linked invoices in the correct context.</li><li>Confirm medicine, batch, expiry, stock, rate, tax, discount, and quantity.</li><li>Use <strong>Medicine Return</strong> or <strong>Medicine Return 2</strong> for the applicable return flow.</li><li>Use Org. Credit Invoice for corporate/insurance-linked medicine billing.</li><li>Finalize an IPD medicine account only after invoices, returns, discounts, and payments reconcile.</li></ul>
<h3>Inventory and purchase</h3><ul><li>Maintain drug, generic, formulation, category, company, supplier, batch, tax, and rate masters.</li><li>Create purchase orders, receive invoices/batches, and process purchase returns.</li><li>Monitor expiry, low stock, movement, and supplier ledger reports.</li></ul>
<h3>Credit payout request</h3><ol class="workflow"><li>Open Pharmacy → Credit Payout Request.</li><li>Review/filter the eligible pool.</li><li>Select valid lines, confirm amounts, add remarks, and submit.</li><li>Monitor status while Finance handles approval and payment.</li></ol>
</section>
<h2 id="troubleshooting" class="h4 mt-4">10. Troubleshooting</h2>
<ul>
<li>Access denied: verify group permissions.</li>
<li>Form not loading: check session status and route URL.</li>
<li>Wrong stock: verify conversion fields and ledger actions.</li>
<li>Print mismatch: verify template and print setting configuration.</li>
</ul>
<section id="billing" class="guide-section searchable-section">
<h2><span class="section-number">10</span>Billing, Invoices &amp; Payments</h2>
<ul><li>Bill OPD consultation, procedures, diagnostics, IPD charges, packages, and pharmacy links.</li><li>Apply discounts only with authority and supporting remarks.</li><li>Use payment/refund request workflows instead of informal adjustments.</li><li>Confirm organization/insurance case before posting payer charges.</li><li>Print/export daily collection and balance reports for reconciliation.</li></ul>
<h3>Payment Edit</h3><p>Authorized users can correct payment mode, amount, or recorded user. Amount may be <strong>0.00</strong> for a valid correction but cannot be negative.</p>
<div class="safety"><strong>Do not use Payment Edit to hide a refund or cancellation.</strong> Use the approved reversal workflow and retain the reason.</div>
</section>
<div class="mt-4 text-muted small">For legal terms, see <a href="software-use-license.html">Software Use License</a>.</div>
<section id="finance" class="guide-section searchable-section">
<h2><span class="section-number">11</span>Finance &amp; Accounting</h2>
<div class="quick-grid"><div class="quick-item"><strong>Cash Book</strong>Daily department collections and opening/closing position.</div><div class="quick-item"><strong>Bank Deposits</strong>Deposit references, dates, amounts, and status.</div><div class="quick-item"><strong>Reconciliation</strong>Match statements to system transactions.</div><div class="quick-item"><strong>POS Settlement</strong>Track terminal settlements, charges, and differences.</div><div class="quick-item"><strong>Doctor Payouts</strong>Agreements, commission, approval, and disbursement.</div><div class="quick-item"><strong>Vendor Control</strong>PO, receipt, invoice, payment, and balance.</div></div>
<p class="mt-3">Review pharmacy payout line evidence, approve/reject according to policy, record payments, and retain remarks for each status change.</p>
</section>
<section id="insurance" class="guide-section searchable-section">
<h2><span class="section-number">12</span>Insurance &amp; Organization Cases</h2>
<ol class="workflow"><li>Create/select the case and verify patient, payer, policy, approval, and validity.</li><li>Link OPD, IPD, diagnosis, procedures, and pharmacy invoices.</li><li>Apply approved rates/packages, including Ayushman mappings.</li><li>Use contingent billing when liability depends on case outcome.</li><li>Prepare claim sheets and supporting documents.</li><li>Track submission, query, approval, deduction, payment, and balance.</li></ol>
<div class="warning"><strong>Case selection:</strong> Select a valid system case. Empty or placeholder identifiers are not payer cases.</div>
</section>
<section id="abdm" class="guide-section searchable-section">
<h2><span class="section-number">13</span>ABDM, ABHA &amp; Health Records</h2>
<h3>ABHA identity</h3><ul><li>Create ABHA through supported Aadhaar/mobile OTP flows.</li><li>Verify/fetch profile before linking to the HMS patient.</li><li>Display/download ABHA card and use facility QR for Scan &amp; Share.</li></ul>
<h3>Care context and sharing</h3><ol class="workflow"><li>Confirm verified ABHA and correct visit/admission.</li><li>Discover/link the care context.</li><li>Select e-Prescription, Discharge Summary, Diagnostic Report, Immunization, Wellness, Health Document, or supported invoice.</li><li>Preview FHIR R4 data: identity, dates, practitioner, coding, and attachments.</li><li>Share and monitor gateway/bridge status.</li></ol>
<h3>Consent and HIU</h3><ul><li>Request consent only for a legitimate purpose and date range.</li><li>Track requested, granted, denied, expired, and revoked status.</li><li>Fetch health information only after grant; data may contain FHIR documents and attachments.</li></ul>
<div class="safety"><strong>Privacy:</strong> ABDM access is purpose-limited and consent-driven. Use data only for authorized care.</div>
</section>
<section id="stock" class="guide-section searchable-section">
<h2><span class="section-number">14</span>Hospital Stock</h2>
<ol class="workflow"><li>Configure category, item, units, conversion, location, min/reorder, and expiry control.</li><li>Departments raise indents with quantity and purpose.</li><li>Authorized users approve, reject, or revise.</li><li>Storekeepers issue approved quantities and batches.</li><li>Create purchase orders and goods receipts.</li><li>Review consumption, issues, expiry, low-stock, reorder, and daily-use reports.</li></ol>
<div class="note">Purchase and issue units may differ. Wrong conversion causes incorrect stock and reorder quantities.</div>
</section>
<section id="reports" class="guide-section searchable-section">
<h2><span class="section-number">15</span>Reports &amp; Dashboards</h2>
<div class="table-responsive"><table class="table table-bordered table-guide"><thead><tr><th>Area</th><th>Examples</th><th>Review focus</th></tr></thead><tbody><tr><td>Clinical</td><td>OPD, diagnosis workload/TAT, discharge, OT queue</td><td>Completeness and delays</td></tr><tr><td>Billing</td><td>Collections, balances, refunds, credit invoices</td><td>Mode/user totals and exceptions</td></tr><tr><td>Finance</td><td>Cash book, bank audit, POS, doctor payout</td><td>Unmatched/unapproved items</td></tr><tr><td>Pharmacy</td><td>Stock, expiry, movement, sales, returns, supplier ledger</td><td>Negative stock and expiry risk</td></tr><tr><td>Insurance</td><td>Organization dues, claims, deductions</td><td>Aging and documents</td></tr><tr><td>Audit</td><td>NABH edits, billing logs, user actions</td><td>Who changed what, when, and why</td></tr></tbody></table></div>
<p>Use drill-down links from totals to source records. Retain the same dates and filters while reconciling.</p>
</section>
<section id="admin" class="guide-section searchable-section">
<h2><span class="section-number">16</span>Administration &amp; System Operations</h2>
<h3>Application administration</h3><ul><li>Manage users, groups, permissions, passwords, and active access.</li><li>Maintain doctor, referral, insurance, bank/payment, charge, diagnosis, medicine, and stock masters.</li><li>Configure OPD, diagnosis, and discharge print templates.</li><li>Configure AI, HealthPlix, ABDM HFR/gateway/bridge, and report-doctor mappings.</li></ul>
<h3>System Operations</h3><ul><li>Review OS/uptime, CPU, memory, disk, RAID, database, web, PHP-FPM, and SSH health.</li><li>Use Update HMS only during an approved window and review its log.</li><li>Restart services only when needed. Reboot/shutdown require confirmation and coordination.</li></ul>
<div class="safety"><strong>Production safety:</strong> Confirm backup and rollback readiness before migrations, updates, restarts, or environment changes.</div>
</section>
<section id="security" class="guide-section searchable-section">
<h2><span class="section-number">17</span>Security, Audit &amp; Compliance</h2>
<ul><li>Never disclose passwords, OTPs, API keys, or tokens.</li><li>Single-active-session protection may end an older login.</li><li>Grant the least permission required and review access after role changes.</li><li>Clinical verification, payment edits, refunds, cancellations, OT changes, and completed-form revisions require audit evidence.</li><li>Verify SNOMED CT/ICD-10 codes against documented clinical meaning.</li><li>Follow NABH, ABDM/FHIR, NHCX, privacy, retention, and hospital policies.</li></ul>
</section>
<section id="backup" class="guide-section searchable-section">
<h2><span class="section-number">18</span>Backup &amp; Maintenance</h2>
<ul><li>Schedule database and uploaded-document backups and test restoration.</li><li>Retain an off-server/off-site copy according to policy.</li><li>Apply code updates and migrations in a controlled sequence.</li><li>After deployment test login, dashboard, patient search, billing, PDF, uploads, jobs, and integrations.</li><li>Monitor storage, database growth, logs, failed queues, ABDM tasks, and large attachments.</li><li>Keep production error display disabled; use protected logs.</li></ul>
</section>
<section id="troubleshooting" class="guide-section searchable-section">
<h2><span class="section-number">19</span>Troubleshooting</h2>
<div class="table-responsive"><table class="table table-bordered table-guide"><thead><tr><th>Problem</th><th>Check</th><th>Action</th></tr></thead><tbody>
<tr><td>Access denied</td><td>Role, permission, module</td><td>Ask Admin; do not borrow credentials.</td></tr>
<tr><td>Page/form does not load</td><td>Session, network, URL/status, console</td><td>Refresh dashboard, reopen, report exact URL/status.</td></tr>
<tr><td>Save does nothing</td><td>Required/invalid number or date fields</td><td>Correct highlighted fields; report console/network details.</td></tr>
<tr><td>DataTables warning</td><td>Empty table, screen URL, table ID</td><td>Report URL and table ID.</td></tr>
<tr><td>Unexpected token &lt;</td><td>HTML server error returned instead of JSON</td><td>Capture endpoint/status; Admin checks logs.</td></tr>
<tr><td>PDF mismatch</td><td>Template, paper mode, placeholders, pasted HTML</td><td>Preview intended template and report record/template.</td></tr>
<tr><td>Wrong stock</td><td>Batch, conversion, return, issue, receipt, transfer</td><td>Reconcile ledger before adjustment.</td></tr>
<tr><td>Payment mismatch</td><td>Invoice, mode, user, amount, refund/void</td><td>Use approved correction and document reason.</td></tr>
<tr><td>ABDM pending/failed</td><td>ABHA, consent, HFR/token, bridge/task log</td><td>Identify failure; preserve request ID.</td></tr>
<tr><td>OT changed elsewhere</td><td>Stale version warning</td><td>Refresh, review history, re-enter update.</td></tr>
</tbody></table></div>
<h3>Include in a support request</h3><ul><li>Exact URL and module</li><li>Date/time and user role, never password</li><li>Patient/IPD/invoice/case code through approved channels</li><li>Steps, expected result, and actual result</li><li>Screenshot and console/network status</li></ul>
</section>
<footer class="px-2 py-3 small"><div>For legal terms, see <a href="software-use-license.html">Software Use License</a>.</div><div>Hospital policy and permissions control which described workflows each user may perform.</div></footer>
</div>
</div>
</div>
</main>
<script>
(function () {
var input=document.getElementById('guide-search');
var sections=Array.prototype.slice.call(document.querySelectorAll('.searchable-section'));
var emptyState=document.getElementById('no-results');
input.addEventListener('input',function(){
var query=input.value.trim().toLowerCase();
var visibleCount=0;
sections.forEach(function(section){var matches=query===''||section.textContent.toLowerCase().indexOf(query)!==-1;section.classList.toggle('search-hidden',!matches);if(matches){visibleCount++;}});
emptyState.style.display=visibleCount===0?'block':'none';
});
})();
</script>
</body>
</html>