http://stackoverflow.com/questions/3585428/programmatically-managing-a-balance-of-time-sick-vacation
- we use utilize task table to track how many days an employee have at one point of time.
- any time user submit a timeoff_task, we document the total_hours field with negative number of hours.
- any time the system runs an accrue task, we document the total_hours with a positive number of hours the employee accrued during this period.
- any time the system runs an adjustment task, we document the total_hours with a positive or negative number of hours the employee. (it could be an adjustment from his manager or because of the cap rule they set inside a policy)
currently we allow company to have accrue rate of following
enum accrue_rate:[:weekly, :bi_weekly, :monthly, :yearly]
. As a result we need to have a background process to run on weekly, biweekly, monthly and yearly to accrue vacation and sick days to user.
we currently use clockwork lib\clock.rb
to run this task on all policies. i need you to double check its logic and make sure it works as design.
reference task_hrdate.png
a. for any accrue task should be Task.create(:type=>:system, :name=> "accrue", :amount => xxxx)
b. for any adjustment task (which is trigger by cap policy.
Task.create(:type=>system, :name=> "adjustment", :amount => xxxx)
c. The amount should be negative if it is deducting from user, positive if it is adding to user
d. so if u want to calculate how many days this employee can spend (task_type==system)
e. so if u want to calculate how many days this employee already spent (task_type==:timeoff)
- code the accrue vacation and sick day.
- code the adjustment (adjustment comes in when there is a cap set on carry over)
- code the tenture (the way of calculating user's total vacation days for a year).
Company uses time off policy to decide how many dates an employee should have as vacation days and sick days, etc. Please check the details documentation in doc/TimeOffPolicy.html
to details
#Every first day of the month, this accrue method will run and it will add the accrued amount to each user. On Nov 1st, 2014
policy = TimeoffPolicy.create!(
:hours_per_year => 160,
:accrue_rate => :accrue_by_time,
:accrue_rate => :monthly,
:allow_negative => false,
:carry_over => :yearly_cap,
:carry_over_cap => 10,
:total_personal_days => 10,
:total_sick_days => 5,
:work_hours_per_day => 8,
:created_at => '10/1/2014'
)
user1 = User.find(1)
user1.start_date = '10/15/2014'
hours_per_month = 160 / 12
if user1.start_date - Date.today < 1_month
hours_per_month = hours_per_month / weeks_of_worked
end
TimeoffTask.create!(:sub_type => :accrue, :user => user, :total_hours=> hours_per_month)
*********If it runs on Jan 1st, 2105************
if user.total_accrue_hours > policy.carry_over_cap
TimeoffTask.create!(:sub_type => :adjustment, :user => user, :amount=> policy.carry_over_cap - user.total_accrue_hours)
end
Suppose we have a policy
- Total per year: 12 days
- Accural Type: accrue by time adv
- Accrue Rate: yearly
- Do you allow vacation days to be carried over to next year? YES
- How many hours do you allow them to be carried over per year?: 5 days
- Does the carried over the vacation days ever expire?: YES
- Expired date: Mar 31
- (Ignore tenure rules)
On Jan 1, Ken has 10 remaining days of last year and 12 days of this year.
So total vacation days of Ken to Jan 01 is 17
On Feb he takes 2 days off.
So, total vacation days of Ken to Mar is 17 - 2 = 15
On Apr 01, total vacation days of Ken is 12 (because Expired date for carrying over = Mar 31)
Suppose we have a policy
- Total per year: 12 days
- Accural Type: accrue by time adv
- Accrue Rate: monthly
- Do you allow vacation days to be carried over to next year? YES
- How many hours do you allow them to be carried over per year?: 12 days
- Does the carried over the vacation days ever expire?: YES
- Expired date: Mar 31
- (Ignore tenure rules)
On Jan 01, Ken has 12 remaining days of last year and 1 days of this year
So total vacation days of Ken to Jan 01 is 13 Total vacation days of Ken to Feb 01 is 14 Total vacation days of Ken to Mar 01 is 15
So, Total vacation days of Ken to Apr 01 is 4 (because Expired date for carrying over = Mar 31)
Suppose we have a policy
- Total per year: 12 days
- Accural Type: accrue by time
- Accrue Rate: monthly
- Do you allow vacation days to be carried over to next year? YES
- How many hours do you allow them to be carried over per year?: 12 days
- Does the carried over the vacation days ever expire?: NO
- (Ignore tenure rules)
On Jan 01, Ken has 12 remaining days of last year and 0 days of this year
So total vacation days of Ken to Jan 01 is 12 Total vacation days of Ken to Feb 01 is 13 Total vacation days of Ken to Mar 01 is 14 ... Total vacation days of Ken to Jan 01 next year is 12
- A policy will apply for multiple years?
the accrue task will only start after you have activated in our system. it doesn't care how long the employee has been with the company, if you want to move the employee's vacation days over from previous system, you can create an adjustment.
- "Are employees allowed to borrow PTO days from the future?": future means "next year only"?
Yes, but there is a cap, if no cap is set, then he can borrow as many.
- If user is not assigned to a policy? How can calculate total vacation days for this user (i.e. this user is a new employee)?
You cannot in this case. every employee has to have a policy.
- In case "yearly" the clockwork runs on the first date of a year, a new employee join in Mar and is assigned to this policy. How can this policy apply for the new employee?
The new employee's vacation days will be prorated.
- With tab 2, in working time configuration area, this configuration will impact to where?
No the scope of this, it will impact the tasks module.
- Follow up the question No.5, the working time is configured "From" and "To". How can we know the lunch break in working time configuration?
we ignore that for now.
- How can relate employee to a policy? From tab 4 (leave it for now as you mentioned) and from employee page?
this can be set in employee module.
- In case "edit a policy", it could break the rules of old policy which was run? What should we do?
nothing. accrue happens with the new policy at the next run cycle.
9.In case "Accrual Type" = "Accrue By Time", "Accrue Rate" = "Yearly", "Total days" = 12 days per year. It means that CLOCKWORK runs on the first day of year, total will be 0 days as definition of "Accrual By Time" or be equal to 12.
zero
- Please explain if the number is 12
With tab 2, configure anniversary of hire
User only added 1st = 1 day
2nd = 3 days
5th = 6 days
Please correct my understanding
3rd & 4th = 3 days? (following rule of 2nd)
No, it means after first anniversary, user has 13 days, after second user has 16 days, after 5th, then user has 22 days
- With anniversary rules, Ken joined in the company on Feb 29, 2014, 1st anniversary he will be added 1 extra day, next year 2015 has Feb 28, 2015 (the last day of Feb) is the anniversary date? Is it correct?
Yes.
- With accrue rate = yearly, in tab 2, admin only configures 1st = 1 day, 2nd = 2 days, total vacation days = 12 and not carry over to next year.
On Feb 03, 2014 an employee joined in company
On Feb 03, 2015 total vacation days = 13
On Jan 01, 2016 total vacation days = 13
On Feb 03, 2016 total vacation days = 14
Is it correct?
yes if its accrue_type == :accrue_by_time_adv
- Adjustment will run according to hours or days?
Day
- In case Monthly/Accrue By Time Adv/ Total days per year = 15.
May 25, 2014, Ken joined in company
Jan 01, 2015, plus-days for this month is (15/12) days
Feb 01, 2015, plus-days for this month is (15/12) days
Jun 01, 2015, plus-days for this month is (16/12) days
Yes if tenture is set to 1st anniversery to 1 day