How to calculate annual leave - please advise

Hi,
I need your advise please..
here is the detail:::
The employee contract can be definite (with expiry date) or indefinite (open without expiry date).
The employee contract will always have date of join
if the contract is definite then employee will have 30 days every year where the year is the period between the date of join and
+365 days and the renewal is the same (from the renewal date and +365)
if the contract is indefinite then employee will have 30 days every year where the year is the period between the date of join
it's every 365 days so the contract has not renewal but the employee will have 30 days annually.
for example, if indefinite and date of join is 1 April 2010 then every period from 1 April until 30 March will have 30 days for
the employee
I want to calculate the leaves for the employee without having to keep a renew table so it will be calculated based on the leave
date and the first date of join.
so the data will be just one leave table with from and to indicating the leave period for every leave and the result will be
1 April - 31 March - [Total Taken Leaves] - [Total Remaining Leaves]
hope
I explained it well...

I think I understand what you're saying.  Try out the code below to see if it works for you.
I know you mentioned possibly have a table with leave_from and leave_to as the structure for how you would keep track of each employee's leave days, but I would simplify it to just EmployeeID and the LeaveDate, which is what I did below. 
If you choose to go with a range, then you need to start dealing with only business days in your leave range calculations.
-- CREATE SOME DATA
IF OBJECT_ID('tempdb..#Employee', 'U') IS NOT NULL DROP TABLE #Employee;
CREATE TABLE #Employee (
EmployeeID int NOT NULL
,FullName varchar(30) NOT NULL
,JoinDate date NOT NULL
,EndDate date NULL
IF OBJECT_ID('tempdb..#EmployeeDaysOnLeave', 'U') IS NOT NULL DROP TABLE #EmployeeDaysOnLeave;
CREATE TABLE #EmployeeDaysOnLeave (
EmployeeID int NOT NULL
,LeaveDate date NOT NULL
INSERT #Employee
SELECT A.*
FROM (SELECT * FROM #Employee WHERE 1=2
UNION ALL SELECT 1, 'Joe', '01/01/2014', NULL
UNION ALL SELECT 2, 'Bob', '07/01/2014', '01/01/2015'
UNION ALL SELECT 3, 'Eve', '10/15/2007', NULL
UNION ALL SELECT 4, 'Ila', '09/08/2000', NULL
UNION ALL SELECT 5, 'Oto', '07/01/2014', '01/01/2017'
UNION ALL SELECT 6, 'Pop', '01/01/2013', '06/01/2013' -- Already let go
) A
INSERT #EmployeeDaysOnLeave
SELECT A.*
FROM (SELECT * FROM #EmployeeDaysOnLeave WHERE 1=2
UNION ALL SELECT 1, '01/30/2013'
UNION ALL SELECT 1, '01/31/2013'
UNION ALL SELECT 1, '02/01/2013'
UNION ALL SELECT 1, '02/04/2013'
UNION ALL SELECT 1, '04/15/2013'
UNION ALL SELECT 1, '04/16/2013'
UNION ALL SELECT 1, '04/17/2013'
UNION ALL SELECT 1, '04/18/2013'
UNION ALL SELECT 1, '04/19/2013'
UNION ALL SELECT 1, '01/30/2014'
UNION ALL SELECT 1, '01/31/2014'
UNION ALL SELECT 1, '02/03/2014'
UNION ALL SELECT 1, '02/04/2014'
UNION ALL SELECT 1, '04/14/2014'
UNION ALL SELECT 1, '04/15/2014'
UNION ALL SELECT 1, '04/16/2014'
UNION ALL SELECT 1, '04/17/2014'
UNION ALL SELECT 1, '04/18/2014'
UNION ALL SELECT 2, '07/21/2014'
UNION ALL SELECT 2, '07/22/2014'
UNION ALL SELECT 2, '07/23/2014'
UNION ALL SELECT 2, '07/24/2014'
UNION ALL SELECT 2, '07/25/2014'
UNION ALL SELECT 2, '07/28/2014'
UNION ALL SELECT 2, '07/29/2014'
UNION ALL SELECT 2, '07/30/2014'
) A
-- NOTE: I'm throwing all these calculations into a quick temp table, but you may want to put this logic into a view or table function
IF OBJECT_ID('tempdb..#EmployeeLeaveCalculations', 'U') IS NOT NULL DROP TABLE #EmployeeLeaveCalculations;
DECLARE @DaysPerYear int
,@CurrentDate date
SELECT @DaysPerYear = 30
,@CurrentDate = CONVERT(date, GETDATE())
SELECT A.EmployeeID
,A.FullName
,A.JoinDate
,A.EndDate
,A.LeaveCalculationStartDate
,A.LeaveCalculationEndDate
,CASE WHEN A.LeaveCalculationEndDate < A.LeaveCalculationStartDate -- Ignore if they are no longer with the company
THEN 0
ELSE CASE WHEN DATEDIFF(DAY, A.LeaveCalculationStartDate, A.LeaveCalculationEndDate) < 365
THEN @DaysPerYear * DATEDIFF(DAY, A.LeaveCalculationStartDate, A.LeaveCalculationEndDate) / 365.0
ELSE @DaysPerYear * 1.0
END
END as LeaveDaysEntitledTo
,CASE WHEN DATEDIFF(DAY, A.LeaveCalculationStartDate, A.LeaveCalculationEndDate) = 0 OR -- Avoid divide by zero
A.LeaveCalculationEndDate < A.LeaveCalculationStartDate -- Ignore if they are no longer with the company
THEN 0
ELSE ROUND(DATEDIFF(DAY, A.LeaveCalculationStartDate, @CurrentDate) * 1.0 /
DATEDIFF(DAY, A.LeaveCalculationStartDate, A.LeaveCalculationEndDate)* 1.0 *
CASE WHEN DATEDIFF(DAY, A.LeaveCalculationStartDate, A.LeaveCalculationEndDate) < 365
THEN @DaysPerYear * DATEDIFF(DAY, A.LeaveCalculationStartDate, A.LeaveCalculationEndDate) / 365.0
ELSE @DaysPerYear * 1.0
END
, 1)
END as CurrentLeaveDaysAccrued
INTO #EmployeeLeaveCalculations
FROM (
SELECT EmployeeID
,FullName
,JoinDate
,ISNULL(EndDate, '12/12/9999') as EndDate
-- If the Month/Date of their JoinDate is less than the current Month/Date,
-- then we reset the leave start date to this year
-- else it will be the previous year
,CASE WHEN CONVERT(int, RIGHT(CONVERT(char(8), JoinDate, 112),4)) <= CONVERT(int, RIGHT(CONVERT(char(8), @CurrentDate, 112),4))
THEN CONVERT(date, CONVERT(char(4), YEAR(@CurrentDate)) + RIGHT(CONVERT(char(8), JoinDate, 112),4))
ELSE CONVERT(date, CONVERT(char(4), YEAR(@CurrentDate)-1) + RIGHT(CONVERT(char(8), JoinDate, 112),4))
END as LeaveCalculationStartDate
,CASE WHEN EndDate IS NOT NULL AND EndDate < DATEADD(YEAR,1,JoinDate)
THEN EndDate
WHEN CONVERT(int, RIGHT(CONVERT(char(8), JoinDate, 112),4)) <= CONVERT(int, RIGHT(CONVERT(char(8), @CurrentDate, 112),4))
THEN CONVERT(date, CONVERT(char(4), YEAR(@CurrentDate)+1) + RIGHT(CONVERT(char(8), JoinDate, 112),4))
ELSE CONVERT(date, CONVERT(char(4), YEAR(@CurrentDate)) + RIGHT(CONVERT(char(8), JoinDate, 112),4))
END as LeaveCalculationEndDate
FROM #Employee
) A
SELECT X.*
,Y.TotalLeaveDaysTaken
,X.CurrentLeaveDaysAccrued - Y.TotalLeaveDaysTaken as CurrentLeaveDaysBalance
,X.LeaveDaysEntitledTo - Y.TotalLeaveDaysTaken as TotalRemainingLeaveDays
FROM #EmployeeLeaveCalculations X
JOIN (
-- Get the total leave days taken from the given Employee's leave calculation start date
SELECT A.EmployeeID
,SUM(CASE WHEN B.EmployeeID IS NOT NULL THEN 1 ELSE 0 END) as TotalLeaveDaysTaken
FROM #EmployeeLeaveCalculations A
LEFT JOIN #EmployeeDaysOnLeave B
ON A.EmployeeID = B.EmployeeID
AND A.LeaveCalculationStartDate <= B.LeaveDate
GROUP BY A.EmployeeID
) Y
ON X.EmployeeID = Y.EmployeeID

Similar Messages

Maybe you are looking for

  • Only some of my folders are in the drop down when I try to bookmark a page. I have many more folders, but can't bookmark to them

    I used to be able to choose from all folders when bookmarking a site. I was able to click on 'Choose' and all folder would drop down. After a firefox update yesterday, only 5 folders show up, along with the 'Choose' option. When I click on 'Choose' i

  • Error code 39 - CD/DVD drive not working properly

    Satellite C55D-5170 came with Win 8 and the first automatic software update upgraded it to Win 8.1.  I believe this is the first time I have tried to access the DVD drive but I had successfully used the flash drive.  The DVD drive is not recognized. 

  • Uploading Multiple files in One-Click!!!

    Hi All, I have got nearly about 900 PDF files in my file server which need to be uploaded to the KM CONTENT Repository. what is the best methodology to upload all these file in to the repository in <u><b>one click.</b></u> Is it possible to achieve t

  • IPhone 5 sound on video is almost nonexistent

    The iPhone 5 takes great video, but the sound is almost not there at all.  Husband still has his iPhone 4 and the sound is fine.  Any thoughts?  I looked at settings and the sound is all the way up, and it isn't a problem hearing messages, etc. 

  • [SOLVED]Keyboard layout changed.

    Hi i did a major upgrade yesterday, having waited to do an upgrade for a few weeks because of wonky nvidia drivers i finally managed to Syu yesterday and upgraded 133 packages. Everything works fine it seems apart from one thing i noticed this mornin