sozsoft-platform/configs/seeds/postgres/object/Hr_F_LeaveWorkDays.sql

77 lines
2.9 KiB
MySQL
Raw Normal View History

2026-10-06 11:24:30 +00:00
CREATE OR REPLACE FUNCTION public."Hr_F_LeaveWorkDays"
(
p_TenantId uuid,
p_StartDate date,
p_EndDate date
)
RETURNS numeric(9, 1)
LANGUAGE plpgsql
STABLE
AS $$
DECLARE
v_Work boolean[];
v_Total numeric(9, 1) := 0;
v_Day date := p_StartDate;
v_Value numeric(3, 1);
v_Calendar numeric(3, 1);
BEGIN
-- İzin günü = ayarlarda çalışma günü işaretli olup Çalışma Takvimi'nde tatil olmayan gün.
-- Yarım gün (arife) 0,5 sayılır. Yıllık tekrarlı satır başlangıç yılından itibaren her yıl
-- aynı gün/ay aralığına düşer (29 Şubat artık olmayan yılda 28 Şubat'a kayar).
IF p_StartDate IS NULL OR p_EndDate IS NULL OR p_EndDate < p_StartDate THEN
RETURN 0;
END IF;
-- Gün sırası Pazartesi = 1 (ISODOW). Ayar tanımı yoksa Pzt–Cum.
SELECT array_agg(
CASE
WHEN s.v IS NULL THEN d.DayIndex <= 5
WHEN lower(s.v) = 'true' THEN TRUE
ELSE FALSE
END
ORDER BY d.DayIndex)
INTO v_Work
FROM (VALUES
(1, 'App.HrSettings.Leave.WorkMonday'),
(2, 'App.HrSettings.Leave.WorkTuesday'),
(3, 'App.HrSettings.Leave.WorkWednesday'),
(4, 'App.HrSettings.Leave.WorkThursday'),
(5, 'App.HrSettings.Leave.WorkFriday'),
(6, 'App.HrSettings.Leave.WorkSaturday'),
(7, 'App.HrSettings.Leave.WorkSunday')) d (DayIndex, SettingName)
CROSS JOIN LATERAL (SELECT public."Hr_F_HrSetting"(p_TenantId, d.SettingName) AS v) s;
WHILE v_Day <= p_EndDate LOOP
v_Value := 0;
IF v_Work[EXTRACT(ISODOW FROM v_Day)::int] THEN
v_Value := 1;
SELECT CASE WHEN MAX(CASE WHEN c."DayType" = 'Holiday' THEN 1 ELSE 0 END) = 1 THEN 0 ELSE 0.5 END
INTO v_Calendar
FROM "Hr_T_WorkCalendar" c
WHERE c."IsDeleted" = FALSE AND c."IsActive" = TRUE
AND c."TenantId" IS NOT DISTINCT FROM p_TenantId
AND (
((c."RecurrenceRule" IS NULL OR c."RecurrenceRule" = '') AND v_Day BETWEEN c."StartDate" AND c."EndDate")
OR (c."RecurrenceRule" = 'FREQ=YEARLY'
AND EXTRACT(YEAR FROM v_Day) >= EXTRACT(YEAR FROM c."StartDate")
AND v_Day BETWEEN (c."StartDate" + make_interval(years => (EXTRACT(YEAR FROM v_Day) - EXTRACT(YEAR FROM c."StartDate"))::int))::date
AND (c."EndDate" + make_interval(years => (EXTRACT(YEAR FROM v_Day) - EXTRACT(YEAR FROM c."StartDate"))::int))::date)
)
HAVING COUNT(*) > 0;
-- Takvimde satır yoksa gün tam sayılır (SELECT INTO satırsızken değişkeni NULL yapar).
IF FOUND THEN
v_Value := v_Calendar;
END IF;
END IF;
v_Total := v_Total + v_Value;
v_Day := v_Day + 1;
END LOOP;
RETURN v_Total;
END;
$$;