Last active
August 29, 2015 14:14
-
-
Save ziweizhou/77070b01691243430ab5 to your computer and use it in GitHub Desktop.
Revisions
-
ziweizhou revised this gist
Feb 13, 2015 . 1 changed file with 104 additions and 21 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,21 +3,38 @@ class Task < ActiveRecord::Base belongs_to :author, class_name:"User", foreign_key: :author_id belongs_to :user, class_name:"User", foreign_key: :user_id belongs_to :assignee, class_name:"User", foreign_key: :assignee_id belongs_to :parent_task, class_name: 'Task', foreign_key: :task_parent_id has_many :sub_tasks, class_name: 'Task', foreign_key: :task_parent_id before_save :calculate_hours, :accrue_attachments after_save :log_activities validate :validate_total_hours attr_accessor :editor TASKS_TYPE = { all: 'All', timeoff: 'TimeoffTask', travel: 'TravelTask', expense: 'ExpenseTask' } # @!attribute name # @return [String] the task's title, but it is possible to be used to hold the descriptions of user defined sub-types # @example # :start => starting balance # :accrue_vacation => accrue vacation basing on the accrue rate # :adjustment_vacation => manual vacation adjustment by manager or admin # :accrue_sick => accrue sick days basing on the accrue rate # :adjustment_sick => manual sick days adjustment by manager or admin # :vacation => Vacations # :sick => Sick Leave # :personal => Personal Holidays # :others => Misc ones, employee won't be in office, but it doesn't consider his vacation/sick/personal days. such as jury duty or working from home. enum task_types: [:timeoff, :travel, :expense, :sytem] # @!attribute total_hours # @return [Integer] it is a calculated field when user made changes on the start_at or the end_at field @@ -31,30 +48,29 @@ class Task < ActiveRecord::Base # @!attribute user # @return [User] who is this task for. like user1 create a task for user2. # @!attribute desciption # @return [Text] user's memo/reasons if it is a sick leave # @!attribute start_at # @return [DateTime] when is this task start # @!attribute end_at # @return [DateTime] when is this task ends # @!attribute attachment # @return [Array<Object>] attachments for this task. serialize :attachments mount_uploaders :attachments, FileUploader # @!attribute status # @return [Enumerable<String>] task's status # @example # :pending => pending for level1 approval # :pending2 => pending for secondary approval # :approved => approved by all manager # :rejected => rejected by manager. # :paid => Use in expense request # :booked => Used in travel request. # :cancelled => cancelled, could be from the requester @@ -84,8 +100,8 @@ class Task < ActiveRecord::Base # @!attribute followers # @return [Array<User>] # array of people who will be notified and possibly all the followers should have this task on their calendar. # 如果是出公差,从深圳分公司到上海总公司,那么这个Task,应该出现在所有followers的日历上面。 acts_as_followable @@ -96,37 +112,104 @@ class Task < ActiveRecord::Base tracked # tracked owner: Proc.new{ |controller, model| controller.current_user } scope :children_tasks, -> (parent_id) { where(task_parent_id: parent_id)} # @todo calculate the total hours used for this task. def calculate_hours if self.task_type == Task.task_types[:timeoff] if self.user.policy self.amount = Time.with(self.user.policy) {self.start_at.business_time_until(self.end_at)/3600 * -1} else self.amount = self.start_at.business_time_until(self.end_at)/3600 * -1 end end end def validate_total_hours end # @!method all_approved? # @return [Boolean] # has all the user's manager approved this task? def all_approved? self.user.following_users.count == self.get_upvotes.size end def approve self.vote_by :voter => self.assignee, :vote => 'yes' # auto change the assignee to the manager who has not approved this task yet. next_assignee = self.user.following_users.select {|f| !self.votes_for.up.voters.include?(f) }.first if next_assignee.present? self.assignee = next_assignee self.save! end end def on_approved_exit(new_state, event, *args) # notify followers for its approval self.followers.map {|f| self.create_activity(owner: f, key: 'task.change', action: :mood_changed)} # mark all sub-tasks as approved self.descendants.each { |t| t.workflow_state = 'approved'} end def all_activities PublicActivity::Activity.where( trackable_id: self.sub_tasks.pluck(:id) << self.id, trackable_type: self.class.to_s ).order(:created_at) end def showable_activities all_activities.where(key: [ACTIVITY_AVAILABLE_KEYS[:task_add_attachment], ACTIVITY_AVAILABLE_KEYS[:task_new_comment]]) end def self_attachment_activities activities.where(key: ACTIVITY_AVAILABLE_KEYS[:task_add_attachment]).order(:created_at) end private def log_activities activity_array = [] if self.workflow_state_changed? case self.workflow_state when 'approved' activity_array << PublicActivity::Activity.new(trackable: self, key: ACTIVITY_AVAILABLE_KEYS[:task_approved]).attributes.except('id', 'created_at', 'updated_at') when 'cancelled' activity_array << PublicActivity::Activity.new(trackable: self, key: ACTIVITY_AVAILABLE_KEYS[:task_cancelled]).attributes.except('id', 'created_at', 'updated_at') when 'booked' activity_array << PublicActivity::Activity.new(trackable: self, key: ACTIVITY_AVAILABLE_KEYS[:task_booked], parameters: {data: self.id}).attributes.except('id', 'created_at', 'updated_at') when 'paid' activity_array << PublicActivity::Activity.new(trackable: self, key: ACTIVITY_AVAILABLE_KEYS[:task_paid], parameters: {data: self.id}).attributes.except('id', 'created_at', 'updated_at') end end if self.attachments_changed? if self.attachments_was.present? log_attachments = self.attachments[self.attachments_was.size, self.attachments.size - 1] else log_attachments = self.attachments end if log_attachments.present? log_attachments.each do |a| activity_array << PublicActivity::Activity.new( trackable: self, owner: self.editor, key: ACTIVITY_AVAILABLE_KEYS[:task_add_attachment], parameters: { data: "uploads/#{self.class.to_s.underscore}/#{self.id}/#{a.mounted_as.to_s}/#{a.file.filename}", name: a.file.filename } ).attributes.except('id', 'created_at', 'updated_at') end end end PublicActivity::Activity.create(activity_array) if activity_array.present? end def accrue_attachments if self.attachments_was && self.attachments_changed? self.attachments = self.attachments_was + self.attachments end end end -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 9 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -24,8 +24,15 @@ 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) TASK ------ 1. code the accrue vacation and sick day. 2. code the adjustment (adjustment comes in when there is a cap set on carry over) 3. code the tenture (the way of calculating user's total vacation days for a year). Example --------- -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 21 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -21,9 +21,9 @@ we currently use clockwork `lib\clock.rb` to run this task on all policies. i ne 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 @@ -164,30 +164,44 @@ nothing. accrue happens with the new policy at the next run cycle. zero 10. 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 11. 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. 12. 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 13. Adjustment will run according to hours or days? ### Day 14. 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 -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 8 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -170,17 +170,21 @@ User only added 1st = 1 day 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 11. 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. 12. 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? In case Monthly/Accrue By Time Adv/ Total days per year = 15. May 25, 2014, Ken joined in company -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 83 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,6 +9,23 @@ http://stackoverflow.com/questions/3585428/programmatically-managing-a-balance-o - 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) Background ======== 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. current solution ======= 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 Example --------- @@ -104,4 +121,69 @@ 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 FAQ ======= 1. 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. 2. "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. 3. 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. 4. 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. 5. 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. 6. 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. 7. 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. 8. 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 10. 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? 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? Adjustment will run according to hours or days? 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 -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 79 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,79 @@ class User < ActiveRecord::Base # @!attribute role # @return [Enumberable<String>] companyadmin role is assign to the company's admin enum role: [:user, :corp_admin, :admin] # @!attribute employment_type # @return [Enumberable<String>] companyadmin role is assign to the company's admin enum employment_type: [:full_time, :part_time, :contractor] # @!attribute status # @return [Enumberable<String>] if he is still a part of this company enum status: [:active, :terminated] # @!attribute email # @!attribute join_on # the date joined this company. # calculate the total vacation days this user has in this calendar year. # It can include days from previous years, depending on the accural type. # @return [Integer] the total vacation days def total_vacation_hours total_vacation_days * self.policy.work_hours_per_day end # calculate total vacation days of this year def total_vacation_days self.policy.tentures.inject(self.policy.base_vacation_days) do |res , i| res + (Time.zone.now - i[:anniversary].to_i.years > self.join_on ? i[:extra_days]: 0) end end # calculate the total vacation days that is used for in this calendar year # @return [Integer] the total used vacation days def total_used_vacation_days total_used_vacation_hours / self.policy.work_hours_per_day end def total_used_vacation_hours total_vacation_hours - total_remain_vacation_hours end # total_vacation_days - total_used_vacation_days # @return [Integer] total left over vacation days def total_remain_vacation_days total_remain_vacation_hours / self.policy.work_hours_per_day end def total_remain_vacation_hours TimeoffTask.where(user: self, sub_type: [:accrue, :adjustment, :vacation].map {|i| TimeoffTask.sub_types[i]}).sum(:total_hours) end def total_remain_personal_hours TimeoffTask.total_personal_hours_for_user(self) end def total_remain_sick_hours TimeoffTask.total_sick_hours_for_user(self) end # TODO: # check if user is on vacation, depending on his vacation requests # @return [Boolean] true or false def on_vacation? false end # TODO: # check if user is sick # @return [Boolean] true or false def is_sick? false end def self.policy_class EmployeePolicy end end -
ziweizhou revised this gist
Feb 5, 2015 . 2 changed files with 5 additions and 2045 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,2045 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -41,12 +41,17 @@ class TimeoffPolicy < ActiveRecord::Base # @example # carry_over:true,carry_over_cap:16, carry_over_expire_on:nil # with this setting, every year carry_over 16 hours and it never expires。 # 如果 这样就是 每年carry_over 16小时,永不过期。 # carry_over:true,carry_over_cap:16, carry_over_expire_on:"12/31/1999" # with this setting, every year carry_over 16 hours,it means all the accumulated vacations days will be expired at the end of the year. # 如果 这样就是 每年carry_over 16小时,前年都不算,相当于yearly。 # carry_over:true,carry_over_cap:16, carry_over_expire_on:“03/01/2000” # with this setting, every year carry_over 16 hours,it means all the accumulated vacations days will be expired at the end of Feburary. # 如果 这样就是 每年carry_over 16小时,以前累积的每年3月过期。 # carry_over:true,carry_over_cap:16, carry_over_expire_on:“06/01/2000” # with this setting, every year carry_over 16 hours,it means all the accumulated vacations days will be expired at the end of May. # 如果 这样就是 每年carry_over 16小时,以前累积的每年6月过期。 # @!attribute allow_negative # @return [Boolean] Do you allow user to borrow vacation days in advance? -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 2045 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,2045 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> Class: TimeoffPolicy — Documentation by YARD 0.8.7.6 </title> </head> <body> <div id="header"> <div id="menu"> <a href="_index.html">Index (T)</a> » <span class="title">TimeoffPolicy</span> <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div> </div> <div id="search"> <a class="full_list_link" id="class_list_link" href="class_list.html"> Class List </a> <a class="full_list_link" id="method_list_link" href="method_list.html"> Method List </a> <a class="full_list_link" id="file_list_link" href="file_list.html"> File List </a> </div> <div class="clear"></div> </div> <iframe id="search_frame"></iframe> <div id="content"><h1>Class: TimeoffPolicy </h1> <dl class="box"> <dt class="r1">Inherits:</dt> <dd class="r1"> <span class="inheritName">ActiveRecord::Base</span> <ul class="fullTree"> <li>Object</li> <li class="next">ActiveRecord::Base</li> <li class="next">TimeoffPolicy</li> </ul> <a href="#" class="inheritanceTree">show all</a> </dd> <dt class="r2 last">Defined in:</dt> <dd class="r2 last">app/models/timeoff_policy.rb</dd> </dl> <div class="clear"></div> <h2>Instance Attribute Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small></h2> <ul class="summary"> <li class="public "> <span class="summary_signature"> <a href="#accrue_rate-instance_method" title="#accrue_rate (instance method)">- (Enumerable<String>) <strong>accrue_rate</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Indicate how often this policy should be ran to calculate employees vacation days balance.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#accrue_type-instance_method" title="#accrue_type (instance method)">- (Enumerable<String>) <strong>accrue_type</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Vacation Data Accural Type.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#allow_negative-instance_method" title="#allow_negative (instance method)">- (Boolean) <strong>allow_negative</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Do you allow user to borrow vacation days in advance?.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#base_vacation_days-instance_method" title="#base_vacation_days (instance method)">- (Integer) <strong>base_vacation_days</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Total vacation days per year.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#beginning_of_workday-instance_method" title="#beginning_of_workday (instance method)">- (String) <strong>beginning_of_workday</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Start time for every working day.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#carry_over-instance_method" title="#carry_over (instance method)">- (Boolean) <strong>carry_over</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Carry Over ? (跨年累积).</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#carry_over_cap-instance_method" title="#carry_over_cap (instance method)">- (Integer) <strong>carry_over_cap</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Total carry over hours.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#carry_over_expire_on-instance_method" title="#carry_over_expire_on (instance method)">- (Date) <strong>carry_over_expire_on</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Total carry over hours expiration date.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#end_of_workday-instance_method" title="#end_of_workday (instance method)">- (Integer) <strong>end_of_workday</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>End time for every working day.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#holidays-instance_method" title="#holidays (instance method)">- (Array<Hash>) <strong>holidays</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>A list of holidays.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#name-instance_method" title="#name (instance method)">- (String) <strong>name</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>The name of the policy.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#negative_cap-instance_method" title="#negative_cap (instance method)">- (Integer) <strong>negative_cap</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>How many vacation hours that user can borrow in advance.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#tentures-instance_method" title="#tentures (instance method)">- (Array<Object>) <strong>tentures</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>We’ll automatically increase your employees’ vacation accrual rate based on the milestones you set below.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#total_personal_days-instance_method" title="#total_personal_days (instance method)">- (Integer) <strong>total_personal_days</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Total allowed personal days (个人年假).</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#total_sick_days-instance_method" title="#total_sick_days (instance method)">- (Integer) <strong>total_sick_days</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Total allowed sick days (病假).</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#types-instance_method" title="#types (instance method)">- (Array<Hash>) <strong>types</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>A list of types.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#work_dates-instance_method" title="#work_dates (instance method)">- (Array<Hash>) <strong>work_dates</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>A list of working dates, which addition to the work_week setting.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#work_hours-instance_method" title="#work_hours (instance method)">- (Hash) <strong>work_hours</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>List different working hours per day.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#work_hours_per_day-instance_method" title="#work_hours_per_day (instance method)">- (Integer) <strong>work_hours_per_day</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>Total work hours per day.</p> </div></span> </li> <li class="public "> <span class="summary_signature"> <a href="#work_week-instance_method" title="#work_week (instance method)">- (Array<String>) <strong>work_week</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>List of working week days.</p> </div></span> </li> </ul> <h2> Instance Method Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small> </h2> <ul class="summary"> <li class="public "> <span class="summary_signature"> <a href="#accrue-instance_method" title="#accrue (instance method)">- (Object) <strong>accrue</strong> </a> </span> <span class="summary_desc"><div class='inline'> <p>calculate how many hours has user accrued in this policies period.</p> </div></span> </li> </ul> <div id="instance_attr_details" class="attr_details"> <h2>Instance Attribute Details</h2> <span id="accrue_rate=-instance_method"></span> <div class="method_details first"> <h3 class="signature first" id="accrue_rate-instance_method"> - (<tt>Enumerable<String></tt>) <strong>accrue_rate</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns indicate how often this policy should be ran to calculate employees vacation days balance.</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Enumerable<String></tt>)</span> — <div class='inline'> <p>indicate how often this policy should be ran to calculate employees vacation days balance.</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 11</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 11</span> <span class='id identifier rubyid_enum'>enum</span> <span class='label'>accrue_rate:</span><span class='lbracket'>[</span><span class='symbol'>:weekly</span><span class='comma'>,</span> <span class='symbol'>:bi_weekly</span><span class='comma'>,</span> <span class='symbol'>:monthly</span><span class='comma'>,</span> <span class='symbol'>:yearly</span><span class='rbracket'>]</span></pre> </td> </tr> </table> </div> <span id="accrue_type=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="accrue_type-instance_method"> - (<tt>Enumerable<String></tt>) <strong>accrue_type</strong> </h3><div class="docstring"> <div class="discussion"> <div class="note notetag"> <strong>Note:</strong> <div class='inline'> <p>if accrue_by_time_adv and :yearly, means all days will be given to user at once</p> </div> </div> <p>Returns Vacation Data Accural Type</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <p class="example_title"><div class='inline'> <p>Assuming you have 20 vacation days per year (假设你每年有20天休假)</p> </div></p> <pre class="example code"><code>:accrue_by_time => if it is accrue per month, u will have 20/12 = 1.66 days on Feb 1st :accrue_by_time_adv => if it is accrue per month, u will have 20/12 = 1.66 days on January 1st</code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Enumerable<String></tt>)</span> — <div class='inline'> <p>Vacation Data Accural Type</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 19</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 19</span> <span class='id identifier rubyid_enum'>enum</span> <span class='label'>accrue_type:</span> <span class='lbracket'>[</span><span class='symbol'>:accrue_by_time</span><span class='comma'>,</span> <span class='symbol'>:accrue_by_time_adv</span><span class='rbracket'>]</span></pre> </td> </tr> </table> </div> <span id="allow_negative=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="allow_negative-instance_method"> - (<tt>Boolean</tt>) <strong>allow_negative</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns Do you allow user to borrow vacation days in advance?</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Boolean</tt>)</span> — <div class='inline'> <p>Do you allow user to borrow vacation days in advance?</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 47</span> </pre> </td> </tr> </table> </div> <span id="base_vacation_days=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="base_vacation_days-instance_method"> - (<tt>Integer</tt>) <strong>base_vacation_days</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns total vacation days per year</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Integer</tt>)</span> — <div class='inline'> <p>total vacation days per year</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 6</span> </pre> </td> </tr> </table> </div> <span id="beginning_of_workday=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="beginning_of_workday-instance_method"> - (<tt>String</tt>) <strong>beginning_of_workday</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns start time for every working day. '9:00 am'</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>String</tt>)</span> — <div class='inline'> <p>start time for every working day. '9:00 am'</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 62</span> </pre> </td> </tr> </table> </div> <span id="carry_over=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="carry_over-instance_method"> - (<tt>Boolean</tt>) <strong>carry_over</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns Carry Over ? (跨年累积)</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Boolean</tt>)</span> — <div class='inline'> <p>Carry Over ? (跨年累积)</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 32</span> </pre> </td> </tr> </table> </div> <span id="carry_over_cap=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="carry_over_cap-instance_method"> - (<tt>Integer</tt>) <strong>carry_over_cap</strong> </h3><div class="docstring"> <div class="discussion"> <div class="note notetag"> <strong>Note:</strong> <div class='inline'> <p>if carry_over_cap is ZERO, it means cannot carry over any hours.</p> </div> </div> <p>Returns total carry over hours</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Integer</tt>)</span> — <div class='inline'> <p>total carry over hours</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 35</span> </pre> </td> </tr> </table> </div> <span id="carry_over_expire_on=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="carry_over_expire_on-instance_method"> - (<tt>Date</tt>) <strong>carry_over_expire_on</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns total carry over hours expiration date</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <pre class="example code"><code>如果 这样就是 每年carry_over 16小时,永不过期。 carry_over:true,carry_over_cap:16, carry_over_expire_on:nil 如果 这样就是 每年carry_over 16小时,前年都不算,相当于yearly。 carry_over:true,carry_over_cap:16, carry_over_expire_on:"12/31/1999" 如果 这样就是 每年carry_over 16小时,以前累积的每年3月过期。 carry_over:true,carry_over_cap:16, carry_over_expire_on:“03/01/2000” 如果 这样就是 每年carry_over 16小时,以前累积的每年6月过期。 carry_over:true,carry_over_cap:16, carry_over_expire_on:“06/01/2000”</code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Date</tt>)</span> — <div class='inline'> <p>total carry over hours expiration date</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 39</span> </pre> </td> </tr> </table> </div> <span id="end_of_workday=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="end_of_workday-instance_method"> - (<tt>Integer</tt>) <strong>end_of_workday</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns end time for every working day. '5:00 pm'</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <p class="example_title"><div class='inline'> <p>We can adjust the start and end time of our business hours</p> </div></p> <pre class="example code"><code><span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_beginning_of_workday'>beginning_of_workday</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>8:30 am</span><span class='tstring_end'>"</span></span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_end_of_workday'>end_of_workday</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>5:30 pm</span><span class='tstring_end'>"</span></span></code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Integer</tt>)</span> — <div class='inline'> <p>end time for every working day. '5:00 pm'</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 65</span> </pre> </td> </tr> </table> </div> <span id="holidays=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="holidays-instance_method"> - (<tt>Array<Hash></tt>) <strong>holidays</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns a list of holidays</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <pre class="example code"><code><span class='id identifier rubyid_holidays'>holidays</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='lbrace'>{</span><span class='symbol'>:name</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>Indepedence Day</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='symbol'>:date</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>10/01/2014</span><span class='tstring_end'>"</span></span><span class='rbrace'>}</span><span class='comma'>,</span> <span class='lbrace'>{</span><span class='symbol'>:name</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>New Year</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='symbol'>:date</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>1/01/2015</span><span class='tstring_end'>"</span></span><span class='rbrace'>}</span><span class='rbracket'>]</span></code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Array<Hash></tt>)</span> — <div class='inline'> <p>a list of holidays</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 97</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 97</span> <span class='id identifier rubyid_serialize'>serialize</span> <span class='symbol'>:holidays</span></pre> </td> </tr> </table> </div> <span id="name=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="name-instance_method"> - (<tt>String</tt>) <strong>name</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns the name of the policy</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>String</tt>)</span> — <div class='inline'> <p>the name of the policy</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 3</span> </pre> </td> </tr> </table> </div> <span id="negative_cap=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="negative_cap-instance_method"> - (<tt>Integer</tt>) <strong>negative_cap</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns how many vacation hours that user can borrow in advance</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Integer</tt>)</span> — <div class='inline'> <p>how many vacation hours that user can borrow in advance</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 50</span> </pre> </td> </tr> </table> </div> <span id="tentures=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="tentures-instance_method"> - (<tt>Array<Object></tt>) <strong>tentures</strong> </h3><div class="docstring"> <div class="discussion"> <p>We’ll automatically increase your employees’ vacation accrual rate based on the milestones you set below. (These bonuses will be your default policy, but you can turn this feature off for individual employees.) 根据您设置下面的里程碑,我们将自动增加员工的假期累积率。 (这些奖金将是你的默认策略,但您可以关闭此功能对于员工个人。)</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <pre class="example code"><code>self.tentures = [{anniversary:2, extra_days: 2}, {anniversary:4, extra_days: 2}] means if you worked for 2 years, then you have 22 days vacation. If 4 years then u have 24 days. 如果你工作了2年指,那么你有22天假期。如果4年那么你有24天假期。</code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Array<Object></tt>)</span> — <div class='inline'> <p>List of tenture. 年假逐年递增 年假递增率</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 29</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 29</span> <span class='id identifier rubyid_serialize'>serialize</span> <span class='symbol'>:tentures</span></pre> </td> </tr> </table> </div> <span id="total_personal_days=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="total_personal_days-instance_method"> - (<tt>Integer</tt>) <strong>total_personal_days</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns total allowed personal days (个人年假)</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Integer</tt>)</span> — <div class='inline'> <p>total allowed personal days (个人年假)</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 56</span> </pre> </td> </tr> </table> </div> <span id="total_sick_days=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="total_sick_days-instance_method"> - (<tt>Integer</tt>) <strong>total_sick_days</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns total allowed sick days (病假)</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Integer</tt>)</span> — <div class='inline'> <p>total allowed sick days (病假)</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 53</span> </pre> </td> </tr> </table> </div> <span id="types=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="types-instance_method"> - (<tt>Array<Hash></tt>) <strong>types</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns a list of types</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <pre class="example code"><code><span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_timeoff_types'>timeoff_types</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='lbrace'>{</span><span class='symbol'>:name</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>Sick Day</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='symbol'>:type</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>sick_leave</span><span class='tstring_end'>"</span></span><span class='rbrace'>}</span><span class='comma'>,</span> <span class='lbrace'>{</span><span class='symbol'>:name</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>Personal Day</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='symbol'>:type</span><span class='op'>=></span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>personal_leave</span><span class='tstring_end'>"</span></span><span class='rbrace'>}</span><span class='rbracket'>]</span></code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Array<Hash></tt>)</span> — <div class='inline'> <p>a list of types</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 104</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 104</span> <span class='id identifier rubyid_serialize'>serialize</span> <span class='symbol'>:timeoff_types</span></pre> </td> </tr> </table> </div> <span id="work_dates=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="work_dates-instance_method"> - (<tt>Array<Hash></tt>) <strong>work_dates</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns a list of working dates, which addition to the work_week setting.</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <pre class="example code"><code><span class='id identifier rubyid_work_dates'>work_dates</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>02/01/2015</span><span class='tstring_end'>"</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>02/14/2015</span><span class='tstring_end'>"</span></span><span class='rbracket'>]</span></code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Array<Hash></tt>)</span> — <div class='inline'> <p>a list of working dates, which addition to the work_week setting.</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 91</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 91</span> <span class='id identifier rubyid_serialize'>serialize</span> <span class='symbol'>:work_dates</span></pre> </td> </tr> </table> </div> <span id="work_hours=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="work_hours-instance_method"> - (<tt>Hash</tt>) <strong>work_hours</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns list different working hours per day. Not sure if it is necessary.</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <p class="example_title"><div class='inline'> <p>as alternative we also can change the business hours for each work day:</p> </div></p> <pre class="example code"><code><span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_work_hours'>work_hours</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='symbol'>:mon</span><span class='op'>=></span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>9:00</span><span class='tstring_end'>"</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>17:00</span><span class='tstring_end'>"</span></span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='symbol'>:fri</span><span class='op'>=></span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>9:00</span><span class='tstring_end'>"</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>17:00</span><span class='tstring_end'>"</span></span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='symbol'>:sat</span><span class='op'>=></span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>10:00</span><span class='tstring_end'>"</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>15:00</span><span class='tstring_end'>"</span></span><span class='rbracket'>]</span> <span class='rbrace'>}</span> </code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Hash</tt>)</span> — <div class='inline'> <p>list different working hours per day. Not sure if it is necessary.</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 85</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 85</span> <span class='id identifier rubyid_serialize'>serialize</span> <span class='symbol'>:work_hours</span></pre> </td> </tr> </table> </div> <span id="work_hours_per_day=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="work_hours_per_day-instance_method"> - (<tt>Integer</tt>) <strong>work_hours_per_day</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns total work hours per day</p> </div> </div> <div class="tags"> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Integer</tt>)</span> — <div class='inline'> <p>total work hours per day</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> </pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 59</span> </pre> </td> </tr> </table> </div> <span id="work_week=-instance_method"></span> <div class="method_details "> <h3 class="signature " id="work_week-instance_method"> - (<tt>Array<String></tt>) <strong>work_week</strong> </h3><div class="docstring"> <div class="discussion"> <p>Returns list of working week days. '%w(mon tue wed thu fri)'</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <pre class="example code"><code><span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_work_week'>work_week</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>%w(mon tue wed thu fri)</span><span class='tstring_end'>'</span></span></code></pre> </div> <p class="tag_title">Returns:</p> <ul class="return"> <li> <span class='type'>(<tt>Array<String></tt>)</span> — <div class='inline'> <p>list of working week days. '%w(mon tue wed thu fri)'</p> </div> </li> </ul> </div><table class="source_code"> <tr> <td> <pre class="lines"> 75</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 75</span> <span class='id identifier rubyid_serialize'>serialize</span> <span class='symbol'>:work_week</span></pre> </td> </tr> </table> </div> </div> <div id="instance_method_details" class="method_details_list"> <h2>Instance Method Details</h2> <div class="method_details first"> <h3 class="signature first" id="accrue-instance_method"> - (<tt>Object</tt>) <strong>accrue</strong> </h3><div class="docstring"> <div class="discussion"> <div class="note todo"> <strong>TODO:</strong> <div class='inline'> <p>calculate how many hours has user accrued in this policies period.</p> </div> </div> <p>calculate how many hours has user accrued in this policies period.</p> </div> </div> <div class="tags"> <div class="examples"> <p class="tag_title">Examples:</p> <p class="example_title"><div class='inline'> <p>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</p> </div></p> <pre class="example code"><code>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, :amount=> 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</code></pre> </div> </div><table class="source_code"> <tr> <td> <pre class="lines"> 137 138 139 140 141</pre> </td> <td> <pre class="code"><span class="info file"># File 'app/models/timeoff_policy.rb', line 137</span> <span class='kw'>def</span> <span class='id identifier rubyid_accrue'>accrue</span> <span class='id identifier rubyid_users'>users</span><span class='period'>.</span><span class='id identifier rubyid_each'>each</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_user'>user</span><span class='op'>|</span> <span class='const'>TimeoffTask</span><span class='period'>.</span><span class='id identifier rubyid_create'>create</span><span class='lparen'>(</span><span class='symbol'>:sub_type</span> <span class='op'>=></span> <span class='symbol'>:accrue</span><span class='comma'>,</span> <span class='symbol'>:user</span> <span class='op'>=></span> <span class='id identifier rubyid_user'>user</span><span class='comma'>,</span> <span class='symbol'>:amount</span><span class='op'>=></span> <span class='id identifier rubyid_amount'>amount</span><span class='rparen'>)</span> <span class='kw'>end</span> <span class='kw'>end</span></pre> </td> </tr> </table> </div> </div> </div> <div id="footer"> Generated on Tue Dec 30 16:37:05 2014 by <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a> 0.8.7.6 (ruby-2.1.2). </div> </body> </html> -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 23 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -46,14 +46,14 @@ Example 2 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. @@ -69,14 +69,14 @@ Example 3 ========= 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 @@ -90,14 +90,13 @@ Example 4 ========= 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 -
ziweizhou revised this gist
Feb 5, 2015 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -43,7 +43,9 @@ end Example 2 ========= Suppose we have a policy ### -Total per year: 12 days -Accural Type: accrue by time adv -Accrue Rate: yearly @@ -66,6 +68,7 @@ On Apr 01, total vacation days of Ken is 12 (because Expired date for carrying o Example 3 ========= Suppose we have a policy ### -Total per year: 12 days -Accural Type: accrue by time adv -Accrue Rate: monthly @@ -86,6 +89,7 @@ So, Total vacation days of Ken to Apr 01 is 4 (because Expired date for carrying Example 4 ========= Suppose we have a policy ### -Total per year: 12 days -Accural Type: accrue by time -Accrue Rate: monthly -
ziweizhou created this gist
Feb 5, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,54 @@ require File.expand_path('../../config/boot', __FILE__) require File.expand_path('../../config/environment', __FILE__) require 'clockwork' include Clockwork every(1.day, 'Yearly Carry Job', :if => lambda { |t| t.day == 1 and t.month == 1}, :at => '0:00'){ now = Time.zone.now if now.month == 1 and now.day == 1 # clean sick days and personal days User.all.each do |user| next if not user.policy.present? Task.create(sub_type: :personal, user: user, total_hours: user.policy.total_personal_days * user.policy.work_hours_per_day - user.total_remain_personal_hours) Task.create(sub_type: :sick, user: user, total_hours: user.policy.total_sick_days * user.policy.work_hours_per_day - user.total_remain_sick_hours) end TimeoffPolicy.where(carry_over: :co_no_cap).each do |policy| policy.users.each do |user| Task.create(sub_type: :accrue, user: user, total_hours: -user.total_remain_vacation_hours) end end TimeoffPolicy.where(carry_over: :co_total_cap).each do |policy| policy.users.each do |user| remain = user.total_remain_vacation_hours if remain > user.policy.carry_over_cap Task.create(sub_type: :accrue, user: user, total_hours: -(remain - user.policy.carry_over_cap)) end end end # @todo calculate yearly_cap, take vacation days of the year before last year into account # carry_over = nolimit, sick days and personal days have been cleaned, do nothing to vacation days end } # use multi job to make job info log more clear every(1.day, 'Yearly Accrue Job', :if => lambda { |t| t.day == 1 and t.month == 1}, :at => '0:00'){ TimeoffPolicy.where(accrue_rate: :yearly).each do |policy| policy.users.each do |user| Task.create(sub_type: :accrue, user: user, total_hours: user.total_vacation_hours) end end } every(1.day, 'Monthly Accrue Job', :if => lambda { |t| t.day == 1 }, :at => '0:00'){ # @todo differentiate :accrue_by_time and :accrue_by_time_adv TimeoffPolicy.where(accrue_rate: :monthly).each do |policy| policy.users.each do |user| Task.create(sub_type: :accrue, user: user, total_hours: (user.total_vacation_hours / 12.0 - 0.005).round(2)) end end } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ class CreateTasks < ActiveRecord::Migration def change create_table :tasks do |t| t.string :name t.text :description t.references :author, index: true t.references :user, index: true t.references :assignee, index: true t.datetime :start_at t.datetime :end_at t.integer :task_type t.string :ancestry t.string :workflow_state t.text :attachments t.text :details t.float :total_hours t.timestamps end add_index :tasks, :ancestry add_index :tasks, :task_type add_index :tasks, :name end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,29 @@ class CreateTimeoffPolicies < ActiveRecord::Migration def change create_table :timeoff_policies do |t| t.string :name t.integer :base_vacation_days, :null => false, :default => 20 t.integer :accrue_type, :null => false, :default => 0 t.integer :accrue_rate, :null => false, :default => 0 t.boolean :allow_negative t.integer :negative_cap t.boolean :carry_over,:null => false, :default => false t.integer :carry_over_cap t.date :carry_over_expire_on t.integer :total_sick_days t.integer :total_personal_days t.integer :work_hours_per_day, :null => false, :default => 8 t.string :beginning_of_workday,:null => false, :default => "9:00 AM" t.string :end_of_workday,:null => false, :default => "5:00 PM" t.text :work_week,:null => false, :default => %w(mon tue wed thu fri) t.text :work_hours, :default => {} t.text :tentures, :default => [] t.text :holidays, :default => [] t.text :work_dates, :default => [] t.text :timeoff_types,:null => false, :default => [{:name => "Vacation", :type => "PTO"}] t.references :company, index: true t.string :zone,:null => false, :default => 'UTC' t.timestamps end end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,104 @@ Design Idea ================ inspired by this design strategy -------- 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) Example --------- 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 ``` Example 2 ========= 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) Example 3 ========= 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) Example 4 ========= 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 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,132 @@ # coding: utf-8 class Task < ActiveRecord::Base belongs_to :author, class_name:"User", foreign_key: :author_id belongs_to :user, class_name:"User", foreign_key: :user_id belongs_to :assignee, class_name:"User", foreign_key: :assignee_id after_update :calculate_hours validate :validate_total_hours # @!attribute sub_type # @return [Enumerable<String>] task's sub types to further distinguish them # @example # :start => starting balance # :accrue => accrue basing on the accrue rate # :adjustment => manual adjustment by manager or admin # :vacation => Vacations # :sick => Sick Leave # :personal => Personal Holidays # :others => Misc ones, employee won't be in office, but it doesn't consider his vacation/sick/personal days. such as jury duty or working from home. enum sub_type:[:start, :accrue, :adjustment, :vacation, :sick, :personal, :others] # @!attribute total_hours # @return [Integer] it is a calculated field when user made changes on the start_at or the end_at field # @!attribute author # @return [User] the person who opened task # @!attribute assignee # @return [User] task's assignee # @!attribute user # @return [User] who is this task for. like user1 create a task for user2. # @!attribute name # @return [String] the task's title, but it is possible to be used to hold the descriptions of user defined sub-types # @!attribute desciption # @return [Text] user's memo/reasons if it is a sick leave # @!attribute start_at # @return [DateTime] when is this task start # @!attribute end_at # @return [DateTime] when is this task ends # @!attribute attachment # @return [Array<Object>] attachments for this task. serialize :attachments mount_uploaders :attachments, FileUploader # @!attribute status # @return [Enumerable<String>] task's status # @example # :pending => pending for level1 approval # :pending2 => pending for secondary approval # :approved => approved by all manager # :rejected => rejected by manager. # :paid => Use in expense request # :booked => Used in travel request. # :cancelled => cancelled, could be from the requester # enum status:[:pending, :pending2, :approved, :rejected, :paid, :booked, :cancelled] include Workflow workflow do state :pending do event :approve, :transitions_to => :approved, :if => :all_approved? event :reject, :transitions_to => :rejected event :cancel, :transitions_to => :cancelled end state :approved do event :pay, :transitions_to => :paid event :book, :transitions_to => :booked end state :booked state :paid state :cancelled state :approved state :rejected end # @!attribute details # depending the type of the task, the content of the data field is different. # @return [Object] details in Hash/Openstruct format serialize :details # @!attribute followers # @return [Array<User>] # array of people who will be notified and possibly all the followers should have this task on their calendar. # 如果是出公差,从深圳分公司到上海总公司,那么这个Task,应该出现在所有followers的日历上面。 acts_as_followable acts_as_votable has_ancestry # comments and public activity include PublicActivity::Model tracked # tracked owner: Proc.new{ |controller, model| controller.current_user } # @todo calculate the total hours used for this task. def calculate_hours end def validate_total_hours end # @!method all_approved? # @return [Boolean] # has all the user's manager approved this task? def all_approved? self.user.following_users.count == self.get_upvotes.size end def approve self.vote_by :voter => self.assignee, :vote => 'yes' # auto change the assignee to the manager who has not approved this task yet. next_assignee = self.user.following_users.select {|f| !self.votes_for.up.voters.include?(f) }.first if next_assignee.present? self.assignee = next_assignee self.save! end end def on_approved_exit(new_state, event, *args) # notify followers for its approval self.followers.map {|f| self.create_activity(owner: f, key: 'task.change', action: :mood_changed)} # mark all sub-tasks as approved self.descendants.each { |t| t.workflow_state = 'approved'} end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,175 @@ # coding: utf-8 class TimeoffPolicy < ActiveRecord::Base # @!attribute name # @return [String] the name of the policy # @!attribute base_vacation_days # @return [Integer] total vacation days per year # @!attribute accrue_rate # @return [Enumerable<String>] indicate how often this policy should be ran to calculate employees vacation days balance. enum accrue_rate:[:weekly, :bi_weekly, :monthly, :yearly] # @!attribute accrue_type # @return [Enumerable<String>] Vacation Data Accural Type # @example Assuming you have 20 vacation days per year (假设你每年有20天休假) # :accrue_by_time => if it is accrue per month, u will have 20/12 = 1.66 days on Feb 1st # :accrue_by_time_adv => if it is accrue per month, u will have 20/12 = 1.66 days on January 1st # @note if accrue_by_time_adv and :yearly, means all days will be given to user at once enum accrue_type: [:accrue_by_time, :accrue_by_time_adv] # @!attribute tentures # We’ll automatically increase your employees’ vacation accrual rate based on the milestones you set below. (These bonuses will be your default policy, but you can turn this feature off for individual employees.) # 根据您设置下面的里程碑,我们将自动增加员工的假期累积率。 (这些奖金将是你的默认策略,但您可以关闭此功能对于员工个人。) # @return [Array<Object>] List of tenture. 年假逐年递增 年假递增率 # @example # self.tentures = [{anniversary:2, extra_days: 2}, {anniversary:4, extra_days: 2}] # means if you worked for 2 years, then you have 22 days vacation. If 4 years then u have 24 days. # 如果你工作了2年指,那么你有22天假期。如果4年那么你有24天假期。 serialize :tentures # @!attribute carry_over # @return [Boolean] Carry Over ? (跨年累积) # @!attribute carry_over_cap # @return [Integer] total carry over hours # @note if carry_over_cap is ZERO, it means cannot carry over any hours. # @!attribute carry_over_expire_on # @return [Date] total carry over hours expiration date # @example # carry_over:true,carry_over_cap:16, carry_over_expire_on:nil # with this setting, every year carry_over 16 hours and it never expires。 # carry_over:true,carry_over_cap:16, carry_over_expire_on:"12/31/1999" # with this setting, every year carry_over 16 hours,it means all the accumulated vacations days will be expired at the end of the year. # carry_over:true,carry_over_cap:16, carry_over_expire_on:“03/01/2000” # with this setting, every year carry_over 16 hours,it means all the accumulated vacations days will be expired at the end of Feburary. # carry_over:true,carry_over_cap:16, carry_over_expire_on:“06/01/2000” # with this setting, every year carry_over 16 hours,it means all the accumulated vacations days will be expired at the end of May. # @!attribute allow_negative # @return [Boolean] Do you allow user to borrow vacation days in advance? # @!attribute negative_cap # @return [Integer] how many vacation hours that user can borrow in advance # @!attribute total_sick_days # @return [Integer] total allowed sick days (病假) # @!attribute total_personal_days # @return [Integer] total allowed personal days (个人年假) # @!attribute work_hours_per_day # @return [Integer] total work hours per day # @!attribute beginning_of_workday # @return [String] start time for every working day. '9:00 am' # @!attribute end_of_workday # @return [Integer] end time for every working day. '5:00 pm' # @example We can adjust the start and end time of our business hours # self.beginning_of_workday = "8:30 am" # self.end_of_workday = "5:30 pm" # @!attribute work_week # @return [Array<String>] list of working week days. '%w(mon tue wed thu fri)' # @example # self.work_week = '%w(mon tue wed thu fri)' serialize :work_week # @!attribute work_hours # @return [Hash] list different working hours per day. Not sure if it is necessary. # @example as alternative we also can change the business hours for each work day: # self.work_hours = { # :mon=>["9:00","17:00"], # :fri=>["9:00","17:00"], # :sat=>["10:00","15:00"] # } serialize :work_hours # @!attribute work_dates # @return [Array<Hash>] a list of working dates, which addition to the work_week setting. # @example # work_dates = ["02/01/2015","02/14/2015"] serialize :work_dates # @!attribute holidays # @return [Array<Hash>] a list of holidays # @example # holidays = [{:name=>"Indepedence Day", :date=>"10/01/2014", :repeat => true}, {:name=>"New Year", :date=>"1/01/2015", :repeat => true}] serialize :holidays # @!attribute types # @return [Array<Hash>] a list of types # @example # self.timeoff_types = [{:name=>"Sick Day", :type=>"sick_leave"}, {:name=>"Personal Day", :type=>"personal_leave"}] serialize :timeoff_types belongs_to :company, class_name:"Company" has_many :users, class_name:"User" # calculate how many hours has user accrued in this policies period. # @todo calculate how many hours has user accrued in this policies period. # @example 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, :amount=> 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 def accrue users.each do |user| TimeoffTask.create(:sub_type => :accrue, :user => user, :amount=> amount) end end def work_hours_hash hash = {} self.work_hours.each do |item| hash[item[:day]] = item end hash end # compatible with business_time def each (&block) # XXX: _weekdays keys = ['beginning_of_workday', 'end_of_workday', 'work_week', 'work_hours'] keys.each do |k| yield k, self.attributes[k] end # reformat work_dates yield 'work_dates', self.work_dates.map{|i| Date.parse(i)} # reformat holidays yield 'holidays', self.holidays.inject([]){|res, i| d = Date.parse(i[:date]) if i[:repeat] res << d.change(year: Date.today.year) res << d.change(year: Date.today.year + 1) else res << d end } end end