diff --git a/AGENTS.md b/AGENTS.md
index 88b9211..9a372a7 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -4,14 +4,14 @@ This file provides guidance to agents when working with code in this repository.
## Project Overview
-This is a CodeIgniter 4 PHP application for a laboratory management system (CMOD). It uses SQL Server database with role-based access control for different user types (admin, doctor/analyst, customer service).
+CodeIgniter 4 PHP application for laboratory management (GDC CMOD). Handles specimen tracking, request validation, and result management with role-based access control. SQL Server database with Firebird legacy patient data.
## Commands
```bash
# Run all tests
-./vendor/bin/phpunit
composer test
+./vendor/bin/phpunit
# Run single test file
./vendor/bin/phpunit tests/unit/HealthTest.php
@@ -19,249 +19,145 @@ composer test
# Run single test method
./vendor/bin/phpunit tests/unit/HealthTest.php --filter testIsDefinedAppPath
-# Development server (Linux/Mac)
+# Development server
php spark serve
# List all routes
php spark list
-# Create controller
+# Create controller/model
php spark make:controller Admin
-
-# Create model
php spark make:model User
```
-## Code Style Guidelines
+## PHP Standards
-### PHP Standards
-- Use PHP 8.1+ features (typed properties, match expressions where appropriate)
+- PHP 8.1+ features (typed properties, match expressions)
- Always declare return types for public methods
-- Use `strict_types=1` not required (CodeIgniter doesn't use it)
-- No comments unless explaining complex logic (per project convention)
+- No comments unless explaining complex logic
+- Use `esc()` when outputting user data in views
-### Naming Conventions
-- **Classes**: PascalCase (e.g., `Admin`, `UserController`)
-- **Methods**: camelCase (e.g., `index()`, `getUsers()`)
-- **Variables**: camelCase (e.g., `$userId`, `$dataList`)
-- **Constants**: UPPER_SNAKE_CASE (e.g., `DB_HOST`)
-- **Database tables**: UPPER_SNAKE_CASE (e.g., `GDC_CMOD.dbo.USERS`)
-- **Views**: lowercase with underscores (e.g., `admin/index.php`)
+## Naming Conventions
-### Controller Patterns
+| Type | Convention | Example |
+|------|------------|---------|
+| Classes | PascalCase | `Admin`, `UserController` |
+| Methods/Variables | camelCase | `getUsers()`, `$userId` |
+| Constants | UPPER_SNAKE_CASE | `DB_HOST` |
+| Database tables | UPPER_SNAKE_CASE | `GDC_CMOD.dbo.USERS` |
+| Views | lowercase_underscores | `admin/index.php` |
-#### Base Controllers
-- All controllers extend `App\Controllers\BaseController`
-- BaseController extends CodeIgniter\Controller
+## Role-Based Access Control
+
+| Role ID | Name | Route Prefix |
+|---------|------|--------------|
+| 0 | Superuser | `/superuser` |
+| 1 | Admin | `/admin` |
+| 2 | Lab | `/lab` |
+| 3 | Phlebo | `/phlebo` |
+| 4 | CS | `/cs` |
+
+```php
+// Single role
+['filter' => 'role:1']
+// Multiple roles
+['filter' => 'role:1,2']
+```
+
+## Controller Patterns
```php
namespace App\Controllers;
class Admin extends BaseController {
- public function index() {
- // Method body
- }
+ public function index() { }
}
-```
-
-#### API Controllers
-- Controllers use `ResponseTrait` for API responses
-- Use `$this->respond()` or `$this->response->setJSON()` for responses
-
-```php
-namespace App\Controllers;
+// API Controllers use ResponseTrait
use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;
class Users extends BaseController {
use ResponseTrait;
-
protected $db;
public function __construct() {
$this->db = \Config\Database::connect();
helper(['url', 'form', 'text']);
}
-
- public function index() {
- $query = $this->db->query("SELECT * FROM table");
- return $this->respond(['data' => $query->getResultArray()]);
- }
}
```
-### Database Operations
+## Database Operations
-#### Connection Pattern
```php
$this->db = \Config\Database::connect();
-```
-#### Query Methods
-- `getRowArray()` - returns single row as associative array
-- `getResultArray()` - returns multiple rows as array of arrays
-- Use parameterized queries to prevent SQL injection
-
-```php
+// Parameterized queries only
$query = $this->db->query("SELECT * FROM table WHERE id = ?", [$id]);
$row = $query->getRowArray();
$results = $query->getResultArray();
-```
-#### Transactions
-```php
+// Transactions
$this->db->transBegin();
try {
$this->db->query("INSERT INTO ...", [$data]);
$this->db->transCommit();
} catch (\Throwable $e) {
$this->db->transRollback();
- return $this->response->setJSON(['message' => 'Error']);
}
```
-### Session Management
+## Request/Response Patterns
-#### Session Structure
```php
-$session->set([
- 'isLoggedIn' => true,
- 'userid' => (string) $user['USERID'],
- 'userlevel' => (int) $user['USERLEVEL'],
- 'userrole' => (string) $role, // 'admin', 'doctor', 'analyst', 'cs'
-]);
-```
-
-#### Session Values
-- `isLoggedIn`: bool
-- `userid`: string
-- `userlevel`: int
-- `userrole`: string
-
-### Role-Based Access Control
-
-#### Role Values
-- `1` = admin
-- `2` = doctor (or lab/analyst)
-- `3` = analyst
-- `4` = cs (customer service)
-
-#### Route Filter Syntax
-```php
-// Single role
-['filter' => 'role:1']
-
-// Multiple roles
-['filter' => 'role:1,2']
-```
-
-### Request/Response Patterns
-
-#### Getting Input
-```php
-// POST data
-$input = $this->request->getJSON(true);
-$userid = $input['userid'];
-
-// Query parameters
+// GET input
$date1 = $this->request->getVar('date1') ?? date('Y-m-d');
-```
-#### JSON Response (V2 API)
-```php
+// POST JSON
+$input = $this->request->getJSON(true);
+
+// JSON response
return $this->respond(['data' => $results]);
return $this->response->setJSON(['message' => 'Success']);
-```
-#### View Response (Traditional)
-```php
+// View response
return view('admin/index', $data);
-```
-#### Redirect with Errors
-```php
+// Redirect with errors
return redirect()->back()->with('errors', ['key' => 'message']);
```
-### API Endpoint Patterns
+## Session Structure
+
+```php
+session()->set([
+ 'isLoggedIn' => true,
+ 'userid' => (string) $user['USERID'],
+ 'userroleid' => (int) $user['USERROLEID'],
+ 'userrole' => (string) $role,
+]);
+```
+
+## Validation Endpoints
-#### Validation Endpoints
- `POST /api/{resource}/validate/{id}` - validate a record
- `DELETE /api/{resource}/validate/{id}` - unvalidate a record
-#### Route Examples
-```php
-// Admin routes
-$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');
-});
+## Security
-// Lab routes
-$routes->group('lab', ['filter' => 'role:2'], function($routes) {
- $routes->get('/', 'Lab::index');
- $routes->get('api/requests', 'Requests::index');
-});
-```
-
-### Error Handling
-
-#### Database Operations
-```php
-try {
- // DB operations
-} catch (\Throwable $e) {
- // Handle error
- return $this->response->setJSON(['message' => 'Server error']);
-}
-```
-
-#### Validation Errors
-```php
-if ($condition) {
- return $this->response->setJSON(['message' => 'Error message']);
-}
-```
-
-### Views
-
-#### View Pattern
-- Views are plain PHP files in `app/Views/`
-- Use `` syntax
-- Pass data as associative array
-
-```php
-// Controller
-$data['dataList'] = $results;
-return view('admin/index', $data);
-
-// View
-
-
| = esc($item['name']) ?> |
-
-```
-
-### Security
-
-- Always use parameterized queries (never interpolate directly)
-- Use `esc()` when outputting user data in views
-- Hash passwords with `password_hash()` and verify with `password_verify()`
+- Use parameterized queries (never interpolate directly)
+- Hash passwords with `password_hash()` / `password_verify()`
- Validate and sanitize all input before use
-### Helper Functions
+## Database Schema
-Available helpers loaded via `helper(['name', 'name2'])`:
-- `url` - URL helpers
-- `form` - Form helpers
-- `text` - Text formatting
+- Primary: SQL Server (`GDC_CMOD.dbo`)
+- Legacy: Firebird (`GLENEAGLES` via ODBC)
+- No CI4 Models - raw SQL queries via `Database::connect()`
-### Database Schema
+## Dual-Level Validation
-- Database: SQL Server
-- Schema: `dbo`
-- Main database: `GDC_CMOD`
-- Reference database: `glendb`
-- Table naming: `GDC_CMOD.dbo.TABLENAME`
+Validation requires 2 different users:
+1. First: `ISVAL1=1`, `VAL1USER`, `VAL1DATE`
+2. Second (different user): `ISVAL2=1`, `VAL2USER`, `VAL2DATE`
diff --git a/CHECKLIST.md b/CHECKLIST.md
index c36a7d8..8d4b2d4 100644
--- a/CHECKLIST.md
+++ b/CHECKLIST.md
@@ -3,16 +3,16 @@
**Last Updated:** January 22, 2026
Pending:
-
-- Restrict 'UnValidate' to Admin
- Restrict Print/Save-to-PDF to CS Role only (Lab can only preview, CS can print/save)
+- Add Dedicated Print Button (Trigger browser/system print dialog)
- Create 'Detail Unvalidated' History Log/View (Log unvalidation actions with timestamp, user ID, and reason)
- Enhanced Patient Detail Logging (Track: Sample Collection Time, Sample Received Time, Print History)
-- Add Dedicated Print Button (Trigger browser/system print dialog)
- Add Error Handling for Preview Button (Handle empty data gracefully)
- Ensure 'Uncollect' Feature Functional (Maintain Uncollect feature functionality)
- Backend Performance & Connectivity (Investigate intermittent connection issues with Server 253)
- Update PDF Report Metadata (Replace 'Printed By' with validating user's name)
+- Reprint Label (Add functionality to reprint labels)
+- **Print Result Audit** (Track when result reports are printed/exported, log user and timestamp)
Completed:
- 01 : Update User Role levels (Standardize roles: Superuser, Admin, Lab, Phlebo, CS)
@@ -29,6 +29,9 @@ Completed:
- 12 : Remove 'status' field on dashboard
- 13 : Restrict 'Validate' to Lab, Admin, Superuser
- 14 : Hide/Disable 'Validation' button after 2nd validation (Prevent redundant validation actions)
+- 15 : Restrict 'UnValidate' to Admin, Superuser
+- 16 : Remove 'UnCollect'
+
Addition on dev :
- adding init-isDev on index.php to set default date on dev dashboard
\ No newline at end of file
diff --git a/README.md b/README.md
index 5da909d..1e4dc0b 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ This application uses role-based access control with four user roles.
- **Dashboard** - View all requests with status filters (Pend, Coll, Recv, Inc, Fin, Val)
- **User Management** - Create, edit, delete users; assign roles
- **Request Management** - View, validate, unvalidate all requests
-- **Sample Management** - Collect, uncollect, receive, unreceive samples
+- **Sample Management** - Collect, receive, unreceive samples
- **Result Management** - Preview and print results
#### Lab
diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 53fb98b..cc8cbfb 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -35,6 +35,7 @@ $routes->group('api', function ($routes) {
// 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->get('(:any)/audit', 'ApiRequestsAuditController::show/$1');
$routes->post('validate/(:any)', 'RequestsController::val/$1');
$routes->delete('validate/(:any)', 'RequestsController::unval/$1');
});
@@ -52,9 +53,8 @@ $routes->group('api', function ($routes) {
$routes->get('(:any)', 'SamplesController::show/$1');
});
- // Uncollect & Unreceive - Only Superuser (0) and Admin (1)
+ // 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');
});
});
diff --git a/app/Controllers/ApiRequestsAuditController.php b/app/Controllers/ApiRequestsAuditController.php
new file mode 100644
index 0000000..c620999
--- /dev/null
+++ b/app/Controllers/ApiRequestsAuditController.php
@@ -0,0 +1,52 @@
+ $accessnumber,
+ 'validation' => [],
+ 'sample_collection' => []
+ ];
+
+ $sqlAudit = "SELECT EVENT_TYPE, USERID, EVENT_AT, REASON
+ FROM GDC_CMOD.dbo.AUDIT_EVENTS
+ WHERE ACCESSNUMBER = ?
+ ORDER BY EVENT_AT ASC";
+ $auditRows = $db->query($sqlAudit, [$accessnumber])->getResultArray();
+
+ foreach ($auditRows as $row) {
+ $isUnval = $row['EVENT_TYPE'] === 'UNVAL';
+ $result['validation'][] = [
+ 'type' => $row['EVENT_TYPE'],
+ 'user' => trim($row['USERID']),
+ 'datetime' => $row['EVENT_AT'] ? date('Y-m-d H:i:s', strtotime($row['EVENT_AT'])) : null,
+ 'reason' => $isUnval ? trim($row['REASON']) : null
+ ];
+ }
+
+ $sqlTube = "SELECT TUBENUMBER, USERID, STATUS, LOGDATE
+ FROM GDC_CMOD.dbo.AUDIT_TUBES
+ WHERE ACCESSNUMBER = ?
+ ORDER BY LOGDATE ASC";
+ $tubeRows = $db->query($sqlTube, [$accessnumber])->getResultArray();
+
+ foreach ($tubeRows as $row) {
+ $action = $row['STATUS'] == 1 ? 'COLLECTED' : 'UNRECEIVED';
+ $result['sample_collection'][] = [
+ 'tubenumber' => trim($row['TUBENUMBER']),
+ 'user' => trim($row['USERID']),
+ 'datetime' => $row['LOGDATE'] ? date('Y-m-d H:i:s', strtotime($row['LOGDATE'])) : null,
+ 'action' => $action
+ ];
+ }
+
+ return $this->respond(['status' => 'success', 'data' => $result]);
+ }
+}
diff --git a/app/Controllers/LabelController.php b/app/Controllers/LabelController.php
index 8cc230a..9124fb1 100644
--- a/app/Controllers/LabelController.php
+++ b/app/Controllers/LabelController.php
@@ -6,7 +6,8 @@ class LabelController extends BaseController
public function coll($reqnum)
{
$db = \Config\Database::connect();
- //$reqnum = str_pad($reqnum, 10, 0, STR_PAD_LEFT);
+ $userid = session()->get('userid') ?? 'system';
+
$sql = "select p.PATNUMBER,
[Name] = case
when p.TITLEID is not null then ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') + ', ' + tx.SHORTTEXT
@@ -70,6 +71,8 @@ P1\n]";
public function dispatch($reqnum, $samid)
{
$db = \Config\Database::connect();
+ $userid = session()->get('userid') ?? 'system';
+
$sql = "select p.PATNUMBER,
[Name] = case
when p.TITLEID is not null then ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') + ', ' + tx.SHORTTEXT
@@ -147,6 +150,8 @@ P1
public function print_all($accessnumber)
{
$db = \Config\Database::connect();
+ $userid = session()->get('userid') ?? 'system';
+
$this->coll($accessnumber);
$sql = "select SAMPCODE from GDC_CMOD.dbo.v_sp_reqtube where SP_ACCESSNUMBER='$accessnumber'";
$rows = $db->query($sql)->getResultArray();
diff --git a/app/Controllers/Pages/AdminController.php b/app/Controllers/Pages/AdminController.php
index 1cfc957..c4a4f70 100644
--- a/app/Controllers/Pages/AdminController.php
+++ b/app/Controllers/Pages/AdminController.php
@@ -4,24 +4,29 @@ namespace App\Controllers\Pages;
use App\Controllers\BaseController;
-class AdminController extends BaseController {
+class AdminController extends BaseController
+{
- public function __construct() {
+ public function __construct()
+ {
helper(['url', 'form', 'text']);
}
- public function index() {
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ public function index()
+ {
+ $config = require APPPATH . 'Views/shared/config.php';
return view('admin/index', ['roleConfig' => $config['admin']]);
}
- public function users() {
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ public function users()
+ {
+ $config = require APPPATH . 'Views/shared/config.php';
return view('admin/users', ['roleConfig' => $config['admin']]);
}
- public function validationPage() {
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ public function validationPage()
+ {
+ $config = require APPPATH . 'Views/shared/config.php';
return view('admin/validate', ['roleConfig' => $config['admin']]);
}
diff --git a/app/Controllers/Pages/CsController.php b/app/Controllers/Pages/CsController.php
index cc65f84..c6e0c98 100644
--- a/app/Controllers/Pages/CsController.php
+++ b/app/Controllers/Pages/CsController.php
@@ -4,14 +4,17 @@ namespace App\Controllers\Pages;
use App\Controllers\BaseController;
-class CsController extends BaseController {
+class CsController extends BaseController
+{
- public function __construct() {
+ public function __construct()
+ {
helper(['url', 'form', 'text']);
}
- public function index() {
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ public function index()
+ {
+ $config = require APPPATH . 'Views/shared/config.php';
return view('cs/index', ['roleConfig' => $config['cs']]);
}
diff --git a/app/Controllers/Pages/LabController.php b/app/Controllers/Pages/LabController.php
index 7bc551e..bd6e41f 100644
--- a/app/Controllers/Pages/LabController.php
+++ b/app/Controllers/Pages/LabController.php
@@ -4,19 +4,23 @@ namespace App\Controllers\Pages;
use App\Controllers\BaseController;
-class LabController extends BaseController {
+class LabController extends BaseController
+{
- public function __construct() {
+ public function __construct()
+ {
helper(['url', 'form', 'text']);
}
- public function index() {
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ public function index()
+ {
+ $config = require APPPATH . 'Views/shared/config.php';
return view('lab/index', ['roleConfig' => $config['lab']]);
}
- public function validationPage() {
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ public function validationPage()
+ {
+ $config = require APPPATH . 'Views/shared/config.php';
return view('lab/validate', ['roleConfig' => $config['lab']]);
}
diff --git a/app/Controllers/Pages/PhlebotomistController.php b/app/Controllers/Pages/PhlebotomistController.php
index 4f33b8d..441ac82 100644
--- a/app/Controllers/Pages/PhlebotomistController.php
+++ b/app/Controllers/Pages/PhlebotomistController.php
@@ -4,14 +4,17 @@ namespace App\Controllers\Pages;
use App\Controllers\BaseController;
-class PhlebotomistController extends BaseController {
+class PhlebotomistController extends BaseController
+{
- public function __construct() {
+ public function __construct()
+ {
helper(['url', 'form', 'text']);
}
- public function index() {
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ public function index()
+ {
+ $config = require APPPATH . 'Views/shared/config.php';
return view('phlebo/index', ['roleConfig' => $config['phlebo']]);
}
diff --git a/app/Controllers/Pages/SuperuserController.php b/app/Controllers/Pages/SuperuserController.php
index 16185cb..329c8c7 100644
--- a/app/Controllers/Pages/SuperuserController.php
+++ b/app/Controllers/Pages/SuperuserController.php
@@ -14,19 +14,19 @@ class SuperuserController extends BaseController
public function index()
{
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ $config = require APPPATH . 'Views/shared/config.php';
return view('superuser/index', ['roleConfig' => $config['superuser']]);
}
public function users()
{
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ $config = require APPPATH . 'Views/shared/config.php';
return view('superuser/users', ['roleConfig' => $config['superuser']]);
}
public function validatePage()
{
- $config = require APPPATH . 'Views/shared/dashboard_config.php';
+ $config = require APPPATH . 'Views/shared/config.php';
return view('superuser/validate', ['roleConfig' => $config['superuser']]);
}
diff --git a/app/Controllers/RequestsController.php b/app/Controllers/RequestsController.php
index b2a09cf..02482d0 100644
--- a/app/Controllers/RequestsController.php
+++ b/app/Controllers/RequestsController.php
@@ -63,13 +63,17 @@ class RequestsController extends BaseController
public function unval($accessnumber)
{
$input = $this->request->getJSON(true);
- // 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);
+
+ $logAudit = "INSERT INTO GDC_CMOD.dbo.AUDIT_EVENTS (ACCESSNUMBER, EVENT_TYPE, USERID, EVENT_AT, REASON)
+ VALUES (?, 'UNVAL', ?, GETDATE(), ?)";
+ $db->query($logAudit, [$accessnumber, $userid, $comment]);
+
$data = ['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber"];
return $this->response->setJSON($data);
@@ -86,6 +90,10 @@ class RequestsController extends BaseController
if (!isset($result[0])) {
$sql = "insert into GDC_CMOD.dbo.CM_REQUESTS(ACCESSNUMBER, ISVAL1, VAL1USER, VAL1DATE) VALUES ('$accessnumber', 1, '$userid', GETDATE())";
$db->query($sql);
+
+ $logAudit = "INSERT INTO GDC_CMOD.dbo.AUDIT_EVENTS (ACCESSNUMBER, EVENT_TYPE, USERID, EVENT_AT) VALUES (?, 'VAL1', ?, GETDATE())";
+ $db->query($logAudit, [$accessnumber, $userid]);
+
$data['val'] = 1;
$data['userid'] = $userid;
} else {
@@ -99,6 +107,10 @@ class RequestsController extends BaseController
} else {
if ($val1user != $userid) {
$sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL2=1, VAL2USER='$userid', VAL2DATE=GETDATE() where ACCESSNUMBER='$accessnumber'";
+
+ $logAudit = "INSERT INTO GDC_CMOD.dbo.AUDIT_EVENTS (ACCESSNUMBER, EVENT_TYPE, USERID, EVENT_AT) VALUES (?, 'VAL2', ?, GETDATE())";
+ $db->query($logAudit, [$accessnumber, $userid]);
+
$data['val'] = 2;
$data['userid'] = $userid;
} else {
@@ -108,6 +120,10 @@ class RequestsController extends BaseController
}
} else {
$sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL1=1, VAL1USER='$userid', VAL1DATE=GETDATE() where ACCESSNUMBER='$accessnumber'";
+
+ $logAudit = "INSERT INTO GDC_CMOD.dbo.AUDIT_EVENTS (ACCESSNUMBER, EVENT_TYPE, USERID, EVENT_AT) VALUES (?, 'VAL1', ?, GETDATE())";
+ $db->query($logAudit, [$accessnumber, $userid]);
+
$data['val'] = 1;
$data['userid'] = $userid;
}
diff --git a/app/Controllers/SamplesController.php b/app/Controllers/SamplesController.php
index f6cecfa..205dbdd 100644
--- a/app/Controllers/SamplesController.php
+++ b/app/Controllers/SamplesController.php
@@ -76,20 +76,6 @@ class SamplesController extends BaseController
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
}
- public function uncollect($accessnumber)
- {
- $db = \Config\Database::connect();
- $input = $this->request->getJSON(true);
- $samplenumber = $input['samplenumber'];
- $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)
- VALUES ('$accessnumber', '$samplenumber', '$userid', '0', getdate())";
- $db->query($sql);
- return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
- }
-
public function unreceive($accessnumber)
{
$db = \Config\Database::connect();
diff --git a/app/Controllers/backup/Sample.php b/app/Controllers/backup/Sample.php
index 01f0d75..ef3bdce 100644
--- a/app/Controllers/backup/Sample.php
+++ b/app/Controllers/backup/Sample.php
@@ -72,19 +72,6 @@ class Sample extends BaseController {
return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201);
}
- public function uncollect($accessnumber) {
- $db = \Config\Database::connect();
- $input = $this->request->getJSON(true);
- $samplenumber = $input['samplenumber'];
- $userid = $input['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)
- VALUES ('$accessnumber', '$samplenumber', '$userid', '0', getdate())";
- $db->query($sql);
- return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201);
- }
-
public function unreceive($accessnumber) {
$db = \Config\Database::connect();
$input = $this->request->getJSON(true);
diff --git a/app/Views/admin/index.php b/app/Views/admin/index.php
index 6a0bd70..30d690d 100644
--- a/app/Views/admin/index.php
+++ b/app/Views/admin/index.php
@@ -1,22 +1,23 @@
-= $this->extend('shared/layout_dashboard', ['roleConfig' => $roleConfig]); ?>
+= $this->extend('shared/layout', ['roleConfig' => $roleConfig]); ?>
= $this->section('content'); ?>
- = $this->include('shared/dashboard_table', ['config' => $roleConfig]); ?>
+ = $this->include('shared/content_requests', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_sample', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_unval'); ?>
= $this->include('shared/dialog_preview'); ?>
+ = $this->include('shared/dialog_audit'); ?>
= $this->endSection(); ?>
= $this->section('script'); ?>
-= $this->endSection(); ?>
+= $this->endSection(); ?>
\ No newline at end of file
diff --git a/app/Views/admin/validate.php b/app/Views/admin/validate.php
index 37c18db..dd01237 100644
--- a/app/Views/admin/validate.php
+++ b/app/Views/admin/validate.php
@@ -1,19 +1,19 @@
-= $this->extend('shared/layout_dashboard', ['roleConfig' => $roleConfig]); ?>
+= $this->extend('shared/layout', ['roleConfig' => $roleConfig]); ?>
= $this->section('content'); ?>
- = $this->include('shared/dashboard_validate', ['config' => $roleConfig]); ?>
+ = $this->include('shared/content_validation', ['config' => $roleConfig]); ?>
= $this->endSection(); ?>
= $this->section('script'); ?>
-= $this->endSection(); ?>
+= $this->endSection(); ?>
\ No newline at end of file
diff --git a/app/Views/cs/index.php b/app/Views/cs/index.php
index 4872ef0..0163abb 100644
--- a/app/Views/cs/index.php
+++ b/app/Views/cs/index.php
@@ -1,22 +1,23 @@
-= $this->extend('shared/layout_dashboard', ['roleConfig' => $roleConfig]); ?>
+= $this->extend('shared/layout', ['roleConfig' => $roleConfig]); ?>
= $this->section('content'); ?>
- = $this->include('shared/dashboard_table', ['config' => $roleConfig]); ?>
+ = $this->include('shared/content_requests', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_sample', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_unval'); ?>
= $this->include('shared/dialog_preview'); ?>
+ = $this->include('shared/dialog_audit'); ?>
= $this->endSection(); ?>
= $this->section('script'); ?>
-= $this->endSection(); ?>
+= $this->endSection(); ?>
\ No newline at end of file
diff --git a/app/Views/dummy_page.php b/app/Views/dummy_page.php
index 8edb1cc..1db2b63 100644
--- a/app/Views/dummy_page.php
+++ b/app/Views/dummy_page.php
@@ -1,5 +1,6 @@
+
@@ -10,6 +11,7 @@
padding: 0;
box-sizing: border-box;
}
+
body {
min-height: 100vh;
display: flex;
@@ -22,51 +24,71 @@
text-align: center;
padding: 20px;
}
+
.container {
max-width: 600px;
}
+
h1 {
font-size: 3rem;
margin-bottom: 1rem;
animation: bounce 2s infinite;
}
+
@keyframes bounce {
- 0%, 100% { transform: translateY(0); }
- 50% { transform: translateY(-20px); }
+
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+
+ 50% {
+ transform: translateY(-20px);
+ }
}
+
.message {
font-size: 1.5rem;
margin-bottom: 2rem;
opacity: 0.9;
}
+
.loader {
width: 80px;
height: 80px;
- border: 8px solid rgba(255,255,255,0.3);
+ border: 8px solid rgba(255, 255, 255, 0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 2rem;
}
+
@keyframes spin {
- to { transform: rotate(360deg); }
+ to {
+ transform: rotate(360deg);
+ }
}
+
.cat {
font-size: 5rem;
margin-bottom: 1rem;
}
+
.fact {
- background: rgba(255,255,255,0.2);
+ background: rgba(255, 255, 255, 0.2);
padding: 1.5rem;
border-radius: 15px;
margin-top: 2rem;
}
+
.fact h3 {
margin-bottom: 0.5rem;
}
+
.buttons {
margin-top: 2rem;
}
+
.btn {
display: inline-block;
padding: 12px 30px;
@@ -78,16 +100,19 @@
font-weight: bold;
transition: transform 0.2s, box-shadow 0.2s;
}
+
.btn:hover {
transform: scale(1.05);
- box-shadow: 0 5px 20px rgba(0,0,0,0.3);
+ box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3);
}
+
.shrug {
font-size: 2rem;
margin: 1rem 0;
}
+
🙹 🧀 🦽
-
-
-
+
+