sp_generate_dashboard_data menebak Mcu_CheckinoutOutTime dari MAX() timestamp event lab (sample receive/sampling done), bukan dari checkout fisik pasien, sehingga pasien yang belum checkout bisa tampil "Checked Out" walau stationnya belum selesai. Ganti sumbernya ke cpone.preregister_checkin_checkout (log checkin/checkout asli) dan hentikan pemaksaan Mcu_CheckinoutID = order_id yang bentrok untuk project multi-hari. KPI "Checked Out" di GetKPI juga diselaraskan dengan detail pasien: sekarang hitung dari GetAllPatients dan mensyaratkan semua station wajib sudah selesai, bukan cuma checkout fisik saja, supaya angka KPI dan modal detail selalu sinkron.
247 lines
13 KiB
SQL
247 lines
13 KiB
SQL
-- 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 ;
|