From 219c66b94b8d2a8f0e352b6caca7eb04ca457709 Mon Sep 17 00:00:00 2001 From: "sas.fajri" Date: Fri, 28 Aug 2026 16:20:15 +0700 Subject: [PATCH] BUG-DASH-280826 - sinkronkan field demografis pasien saat re-sync sp_generate_dashboard_data step 2 (mcu_patient) tidak menyertakan Mcu_PatientNIP, Gender, DOB, Department, Divisi, dan Posisi di ON DUPLICATE KEY UPDATE, sehingga sekali preregister ID ke-sync, field2 itu beku selamanya walau dikoreksi di source (cpone.mcu_preregister_patients). Terverifikasi: NIP Rina Hidayat di dashboard tetap salah walau sumbernya sudah dibetulkan, sampai kolom ini ditambahkan ke UPDATE clause. --- .../020_fix_patient_demographic_sync.sql | 247 ++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 cpone-dashboard/db/migrations/020_fix_patient_demographic_sync.sql diff --git a/cpone-dashboard/db/migrations/020_fix_patient_demographic_sync.sql b/cpone-dashboard/db/migrations/020_fix_patient_demographic_sync.sql new file mode 100644 index 0000000..35629ed --- /dev/null +++ b/cpone-dashboard/db/migrations/020_fix_patient_demographic_sync.sql @@ -0,0 +1,247 @@ +-- Migration 020: BUG-DASH-280826 +-- Fix sp_generate_dashboard_data step 2 (mcu_patient): +-- ON DUPLICATE KEY UPDATE tidak menyertakan Mcu_PatientNIP, Mcu_PatientGender, +-- Mcu_PatientDOB, Mcu_PatientDepartment, Mcu_PatientDivision, Mcu_PatientPosisi. +-- Akibatnya begitu satu preregister ID pertama kali ke-sync, kolom2 tsb beku +-- selamanya walau datanya dikoreksi di source (cpone.mcu_preregister_patients) — +-- misalnya NIP pasien yang salah ketik lalu dibetulkan di source tidak pernah +-- ikut terupdate di dashboard. +-- +-- Tambahkan kolom2 itu ke ON DUPLICATE KEY UPDATE supaya selalu mengikuti +-- kondisi sumber terkini, konsisten dengan Mcu_PatientName/Mcu_PatientIsActive +-- yang memang sudah di-refresh setiap sync. + +DROP PROCEDURE IF EXISTS sp_generate_dashboard_data; + +DELIMITER $$ + +CREATE PROCEDURE sp_generate_dashboard_data(IN p_mcu_id INT) +BEGIN + + -- ---------------------------------------------------------- + -- 1. mcu_project + -- ---------------------------------------------------------- + INSERT INTO mcu_project ( + Mcu_ProjectMcuID, Mcu_ProjectCorporateID, Mcu_ProjectCorporateName, + Mcu_ProjectNumber, Mcu_ProjectLabel, Mcu_ProjectBranchID, + Mcu_ProjectStartDate, Mcu_ProjectEndDate, Mcu_ProjectIsActive, + Mcu_ProjectTotalParticipant, Mcu_ProjectSyncedAt + ) + SELECT + m.Mgm_McuID, m.Mgm_McuCorporateID, c.CorporateName, + m.Mgm_McuNumber, m.Mgm_McuLabel, m.Mgm_McuM_BranchID, + m.Mgm_McuStartDate, m.Mgm_McuEndDate, m.Mgm_McuIsActive, + COALESCE(pp.total, 0), NOW() + FROM cpone.mgm_mcu m + LEFT JOIN cpone.corporate c ON c.CorporateID = m.Mgm_McuCorporateID + LEFT JOIN ( + SELECT Mcu_PreregisterPatientsMgm_McuID AS mcu_id, COUNT(*) AS total + FROM cpone.mcu_preregister_patients + WHERE Mcu_PreregisterPatientsMgm_McuID = p_mcu_id + AND Mcu_PreregisterPatientsIsActive = 'Y' + GROUP BY Mcu_PreregisterPatientsMgm_McuID + ) pp ON pp.mcu_id = m.Mgm_McuID + WHERE m.Mgm_McuID = p_mcu_id + ON DUPLICATE KEY UPDATE + Mcu_ProjectCorporateName = VALUES(Mcu_ProjectCorporateName), + Mcu_ProjectLabel = VALUES(Mcu_ProjectLabel), + Mcu_ProjectIsActive = VALUES(Mcu_ProjectIsActive), + Mcu_ProjectTotalParticipant = VALUES(Mcu_ProjectTotalParticipant), + Mcu_ProjectSyncedAt = NOW(); + + + -- ---------------------------------------------------------- + -- 2. mcu_patient (with age + pemeriksaan) + -- Semua kolom demografis (NIP, gender, DOB, department, divisi, posisi) + -- ikut di-refresh setiap sync supaya koreksi di source selalu terbawa. + -- ---------------------------------------------------------- + INSERT INTO mcu_patient ( + Mcu_PatientPreregisterID, Mcu_PatientMcuID, Mcu_PatientName, + Mcu_PatientNIP, Mcu_PatientGender, Mcu_PatientDOB, Mcu_PatientAge, + Mcu_PatientDepartment, Mcu_PatientDivision, Mcu_PatientPosisi, + Mcu_PatientPemeriksaan, + Mcu_PatientIsRegistered, Mcu_PatientOrderID, Mcu_PatientIsActive, + Mcu_PatientSyncedAt + ) + SELECT + p.Mcu_PreregisterPatientsID, p.Mcu_PreregisterPatientsMgm_McuID, + p.Mcu_PreregisterPatientsPatientName, p.Mcu_PreregisterPatientsNIP, + p.Mcu_PreregisterPatientsGender, p.Mcu_PreregisterPatientsDOB, + CAST(o.T_OrderHeaderM_PatientAge AS UNSIGNED), + p.Mcu_PreregisterPatientsDepartment, p.Mcu_PreregisterPatientsDivisi, + p.Mcu_PreregisterPatientsPosisi, + p.Mcu_PreregisterPatientsOrders, + p.Mcu_PreregisterPatientsIsRegistered, p.Mcu_PreregisterPatientsT_OrderHeaderID, + p.Mcu_PreregisterPatientsIsActive, NOW() + FROM cpone.mcu_preregister_patients p + LEFT JOIN cpone.t_orderheader o ON o.T_OrderHeaderID = p.Mcu_PreregisterPatientsT_OrderHeaderID + WHERE p.Mcu_PreregisterPatientsMgm_McuID = p_mcu_id + ON DUPLICATE KEY UPDATE + Mcu_PatientName = VALUES(Mcu_PatientName), + Mcu_PatientNIP = VALUES(Mcu_PatientNIP), + Mcu_PatientGender = VALUES(Mcu_PatientGender), + Mcu_PatientDOB = VALUES(Mcu_PatientDOB), + Mcu_PatientAge = VALUES(Mcu_PatientAge), + Mcu_PatientDepartment = VALUES(Mcu_PatientDepartment), + Mcu_PatientDivision = VALUES(Mcu_PatientDivision), + Mcu_PatientPosisi = VALUES(Mcu_PatientPosisi), + Mcu_PatientPemeriksaan = VALUES(Mcu_PatientPemeriksaan), + Mcu_PatientIsRegistered = VALUES(Mcu_PatientIsRegistered), + Mcu_PatientOrderID = VALUES(Mcu_PatientOrderID), + Mcu_PatientIsActive = VALUES(Mcu_PatientIsActive), + Mcu_PatientSyncedAt = NOW(); + + + -- ---------------------------------------------------------- + -- 3. mcu_patient_schedule + -- ---------------------------------------------------------- + INSERT INTO mcu_patient_schedule ( + Mcu_PatientSchedulePreregisterID, Mcu_PatientScheduleDate, + Mcu_PatientScheduleIsActive, Mcu_PatientScheduleSyncedAt + ) + SELECT + p.Mcu_PreregisterPatientsID, DATE(o.T_OrderHeaderDate), 'Y', NOW() + FROM cpone.mcu_preregister_patients p + JOIN cpone.t_orderheader o ON o.T_OrderHeaderID = p.Mcu_PreregisterPatientsT_OrderHeaderID + WHERE p.Mcu_PreregisterPatientsMgm_McuID = p_mcu_id + AND p.Mcu_PreregisterPatientsT_OrderHeaderID > 0 + AND p.Mcu_PreregisterPatientsIsActive = 'Y' + ON DUPLICATE KEY UPDATE + Mcu_PatientScheduleSyncedAt = NOW(); + + + -- ---------------------------------------------------------- + -- 4. mcu_checkinout + -- Source: cpone.preregister_checkin_checkout (log checkin/checkout asli + -- dari kiosk/front-desk) — BUKAN ditebak dari event lab. + -- CheckOutDate = '0000-00-00' artinya pasien belum checkout. + -- ---------------------------------------------------------- + INSERT INTO mcu_checkinout ( + Mcu_CheckinoutPreregisterID, Mcu_CheckinoutOrderID, + Mcu_CheckinoutDate, Mcu_CheckinoutInTime, Mcu_CheckinoutOutTime, + Mcu_CheckinoutOutUserID, Mcu_CheckinoutNextDate, Mcu_CheckinoutNote, + Mcu_CheckinoutIsActive, Mcu_CheckinoutSyncedAt, Mcu_CheckinoutMcuID + ) + SELECT + pcc.PreregisterCheckInCheckOutPreregisterID, + pcc.PreregisterCheckInCheckOutT_OrderHeaderID, + pcc.PreregisterCheckInCheckInDate, + pcc.PreregisterCheckInCheckOutInTime, + CASE + WHEN pcc.PreregisterCheckInCheckOutDate = '0000-00-00' THEN NULL + ELSE pcc.PreregisterCheckInCheckOutOutTime + END, + pcc.PreregisterCheckInCheckOutOutUserID, + CASE + WHEN pcc.PreregisterCheckInCheckOutNextPreregisterDate = '0000-00-00' THEN NULL + ELSE pcc.PreregisterCheckInCheckOutNextPreregisterDate + END, + NULLIF(pcc.PreregisterCheckInCheckOutNote, ''), + pcc.PreregisterCheckInCheckOutIsActive, + NOW(), + p_mcu_id + FROM cpone.preregister_checkin_checkout pcc + JOIN cpone.mcu_preregister_patients p + ON p.Mcu_PreregisterPatientsID = pcc.PreregisterCheckInCheckOutPreregisterID + WHERE p.Mcu_PreregisterPatientsMgm_McuID = p_mcu_id + AND p.Mcu_PreregisterPatientsIsActive = 'Y' + ON DUPLICATE KEY UPDATE + Mcu_CheckinoutOrderID = VALUES(Mcu_CheckinoutOrderID), + Mcu_CheckinoutOutTime = VALUES(Mcu_CheckinoutOutTime), + Mcu_CheckinoutOutUserID = VALUES(Mcu_CheckinoutOutUserID), + Mcu_CheckinoutNextDate = VALUES(Mcu_CheckinoutNextDate), + Mcu_CheckinoutNote = VALUES(Mcu_CheckinoutNote), + Mcu_CheckinoutIsActive = VALUES(Mcu_CheckinoutIsActive), + Mcu_CheckinoutSyncedAt = NOW(); + + + -- ---------------------------------------------------------- + -- 5. mcu_station_progress — lab + -- ---------------------------------------------------------- + INSERT INTO mcu_station_progress ( + Mcu_StationProgressOrderID, Mcu_StationProgressPreregisterID, Mcu_StationProgressMcuID, + Mcu_StationProgressStationID, Mcu_StationProgressStationName, Mcu_StationProgressSource, + Mcu_StationProgressCheckinDate, + Mcu_StationProgressSamplingAt, Mcu_StationProgressReceiveAt, Mcu_StationProgressProcessAt, + Mcu_StationProgressDoneAt, Mcu_StationProgressSyncedAt + ) + SELECT + o.T_OrderHeaderID, p.Mcu_PreregisterPatientsID, p_mcu_id, + s.T_OrderSampleT_SampleStationID, ss.T_SampleStationName, 'lab', + DATE(o.T_OrderHeaderDate), + NULLIF(MAX(TIMESTAMP(s.T_OrderSampleSamplingDate, s.T_OrderSampleSamplingTime)), '0000-00-00 00:00:00'), + NULLIF(MAX(TIMESTAMP(s.T_OrderSampleReceiveDate, s.T_OrderSampleReceiveTime)), '0000-00-00 00:00:00'), + NULLIF(MAX(TIMESTAMP(s.T_OrderSampleProcessingDate, s.T_OrderSampleProcessingTime)), '0000-00-00 00:00:00'), + NULL, NOW() + FROM cpone.mcu_preregister_patients p + JOIN cpone.t_orderheader o ON o.T_OrderHeaderID = p.Mcu_PreregisterPatientsT_OrderHeaderID + JOIN cpone.t_ordersample s ON s.T_OrderSampleT_OrderHeaderID = o.T_OrderHeaderID AND s.T_OrderSampleIsActive = 'Y' + JOIN cpone.t_samplestation ss ON ss.T_SampleStationID = s.T_OrderSampleT_SampleStationID + WHERE p.Mcu_PreregisterPatientsMgm_McuID = p_mcu_id + AND p.Mcu_PreregisterPatientsT_OrderHeaderID > 0 + AND p.Mcu_PreregisterPatientsIsActive = 'Y' + GROUP BY o.T_OrderHeaderID, p.Mcu_PreregisterPatientsID, s.T_OrderSampleT_SampleStationID, ss.T_SampleStationName, o.T_OrderHeaderDate + ON DUPLICATE KEY UPDATE + Mcu_StationProgressSamplingAt = VALUES(Mcu_StationProgressSamplingAt), + Mcu_StationProgressReceiveAt = VALUES(Mcu_StationProgressReceiveAt), + Mcu_StationProgressProcessAt = VALUES(Mcu_StationProgressProcessAt), + Mcu_StationProgressSyncedAt = NOW(); + + + -- ---------------------------------------------------------- + -- 6. mcu_station_progress — nonlab + -- ---------------------------------------------------------- + INSERT INTO mcu_station_progress ( + Mcu_StationProgressOrderID, Mcu_StationProgressPreregisterID, Mcu_StationProgressMcuID, + Mcu_StationProgressStationID, Mcu_StationProgressStationName, Mcu_StationProgressSource, + Mcu_StationProgressCheckinDate, + Mcu_StationProgressSamplingAt, Mcu_StationProgressReceiveAt, Mcu_StationProgressProcessAt, + Mcu_StationProgressDoneAt, Mcu_StationProgressSyncedAt + ) + SELECT + o.T_OrderHeaderID, p.Mcu_PreregisterPatientsID, p_mcu_id, + ts.T_SamplingSoT_SampleStationID, ss.T_SampleStationName, 'nonlab', + DATE(o.T_OrderHeaderDate), + NULL, NULL, + NULLIF(MAX(TIMESTAMP(ts.T_SamplingSoProcessDate, ts.T_SamplingSoProcessTime)), '0000-00-00 00:00:00'), + NULLIF(MAX(TIMESTAMP(ts.T_SamplingSoDoneDate, ts.T_SamplingSoDoneTime)), '0000-00-00 00:00:00'), + NOW() + FROM cpone.mcu_preregister_patients p + JOIN cpone.t_orderheader o ON o.T_OrderHeaderID = p.Mcu_PreregisterPatientsT_OrderHeaderID + JOIN cpone.t_samplingso ts ON ts.T_SamplingSoT_OrderHeaderID = o.T_OrderHeaderID AND ts.T_SamplingSoIsActive = 'Y' + JOIN cpone.t_samplestation ss ON ss.T_SampleStationID = ts.T_SamplingSoT_SampleStationID + WHERE p.Mcu_PreregisterPatientsMgm_McuID = p_mcu_id + AND p.Mcu_PreregisterPatientsT_OrderHeaderID > 0 + AND p.Mcu_PreregisterPatientsIsActive = 'Y' + GROUP BY o.T_OrderHeaderID, p.Mcu_PreregisterPatientsID, ts.T_SamplingSoT_SampleStationID, ss.T_SampleStationName, o.T_OrderHeaderDate + ON DUPLICATE KEY UPDATE + Mcu_StationProgressProcessAt = VALUES(Mcu_StationProgressProcessAt), + Mcu_StationProgressDoneAt = VALUES(Mcu_StationProgressDoneAt), + Mcu_StationProgressSyncedAt = NOW(); + + + -- ---------------------------------------------------------- + -- 7. mcu_patient_resume_status + -- ---------------------------------------------------------- + INSERT INTO mcu_patient_resume_status ( + Mcu_PatientResumeStatusPreregisterID, Mcu_PatientResumeStatusMcuID, + Mcu_PatientResumeStatusStatus, Mcu_PatientResumeStatusValidated, + Mcu_PatientResumeStatusPublished, Mcu_PatientResumeSyncedAt + ) + SELECT + p.Mcu_PreregisterPatientsID, p_mcu_id, + r.Mcu_ResumeStatus, r.Mcu_ResumeValidation, 'N', NOW() + FROM cpone.mcu_preregister_patients p + JOIN cpone.t_orderheader o ON o.T_OrderHeaderID = p.Mcu_PreregisterPatientsT_OrderHeaderID + LEFT JOIN cpone.mcu_resume r ON r.Mcu_ResumeT_OrderHeaderID = o.T_OrderHeaderID AND r.Mcu_ResumeIsActive = 'Y' + WHERE p.Mcu_PreregisterPatientsMgm_McuID = p_mcu_id + AND p.Mcu_PreregisterPatientsT_OrderHeaderID > 0 + AND p.Mcu_PreregisterPatientsIsActive = 'Y' + ON DUPLICATE KEY UPDATE + Mcu_PatientResumeStatusStatus = VALUES(Mcu_PatientResumeStatusStatus), + Mcu_PatientResumeStatusValidated = VALUES(Mcu_PatientResumeStatusValidated), + Mcu_PatientResumeSyncedAt = NOW(); + +END $$ + +DELIMITER ;