-- ==================================================================== -- Fix GetProfileSalaryExecutive to use calendar arithmetic -- This changes the years/months/days calculation from fixed formulas -- to actual calendar arithmetic, matching calculateGovAge behavior -- ==================================================================== DELIMITER $$ DROP PROCEDURE IF EXISTS `GetProfileSalaryExecutive`$$ CREATE DEFINER=`root`@`%` PROCEDURE `GetProfileSalaryExecutive`( IN personId VARCHAR(36), IN _date DATE ) BEGIN WITH ordered AS ( SELECT * FROM profileSalary WHERE profileId = personId AND commandCode IN ('0','1','2','3','4','8','9','10','11','12','13','14','15','16','20') AND positionExecutive <> '' ), work_session AS ( SELECT *, COALESCE( SUM(CASE WHEN commandCode IN (12,15,16) THEN 1 ELSE 0 END) OVER (ORDER BY commandDateAffect, commandDateSign ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), 0) AS sessionId FROM ordered ), session_end AS ( SELECT sessionId, MAX(commandDateAffect) AS sessionEndDate FROM work_session GROUP BY sessionId ), executive_change AS ( SELECT *, CASE WHEN LAG(positionExecutive) OVER (ORDER BY commandDateAffect, commandDateSign) = positionExecutive AND LAG(sessionId) OVER (ORDER BY commandDateAffect, commandDateSign) = sessionId THEN 0 ELSE 1 END AS isNewExecutive FROM work_session ), executive_group AS ( SELECT *, SUM(isNewExecutive) OVER (ORDER BY commandDateAffect, commandDateSign) AS execGroup FROM executive_change ), first_rows AS ( SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY execGroup ORDER BY commandDateAffect, commandDateSign) AS rnExec FROM executive_group ) t WHERE rnExec = 1 ), rows_with_duration AS ( SELECT fr.*, LEAD(fr.sessionId) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) AS nextSessionId, CASE WHEN LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) IS NULL THEN NULL WHEN LEAD(fr.sessionId) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) <> fr.sessionId THEN TIMESTAMPDIFF(DAY, fr.commandDateAffect, se.sessionEndDate) + 1 ELSE TIMESTAMPDIFF(DAY, fr.commandDateAffect, LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign)) END AS duration_days FROM first_rows fr LEFT JOIN session_end se ON se.sessionId = fr.sessionId ), resultWithDiff AS ( SELECT *, LAG(duration_days) OVER (ORDER BY commandDateAffect, commandDateSign) AS days_diff FROM rows_with_duration ) SELECT r.commandDateAffect, r.positionExecutive, r.days_diff, CASE WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN TIMESTAMPDIFF(YEAR, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) ELSE 0 END AS Years, CASE WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) % 12 ELSE 0 END AS Months, CASE WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN DATEDIFF(r.commandDateAffect, DATE_ADD( DATE_ADD(LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), INTERVAL TIMESTAMPDIFF(YEAR, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) YEAR), INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) % 12 MONTH) ) ELSE 0 END AS Days, r.posNo, r.positionType, r.positionLevel, r.positionCee, r.orgRoot, r.orgChild1, r.orgChild2, r.orgChild3, r.orgChild4, r.commandCode, r.commandName, r.commandNo, r.commandYear, r.remark FROM resultWithDiff r UNION ALL SELECT _date, NULL, TIMESTAMPDIFF(DAY, MAX(commandDateAffect), _date) + 1, TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date), TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12, DATEDIFF(_date, DATE_ADD( DATE_ADD(MAX(commandDateAffect), INTERVAL TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date) YEAR), INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12 MONTH) ), NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL FROM resultWithDiff; END$$ DELIMITER ;