CREATE OR REPLACE PROCEDURE public."Hr_S_TimesheetPeriodAfterSave"( p_PeriodId uuid, p_ActorId uuid ) LANGUAGE plpgsql AS $$ DECLARE v_TenantId uuid; v_Year integer; v_Month integer; v_Status varchar(16); v_ClosedAt timestamp; v_From date; v_To date; BEGIN -- Puantaj Dönemleri kaydı: açık dönemin her kaydı ayı bütün çalışanlar için yeniden hesaplar; -- kapatma son kez hesaplayıp ayı kilitler. Kapalı ayın hareketleri ve günleri değiştirilemez. SELECT "TenantId", "PeriodYear", "PeriodMonth", "Status", "ClosedAt" INTO v_TenantId, v_Year, v_Month, v_Status, v_ClosedAt FROM public."Hr_T_TimesheetPeriod" WHERE "Id" = p_PeriodId AND "IsDeleted" = FALSE; IF v_Year IS NULL THEN RETURN; END IF; IF v_Month NOT BETWEEN 1 AND 12 OR v_Year NOT BETWEEN 2000 AND 2100 THEN RAISE EXCEPTION 'Dönem yılı 2000–2100, ayı 1–12 arasında olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '51220'; END IF; IF EXISTS (SELECT 1 FROM public."Hr_T_TimesheetPeriod" WHERE "Id" <> p_PeriodId AND "IsDeleted" = FALSE AND "PeriodYear" = v_Year AND "PeriodMonth" = v_Month AND ("TenantId" = v_TenantId OR ("TenantId" IS NULL AND v_TenantId IS NULL))) THEN RAISE EXCEPTION 'Bu yıl ve ay için puantaj dönemi zaten var.' USING ERRCODE = 'P0001', DETAIL = '51221'; END IF; v_From := make_date(v_Year, v_Month, 1); v_To := (v_From + INTERVAL '1 month - 1 day')::date; IF v_Status = 'Closed' AND v_ClosedAt IS NOT NULL THEN RETURN; END IF; -- Kapalı aya izin yazılamadığı için ayda onay bekleyen talep varken dönem kapanmaz; aksi hâlde -- sonradan onaylanan izin puantaja hiç yansımazdı. IF v_Status = 'Closed' AND EXISTS ( SELECT 1 FROM public."Hr_T_LeaveRequest" q WHERE q."IsDeleted" = FALSE AND (q."TenantId" = v_TenantId OR (q."TenantId" IS NULL AND v_TenantId IS NULL)) AND (q."ApprovalStatus" IS NULL OR q."ApprovalStatus" IN ('Onaya Gönderildi', 'Müdür Onayı', 'İK Onayı')) AND q."StartDate"::date <= v_To AND q."EndDate"::date >= v_From) THEN RAISE EXCEPTION 'Bu ayda onay bekleyen izin talebi var. Talepler sonuçlanmadan dönem kapatılamaz.' USING ERRCODE = 'P0001', DETAIL = '51223'; END IF; -- Kapatma anında da son hesap yapılır; hesap kapalı ayı yazmadığı için önce açık sayılır. UPDATE public."Hr_T_TimesheetPeriod" SET "Status" = 'Open' WHERE "Id" = p_PeriodId; CALL public."Hr_S_TimesheetCalculate"(v_TenantId, NULL, v_From, v_To, p_ActorId); UPDATE public."Hr_T_TimesheetPeriod" SET "Status" = COALESCE(v_Status, 'Open'), "CalculatedAt" = (NOW() AT TIME ZONE 'UTC'), "ClosedAt" = CASE WHEN v_Status = 'Closed' THEN (NOW() AT TIME ZONE 'UTC') END, "ClosedById" = CASE WHEN v_Status = 'Closed' THEN p_ActorId END WHERE "Id" = p_PeriodId; END; $$;