-- Migration 019: Cpone-BUG-00024 -- Fix sp_generate_dashboard_data step 4 (mcu_checkinout): -- Sebelumnya Mcu_CheckinoutOutTime "ditebak" dari MAX(event_dt) gabungan -- T_OrderHeaderDate, T_OrderSampleReceiveDate/Time, dan T_SamplingSoDoneDate/Time. -- Ini SALAH karena event2 itu adalah aktivitas lab, bukan checkout fisik pasien — -- akibatnya pasien yang belum checkout (masih di lokasi) bisa muncul sebagai -- "Checked Out" di dashboard hanya karena sample-nya sudah diterima/diproses lab. -- -- Sumber checkout yang benar adalah cpone.preregister_checkin_checkout (lihat -- komentar kolom di db/migrations/001_init_schema.sql yang memang sudah -- mendokumentasikan tabel ini sebagai sumber asli mcu_checkinout, tapi belum -- pernah dipakai oleh stored procedure manapun sebelumnya). -- PreregisterCheckInCheckOutDate = '0000-00-00' berarti pasien tsb belum checkout. -- -- Efek samping perbaikan ini: Mcu_CheckinoutID tidak lagi dipaksa = order_id, -- supaya project multi-hari (1 preregister/order bisa checkin-checkout di -- beberapa tanggal berbeda) tidak saling bentrok pada primary key. Idempotensi -- re-sync tetap dijaga oleh UNIQUE KEY uq_checkinout_segment -- (Mcu_CheckinoutPreregisterID, Mcu_CheckinoutDate, Mcu_CheckinoutInTime). 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) -- ---------------------------------------------------------- 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_PatientAge = VALUES(Mcu_PatientAge), 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 ;