From 02762bb355db9ce2b3742c59b62e79630b2bf67e Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Wed, 21 Jan 2026 17:00:05 +0700 Subject: [PATCH] Fix Superuser User Management and Refactor Dashboard Layouts - Refactor 'app/Views/superuser/users.php' to fix user creation/editing logic using Alpine.js. - Ensure efficient form state management (userid, username, password handling) in user modal. - Standardize dashboard layouts and script initialization (window.BASEURL) across 'admin', 'cs', 'lab', 'phlebo', and 'superuser' main views. - Remove redundant 'app/Views/admin/users.php' to consolidate user management. --- CLAUDE.md | 120 ++++++ app/Config/Constants.php | 15 + app/Config/Routes.php | 116 +++--- .../{Auth.php => AuthController.php} | 47 +-- .../{Label.php => LabelController.php} | 38 +- .../{Admin.php => Pages/AdminController.php} | 4 +- .../{Cs.php => Pages/CsController.php} | 6 +- .../{Lab.php => Pages/LabController.php} | 6 +- .../PhlebotomistController.php} | 6 +- .../SuperuserController.php} | 4 +- .../{Requests.php => RequestsController.php} | 83 ++-- .../{Samples.php => SamplesController.php} | 123 +++--- app/Controllers/Users.php | 115 ------ app/Controllers/UsersController.php | 140 +++++++ app/Controllers/{ => backup}/Sample.php | 0 app/Controllers/{ => backup}/Specimen.php | 0 app/Controllers/{ => backup}/User.php | 0 app/Views/admin/main.php | 85 ++-- app/Views/admin/users.php | 269 ------------- app/Views/cs/main.php | 84 ++-- app/Views/lab/main.php | 84 ++-- app/Views/phlebo/main.php | 84 ++-- app/Views/superuser/main.php | 86 ++-- app/Views/superuser/users.php | 367 ++++++++++-------- 24 files changed, 849 insertions(+), 1033 deletions(-) create mode 100644 CLAUDE.md rename app/Controllers/{Auth.php => AuthController.php} (64%) rename app/Controllers/{Label.php => LabelController.php} (89%) rename app/Controllers/{Admin.php => Pages/AdminController.php} (77%) rename app/Controllers/{Cs.php => Pages/CsController.php} (69%) rename app/Controllers/{Lab.php => Pages/LabController.php} (69%) rename app/Controllers/{Phlebotomist.php => Pages/PhlebotomistController.php} (69%) rename app/Controllers/{Superuser.php => Pages/SuperuserController.php} (77%) rename app/Controllers/{Requests.php => RequestsController.php} (61%) rename app/Controllers/{Samples.php => SamplesController.php} (57%) delete mode 100644 app/Controllers/Users.php create mode 100644 app/Controllers/UsersController.php rename app/Controllers/{ => backup}/Sample.php (100%) rename app/Controllers/{ => backup}/Specimen.php (100%) rename app/Controllers/{ => backup}/User.php (100%) delete mode 100644 app/Views/admin/users.php diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2b0f5ef --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,120 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a **CodeIgniter 4** PHP application for laboratory management (GDC CMOD - Laboratory Request Management System). It handles specimen collection tracking, request validation, and result management with role-based access control. + +## Development Commands + +```bash +# Run PHP built-in server (from project root) +php spark serve + +# Run tests +composer test +``` + +**Note:** This is a Windows-based deployment using IIS/XAMPP. For production, configure a virtual host pointing to the `public/` folder. + +## Database Configuration + +- **Primary DB:** SQL Server (`GDC_CMOD.dbo`) via Microsoft ODBC Driver (MSOLEDBSQL) +- **Legacy DB:** Firebird/InterBase (`GLENEAGLES` via ODBC) for patient data +- **Connection:** `\Config\Database::connect()` returns MySQLi connection +- **No CI4 Models** - uses raw SQL queries via `Database::connect()` + +## Architecture + +### Role-Based Access Control (RBAC) + +| Role ID | Name | Route Prefix | Permissions | +|---------|------|--------------|-------------| +| 0 | Superuser | `/superuser` | Full access + Users CRUD | +| 1 | Admin | `/admin` | Full access + Users CRUD | +| 2 | Lab | `/lab` | Request validation, Sample collection | +| 3 | Phlebo | `/phlebo` | Request validation, Sample collection | +| 4 | CS | `/cs` | Request validation, Sample collection | + +### Authentication Flow + +1. `Auth::login()` - Verifies credentials against `GDC_CMOD.dbo.USERS`, sets session +2. `RoleFilter` - Checks `session()->get('isLoggedIn')` and role ID +3. `GuestFilter` - Redirects logged-in users to role-based dashboard + +### Key Database Tables + +- `GDC_CMOD.dbo.USERS` - Users with `USERID`, `USERROLEID`, `PASSWORD` +- `GDC_CMOD.dbo.CM_REQUESTS` - Validation tracking (`ISVAL1`, `ISVAL2`, validation users/dates) +- `GDC_CMOD.dbo.TUBES` - Sample collection status +- `GDC_CMOD.dbo.V_DASHBOARD_DEV` - Dashboard data view +- `glendb.dbo.*` - Legacy Firebird patient data + +### Request Validation (Dual-Level) + +Validation requires 2 different users to validate the same request: +1. First validation sets `ISVAL1=1`, `VAL1USER`, `VAL1DATE` +2. Second validation (different user) sets `ISVAL2=1`, `VAL2USER`, `VAL2DATE` + +## Code Conventions + +### Controllers +- All extend `BaseController` (which extends `CodeIgniter\Controller`) +- Use `ResponseTrait` for JSON APIs +- Raw SQL queries via `\Config\Database::connect()->query()` + +### Routing Pattern + +```php +$routes->group('prefix', ['filter' => 'role:N'], function($routes) { + $routes->get('', 'Controller::index'); + $routes->get('api/resource', 'Controller::method'); +}); +``` + +### Session Structure + +```php +session()->set([ + 'isLoggedIn' => true, + 'userid' => (string) $user['USERID'], + 'userroleid' => (int) $user['USERROLEID'], + 'userrole' => (string) $role, +]); +``` + +## Important Routes + +| Route | Purpose | +|-------|---------| +| `/login`, `/logout` | Authentication | +| `/label/coll/:accessnumber` | Zebra printer label (public) | +| `/api/requests` | Dashboard data (date-filtered) | +| `/api/requests/validate/:accessnumber` | Dual-level validation | +| `/api/samples/collect/:accessnumber` | Mark sample collected | +| `/api/samples/receive/:accessnumber` | Mark sample received (Admin/Superuser only) | + +## Frontend Stack + +- TailwindCSS + DaisyUI 5 (CDN) +- Alpine.js for reactivity +- Font Awesome 7 for icons + +## Common Patterns + +### JSON API Response +```php +return $this->response->setJSON(['status' => 'success', 'data' => $result]); +``` + +### Database Query +```php +$db = \Config\Database::connect(); +$result = $db->query("SELECT * FROM table WHERE col = ?", [$value])->getResultArray(); +``` + +### Date Formatting from SQL Server +```php +$row['DATE_COLUMN'] = date('Y-m-d H:i', strtotime($row['DATE_COLUMN'])); +``` diff --git a/app/Config/Constants.php b/app/Config/Constants.php index fb56bb1..051b0db 100644 --- a/app/Config/Constants.php +++ b/app/Config/Constants.php @@ -77,3 +77,18 @@ defined('EXIT_USER_INPUT') || define('EXIT_USER_INPUT', 7); // invalid u defined('EXIT_DATABASE') || define('EXIT_DATABASE', 8); // database error defined('EXIT__AUTO_MIN') || define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code defined('EXIT__AUTO_MAX') || define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code + +/* + |-------------------------------------------------------------------------- + | Role Names + |-------------------------------------------------------------------------- + | + | Mapping of role IDs to role names for the application. + */ +defined('ROLE_NAMES') || define('ROLE_NAMES', [ + 0 => 'Superuser', + 1 => 'Admin', + 2 => 'Lab Analyst', + 3 => 'Phlebotomist', + 4 => 'Customer Service', +]); diff --git a/app/Config/Routes.php b/app/Config/Routes.php index c9ef2c6..5563c1f 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -2,7 +2,7 @@ use CodeIgniter\Router\RouteCollection; -$routes->set404Override(function() { +$routes->set404Override(function () { $response = service('response'); $response->setStatusCode(404); echo view('errors/notfound'); @@ -11,72 +11,74 @@ $routes->get('/unauthorized', 'ErrorPage::unauthorized'); $routes->get('/', 'Home::index'); -$routes->get('/login', 'Auth::loginPage', ['filter' => 'guest']); -$routes->post('/login', 'Auth::login', ['filter' => 'guest']); -$routes->get('/logout', 'Auth::logout'); -$routes->patch('/setPassword', 'Auth::setPassword'); +$routes->get('/login', 'AuthController::loginPage', ['filter' => 'guest']); +$routes->post('/login', 'AuthController::login', ['filter' => 'guest']); +$routes->get('/logout', 'AuthController::logout'); +$routes->patch('/setPassword', 'AuthController::setPassword'); -$routes->get('label/coll/(:any)', 'Label::coll/$1'); -$routes->get('label/dispatch/(:any)/(:any)', 'Label::dispatch/$1/$2'); -$routes->get('label/all/(:any)', 'Label::print_all/$1'); +$routes->get('label/coll/(:any)', 'LabelController::coll/$1'); +$routes->get('label/dispatch/(:any)/(:any)', 'LabelController::dispatch/$1/$2'); +$routes->get('label/all/(:any)', 'LabelController::print_all/$1'); + + +// --- API Group --- +$routes->group('api', function ($routes) { + + // Users Management - Only Superuser (0) and Admin (1) + $routes->group('users', ['filter' => 'role:0,1'], function ($routes) { + $routes->get('', 'UsersController::index'); + $routes->post('', 'UsersController::create'); + $routes->patch('(:any)', 'UsersController::update/$1'); + $routes->delete('(:any)', 'UsersController::delete/$1'); + }); + + // Requests - All Roles (0,1,2,3,4) + $routes->group('requests', ['filter' => 'role:0,1,2,3,4'], function ($routes) { + $routes->get('', 'RequestsController::index'); + $routes->post('validate/(:any)', 'RequestsController::val/$1'); + $routes->delete('validate/(:any)', 'RequestsController::unval/$1'); + }); + + // Samples + $routes->group('samples', function ($routes) { + // Collect & Show - All Roles + $routes->group('', ['filter' => 'role:0,1,2,3,4'], function ($routes) { + $routes->post('collect/(:any)', 'SamplesController::collect/$1'); + $routes->get('(:any)', 'SamplesController::show/$1'); + }); + + // Uncollect & Unreceive - Only Superuser (0) and Admin (1) + $routes->group('', ['filter' => 'role:0,1'], function ($routes) { + $routes->delete('collect/(:any)', 'SamplesController::uncollect/$1'); + $routes->delete('receive/(:any)', 'SamplesController::unreceive/$1'); + }); + }); -$routes->group('superuser', ['filter' => 'role:0'], function($routes) { - $routes->get('', 'Superuser::index'); - $routes->get('users', 'Superuser::users'); - $routes->get('api/users', 'Users::index'); - $routes->post('api/users', 'Users::create'); - $routes->patch('api/users/(:any)', 'Users::update/$1'); - $routes->delete('api/users/(:any)', 'Users::delete/$1'); - $routes->get('api/requests', 'Requests::index'); - $routes->post('api/requests/validate/(:any)', 'Requests::val/$1'); - $routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1'); - $routes->post('api/samples/collect/(:any)', 'Samples::collect/$1'); - $routes->delete('api/samples/collect/(:any)', 'Samples::uncollect/$1'); - $routes->delete('api/samples/receive/(:any)', 'Samples::unreceive/$1'); - $routes->get('api/samples/(:any)', 'Samples::show/$1'); }); -$routes->group('admin', ['filter' => 'role:1'], function($routes) { - $routes->get('', 'Admin::index'); - $routes->get('users', 'Admin::users'); - $routes->get('api/users', 'Users::index'); - $routes->post('api/users', 'Users::create'); - $routes->patch('api/users/(:any)', 'Users::update/$1'); - $routes->delete('api/users/(:any)', 'Users::delete/$1'); - $routes->get('api/requests', 'Requests::index'); - $routes->post('api/requests/validate/(:any)', 'Requests::val/$1'); - $routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1'); - $routes->post('api/samples/collect/(:any)', 'Samples::collect/$1'); - $routes->delete('api/samples/collect/(:any)', 'Samples::uncollect/$1'); - $routes->delete('api/samples/receive/(:any)', 'Samples::unreceive/$1'); - $routes->get('api/samples/(:any)', 'Samples::show/$1'); + +// --- Page Routes --- + +$routes->group('superuser', ['filter' => 'role:0'], function ($routes) { + $routes->get('', 'Pages\SuperuserController::index'); + $routes->get('users', 'Pages\SuperuserController::users'); }); -$routes->group('lab', ['filter' => 'role:2'], function($routes) { - $routes->get('', 'Lab::index'); - $routes->get('api/requests', 'Requests::index'); - $routes->post('api/requests/validate/(:any)', 'Requests::val/$1'); - $routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1'); - $routes->post('api/samples/collect/(:any)', 'Samples::collect/$1'); - $routes->get('api/samples/(:any)', 'Samples::show/$1'); +$routes->group('admin', ['filter' => 'role:1'], function ($routes) { + $routes->get('', 'Pages\AdminController::index'); + $routes->get('users', 'Pages\AdminController::users'); }); -$routes->group('phlebo', ['filter' => 'role:3'], function($routes) { - $routes->get('', 'Phlebotomist::index'); - $routes->get('api/requests', 'Requests::index'); - $routes->post('api/requests/validate/(:any)', 'Requests::val/$1'); - $routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1'); - $routes->post('api/samples/collect/(:any)', 'Samples::collect/$1'); - $routes->get('api/samples/(:any)', 'Samples::show/$1'); +$routes->group('lab', ['filter' => 'role:2'], function ($routes) { + $routes->get('', 'Pages\LabController::index'); }); -$routes->group('cs', ['filter' => 'role:4'], function($routes) { - $routes->get('', 'Cs::index'); - $routes->get('api/requests', 'Requests::index'); - $routes->post('api/requests/validate/(:any)', 'Requests::val/$1'); - $routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1'); - $routes->post('api/samples/collect/(:any)', 'Samples::collect/$1'); - $routes->get('api/samples/(:any)', 'Samples::show/$1'); +$routes->group('phlebo', ['filter' => 'role:3'], function ($routes) { + $routes->get('', 'Pages\PhlebotomistController::index'); +}); + +$routes->group('cs', ['filter' => 'role:4'], function ($routes) { + $routes->get('', 'Pages\CsController::index'); }); $routes->get('/dummypage', 'Home::dummyPage'); diff --git a/app/Controllers/Auth.php b/app/Controllers/AuthController.php similarity index 64% rename from app/Controllers/Auth.php rename to app/Controllers/AuthController.php index 6503a9f..80798b3 100644 --- a/app/Controllers/Auth.php +++ b/app/Controllers/AuthController.php @@ -4,13 +4,16 @@ namespace App\Controllers; use App\Controllers\BaseController; -class Auth extends BaseController { +class AuthController extends BaseController +{ - public function loginPage() { + public function loginPage() + { return view("login"); } - public function login() { + public function login() + { helper(['form', 'url']); $session = session(); $db = \Config\Database::connect(); @@ -23,35 +26,17 @@ class Auth extends BaseController { if ($user && !empty($user['PASSWORD']) && password_verify($password, $user['PASSWORD'])) { - switch ((int)$user['USERROLEID']) { - case 0: - $role = 'Superuser'; - break; - case 1: - $role = 'Admin'; - break; - case 2: - $role = 'Lab Analyst'; - break; - case 3: - $role = 'Phlebotomist'; - break; - case 4: - $role = 'Customer Service'; - break; - default: - $role = ''; - break; - } + $roleId = (int) $user['USERROLEID']; + $role = ROLE_NAMES[$roleId] ?? ''; $session->set([ 'isLoggedIn' => true, - 'userid' => (string) $user['USERID'], + 'userid' => (string) $user['USERID'], 'userroleid' => (int) $user['USERROLEID'], - 'userrole' => (string) $role, + 'userrole' => (string) $role, ]); - switch ((int)$user['USERROLEID']) { + switch ((int) $user['USERROLEID']) { case 0: return redirect()->to('superuser'); case 1: @@ -71,13 +56,15 @@ class Auth extends BaseController { } } - public function logout() { + public function logout() + { $session = session(); $session->destroy(); return redirect()->to('login'); } - public function setPassword() { + public function setPassword() + { $input = $this->request->getJSON(true); $userid = $input['userid']; $password = $input['password']; @@ -85,7 +72,7 @@ class Auth extends BaseController { $db = db_connect(); $sql = "update GDC_CMOD.dbo.USERS set PASSWORD='$password' where USERID='$userid'"; $db->query($sql); - $data = ['status' => 'success', 'message' => 'Password updated successfully', 'data' => "$userid" ]; - return $this->response->setJSON($data); + $data = ['status' => 'success', 'message' => 'Password updated successfully', 'data' => "$userid"]; + return $this->response->setJSON($data); } } diff --git a/app/Controllers/Label.php b/app/Controllers/LabelController.php similarity index 89% rename from app/Controllers/Label.php rename to app/Controllers/LabelController.php index fe4fa73..8cc230a 100644 --- a/app/Controllers/Label.php +++ b/app/Controllers/LabelController.php @@ -1,8 +1,10 @@ query($sql)->getResultArray(); $row = $rows[0]; $patnum = $row['PATNUMBER']; - $patnum = substr($patnum,14); + $patnum = substr($patnum, 14); $patname = $row['Name']; $age = $row['age']; $sex = $row['Gender']; @@ -109,11 +112,13 @@ P1\n]"; $samptext = $row['SHORTTEXT']; $tests = $row['TESTS']; $tests1 = $row['TESTS1']; - if($tests == '') {$tests = $tests1;} - $tubeid = $sampcode.substr("$reqnum",5,5); + if ($tests == '') { + $tests = $tests1; + } + $tubeid = $sampcode . substr("$reqnum", 5, 5); $date = date("d/M/Y H:i"); -$bar = "[ + $bar = "[ N OD q400 @@ -132,19 +137,20 @@ A190,190,0,2,1,1,N,\"$date\" P1 ]"; - $handle = fopen("./file.txt","a+"); - fwrite($handle,$bar); + $handle = fopen("./file.txt", "a+"); + fwrite($handle, $bar); fclose($handle); //exec($command); } - public function print_all($accessnumber) { + public function print_all($accessnumber) + { $db = \Config\Database::connect(); $this->coll($accessnumber); $sql = "select SAMPCODE from GDC_CMOD.dbo.v_sp_reqtube where SP_ACCESSNUMBER='$accessnumber'"; $rows = $db->query($sql)->getResultArray(); - foreach($rows as $row) { + foreach ($rows as $row) { $sampcode = $row['SAMPCODE']; $this->dispatch($accessnumber, $sampcode); } diff --git a/app/Controllers/Admin.php b/app/Controllers/Pages/AdminController.php similarity index 77% rename from app/Controllers/Admin.php rename to app/Controllers/Pages/AdminController.php index 55ea447..bdc2909 100644 --- a/app/Controllers/Admin.php +++ b/app/Controllers/Pages/AdminController.php @@ -1,10 +1,10 @@ request->getGet('date1'); - $date2 = $this->request->getGet('date2'); - - $sql = "SELECT * from GDC_CMOD.dbo.V_DASHBOARD_DEV where - COLLECTIONDATE between '$date1 00:00' and '$date2 23:59' + public function index() + { + $db = \Config\Database::connect(); + $date1 = $this->request->getGet('date1'); + $date2 = $this->request->getGet('date2'); + + $sql = "SELECT * from GDC_CMOD.dbo.V_DASHBOARD_DEV where + COLLECTIONDATE between '$date1 00:00' and '$date2 23:59' and ODR_DDATE between '$date1 00:00' and '$date2 23:59'"; - $rows = $db->query($sql)->getResultArray(); + $rows = $db->query($sql)->getResultArray(); foreach ($rows as &$row) { $row['COLLECTIONDATE'] = date('Y-m-d H:i', strtotime($row['COLLECTIONDATE'])); $row['ODR_DDATE'] = date('Y-m-d H:i', strtotime($row['ODR_DDATE'])); $row['REQDATE'] = date('Y-m-d H:i', strtotime($row['REQDATE'])); } - $data['data'] = $rows; + $data['data'] = $rows; return $this->response->setJSON($data); } - public function show($accessnumber) { + public function show($accessnumber) + { $db = \Config\Database::connect(); $data['accessnumber'] = $accessnumber; - $sql = "SELECT d.STATS, r.* FROM GDC_CMOD.dbo.V_DASHBOARD_DEV d + $sql = "SELECT d.STATS, r.* FROM GDC_CMOD.dbo.V_DASHBOARD_DEV d left join GDC_CMOD.dbo.CM_REQUESTS r ON r.ACCESSNUMBER=d.SP_ACCESSNUMBER WHERE d.SP_ACCESSNUMBER='$accessnumber'"; $result = $db @@ -38,62 +41,68 @@ class Requests extends BaseController { $data['val1user'] = $result[0]['VAL1USER']; $data['val2'] = $result[0]['ISVAL2']; $data['val2user'] = $result[0]['VAL2USER']; - return view('admin/modal_request',$data); + return view('admin/modal_request', $data); } - public function showUnval($accessnumber) { + public function showUnval($accessnumber) + { $data['accessnumber'] = $accessnumber; - return view('admin/modal_unvalidate',$data); + return view('admin/modal_unvalidate', $data); } - public function unval($accessnumber) { + public function unval($accessnumber) + { $input = $this->request->getJSON(true); - $userid = $input['userid']; + // Securely get userid from session + $userid = session('userid'); $comment = $input['comment']; $db = \Config\Database::connect(); $sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL1=null, VAL1USER=null, VAL1DATE=null, ISVAL2=null, VAL2USER=null, VAL2DATE=null, ISPENDING=1, PENDINGTEXT='$comment', PENDINGUSER='$userid', PENDINGDATE=GETDATE() where ACCESSNUMBER='$accessnumber'"; $db->query($sql); - $data = ['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber" ]; + $data = ['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber"]; return $this->response->setJSON($data); } - public function val($accessnumber) { + public function val($accessnumber) + { $input = $this->request->getJSON(true); - $userid = $input['userid']; + // Securely get userid from session + $userid = session('userid'); $db = \Config\Database::connect(); $sql = "select * from GDC_CMOD.dbo.CM_REQUESTS where ACCESSNUMBER='$accessnumber'"; $result = $db->query($sql)->getResultArray(); - if(!isset($result[0])) { + if (!isset($result[0])) { $sql = "insert into GDC_CMOD.dbo.CM_REQUESTS(ACCESSNUMBER, ISVAL1, VAL1USER, VAL1DATE) VALUES ('$accessnumber', 1, '$userid', GETDATE())"; $db->query($sql); - $data['val'] = 1; - $data['userid'] = $userid; + $data['val'] = 1; + $data['userid'] = $userid; } else { $row = $result[0]; $isval1 = $row['ISVAL1']; $isval2 = $row['ISVAL2']; $val1user = $row['VAL1USER']; - if( $isval1 == 1 ) { - if ( $isval2 == 1 ) { return $this->response->setJSON(['message'=> 'validation done, not updating anything']); } - else { - if($val1user != $userid) { - $sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL2=1, VAL2USER='$userid', VAL2DATE=GETDATE() where ACCESSNUMBER='$accessnumber'"; - $data['val'] = 2; - $data['userid'] = $userid; - } else { + if ($isval1 == 1) { + if ($isval2 == 1) { + return $this->response->setJSON(['message' => 'validation done, not updating anything']); + } else { + if ($val1user != $userid) { + $sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL2=1, VAL2USER='$userid', VAL2DATE=GETDATE() where ACCESSNUMBER='$accessnumber'"; + $data['val'] = 2; + $data['userid'] = $userid; + } else { $this->response->setStatusCode(500); - return $this->response->setJSON([ 'message'=> 'user already validate this request' ]); + return $this->response->setJSON(['message' => 'user already validate this request']); } } } else { - $sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL1=1, VAL1USER='$userid', VAL1DATE=GETDATE() where ACCESSNUMBER='$accessnumber'"; - $data['val'] = 1; - $data['userid'] = $userid; + $sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL1=1, VAL1USER='$userid', VAL1DATE=GETDATE() where ACCESSNUMBER='$accessnumber'"; + $data['val'] = 1; + $data['userid'] = $userid; } - $db->query($sql); - } + $db->query($sql); + } return $this->response->setJSON($data); } diff --git a/app/Controllers/Samples.php b/app/Controllers/SamplesController.php similarity index 57% rename from app/Controllers/Samples.php rename to app/Controllers/SamplesController.php index 1128cd3..f6cecfa 100644 --- a/app/Controllers/Samples.php +++ b/app/Controllers/SamplesController.php @@ -3,13 +3,15 @@ namespace App\Controllers; use CodeIgniter\API\ResponseTrait; use App\Controllers\BaseController; -class Samples extends BaseController { +class SamplesController extends BaseController +{ use ResponseTrait; - public function show($accessnumber) { - $db = \Config\Database::connect(); + public function show($accessnumber) + { + $db = \Config\Database::connect(); - $sql = "SELECT right(p.PATNUMBER,16) as [patnumber], ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') as [Name], + $sql = "SELECT right(p.PATNUMBER,16) as [patnumber], ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') as [Name], case when format(p.BIRTHDATE,'MMdd')=format(spr.COLLECTIONDATE,'MMdd') then DATEDIFF(YEAR,p.BIRTHDATE, spr.COLLECTIONDATE) else FLOOR(DATEDIFF(DAY, p.BIRTHDATE, spr.COLLECTIONDATE) / 365.25) end , [Gender] = case @@ -17,108 +19,113 @@ class Samples extends BaseController { when p.SEX = 2 then 'F' else '' end, spr.REQDATE, spo.COMMENTTEXT, dmg.DMG_CKTPNO, dmg.DMG_CPLACEOFBIRTH - from SP_REQUESTS spr + from SP_REQUESTS spr left join PATIENTS p on p.PATID=spr.PATID left join SP_REQUESTS_OCOM spo on spr.SP_ACCESSNUMBER=spo.SP_ACCESSNUMBER left join GDC_CMOD.dbo.TDL_DEMOGRAPHIC dmg on right(dmg.DMG_CPATNUMBER,15)=right(p.PATNUMBER,15) where spr.PATID=p.PATID and spr.SP_ACCESSNUMBER='$accessnumber'"; - $query = $db->query($sql); - $results = $query->getRowArray(); - $data = [ - 'patnumber' => $results["patnumber"], - 'age' => $results[""], - 'patname' => $results['Name'] ?? '', - 'reqdate' => $results['REQDATE'] ?? '', - 'gender' => $results['Gender'] ?? '', - 'placeofbirth' => $results['DMG_CPLACEOFBIRTH'] ?? '', - 'ktp' => $results['DMG_CKTPNO'] ?? '', - 'comment' => $results['COMMENTTEXT'] ?? '', - 'accessnumber' => $accessnumber, - ]; + $query = $db->query($sql); + $results = $query->getRowArray(); + $data = [ + 'patnumber' => $results["patnumber"], + 'age' => $results[""], + 'patname' => $results['Name'] ?? '', + 'reqdate' => $results['REQDATE'] ?? '', + 'gender' => $results['Gender'] ?? '', + 'placeofbirth' => $results['DMG_CPLACEOFBIRTH'] ?? '', + 'ktp' => $results['DMG_CKTPNO'] ?? '', + 'comment' => $results['COMMENTTEXT'] ?? '', + 'accessnumber' => $accessnumber, + ]; - $samples = []; - $sql = "SELECT req.SAMPTYPEID, req.SAMPCODE, req.SHORTTEXT, tu.STATUS, st.TUBESTATUS + $samples = []; + $sql = "SELECT req.SAMPTYPEID, req.SAMPCODE, req.SHORTTEXT, tu.STATUS, st.TUBESTATUS from GDC_CMOD.dbo.v_sp_reqtube req left join GDC_CMOD.dbo.TUBES tu on req.SP_ACCESSNUMBER=tu.ACCESSNUMBER and req.SAMPCODE=tu.TUBENUMBER left join glendb.dbo.SP_TUBES st on st.SP_ACCESSNUMBER=req.SP_ACCESSNUMBER and req.SAMPCODE=st.SAMPLETYPE where req.SP_ACCESSNUMBER='$accessnumber'"; - $query = $db->query($sql); - $results = $query->getResultArray(); - foreach ($results as $row) { - $samples[] = [ - 'samptypeid' => $row['SAMPTYPEID'] ?? null, - 'sampcode' => $row['SAMPCODE'] ?? null, - 'name' => $row['SHORTTEXT'] ?? '', - 'colstatus' => $row['STATUS'] ?? '', - 'tubestatus' => $row['TUBESTATUS'] ?? '', - ]; - } - $data['samples'] = $samples; + $query = $db->query($sql); + $results = $query->getResultArray(); + foreach ($results as $row) { + $samples[] = [ + 'samptypeid' => $row['SAMPTYPEID'] ?? null, + 'sampcode' => $row['SAMPCODE'] ?? null, + 'name' => $row['SHORTTEXT'] ?? '', + 'colstatus' => $row['STATUS'] ?? '', + 'tubestatus' => $row['TUBESTATUS'] ?? '', + ]; + } + $data['samples'] = $samples; - $resp = [ 'data' => $data ]; + $resp = ['data' => $data]; - return $this->response->setJSON($resp); + return $this->response->setJSON($resp); } - - public function collect($accessnumber) { + + public function collect($accessnumber) + { $db = \Config\Database::connect(); $input = $this->request->getJSON(true); $samplenumber = $input['samplenumber']; - $userid = $input['userid']; + $userid = session('userid'); $sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='1', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'"; $db->query($sql); - $sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE) + $sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE) VALUES ('$accessnumber', '$samplenumber', '$userid', '1', getdate())"; $db->query($sql); - return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201); + return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201); } - public function uncollect($accessnumber) { + public function uncollect($accessnumber) + { $db = \Config\Database::connect(); $input = $this->request->getJSON(true); $samplenumber = $input['samplenumber']; - $userid = $input['userid']; + $userid = session('userid'); $sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='0', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'"; $db->query($sql); - $sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE) + $sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE) VALUES ('$accessnumber', '$samplenumber', '$userid', '0', getdate())"; $db->query($sql); - return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201); + return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201); } - public function unreceive($accessnumber) { + public function unreceive($accessnumber) + { $db = \Config\Database::connect(); $input = $this->request->getJSON(true); $samplenumber = $input['samplenumber']; - $sql = "select r.EXTERNALORDERNUMBER, dt.TESTCODE, do.HISCODE from glendb.dbo.TESTS t - left join glendb.dbo.DICT_TESTS dt on dt.TESTID=t.TESTID - left join glendb.dbo.REQUESTS r on r.REQUESTID=t.REQUESTID - left join glendb.dbo.DICT_TEST_SAMPLES dts on dts.TESTID=t.TESTID - left join glendb.dbo.DICT_SAMPLES_TYPES ds on ds.SAMPTYPEID=dts.SAMPTYPEID - left join GDC_CMOD.dbo.DICT_TESTS_ORDER do on do.TESTCODE=dt.TESTCODE - where t.DEPTH=0 + $sql = "select r.EXTERNALORDERNUMBER, dt.TESTCODE, do.HISCODE from glendb.dbo.TESTS t + left join glendb.dbo.DICT_TESTS dt on dt.TESTID=t.TESTID + left join glendb.dbo.REQUESTS r on r.REQUESTID=t.REQUESTID + left join glendb.dbo.DICT_TEST_SAMPLES dts on dts.TESTID=t.TESTID + left join glendb.dbo.DICT_SAMPLES_TYPES ds on ds.SAMPTYPEID=dts.SAMPTYPEID + left join GDC_CMOD.dbo.DICT_TESTS_ORDER do on do.TESTCODE=dt.TESTCODE + where t.DEPTH=0 and r.ACCESSNUMBER='$accessnumber' and ds.SAMPCODE='$samplenumber'"; $rows = $db->query($sql)->getResultArray(); $his_test = ''; $lis_test = ''; - foreach( $rows as $row ) { + foreach ($rows as $row) { $hon = $row['EXTERNALORDERNUMBER']; $testcode = $row['TESTCODE']; $hiscode = $row['HISCODE']; $his_test .= "'$hiscode',"; $lis_test .= "'$testcode',"; } - $his_test = rtrim($his_test,','); - $lis_test = rtrim($lis_test,','); - $conn = odbc_connect('GLENEAGLES','',''); + $his_test = rtrim($his_test, ','); + $lis_test = rtrim($lis_test, ','); + $conn = odbc_connect('GLENEAGLES', '', ''); $sql = "UPDATE TDL_ORDERDT SET ODD_NRECEIVED=NULL , ODD_DTRECEIVE=NULL WHERE ODR_CNOLAB='$hon' and ODD_CPRODUCTCODE IN ($his_test)"; - $rs = odbc_exec($conn,$sql); - if (!$rs) {exit("Error in Update FB");} + $rs = odbc_exec($conn, $sql); + if (!$rs) { + exit("Error in Update FB"); + } $sql = "update SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$accessnumber' and SAMPLETYPE='$samplenumber' "; $db->query($sql); $sql = "update SP_TESTS set SP_TESTSTATUS=NULL where SP_ACCESSNUMBER='$accessnumber' and SP_TESTCODE in ($lis_test)"; $db->query($sql); - return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201); + return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201); } } diff --git a/app/Controllers/Users.php b/app/Controllers/Users.php deleted file mode 100644 index 62aa69f..0000000 --- a/app/Controllers/Users.php +++ /dev/null @@ -1,115 +0,0 @@ -db = \Config\Database::connect(); - } - - public function index() { - $sql = "select u.USERID, u.USERLEVEL from GDC_CMOD.dbo.USERS u - left join glendb.dbo.USERS u1 on u1.USERID=u.USERID - where u1.LOCKEDACCOUNT is null"; - $query = $this->db->query($sql); - $results = $query->getResultArray(); - $data['data'] = $results; - - return $this->respond(['data' => $results]); - } - - public function create() { - $input = $this->request->getJSON(true); - $userid = $input['userid']; - $userlevel = $input['userlevel']; - $password = $input['password']; - $password_2 = $input['password_2']; - - if ($password != $password_2) { - return $this->response->setJSON(['message'=> 'Password not the same']); - } - if ( strlen($password) < 3 ) { - return $this->response->setJSON(['message'=> 'Password must be more than 2 characters']); - } - - $sql = $this->db->query("SELECT USERID FROM gdc_cmod.dbo.USERS WHERE USERID = ?", [$userid]); - $query = $sql->getRowArray(); - if ($query != null) { - return $this->response->setJSON(['message'=> 'Userid already exists']); - } - - $hashedPassword = password_hash($password, PASSWORD_DEFAULT); - - $this->db->transBegin(); - try { - $sqlInsert = " - INSERT INTO gdc_cmod.dbo.USERS (USERID, USERLEVEL, PASSWORD) - VALUES (?, ?, ?) - "; - $this->db->query($sqlInsert, [$userid, $userlevel, $hashedPassword]); - - $this->db->transCommit(); - - } catch (\Throwable $e) { - $this->db->transRollback(); - return $this->response->setJSON(['message'=> 'Server error']); - } - - return $this->response->setJSON(['message'=> 'User '.$userid.' Berhasil ditambahkan!']); - } - - public function update($id = null) { - $input = $this->request->getJSON(true); - $userid = $input['userid']; - $userlevel = $input['userlevel']; - $password = $input['password']; - $password_2 = $input['password_2']; - - if ( $password != '' || $password_2 != '') { - if ($password != $password_2) { - return $this->response->setJSON(['message'=> 'Password not the same']); - } - - $hashedPassword = password_hash($password, PASSWORD_DEFAULT); - $sqlUpdate =" - UPDATE gdc_cmod.dbo.USERS - SET USERLEVEL = ?, - PASSWORD = ? - WHERE USERID = ? - "; - $fullUpdate = true; - - } else { - $sqlUpdate =" - UPDATE gdc_cmod.dbo.USERS - SET USERLEVEL = ? - WHERE USERID = ? - "; - $fullUpdate = false; - } - - $this->db->transBegin(); - try { - - if ($fullUpdate) { - $this->db->query($sqlUpdate, [$userlevel, $hashedPassword, $userid]); - } else { - $this->db->query($sqlUpdate, [$userlevel, $userid]); - } - - $this->db->transCommit(); - - } catch (\Throwable $e) { - $this->db->transRollback(); - return $this->response->setJSON(['message'=> 'Terjadi kesalahan pada server.']); - } - - return $this->response->setJSON(['message'=> 'User '.$userid.' Berhasil Diupdate!']); - } - -} diff --git a/app/Controllers/UsersController.php b/app/Controllers/UsersController.php new file mode 100644 index 0000000..ed6cd00 --- /dev/null +++ b/app/Controllers/UsersController.php @@ -0,0 +1,140 @@ +db = \Config\Database::connect(); + } + + public function index() + { + $sql = "select u.USERID, u.USERROLEID, u.USERNAME from GDC_CMOD.dbo.USERS u + left join glendb.dbo.USERS u1 on u1.USERID=u.USERID + where u1.LOCKEDACCOUNT is null"; + $query = $this->db->query($sql); + $results = $query->getResultArray(); + $data['data'] = $results; + + return $this->respond(['data' => $results]); + } + + public function create() + { + $input = $this->request->getJSON(true); + $userid = $input['userid']; + $userroleid = $input['userroleid']; + $password = $input['password']; + $password_2 = $input['password_2']; + + if ($password != $password_2) { + return $this->response->setJSON(['message' => 'Password not the same']); + } + if (strlen($password) < 3) { + return $this->response->setJSON(['message' => 'Password must be more than 2 characters']); + } + + $sql = $this->db->query("SELECT USERID FROM gdc_cmod.dbo.USERS WHERE USERID = ?", [$userid]); + $query = $sql->getRowArray(); + if ($query != null) { + return $this->response->setJSON(['message' => 'Userid already exists']); + } + + $hashedPassword = password_hash($password, PASSWORD_DEFAULT); + + $this->db->transBegin(); + try { + $sqlInsert = " + INSERT INTO gdc_cmod.dbo.USERS (USERID, USERROLEID, PASSWORD) + VALUES (?, ?, ?) + "; + $this->db->query($sqlInsert, [$userid, $userroleid, $hashedPassword]); + + $this->db->transCommit(); + + } catch (\Throwable $e) { + $this->db->transRollback(); + return $this->response->setJSON(['message' => 'Server error']); + } + + return $this->response->setJSON(['message' => 'User ' . $userid . ' Berhasil ditambahkan!']); + } + + public function update($id = null) + { + $input = $this->request->getJSON(true); + $userid = $input['userid']; + $userroleid = $input['userroleid']; + $password = $input['password']; + $password_2 = $input['password_2']; + + if ($password != '' || $password_2 != '') { + if ($password != $password_2) { + return $this->response->setJSON(['message' => 'Password not the same']); + } + + $hashedPassword = password_hash($password, PASSWORD_DEFAULT); + $sqlUpdate = " + UPDATE gdc_cmod.dbo.USERS + SET USERROLEID = ?, + PASSWORD = ? + WHERE USERID = ? + "; + $fullUpdate = true; + + } else { + $sqlUpdate = " + UPDATE gdc_cmod.dbo.USERS + SET USERROLEID = ? + WHERE USERID = ? + "; + $fullUpdate = false; + } + + $this->db->transBegin(); + try { + + if ($fullUpdate) { + $this->db->query($sqlUpdate, [$userroleid, $hashedPassword, $userid]); + } else { + $this->db->query($sqlUpdate, [$userroleid, $userid]); + } + + $this->db->transCommit(); + + } catch (\Throwable $e) { + $this->db->transRollback(); + return $this->response->setJSON(['message' => 'Terjadi kesalahan pada server.']); + } + + return $this->response->setJSON(['message' => 'User ' . $userid . ' Berhasil Diupdate!']); + } + + public function delete($id = null) + { + $this->db->transBegin(); + try { + $sql = "DELETE FROM gdc_cmod.dbo.USERS WHERE USERID = ?"; + $this->db->query($sql, [$id]); + + if ($this->db->affectedRows() == 0) { + throw new \Exception('User not found or already deleted'); + } + + $this->db->transCommit(); + } catch (\Throwable $e) { + $this->db->transRollback(); + return $this->response->setStatusCode(500)->setJSON(['message' => 'Error deleting user: ' . $e->getMessage()]); + } + + return $this->response->setJSON(['message' => 'User ' . $id . ' deleted successfully']); + } + +} diff --git a/app/Controllers/Sample.php b/app/Controllers/backup/Sample.php similarity index 100% rename from app/Controllers/Sample.php rename to app/Controllers/backup/Sample.php diff --git a/app/Controllers/Specimen.php b/app/Controllers/backup/Specimen.php similarity index 100% rename from app/Controllers/Specimen.php rename to app/Controllers/backup/Specimen.php diff --git a/app/Controllers/User.php b/app/Controllers/backup/User.php similarity index 100% rename from app/Controllers/User.php rename to app/Controllers/backup/User.php diff --git a/app/Views/admin/main.php b/app/Views/admin/main.php index ec2ef0b..abe3598 100644 --- a/app/Views/admin/main.php +++ b/app/Views/admin/main.php @@ -28,68 +28,45 @@
-