* @link https://descomplicar.pt * @since 1.0.0 */ namespace Care_API\Services\Database; use Care_API\Models\Encounter; use Care_API\Services\Permission_Service; if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Class Encounter_Service * * Advanced database service for encounter management with business logic * * @since 1.0.0 */ class Encounter_Service { /** * Initialize the service * * @since 1.0.0 */ public static function init() { // Hook into WordPress actions add_action( 'kivicare_encounter_created', array( self::class, 'on_encounter_created' ), 10, 2 ); add_action( 'kivicare_encounter_updated', array( self::class, 'on_encounter_updated' ), 10, 2 ); add_action( 'kivicare_encounter_deleted', array( self::class, 'on_encounter_deleted' ), 10, 1 ); add_action( 'kivicare_encounter_finalized', array( self::class, 'on_encounter_finalized' ), 10, 1 ); } /** * Create encounter with advanced business logic * * @param array $encounter_data Encounter data * @param int $user_id Creating user ID * @return array|WP_Error Encounter data or error * @since 1.0.0 */ public static function create_encounter( $encounter_data, $user_id = null ) { // Permission check if ( ! Permission_Service::can_manage_encounters( get_current_user_id(), $encounter_data['clinic_id'] ?? 0 ) ) { return new \WP_Error( 'insufficient_permissions', 'You do not have permission to create encounters', array( 'status' => 403 ) ); } // Enhanced validation $validation = self::validate_encounter_business_rules( $encounter_data ); if ( is_wp_error( $validation ) ) { return $validation; } // Add metadata $encounter_data['created_by'] = $user_id ?: get_current_user_id(); $encounter_data['created_at'] = current_time( 'mysql' ); $encounter_data['status'] = 'draft'; // Default status // Generate encounter number if not provided if ( empty( $encounter_data['encounter_number'] ) ) { $encounter_data['encounter_number'] = self::generate_encounter_number( $encounter_data['clinic_id'] ); } // Set encounter date if not provided if ( empty( $encounter_data['encounter_date'] ) ) { $encounter_data['encounter_date'] = current_time( 'mysql' ); } // Create encounter $encounter_id = Encounter::create( $encounter_data ); if ( is_wp_error( $encounter_id ) ) { return $encounter_id; } // Post-creation tasks self::setup_encounter_defaults( $encounter_id, $encounter_data ); // Auto-link to appointment if provided if ( ! empty( $encounter_data['appointment_id'] ) ) { self::link_encounter_to_appointment( $encounter_id, $encounter_data['appointment_id'] ); } // Trigger action do_action( 'kivicare_encounter_created', $encounter_id, $encounter_data ); // Return full encounter data return self::get_encounter_with_metadata( $encounter_id ); } /** * Update encounter with business logic * * @param int $encounter_id Encounter ID * @param array $encounter_data Updated data * @return array|WP_Error Updated encounter data or error * @since 1.0.0 */ public static function update_encounter( $encounter_id, $encounter_data ) { // Get current encounter data $current_encounter = Encounter::get_by_id( $encounter_id ); if ( ! $current_encounter ) { return new \WP_Error( 'encounter_not_found', 'Encounter not found', array( 'status' => 404 ) ); } // Permission check if ( ! Permission_Service::can_manage_encounters( get_current_user_id(), $current_encounter['clinic_id'] ) ) { return new \WP_Error( 'insufficient_permissions', 'You do not have permission to update this encounter', array( 'status' => 403 ) ); } // Check if encounter is finalized if ( $current_encounter['status'] === 'finalized' ) { return new \WP_Error( 'encounter_finalized', 'Cannot update a finalized encounter', array( 'status' => 400 ) ); } // Enhanced validation $validation = self::validate_encounter_business_rules( $encounter_data, $encounter_id ); if ( is_wp_error( $validation ) ) { return $validation; } // Add update metadata $encounter_data['updated_by'] = get_current_user_id(); $encounter_data['updated_at'] = current_time( 'mysql' ); // Update encounter $result = Encounter::update( $encounter_id, $encounter_data ); if ( is_wp_error( $result ) ) { return $result; } // Handle status changes self::handle_status_changes( $encounter_id, $current_encounter, $encounter_data ); // Handle SOAP notes updates if ( isset( $encounter_data['soap_notes'] ) ) { self::update_soap_notes( $encounter_id, $encounter_data['soap_notes'] ); } // Handle vital signs updates if ( isset( $encounter_data['vital_signs'] ) ) { self::update_vital_signs( $encounter_id, $encounter_data['vital_signs'] ); } // Trigger action do_action( 'kivicare_encounter_updated', $encounter_id, $encounter_data ); // Return updated encounter data return self::get_encounter_with_metadata( $encounter_id ); } /** * Finalize encounter * * @param int $encounter_id Encounter ID * @param array $final_data Final data * @return array|WP_Error Updated encounter data or error * @since 1.0.0 */ public static function finalize_encounter( $encounter_id, $final_data = array() ) { $encounter = Encounter::get_by_id( $encounter_id ); if ( ! $encounter ) { return new \WP_Error( 'encounter_not_found', 'Encounter not found', array( 'status' => 404 ) ); } // Permission check if ( ! Permission_Service::can_manage_encounters( get_current_user_id(), $encounter['clinic_id'] ) ) { return new \WP_Error( 'insufficient_permissions', 'You do not have permission to finalize this encounter', array( 'status' => 403 ) ); } // Check if already finalized if ( $encounter['status'] === 'finalized' ) { return new \WP_Error( 'already_finalized', 'Encounter is already finalized', array( 'status' => 400 ) ); } // Validate required data for finalization $validation = self::validate_finalization_requirements( $encounter_id ); if ( is_wp_error( $validation ) ) { return $validation; } // Update encounter status $update_data = array_merge( $final_data, array( 'status' => 'finalized', 'finalized_by' => get_current_user_id(), 'finalized_at' => current_time( 'mysql' ), 'updated_at' => current_time( 'mysql' ) )); $result = Encounter::update( $encounter_id, $update_data ); if ( is_wp_error( $result ) ) { return $result; } // Post-finalization tasks self::handle_finalization_tasks( $encounter_id ); // Trigger action do_action( 'kivicare_encounter_finalized', $encounter_id ); return self::get_encounter_with_metadata( $encounter_id ); } /** * Get encounter with enhanced metadata * * @param int $encounter_id Encounter ID * @return array|WP_Error Encounter data with metadata or error * @since 1.0.0 */ public static function get_encounter_with_metadata( $encounter_id ) { $encounter = Encounter::get_by_id( $encounter_id ); if ( ! $encounter ) { return new \WP_Error( 'encounter_not_found', 'Encounter not found', array( 'status' => 404 ) ); } // Permission check if ( ! Permission_Service::can_view_encounter( get_current_user_id(), $encounter_id ) ) { return new \WP_Error( 'access_denied', 'You do not have access to this encounter', array( 'status' => 403 ) ); } // Add enhanced metadata $encounter['patient'] = self::get_encounter_patient( $encounter['patient_id'] ); $encounter['doctor'] = self::get_encounter_doctor( $encounter['doctor_id'] ); $encounter['clinic'] = self::get_encounter_clinic( $encounter['clinic_id'] ); $encounter['appointment'] = self::get_encounter_appointment( $encounter['appointment_id'] ?? null ); $encounter['soap_notes'] = self::get_soap_notes( $encounter_id ); $encounter['vital_signs'] = self::get_vital_signs( $encounter_id ); $encounter['diagnoses'] = self::get_encounter_diagnoses( $encounter_id ); $encounter['prescriptions'] = self::get_encounter_prescriptions( $encounter_id ); $encounter['attachments'] = self::get_encounter_attachments( $encounter_id ); $encounter['bills'] = self::get_encounter_bills( $encounter_id ); return $encounter; } /** * Search encounters with advanced criteria * * @param array $filters Search filters * @return array Search results * @since 1.0.0 */ public static function search_encounters( $filters = array() ) { global $wpdb; $user_id = get_current_user_id(); $accessible_clinic_ids = Permission_Service::get_accessible_clinic_ids( $user_id ); if ( empty( $accessible_clinic_ids ) ) { return array(); } // Build search query $where_clauses = array( "e.clinic_id IN (" . implode( ',', $accessible_clinic_ids ) . ")" ); $where_values = array(); // Date range filter if ( ! empty( $filters['start_date'] ) ) { $where_clauses[] = "DATE(e.encounter_date) >= %s"; $where_values[] = $filters['start_date']; } if ( ! empty( $filters['end_date'] ) ) { $where_clauses[] = "DATE(e.encounter_date) <= %s"; $where_values[] = $filters['end_date']; } // Doctor filter if ( ! empty( $filters['doctor_id'] ) ) { $where_clauses[] = "e.doctor_id = %d"; $where_values[] = $filters['doctor_id']; } // Patient filter if ( ! empty( $filters['patient_id'] ) ) { $where_clauses[] = "e.patient_id = %d"; $where_values[] = $filters['patient_id']; } // Clinic filter if ( ! empty( $filters['clinic_id'] ) && in_array( $filters['clinic_id'], $accessible_clinic_ids ) ) { $where_clauses[] = "e.clinic_id = %d"; $where_values[] = $filters['clinic_id']; } // Status filter if ( ! empty( $filters['status'] ) ) { if ( is_array( $filters['status'] ) ) { $status_placeholders = implode( ',', array_fill( 0, count( $filters['status'] ), '%s' ) ); $where_clauses[] = "e.status IN ({$status_placeholders})"; $where_values = array_merge( $where_values, $filters['status'] ); } else { $where_clauses[] = "e.status = %s"; $where_values[] = $filters['status']; } } // Search term if ( ! empty( $filters['search'] ) ) { $where_clauses[] = "(p.first_name LIKE %s OR p.last_name LIKE %s OR d.first_name LIKE %s OR d.last_name LIKE %s OR e.encounter_number LIKE %s OR e.chief_complaint LIKE %s)"; $search_term = '%' . $wpdb->esc_like( $filters['search'] ) . '%'; $where_values = array_merge( $where_values, array_fill( 0, 6, $search_term ) ); } $where_sql = implode( ' AND ', $where_clauses ); // Pagination $limit = isset( $filters['limit'] ) ? (int) $filters['limit'] : 20; $offset = isset( $filters['offset'] ) ? (int) $filters['offset'] : 0; $query = "SELECT e.*, p.first_name as patient_first_name, p.last_name as patient_last_name, d.first_name as doctor_first_name, d.last_name as doctor_last_name, c.name as clinic_name FROM {$wpdb->prefix}kc_encounters e LEFT JOIN {$wpdb->prefix}kc_patients p ON e.patient_id = p.id LEFT JOIN {$wpdb->prefix}kc_doctors d ON e.doctor_id = d.id LEFT JOIN {$wpdb->prefix}kc_clinics c ON e.clinic_id = c.id WHERE {$where_sql} ORDER BY e.encounter_date DESC LIMIT {$limit} OFFSET {$offset}"; if ( ! empty( $where_values ) ) { $results = $wpdb->get_results( $wpdb->prepare( $query, $where_values ), ARRAY_A ); } else { $results = $wpdb->get_results( $query, ARRAY_A ); } // Get total count for pagination $count_query = "SELECT COUNT(*) FROM {$wpdb->prefix}kc_encounters e LEFT JOIN {$wpdb->prefix}kc_patients p ON e.patient_id = p.id LEFT JOIN {$wpdb->prefix}kc_doctors d ON e.doctor_id = d.id WHERE {$where_sql}"; if ( ! empty( $where_values ) ) { $total = (int) $wpdb->get_var( $wpdb->prepare( $count_query, $where_values ) ); } else { $total = (int) $wpdb->get_var( $count_query ); } return array( 'encounters' => array_map( function( $encounter ) { $encounter['id'] = (int) $encounter['id']; return $encounter; }, $results ), 'total' => $total, 'has_more' => ( $offset + $limit ) < $total ); } /** * Get patient encounter history * * @param int $patient_id Patient ID * @param int $limit Limit * @return array Encounter history * @since 1.0.0 */ public static function get_patient_encounter_history( $patient_id, $limit = 10 ) { global $wpdb; $user_id = get_current_user_id(); $accessible_clinic_ids = Permission_Service::get_accessible_clinic_ids( $user_id ); if ( empty( $accessible_clinic_ids ) ) { return array(); } $query = "SELECT e.*, d.first_name as doctor_first_name, d.last_name as doctor_last_name, c.name as clinic_name FROM {$wpdb->prefix}kc_encounters e LEFT JOIN {$wpdb->prefix}kc_doctors d ON e.doctor_id = d.id LEFT JOIN {$wpdb->prefix}kc_clinics c ON e.clinic_id = c.id WHERE e.patient_id = %d AND e.clinic_id IN (" . implode( ',', $accessible_clinic_ids ) . ") ORDER BY e.encounter_date DESC LIMIT %d"; $results = $wpdb->get_results( $wpdb->prepare( $query, $patient_id, $limit ), ARRAY_A ); return array_map( function( $encounter ) { $encounter['id'] = (int) $encounter['id']; $encounter['soap_notes'] = self::get_soap_notes( $encounter['id'] ); $encounter['diagnoses'] = self::get_encounter_diagnoses( $encounter['id'] ); return $encounter; }, $results ); } /** * Generate unique encounter number * * @param int $clinic_id Clinic ID * @return string Encounter number * @since 1.0.0 */ private static function generate_encounter_number( $clinic_id ) { global $wpdb; $prefix = 'E' . str_pad( $clinic_id, 3, '0', STR_PAD_LEFT ) . date( 'ym' ); // Get the highest existing encounter number for this clinic and month $max_number = $wpdb->get_var( $wpdb->prepare( "SELECT MAX(CAST(SUBSTRING(encounter_number, 8) AS UNSIGNED)) FROM {$wpdb->prefix}kc_encounters WHERE encounter_number LIKE %s", $prefix . '%' ) ); $next_number = ( $max_number ? $max_number + 1 : 1 ); return $prefix . str_pad( $next_number, 4, '0', STR_PAD_LEFT ); } /** * Validate encounter business rules * * @param array $encounter_data Encounter data * @param int $encounter_id Encounter ID (for updates) * @return bool|WP_Error True if valid, WP_Error otherwise * @since 1.0.0 */ private static function validate_encounter_business_rules( $encounter_data, $encounter_id = null ) { $errors = array(); // Validate required fields $required_fields = array( 'patient_id', 'doctor_id', 'clinic_id' ); foreach ( $required_fields as $field ) { if ( empty( $encounter_data[$field] ) ) { $errors[] = "Field {$field} is required"; } } // Validate patient exists if ( ! empty( $encounter_data['patient_id'] ) ) { global $wpdb; $patient_exists = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}kc_patients WHERE id = %d", $encounter_data['patient_id'] ) ); if ( ! $patient_exists ) { $errors[] = 'Invalid patient ID'; } } // Validate doctor exists if ( ! empty( $encounter_data['doctor_id'] ) ) { global $wpdb; $doctor_exists = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}kc_doctors WHERE id = %d", $encounter_data['doctor_id'] ) ); if ( ! $doctor_exists ) { $errors[] = 'Invalid doctor ID'; } } // Validate clinic exists if ( ! empty( $encounter_data['clinic_id'] ) ) { global $wpdb; $clinic_exists = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}kc_clinics WHERE id = %d", $encounter_data['clinic_id'] ) ); if ( ! $clinic_exists ) { $errors[] = 'Invalid clinic ID'; } } // Validate appointment if provided if ( ! empty( $encounter_data['appointment_id'] ) ) { global $wpdb; $appointment_exists = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}kc_appointments WHERE id = %d", $encounter_data['appointment_id'] ) ); if ( ! $appointment_exists ) { $errors[] = 'Invalid appointment ID'; } } if ( ! empty( $errors ) ) { return new \WP_Error( 'encounter_business_validation_failed', 'Encounter business validation failed', array( 'status' => 400, 'errors' => $errors ) ); } return true; } /** * Validate finalization requirements * * @param int $encounter_id Encounter ID * @return bool|WP_Error True if valid, WP_Error otherwise * @since 1.0.0 */ private static function validate_finalization_requirements( $encounter_id ) { $encounter = Encounter::get_by_id( $encounter_id ); $errors = array(); // Check if chief complaint is provided if ( empty( $encounter['chief_complaint'] ) ) { $errors[] = 'Chief complaint is required for finalization'; } // Check if at least one SOAP note section is filled $soap_notes = self::get_soap_notes( $encounter_id ); if ( empty( $soap_notes['subjective'] ) && empty( $soap_notes['objective'] ) && empty( $soap_notes['assessment'] ) && empty( $soap_notes['plan'] ) ) { $errors[] = 'At least one SOAP note section must be completed for finalization'; } if ( ! empty( $errors ) ) { return new \WP_Error( 'encounter_finalization_validation_failed', 'Encounter finalization validation failed', array( 'status' => 400, 'errors' => $errors ) ); } return true; } /** * Setup encounter defaults after creation * * @param int $encounter_id Encounter ID * @param array $encounter_data Encounter data * @since 1.0.0 */ private static function setup_encounter_defaults( $encounter_id, $encounter_data ) { // Initialize SOAP notes structure self::initialize_soap_notes( $encounter_id ); // Initialize vital signs structure self::initialize_vital_signs( $encounter_id ); // Setup encounter preferences self::setup_encounter_preferences( $encounter_id ); } /** * Link encounter to appointment * * @param int $encounter_id Encounter ID * @param int $appointment_id Appointment ID * @since 1.0.0 */ private static function link_encounter_to_appointment( $encounter_id, $appointment_id ) { global $wpdb; // Update appointment with encounter reference $wpdb->update( $wpdb->prefix . 'kc_appointments', array( 'encounter_id' => $encounter_id ), array( 'id' => $appointment_id ), array( '%d' ), array( '%d' ) ); } /** * Handle status changes * * @param int $encounter_id Encounter ID * @param array $current_encounter Current encounter data * @param array $new_data New data * @since 1.0.0 */ private static function handle_status_changes( $encounter_id, $current_encounter, $new_data ) { if ( isset( $new_data['status'] ) && $new_data['status'] != $current_encounter['status'] ) { $status_change = array( 'encounter_id' => $encounter_id, 'from_status' => $current_encounter['status'], 'to_status' => $new_data['status'], 'changed_by' => get_current_user_id(), 'changed_at' => current_time( 'mysql' ) ); do_action( 'kivicare_encounter_status_changed', $status_change ); } } /** * Handle finalization tasks * * @param int $encounter_id Encounter ID * @since 1.0.0 */ private static function handle_finalization_tasks( $encounter_id ) { // Generate encounter summary self::generate_encounter_summary( $encounter_id ); // Auto-create follow-up reminders if needed self::create_follow_up_reminders( $encounter_id ); // Update patient medical history self::update_patient_medical_history( $encounter_id ); } /** * Helper methods for encounter data management */ private static function initialize_soap_notes( $encounter_id ) { $default_soap = array( 'subjective' => '', 'objective' => '', 'assessment' => '', 'plan' => '' ); update_option( "kivicare_encounter_{$encounter_id}_soap_notes", $default_soap ); } private static function initialize_vital_signs( $encounter_id ) { $default_vitals = array( 'temperature' => '', 'blood_pressure_systolic' => '', 'blood_pressure_diastolic' => '', 'heart_rate' => '', 'respiratory_rate' => '', 'oxygen_saturation' => '', 'weight' => '', 'height' => '', 'bmi' => '' ); update_option( "kivicare_encounter_{$encounter_id}_vital_signs", $default_vitals ); } private static function setup_encounter_preferences( $encounter_id ) { $default_preferences = array( 'auto_save' => true, 'show_patient_history' => true, 'template_type' => 'standard' ); update_option( "kivicare_encounter_{$encounter_id}_preferences", $default_preferences ); } private static function update_soap_notes( $encounter_id, $soap_notes ) { update_option( "kivicare_encounter_{$encounter_id}_soap_notes", $soap_notes ); } private static function update_vital_signs( $encounter_id, $vital_signs ) { // Calculate BMI if height and weight are provided if ( ! empty( $vital_signs['height'] ) && ! empty( $vital_signs['weight'] ) ) { $height_m = $vital_signs['height'] / 100; // Convert cm to meters $vital_signs['bmi'] = round( $vital_signs['weight'] / ( $height_m * $height_m ), 2 ); } update_option( "kivicare_encounter_{$encounter_id}_vital_signs", $vital_signs ); } private static function get_soap_notes( $encounter_id ) { return get_option( "kivicare_encounter_{$encounter_id}_soap_notes", array() ); } private static function get_vital_signs( $encounter_id ) { return get_option( "kivicare_encounter_{$encounter_id}_vital_signs", array() ); } private static function get_encounter_patient( $patient_id ) { global $wpdb; return $wpdb->get_row( $wpdb->prepare( "SELECT id, first_name, last_name, user_email, contact_no, dob, gender FROM {$wpdb->prefix}kc_patients WHERE id = %d", $patient_id ), ARRAY_A ); } private static function get_encounter_doctor( $doctor_id ) { global $wpdb; return $wpdb->get_row( $wpdb->prepare( "SELECT id, first_name, last_name, user_email, mobile_number, specialties FROM {$wpdb->prefix}kc_doctors WHERE id = %d", $doctor_id ), ARRAY_A ); } private static function get_encounter_clinic( $clinic_id ) { global $wpdb; return $wpdb->get_row( $wpdb->prepare( "SELECT id, name, address, city, telephone_no FROM {$wpdb->prefix}kc_clinics WHERE id = %d", $clinic_id ), ARRAY_A ); } private static function get_encounter_appointment( $appointment_id ) { if ( ! $appointment_id ) return null; global $wpdb; return $wpdb->get_row( $wpdb->prepare( "SELECT id, appointment_number, appointment_start_date, appointment_start_time, status FROM {$wpdb->prefix}kc_appointments WHERE id = %d", $appointment_id ), ARRAY_A ); } private static function get_encounter_diagnoses( $encounter_id ) { return get_option( "kivicare_encounter_{$encounter_id}_diagnoses", array() ); } private static function get_encounter_prescriptions( $encounter_id ) { global $wpdb; return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}kc_prescriptions WHERE encounter_id = %d ORDER BY created_at DESC", $encounter_id ), ARRAY_A ); } private static function get_encounter_attachments( $encounter_id ) { return get_option( "kivicare_encounter_{$encounter_id}_attachments", array() ); } private static function get_encounter_bills( $encounter_id ) { global $wpdb; return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}kc_bills WHERE encounter_id = %d ORDER BY created_at DESC", $encounter_id ), ARRAY_A ); } private static function generate_encounter_summary( $encounter_id ) { $encounter = Encounter::get_by_id( $encounter_id ); $soap_notes = self::get_soap_notes( $encounter_id ); $summary = array( 'encounter_id' => $encounter_id, 'chief_complaint' => $encounter['chief_complaint'], 'key_findings' => $soap_notes['objective'] ?? '', 'diagnosis' => $soap_notes['assessment'] ?? '', 'treatment_plan' => $soap_notes['plan'] ?? '', 'generated_at' => current_time( 'mysql' ) ); update_option( "kivicare_encounter_{$encounter_id}_summary", $summary ); } private static function create_follow_up_reminders( $encounter_id ) { // This would create follow-up reminders based on the treatment plan // Implementation depends on reminder system } private static function update_patient_medical_history( $encounter_id ) { $encounter = Encounter::get_by_id( $encounter_id ); $patient_id = $encounter['patient_id']; $medical_history = get_option( "kivicare_patient_{$patient_id}_medical_history", array() ); // Add this encounter to patient history if ( ! isset( $medical_history['encounters'] ) ) { $medical_history['encounters'] = array(); } $medical_history['encounters'][] = array( 'encounter_id' => $encounter_id, 'date' => $encounter['encounter_date'], 'chief_complaint' => $encounter['chief_complaint'], 'doctor_id' => $encounter['doctor_id'], 'clinic_id' => $encounter['clinic_id'] ); update_option( "kivicare_patient_{$patient_id}_medical_history", $medical_history ); } /** * Event handlers */ public static function on_encounter_created( $encounter_id, $encounter_data ) { error_log( "Care: New encounter created - ID: {$encounter_id}, Patient: " . ( $encounter_data['patient_id'] ?? 'Unknown' ) ); } public static function on_encounter_updated( $encounter_id, $encounter_data ) { error_log( "Care: Encounter updated - ID: {$encounter_id}" ); wp_cache_delete( "encounter_{$encounter_id}", 'kivicare' ); } public static function on_encounter_deleted( $encounter_id ) { // Clean up related data delete_option( "kivicare_encounter_{$encounter_id}_soap_notes" ); delete_option( "kivicare_encounter_{$encounter_id}_vital_signs" ); delete_option( "kivicare_encounter_{$encounter_id}_preferences" ); delete_option( "kivicare_encounter_{$encounter_id}_diagnoses" ); delete_option( "kivicare_encounter_{$encounter_id}_attachments" ); delete_option( "kivicare_encounter_{$encounter_id}_summary" ); wp_cache_delete( "encounter_{$encounter_id}", 'kivicare' ); error_log( "Care: Encounter deleted - ID: {$encounter_id}" ); } public static function on_encounter_finalized( $encounter_id ) { error_log( "Care: Encounter finalized - ID: {$encounter_id}" ); wp_cache_delete( "encounter_{$encounter_id}", 'kivicare' ); } }