tinyqc/app/Models/Qc/ResultCommentsModel.php
mahdahar 0a96b04bdf feat: Implement Monthly Entry interface and consolidate Entry API controller
- Implement Monthly Entry interface with full data entry grid
    - Add batch save with validation and statistics for monthly results
    - Support daily comments per day per test
    - Add result status indicators and validation summaries
  - Consolidate Entry API controller
    - Refactor EntryApiController to handle both daily/monthly operations
    - Add batch save endpoints with comprehensive validation
    - Implement statistics calculation for result entries
  - Add Control Test master data management
    - Create MasterControlsController for CRUD operations
    - Add dialog forms for control test configuration
    - Implement control-test associations with QC parameters
  - Refactor Report API and views
    - Implement new report index with Levey-Jennings charts placeholder
    - Add monthly report functionality with result statistics
    - Include QC summary with mean, SD, and CV calculations
  - UI improvements
    - Overhaul dashboard with improved layout
    - Update daily entry interface with inline editing
    - Enhance master data management with DaisyUI components
    - Add proper modal dialogs and form validation
  - Database and seeding
    - Update migration for control_tests table schema
    - Remove redundant migration and seed files
    - Update seeders with comprehensive test data
  - Documentation
    - Update CLAUDE.md with comprehensive project documentation
    - Add architecture overview and conventions

  BREAKING CHANGES:
  - Refactored Entry API endpoints structure
  - Removed ReportApiController::view() - consolidated into new report index
2026-01-21 13:41:37 +07:00

153 lines
4.4 KiB
PHP

<?php
namespace App\Models\Qc;
use App\Models\BaseModel;
class ResultCommentsModel extends BaseModel {
protected $table = 'result_comments';
protected $primaryKey = 'result_comment_id';
protected $allowedFields = [
'result_id',
'comment_text',
'created_at',
'updated_at',
'deleted_at'
];
protected $useTimestamps = true;
protected $useSoftDeletes = true;
public function search($keyword = null) {
if ($keyword) {
return $this->groupStart()
->like('comment_text', $keyword)
->groupEnd()
->findAll();
}
return $this->findAll();
}
/**
* Get comments by result_id
*/
public function getByResult(int $resultId): ?array {
return $this->where('result_id', $resultId)
->where('deleted_at', null)
->first();
}
/**
* Get all comments for a control+test combination (via results)
*/
public function getByControlTest(int $controlId, int $testId): ?array {
// First get result IDs for this control+test
$db = \Config\Database::connect();
$results = $db->table('results')
->select('result_id')
->where('control_id', $controlId)
->where('test_id', $testId)
->where('deleted_at', null)
->get()
->getResultArray();
if (empty($results)) {
return null;
}
$resultIds = array_column($results, 'result_id');
return $this->whereIn('result_id', $resultIds)
->where('deleted_at', null)
->orderBy('created_at', 'DESC')
->findAll();
}
/**
* Get all comments for a test (via results)
*/
public function getByTest(int $testId): array {
$db = \Config\Database::connect();
$results = $db->table('results')
->select('result_id')
->where('test_id', $testId)
->where('deleted_at', null)
->get()
->getResultArray();
if (empty($results)) {
return [];
}
$resultIds = array_column($results, 'result_id');
return $this->whereIn('result_id', $resultIds)
->where('deleted_at', null)
->findAll();
}
/**
* Get comments by control, test, and month (for reports)
*/
public function getByControlTestMonth(int $controlId, int $testId, string $month): ?array {
$db = \Config\Database::connect();
$results = $db->table('results')
->select('result_id')
->where('control_id', $controlId)
->where('test_id', $testId)
->where('res_date >=', $month . '-01')
->where('res_date <=', $month . '-31')
->where('deleted_at', null)
->get()
->getResultArray();
if (empty($results)) {
return null;
}
$resultIds = array_column($results, 'result_id');
$comments = $this->whereIn('result_id', $resultIds)
->where('deleted_at', null)
->orderBy('created_at', 'DESC')
->findAll();
return $comments ?: null;
}
/**
* Get comments for multiple results
*/
public function getByResultIds(array $resultIds): array {
if (empty($resultIds)) {
return [];
}
return $this->whereIn('result_id', $resultIds)
->where('deleted_at', null)
->findAll();
}
/**
* Upsert comment for a result
*/
public function upsertComment(array $data): int {
if (!isset($data['result_id'])) {
return 0;
}
$existing = $this->where('result_id', $data['result_id'])
->where('deleted_at', null)
->first();
if ($existing) {
if (empty($data['comment_text'])) {
// If text is empty, soft delete
$this->update($existing['result_comment_id'], ['deleted_at' => date('Y-m-d H:i:s')]);
return $existing['result_comment_id'];
}
$this->update($existing['result_comment_id'], $data);
return $existing['result_comment_id'];
} else {
if (empty($data['comment_text'])) {
return 0; // Don't insert empty comments
}
return $this->insert($data, true);
}
}
}