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

61 lines
4.4 KiB
MySQL
Raw Permalink Normal View History

2026-10-06 11:24:30 +00:00
CREATE OR REPLACE VIEW public."Hr_V_TimesheetMonthly"
AS
-- Personel bazlı aylık puantaj: günlük puantajın çalışan × ay toplamı. Id günlük satırların
-- PeriodKey değeridir (alt form ilişkisi). Fazla mesai ücreti çarpanı ve yıllık sınır ayardan gelir;
-- yıllık fazla mesai ocaktan o aya kadarki birikimdir. Ücretsiz izin günü (bordroda eksik gün) izinli
-- günlerin ücretsiz türdeki kısmıdır; eğitim günü çalışılmış sayılır.
WITH m AS (
SELECT t."PeriodKey" AS PeriodKey, t."TenantId" AS TenantId, t."EmployeeId" AS EmployeeId,
t."PeriodYear" AS PeriodYear, t."PeriodMonth" AS PeriodMonth,
SUM(CASE WHEN t."DayType" = 'Work' THEN 1 ELSE 0 END)::int AS WorkDays,
(SUM(t."NetMinutes") / 60.0)::numeric(9, 2) AS NetHours,
SUM(t."LateMinutes")::int AS LateMinutes,
SUM(CASE WHEN t."LateMinutes" > 0 THEN 1 ELSE 0 END)::int AS LateDays,
SUM(t."EarlyLeaveMinutes")::int AS EarlyLeaveMinutes,
SUM(CASE WHEN t."EarlyLeaveMinutes" > 0 THEN 1 ELSE 0 END)::int AS EarlyLeaveDays,
SUM(t."OvertimeHours")::numeric(9, 2) AS OvertimeHours,
SUM(CASE WHEN t."DayType" = 'WeeklyOff' THEN 1 ELSE 0 END)::int AS WeeklyOffDays,
SUM(CASE WHEN t."DayType" = 'Holiday' THEN 1 ELSE 0 END)::int AS HolidayDays,
SUM(CASE WHEN t."DayType" = 'Leave' THEN 1 ELSE 0 END)::int AS LeaveDays,
SUM(CASE WHEN t."DayType" = 'Leave' AND lt."IsPaid" = FALSE THEN 1 ELSE 0 END)::int AS UnpaidLeaveDays,
SUM(CASE WHEN t."DayType" = 'Training' THEN 1 ELSE 0 END)::int AS TrainingDays,
SUM(CASE WHEN t."DayType" = 'Sick' THEN 1 ELSE 0 END)::int AS SickDays,
SUM(CASE WHEN t."DayType" = 'Absent' THEN 1 ELSE 0 END)::int AS AbsentDays,
SUM(CASE WHEN t."IsIncomplete" = TRUE THEN 1 ELSE 0 END)::int AS IncompleteDays,
SUM(CASE WHEN t."IsAssumed" = TRUE THEN 1 ELSE 0 END)::int AS AssumedDays
FROM "Hr_T_Timesheet" t
LEFT JOIN "Hr_T_LeaveType" lt ON lt."Id" = t."LeaveTypeId"
WHERE t."IsDeleted" = FALSE
GROUP BY t."PeriodKey", t."TenantId", t."EmployeeId", t."PeriodYear", t."PeriodMonth"
)
SELECT m.PeriodKey AS "Id", m.TenantId AS "TenantId", m.EmployeeId AS "EmployeeId", u."DepartmentId", u."JobPositionId",
m.PeriodYear AS "PeriodYear", m.PeriodMonth AS "PeriodMonth", COALESCE(p."Status", 'Open')::varchar(16) AS "PeriodStatus",
m.WorkDays AS "WorkDays", m.NetHours AS "NetHours", m.LateMinutes AS "LateMinutes", m.LateDays AS "LateDays",
m.EarlyLeaveMinutes AS "EarlyLeaveMinutes", m.EarlyLeaveDays AS "EarlyLeaveDays",
m.OvertimeHours AS "OvertimeHours",
(m.OvertimeHours * s.Rate)::numeric(9, 2) AS "OvertimePaidHours",
m.WeeklyOffDays AS "WeeklyOffDays", m.HolidayDays AS "HolidayDays", m.LeaveDays AS "LeaveDays",
m.UnpaidLeaveDays AS "UnpaidLeaveDays", m.TrainingDays AS "TrainingDays", m.SickDays AS "SickDays",
m.AbsentDays AS "AbsentDays", m.IncompleteDays AS "IncompleteDays", m.AssumedDays AS "AssumedDays",
(SUM(m.OvertimeHours) OVER (PARTITION BY m.TenantId, m.EmployeeId, m.PeriodYear ORDER BY m.PeriodMonth
ROWS UNBOUNDED PRECEDING))::numeric(9, 2) AS "YearOvertimeHours",
s.AnnualLimit AS "AnnualOvertimeLimit",
CASE WHEN SUM(m.OvertimeHours) OVER (PARTITION BY m.TenantId, m.EmployeeId, m.PeriodYear ORDER BY m.PeriodMonth
ROWS UNBOUNDED PRECEDING) > s.AnnualLimit THEN 1 ELSE 0 END AS "IsOverAnnualLimit"
FROM m
INNER JOIN "AbpUsers" u ON u."Id" = m.EmployeeId
LEFT JOIN LATERAL (
SELECT x."Status" FROM "Hr_T_TimesheetPeriod" x
WHERE x."IsDeleted" = FALSE AND x."PeriodYear" = m.PeriodYear AND x."PeriodMonth" = m.PeriodMonth
AND x."TenantId" IS NOT DISTINCT FROM m.TenantId
LIMIT 1
) p ON TRUE
CROSS JOIN LATERAL (
2026-10-19 14:35:08 +00:00
SELECT replace(public."Hr_F_HrSetting"(m.TenantId, 'Adm.HrSettings.Attendance.OvertimeRate'), ',', '.') AS RateText,
replace(public."Hr_F_HrSetting"(m.TenantId, 'Adm.HrSettings.Attendance.AnnualOvertimeLimitHours'), ',', '.') AS LimitText
2026-10-06 11:24:30 +00:00
) h
CROSS JOIN LATERAL (
SELECT COALESCE(CASE WHEN pg_input_is_valid(h.RateText, 'numeric(9,2)') THEN h.RateText::numeric(9, 2) END, 1.5)::numeric(9, 2) AS Rate,
COALESCE(CASE WHEN pg_input_is_valid(h.LimitText, 'numeric(9,2)') THEN h.LimitText::numeric(9, 2) END, 270)::numeric(9, 2) AS AnnualLimit
) s;