feat(report): add IPD surgery export report
Add a permissioned IPD surgery report combining discharge surgery, patient, diagnosis, OT, and matched billing details.
This commit is contained in:
parent
83fce47ee1
commit
225721ae02
|
|
@ -150,6 +150,7 @@ class AuthGroups extends ShieldAuthGroups
|
|||
'reports.billing_operations.view' => 'Can view billing operations reports',
|
||||
'reports.document_issue.view' => 'Can view document issue reports',
|
||||
'reports.ipd_census.view' => 'Can view IPD census and discharge reports',
|
||||
'reports.ipd_surgery.view' => 'Can view IPD surgery reports',
|
||||
'finance.workflow.view' => 'Can access Accounts and Finance workflow dashboard',
|
||||
'finance.access' => 'Can access finance procurement and payable workflows',
|
||||
'finance.cash.billing.submit' => 'Can create billing cash entries and submit cash statements',
|
||||
|
|
@ -255,6 +256,7 @@ class AuthGroups extends ShieldAuthGroups
|
|||
'reports.billing_operations.view',
|
||||
'reports.document_issue.view',
|
||||
'reports.ipd_census.view',
|
||||
'reports.ipd_surgery.view',
|
||||
'finance.*',
|
||||
'diagnosis.*',
|
||||
'doctor_work.*',
|
||||
|
|
@ -285,6 +287,7 @@ class AuthGroups extends ShieldAuthGroups
|
|||
'reports.billing_operations.view',
|
||||
'reports.document_issue.view',
|
||||
'reports.ipd_census.view',
|
||||
'reports.ipd_surgery.view',
|
||||
'finance.*',
|
||||
'diagnosis.*',
|
||||
'doctor_work.*',
|
||||
|
|
@ -314,6 +317,7 @@ class AuthGroups extends ShieldAuthGroups
|
|||
'reports.billing_operations.view',
|
||||
'reports.document_issue.view',
|
||||
'reports.ipd_census.view',
|
||||
'reports.ipd_surgery.view',
|
||||
'finance.*',
|
||||
'diagnosis.*',
|
||||
'doctor_work.*',
|
||||
|
|
|
|||
|
|
@ -1063,6 +1063,11 @@ $routes->get('Report/ipd_census_report', 'Report::ipd_census_report', ['filter'
|
|||
$routes->get('Report/ipd_census_data/(:segment)/(:segment)/(:segment)/(:segment)', 'Report::ipd_census_data/$1/$2/$3/$4', ['filter' => $reportsIpdCensusFilter]);
|
||||
$routes->get('Report/ipd_census_data/(:segment)/(:segment)/(:segment)/(:segment)/(:num)', 'Report::ipd_census_data/$1/$2/$3/$4/$5', ['filter' => $reportsIpdCensusFilter]);
|
||||
|
||||
$reportsIpdSurgeryFilter = 'permission:reports.ipd_surgery.view';
|
||||
$routes->get('Report/ipd_surgery_report', 'Report::ipd_surgery_report', ['filter' => $reportsIpdSurgeryFilter]);
|
||||
$routes->get('Report/ipd_surgery_data/(:segment)/(:segment)/(:segment)', 'Report::ipd_surgery_data/$1/$2/$3', ['filter' => $reportsIpdSurgeryFilter]);
|
||||
$routes->get('Report/ipd_surgery_data/(:segment)/(:segment)/(:segment)/(:num)', 'Report::ipd_surgery_data/$1/$2/$3/$4', ['filter' => $reportsIpdSurgeryFilter]);
|
||||
|
||||
$routes->get('Report/billing_operations_report', 'Report::billing_operations_report', ['filter' => 'permission:reports.billing_operations.view']);
|
||||
$routes->get('Report/billing_operations_report_data/(:segment)/(:segment)', 'Report::billing_operations_report_data/$1/$2', ['filter' => 'permission:reports.billing_operations.view']);
|
||||
$routes->get('Report/billing_operations_report_data/(:segment)/(:segment)/(:num)', 'Report::billing_operations_report_data/$1/$2/$3', ['filter' => 'permission:reports.billing_operations.view']);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class Report extends BaseController
|
|||
'operations' => 'reports.billing_operations.view',
|
||||
'clinical' => 'diagnosis.report.view',
|
||||
'ipd' => 'reports.ipd_census.view',
|
||||
'surgery' => 'reports.ipd_surgery.view',
|
||||
'insurance' => 'reports.insurance_credit.view',
|
||||
'quality' => 'reports.nabh_audit.view',
|
||||
'documents' => 'reports.document_issue.view',
|
||||
|
|
@ -174,6 +175,110 @@ class Report extends BaseController
|
|||
return $this->response->setBody($content);
|
||||
}
|
||||
|
||||
public function ipd_surgery_report()
|
||||
{
|
||||
if ($response = $this->requireReportPermission(self::PANEL_PERMISSIONS['surgery'])) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return view('report/ipd_surgery_report', [
|
||||
'doctors' => $this->db->table('doctor_master')->select('id, p_fname')->where('active', 1)->orderBy('p_fname', 'ASC')->get()->getResult(),
|
||||
'departments' => $this->db->table('hc_department')->select('iId, vName')->orderBy('vName', 'ASC')->get()->getResult(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function ipd_surgery_data(
|
||||
string $dateRange,
|
||||
string $doctorId = '0',
|
||||
string $departmentId = '0',
|
||||
int $output = 0
|
||||
) {
|
||||
if ($response = $this->requireReportPermission(self::PANEL_PERMISSIONS['surgery'])) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
[$minRange, $maxRange] = $this->parseDateRangeDateOnly($dateRange);
|
||||
$diagnoses = $this->db->table('ipd_discharge_diagnosis')
|
||||
->select("ipd_id, GROUP_CONCAT(DISTINCT NULLIF(TRIM(COALESCE(snomed_term, comp_report, comp_remark)), '') ORDER BY id SEPARATOR '; ') AS final_diagnosis", false)
|
||||
->groupBy('ipd_id')
|
||||
->getCompiledSelect();
|
||||
$billedProcedures = $this->db->table('invoice_master im')
|
||||
->select('CONVERT(LOWER(TRIM(ii.item_name)) USING utf8mb4) COLLATE utf8mb4_general_ci AS billed_name', false)
|
||||
->select('SUM(COALESCE(ii.item_amount, 0)) AS actual_surgery_cost', false)
|
||||
->join('invoice_item ii', 'ii.inv_master_id = im.id', 'inner')
|
||||
->where('im.ipd_id >', 0)
|
||||
->where('im.invoice_status', 1)
|
||||
->groupBy('im.ipd_id, CONVERT(LOWER(TRIM(ii.item_name)) USING utf8mb4) COLLATE utf8mb4_general_ci')
|
||||
->getCompiledSelect();
|
||||
|
||||
$builder = $this->db->table('ipd_master i')
|
||||
->select('i.id AS ipd_id, i.ipd_code, i.register_date, i.reg_time, i.discharge_date, i.discharge_time')
|
||||
->select('p.p_code AS mr_no, p.referby AS camp_code, p.p_fname AS patient_name, p.age, p.gender')
|
||||
->select("CONCAT_WS(', ', NULLIF(TRIM(COALESCE(p.add1, i.add1)), ''), NULLIF(TRIM(COALESCE(p.add2, i.add2)), ''), NULLIF(TRIM(COALESCE(p.city, i.city)), ''), NULLIF(TRIM(COALESCE(p.district, '')), ''), NULLIF(TRIM(COALESCE(p.state, i.state)), ''), NULLIF(TRIM(p.zip), '')) AS address", false)
|
||||
->select("CONCAT_WS(', ', NULLIF(IF(COALESCE(p.is_hypertesion, 0) = 1, 'Hypertension', ''), ''), NULLIF(IF(COALESCE(p.is_niddm, 0) = 1, 'Diabetes', ''), ''), NULLIF(IF(COALESCE(p.is_smoking, 0) = 1, 'Smoking', ''), ''), NULLIF(IF(COALESCE(p.is_alcohol, 0) = 1, 'Alcohol use', ''), ''), NULLIF(TRIM(p.Others), '')) AS systemic_history", false)
|
||||
->select("COALESCE(NULLIF(sds.surgery_date, '0000-00-00'), NULLIF(i.surgery_date, '0000-00-00')) AS surgery_date", false)
|
||||
->select("COALESCE(NULLIF(sds.surgery_name, ''), NULLIF(i.surgery_name, ''), NULLIF(smaster.term_name, '')) AS surgery_name", false)
|
||||
->select('smaster.term_code AS surgery_code')
|
||||
->select('sds.surgery_remark')
|
||||
->select("COALESCE(NULLIF(dept.vName, ''), 'Unassigned') AS specialty", false)
|
||||
->select("COALESCE(NULLIF(surgeon.p_fname, ''), NULLIF(i.r_doc_name, ''), 'Unassigned') AS doctor_name", false)
|
||||
->select('diagnosis.final_diagnosis')
|
||||
->select('sm.surg_amount AS estimated_surgery_cost, billed.actual_surgery_cost')
|
||||
->join('patient_master p', 'p.id = i.p_id', 'left')
|
||||
->join('ipd_discharge_surgery sds', 'sds.ipd_id = i.id', 'left')
|
||||
->join('ipd_discharge_surgery_master smaster', 'smaster.id = sds.surgery_id', 'left')
|
||||
->join('hc_surgery sm', 'sm.id = sds.surgery_id', 'left')
|
||||
->join('hc_department dept', 'dept.iId = i.dept_id', 'left')
|
||||
->join('doctor_master surgeon', 'surgeon.id = sds.surgery_by_doc_id', 'left')
|
||||
->join("({$diagnoses}) diagnosis", 'diagnosis.ipd_id = i.id', 'left', false)
|
||||
->join("({$billedProcedures}) billed", "billed.ipd_id = i.id AND billed.billed_name = CONVERT(LOWER(TRIM(COALESCE(sds.surgery_name, i.surgery_name, ''))) USING utf8mb4) COLLATE utf8mb4_general_ci", 'left', false)
|
||||
->where("COALESCE(NULLIF(sds.surgery_date, '0000-00-00'), NULLIF(i.surgery_date, '0000-00-00')) BETWEEN '{$minRange}' AND '{$maxRange}'", null, false)
|
||||
->where("(sds.id IS NOT NULL OR COALESCE(i.issurgery, 0) = 1)", null, false);
|
||||
|
||||
if ((int) $doctorId > 0) {
|
||||
$builder->groupStart()->where('sds.surgery_by_doc_id', (int) $doctorId)->orWhere('i.r_doc_id', (int) $doctorId)->groupEnd();
|
||||
}
|
||||
if ((int) $departmentId > 0) {
|
||||
$builder->where('i.dept_id', (int) $departmentId);
|
||||
}
|
||||
|
||||
if ($this->db->tableExists('ipd_ot_cases')) {
|
||||
$otCases = $this->db->table('ipd_ot_cases')
|
||||
->select('ipd_id')
|
||||
->select('MAX(scheduled_start_at) AS scheduled_start_at, MAX(actual_start_at) AS actual_start_at, MAX(actual_end_at) AS actual_end_at', false)
|
||||
->select("GROUP_CONCAT(DISTINCT NULLIF(anesthetist_name_snapshot, '') SEPARATOR '; ') AS anesthetist_name", false)
|
||||
->select("GROUP_CONCAT(DISTINCT NULLIF(procedure_side, '') SEPARATOR '; ') AS procedure_side", false)
|
||||
->groupBy('ipd_id')
|
||||
->getCompiledSelect();
|
||||
$builder->select('ot.scheduled_start_at, ot.actual_start_at, ot.actual_end_at, ot.anesthetist_name, ot.procedure_side')
|
||||
->join("({$otCases}) ot", 'ot.ipd_id = i.id', 'left', false);
|
||||
} else {
|
||||
$builder->select("NULL AS scheduled_start_at, NULL AS actual_start_at, NULL AS actual_end_at, '' AS anesthetist_name, '' AS procedure_side", false);
|
||||
}
|
||||
|
||||
$rows = $builder->orderBy('surgery_date', 'ASC')->orderBy('i.id', 'ASC')->get()->getResultArray();
|
||||
foreach ($rows as &$row) {
|
||||
$start = ! empty($row['actual_start_at']) ? strtotime((string) $row['actual_start_at']) : false;
|
||||
$end = ! empty($row['actual_end_at']) ? strtotime((string) $row['actual_end_at']) : false;
|
||||
$row['actual_duration_minutes'] = $start !== false && $end !== false && $end >= $start
|
||||
? (int) round(($end - $start) / 60)
|
||||
: null;
|
||||
}
|
||||
unset($row);
|
||||
|
||||
$content = view('report/ipd_surgery_report_table', [
|
||||
'rows' => $rows,
|
||||
'min_range' => $minRange,
|
||||
'max_range' => $maxRange,
|
||||
]);
|
||||
if ($output === 1) {
|
||||
ExportExcel($content, 'IPD_Surgery_Report_' . date('YmdHis'));
|
||||
return $this->response->setBody('');
|
||||
}
|
||||
|
||||
return $this->response->setBody($content);
|
||||
}
|
||||
|
||||
public function report_opd_total()
|
||||
{
|
||||
$doctors = $this->db->table('doctor_master')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use App\Libraries\RoleRegistry;
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddIpdSurgeryReportPermission extends Migration
|
||||
{
|
||||
private const PERMISSION = 'reports.ipd_surgery.view';
|
||||
|
||||
public function up()
|
||||
{
|
||||
if (! $this->tableExists('auth_roles') || ! $this->tableExists('auth_role_permissions')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
foreach (['superadmin', 'admin', 'developer'] as $alias) {
|
||||
$role = $this->db->table('auth_roles')->select('id')->where('alias', $alias)->get(1)->getRowArray();
|
||||
if ($role === null) {
|
||||
continue;
|
||||
}
|
||||
$exists = $this->db->table('auth_role_permissions')->where('role_id', (int) $role['id'])->where('permission', self::PERMISSION)->countAllResults();
|
||||
if ($exists === 0) {
|
||||
$this->db->table('auth_role_permissions')->insert(['role_id' => (int) $role['id'], 'permission' => self::PERMISSION, 'created_at' => $now]);
|
||||
}
|
||||
}
|
||||
|
||||
(new RoleRegistry($this->db))->publish();
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if ($this->tableExists('auth_role_permissions')) {
|
||||
$this->db->table('auth_role_permissions')->where('permission', self::PERMISSION)->delete();
|
||||
}
|
||||
if ($this->tableExists('auth_roles')) {
|
||||
(new RoleRegistry($this->db))->publish();
|
||||
}
|
||||
}
|
||||
|
||||
private function tableExists(string $table): bool
|
||||
{
|
||||
return $this->db->query('SHOW TABLES LIKE ' . $this->db->escape($table))->getRowArray() !== null;
|
||||
}
|
||||
}
|
||||
|
|
@ -46,8 +46,8 @@ $can = static fn (string $panel): bool => (bool) ($panels[$panel] ?? false);
|
|||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($can('ipd')) : ?>
|
||||
<div class="col-xl-3 col-md-6"><div class="card report-card h-100"><div class="card-body"><div class="report-card-head"><span class="report-icon report-icon-green"><i class="bi bi-hospital"></i></span><h5 class="report-card-title mb-0">IPD Operations</h5></div><ul class="report-links"><li><a href="javascript:load_form('<?= base_url('Report/ipd_census_report') ?>','IPD Census & Discharge Report');"><i class="bi bi-arrow-right-short"></i> IPD Census & Discharge</a></li></ul></div></div></div>
|
||||
<?php if ($can('ipd') || $can('surgery')) : ?>
|
||||
<div class="col-xl-3 col-md-6"><div class="card report-card h-100"><div class="card-body"><div class="report-card-head"><span class="report-icon report-icon-green"><i class="bi bi-hospital"></i></span><h5 class="report-card-title mb-0">IPD Operations</h5></div><ul class="report-links"><?php if ($can('ipd')) : ?><li><a href="javascript:load_form('<?= base_url('Report/ipd_census_report') ?>','IPD Census & Discharge Report');"><i class="bi bi-arrow-right-short"></i> IPD Census & Discharge</a></li><?php endif; ?><?php if ($can('surgery')) : ?><li><a href="javascript:load_form('<?= base_url('Report/ipd_surgery_report') ?>','IPD Surgery Report');"><i class="bi bi-arrow-right-short"></i> IPD Surgery Report</a></li><?php endif; ?></ul></div></div></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($can('clinical')) : ?>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
|
|
|
|||
18
app/Views/report/ipd_surgery_report.php
Normal file
18
app/Views/report/ipd_surgery_report.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
$doctors = $doctors ?? [];
|
||||
$departments = $departments ?? [];
|
||||
$today = date('Y-m-d');
|
||||
?>
|
||||
<section class="content">
|
||||
<div class="card"><div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2"><div><h5 class="mb-0"><i class="bi bi-scissors me-2"></i>IPD Surgery Report</h5><small class="text-muted">Surgery, discharge, consultant, OT, and matched billing details.</small></div><button type="button" class="btn btn-sm btn-outline-secondary" onclick="load_form('<?= base_url('Report/index') ?>', 'Report Panel')"><i class="bi bi-arrow-left me-1"></i>Report Panel</button></div>
|
||||
<div class="card-body"><div class="row g-3 align-items-end"><div class="col-md-3"><label class="form-label" for="surgery_report_from">Surgery from</label><input type="date" class="form-control" id="surgery_report_from" value="<?= esc(date('Y-m-01')) ?>"></div><div class="col-md-3"><label class="form-label" for="surgery_report_to">Surgery to</label><input type="date" class="form-control" id="surgery_report_to" value="<?= esc($today) ?>"></div><div class="col-md-3"><label class="form-label" for="surgery_report_department">Specialty</label><select class="form-select" id="surgery_report_department"><option value="0">All specialties</option><?php foreach ($departments as $department) : ?><option value="<?= (int) ($department->iId ?? 0) ?>"><?= esc($department->vName ?? '') ?></option><?php endforeach; ?></select></div><div class="col-md-3"><label class="form-label" for="surgery_report_doctor">Surgeon / consultant</label><select class="form-select" id="surgery_report_doctor"><option value="0">All doctors</option><?php foreach ($doctors as $doctor) : ?><option value="<?= (int) ($doctor->id ?? 0) ?>"><?= esc($doctor->p_fname ?? '') ?></option><?php endforeach; ?></select></div></div><div class="d-flex gap-2 mt-3"><button type="button" class="btn btn-primary" id="surgery_report_show"><i class="bi bi-search me-1"></i>Show report</button><button type="button" class="btn btn-outline-success" id="surgery_report_excel"><i class="bi bi-file-earmark-excel me-1"></i>Excel</button></div></div></div>
|
||||
<div class="card mt-3"><div class="card-body"><div id="surgery_report_result" class="table-responsive"><div class="text-center text-muted py-4"><i class="bi bi-scissors d-block mb-2" style="font-size:2rem"></i>Select the surgery date range and show the report.</div></div></div></div>
|
||||
</section>
|
||||
<script>
|
||||
(function () {
|
||||
function buildUrl(output) { var from = $('#surgery_report_from').val(); var to = $('#surgery_report_to').val(); if (!from || !to) { alert('Select both surgery dates.'); return ''; } return '<?= base_url('Report/ipd_surgery_data') ?>/' + encodeURIComponent(from + 'S' + to) + '/' + encodeURIComponent($('#surgery_report_doctor').val() || '0') + '/' + encodeURIComponent($('#surgery_report_department').val() || '0') + (output ? '/' + output : ''); }
|
||||
function show() { var url = buildUrl(0); if (!url) return; $('#surgery_report_result').html('<div class="text-center text-muted py-4"><span class="spinner-border spinner-border-sm me-2"></span>Loading report...</div>'); $.get(url).done(function (html) { $('#surgery_report_result').html(html); }).fail(function (xhr) { $('#surgery_report_result').html('<div class="alert alert-danger mb-0">' + (xhr.status === 403 ? 'You do not have permission to view this report.' : 'Unable to load the surgery report.') + '</div>'); }); }
|
||||
$('#surgery_report_show').off('click.surgeryReport').on('click.surgeryReport', show);
|
||||
$('#surgery_report_excel').off('click.surgeryReport').on('click.surgeryReport', function () { var url = buildUrl(1); if (url) window.open(url, '_blank'); });
|
||||
})();
|
||||
</script>
|
||||
3
app/Views/report/ipd_surgery_report_table.php
Normal file
3
app/Views/report/ipd_surgery_report_table.php
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?php $rows = $rows ?? []; ?>
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-3"><strong>Surgery period: <?= esc($min_range ?? '') ?> to <?= esc($max_range ?? '') ?></strong><span class="text-muted small"><?= count($rows) ?> surgery record<?= count($rows) === 1 ? '' : 's' ?></span></div>
|
||||
<?php if (empty($rows)) : ?><div class="alert alert-info mb-0">No surgery records were found for the selected criteria.</div><?php else : ?><table class="table table-sm table-bordered table-striped align-middle mb-0" style="font-size:.8rem"><thead class="table-light"><tr><th>Surgery Date</th><th>MR No.</th><th>Camp Code</th><th>Patient Name</th><th>Age</th><th>Sex</th><th>Address</th><th>Doctor Name</th><th>Systemic</th><th>Final Diagnosis</th><th>Eye</th><th>Surgery Code</th><th>Surgery Name</th><th>Specialty</th><th>Admission Date</th><th>Discharge Date</th><th>Scheduled Time</th><th>Remarks</th><th>Anaesthetist</th><th>Surgery Start</th><th>Surgery End</th><th>Actual Duration</th><th>Estimated Surgery Cost</th><th>Actual Surgery Cost</th></tr></thead><tbody><?php foreach ($rows as $row) : ?><tr><td><?= esc($row['surgery_date'] ?? '') ?></td><td><?= esc($row['mr_no'] ?? '') ?></td><td><?= esc($row['camp_code'] ?? '') ?></td><td><?= esc($row['patient_name'] ?? '') ?></td><td><?= esc($row['age'] ?? '') ?></td><td><?= esc($row['gender'] ?? '') ?></td><td><?= esc($row['address'] ?? '') ?></td><td><?= esc($row['doctor_name'] ?? '') ?></td><td><?= esc($row['systemic_history'] ?? '') ?></td><td><?= esc($row['final_diagnosis'] ?? '') ?></td><td><?= esc($row['procedure_side'] ?? '') ?></td><td><?= esc($row['surgery_code'] ?? '') ?></td><td><?= esc($row['surgery_name'] ?? '') ?></td><td><?= esc($row['specialty'] ?? '') ?></td><td><?= esc(substr((string) ($row['register_date'] ?? ''), 0, 10)) ?></td><td><?= esc(substr((string) ($row['discharge_date'] ?? ''), 0, 10)) ?></td><td><?= esc($row['scheduled_start_at'] ?? '') ?></td><td><?= esc($row['surgery_remark'] ?? '') ?></td><td><?= esc($row['anesthetist_name'] ?? '') ?></td><td><?= esc($row['actual_start_at'] ?? '') ?></td><td><?= esc($row['actual_end_at'] ?? '') ?></td><td><?= isset($row['actual_duration_minutes']) ? (int) $row['actual_duration_minutes'] . ' min' : '' ?></td><td class="text-end"><?= ($row['estimated_surgery_cost'] ?? null) !== null ? number_format((float) $row['estimated_surgery_cost'], 2) : '' ?></td><td class="text-end"><?= ($row['actual_surgery_cost'] ?? null) !== null ? number_format((float) $row['actual_surgery_cost'], 2) : '' ?></td></tr><?php endforeach; ?></tbody></table><?php endif; ?>
|
||||
Loading…
Reference in New Issue
Block a user