-
Change
-
解决结果: 完成
-
Block
-
无
-
Y-银科控股-Y2021052
-
PRO
-
时间管理
-
隐藏
代码:
- Available variables:
- env: Environment, such as env['ir.model.data'].
- - ValidationError: an exception
- - urllib,json,simplejson,datetime,time,relativedelta: Python libraries
- rule: current allot rule object.
- employee: employee object.
- current_period: current period rule object.
- leave_date: employee leave_date.
- _logger: such as _logger.info('msg')
- return: allot result
- 'result = ' must be included in code.
- frequence == 'day' return list data
- frequence == 'month' return list data
- frequence == 'year' return float or int or dict data, dict is special for annual
result = 0 # 假期额度
LEGAL = [
{'year_num': 0, 'day_num': 0.0}
,
{'year_num': 1, 'day_num': 5.0}
,
{'year_num': 10, 'day_num': 10.0}
,
{'year_num': 20, 'day_num': 15.0}
,
]employee_info = self.data['employees_info'][employee_id]
period_info = self.data['periods_info'][period_id]
package_info = self.data['packages_info'][package_rule_info['holiday_package_id']]_compute_qty = env['leave.uom']._compute_qty
rule_obj = env['hr.holiday.rule.function']
entry_resignation_converter = rule_obj.entry_resignation_converter
allot_divide = rule_obj.allot_divide
precision_round = rule_obj.precision_round
get_days_count = rule_obj.get_days_count- 从界面读取参数
init_num = rule['init_num']
precision = rule['graininess'] if rule['graininess'] != "0" else "0.01" # 颗粒度
company_annual_graininess = rule['company_annual_graininess'] if rule['company_annual_graininess'] != "0" else "0.01"
legal_annual_graininess = rule['legal_annual_graininess'] if rule['legal_annual_graininess'] != "0" else "0.01"
round_rule = rule['carry_rule'] # 进位规则 - 颗粒度和进位规则 区分法定年假和公司年假
legal_precision = legal_annual_graininess if rule['is_enable_legal_annual'] else precision
legal_round_rule = rule['legal_annual_carry_rule'] if rule['is_enable_legal_annual'] else rule['carry_rule']
company_precision = company_annual_graininess if rule['is_enable_company_annual'] else precision
company_round_rule = rule['company_annual_carry_rule'] if rule['is_enable_company_annual'] else rule['carry_rule']
is_increase_with_work_age = rule['is_increase_with_work_age'] # 是否随工龄增长
growth_type = 'normal' # 增长类型为"工龄定档"
frequency = rule['frequency'] # 按年或按月发假,(month/year)
company_only_valid_for_quarter = rule['company_only_valid_for_quarter']
company_only_valid_for_month = rule['company_only_valid_for_month'] # 按月发假是否仅当月有效
is_entry_convert_enable = rule['is_entry_convert_enable'] # 启用入职折算
work_age_count_rule = 'convert' # 工龄计算规则
company_work_age_type = 'inner' # 公司工龄类型
is_resignation_convert_enable = rule['is_resignation_convert_enable'] # 启用离职折算- 指定只发法定,公司,或者两则都发
is_enable_legal_annual = rule['is_enable_legal_annual']
is_enable_company_annual = rule['is_enable_company_annual']
period_start_date = period_info['start_date']
period_end_date = period_info['end_date']
package_start_date = package_rule_info['start_date']
package_end_date = package_rule_info['end_date']
if leave_date and leave_date >= period_end_date:
leave_date = period_end_date # 离职日期最晚也就是当前期间的最后一天
employee_hire_date = employee_info['employee_hire_date']- 计算工龄跨档日,根据使用的工龄类型不同,得到不同的跨档日
- 当启用混合工龄与天数时, 默认用公司工龄计算跨当日;
company_work_age_cross_date, social_work_age_cross_date = self.get_work_age_cross_date(employee_id, period=period_info)
if not employee_info['original_start_date']:
social_work_age_cross_date = company_work_age_cross_date - _logger.info("公司跨档日期 %s" % company_work_age_cross_date)
- _logger.info("社会跨档日期 %s" % social_work_age_cross_date)
- 计算工龄(公司工龄,社会工龄)
social_work_age = 0
inner_work_age = 0
if is_increase_with_work_age: - 计算社会工龄和公司工龄
- 社会工龄, 目前是带小数的
social_work_age = self.work_age_calculate_func(employee_id, work_age_count_rule, "social",
company_work_age_cross_date, social_work_age_cross_date,
period_start_date, period_end_date) - _logger.info("社会工龄 %s" % social_work_age)
- 公司工龄,目前是带小数的
inner_work_age = self.work_age_calculate_func(employee_id, work_age_count_rule, "inner",
company_work_age_cross_date, social_work_age_cross_date,
period_start_date, period_end_date) - _logger.info("公司工龄 %s" % inner_work_age)
- 是否当前期间新入职
is_new = True if period_start_date < employee_hire_date < period_end_date else False - 获取法定/公司 工龄应发的天数
legal_is_cross_year = False
legal_current_num = 0
legal_before_cross_num = 0
company_is_cross_year = False
company_current_num = 0
company_before_cross_num = 0
if is_increase_with_work_age: - 随工龄增长
- 根据公司工龄跟社会工龄获取对应档的假期天数
- 法定年假,如果有跨区间的话:{"is_cross_year":是否跨区间, "last_num":上个区间的假期天数,
- "current_num":下个期间的假期天数},否则last_num和current_num是一致的
legal_holiday_count = {}
company_holiday_count = {} # 公司年假
try:
legal_holiday_count = get_days_count(social_work_age, LEGAL)
except Exception:
{"is_cross_year": False, "last_num": 0, "current_num": 0}
legal_holiday_count =company_holiday_count =
{"is_cross_year": False, "last_num": 0, "current_num": 0}if legal_holiday_count:
legal_is_cross_year = legal_holiday_count["is_cross_year"]
legal_current_num = legal_holiday_count["current_num"]
legal_before_cross_num = legal_holiday_count["last_num"]
if company_holiday_count:
company_is_cross_year = company_holiday_count["is_cross_year"]
company_current_num = company_holiday_count["current_num"]
company_before_cross_num = company_holiday_count["last_num"]
day_product_uom = self.data['uom_info'][package_info['product_uom_categ_id']]['day_uom'] # 获得天类型
standard_product_uom_id = self.data['uom_info'][package_info['product_uom_categ_id']]['hour_uom_id']- 处理初始值
- init_num = _compute_qty(rule['product_uom_id'], init_num, day_product_uom['id'], round=False)
- if growth_type != "normal" and is_increase_with_work_age:
- legal_current_num = init_num + legal_current_num
- legal_before_cross_num = init_num + legal_before_cross_num
- company_current_num = init_num + company_current_num
- company_before_cross_num = init_num + company_before_cross_num
- 不影响折算,另存拆假前期间开始日期和结束日期(跳过离职日期)
whole_start_date = period_start_date
whole_end_date = period_end_date - 根据是否入职离职折算,设置其按月或按天拆分的起止日期
if is_entry_convert_enable and is_new: # 是否是当前期间入职
period_start_date = employee_hire_date
if is_resignation_convert_enable and leave_date:
period_end_date = leave_date
is_package_start_convert = is_package_end_convert = False
if period_start_date < package_start_date and not self._is_first_package(package_rule_info): # 第一个休假包不做休假包有效期折算
period_start_date = package_start_date - 第一个休假包特殊处理
is_package_start_convert = True
if package_end_date and period_end_date > package_end_date:
period_end_date = package_end_date
is_package_end_convert = True
- 处理发放频率
allot_records = []
if frequency == "year": - 按年发的入离职跟按月不一样,这里单独处理
- 入离职折算
if work_age_count_rule in ["preview", "enough"]:
legal_is_cross_year = False
company_is_cross_year = False - 法定假期天数
legal_temp_result = entry_resignation_converter(legal_before_cross_num, legal_current_num, period_end_date,
period_start_date, period_end_date,
social_work_age_cross_date, employee_hire_date,
legal_is_cross_year, is_new and is_entry_convert_enable or is_package_start_convert,
leave_date and is_resignation_convert_enable or is_package_end_convert,is_package_start_convert, is_package_end_convert) - _logger.info("法定假期天数 %s" % legal_temp_result)
- # 公司假期天数
if company_work_age_type == 'social':
company_work_age_cross_date = social_work_age_cross_date
company_temp_result = 0
emp = env['hr.employee'].browse(employee_id)
hire_date = emp.hire_date or None
today = datetime.date.today()
emp = env['hr.employee'].browse(employee_id)
hire_date = emp.hire_date or None
today = datetime.date.today()
if hire_date:
the_years = relativedelta.relativedelta(today, hire_date).years
company_temp_result = min(the_years, 10)- _logger.info("公司假期天数 %s" % company_temp_result)
- 精度处理
if is_enable_legal_annual and not is_enable_company_annual: - 只启用法定年假
result = {"social": legal_temp_result, "start_date": period_start_date, "end_date": period_end_date} - _logger.info("只启用法定年假 %s" % result)
elif not is_enable_legal_annual and is_enable_company_annual: - 只启用公司年假
result = {"company": company_temp_result, "start_date": period_start_date, "end_date": period_end_date} - _logger.info("只启用公司年假 %s" % result)
elif not is_enable_legal_annual and not is_enable_company_annual:
result = []
elif is_enable_legal_annual and is_enable_company_annual: - 法定跟公司都启用
result = {"social": legal_temp_result, "company": min(15 - precision_round(legal_temp_result, legal_precision, legal_round_rule), company_temp_result), "start_date": period_start_date, "end_date": period_end_date}# 年假获得的假期天数是按天来计算的
if employee_hire_date > period_end_date: # 如果入职日期在区间结束时间之后,则不发假
result = []if result:
- 精度处理
if frequency in ['quarter', 'month']:
handle_precision_round_by_month(result, rule_obj, precision_round, company_precision, company_round_rule,
legal_precision, legal_round_rule)
elif rule['frequency'] == 'year':
if 'social' in result:
result['social'] = precision_round(round(result['social'],1), legal_precision, legal_round_rule) - result['social'] = result['social']
if 'company' in result:
result['company'] = precision_round(round(result['company'],1), company_precision, company_round_rule)
显示代码: Available variables: env: Environment, such as env ['ir.model.data'] . - ValidationError: an exception - urllib,json,simplejson,datetime,time,relativedelta: Python libraries rule: current allot rule object. employee: employee object. current_period: current period rule object. leave_date: employee leave_date. _logger: such as _logger.info('msg') return: allot result 'result = ' must be included in code. frequence == 'day' return list data frequence == 'month' return list data frequence == 'year' return float or int or dict data, dict is special for annual result = 0 # 假期额度 LEGAL = [ {'year_num': 0, 'day_num': 0.0} , {'year_num': 1, 'day_num': 5.0} , {'year_num': 10, 'day_num': 10.0} , {'year_num': 20, 'day_num': 15.0} , ] employee_info = self.data ['employees_info'] [employee_id] period_info = self.data ['periods_info'] [period_id] package_info = self.data ['packages_info'] [package_rule_info ['holiday_package_id'] ] _compute_qty = env ['leave.uom'] ._compute_qty rule_obj = env ['hr.holiday.rule.function'] entry_resignation_converter = rule_obj.entry_resignation_converter allot_divide = rule_obj.allot_divide precision_round = rule_obj.precision_round get_days_count = rule_obj.get_days_count 从界面读取参数 init_num = rule ['init_num'] precision = rule ['graininess'] if rule ['graininess'] != "0" else "0.01" # 颗粒度 company_annual_graininess = rule ['company_annual_graininess'] if rule ['company_annual_graininess'] != "0" else "0.01" legal_annual_graininess = rule ['legal_annual_graininess'] if rule ['legal_annual_graininess'] != "0" else "0.01" round_rule = rule ['carry_rule'] # 进位规则 颗粒度和进位规则 区分法定年假和公司年假 legal_precision = legal_annual_graininess if rule ['is_enable_legal_annual'] else precision legal_round_rule = rule ['legal_annual_carry_rule'] if rule ['is_enable_legal_annual'] else rule ['carry_rule'] company_precision = company_annual_graininess if rule ['is_enable_company_annual'] else precision company_round_rule = rule ['company_annual_carry_rule'] if rule ['is_enable_company_annual'] else rule ['carry_rule'] is_increase_with_work_age = rule ['is_increase_with_work_age'] # 是否随工龄增长 growth_type = 'normal' # 增长类型为"工龄定档" frequency = rule ['frequency'] # 按年或按月发假,(month/year) company_only_valid_for_quarter = rule ['company_only_valid_for_quarter'] company_only_valid_for_month = rule ['company_only_valid_for_month'] # 按月发假是否仅当月有效 is_entry_convert_enable = rule ['is_entry_convert_enable'] # 启用入职折算 work_age_count_rule = 'convert' # 工龄计算规则 company_work_age_type = 'inner' # 公司工龄类型 is_resignation_convert_enable = rule ['is_resignation_convert_enable'] # 启用离职折算 指定只发法定,公司,或者两则都发 is_enable_legal_annual = rule ['is_enable_legal_annual'] is_enable_company_annual = rule ['is_enable_company_annual'] period_start_date = period_info ['start_date'] period_end_date = period_info ['end_date'] package_start_date = package_rule_info ['start_date'] package_end_date = package_rule_info ['end_date'] if leave_date and leave_date >= period_end_date: leave_date = period_end_date # 离职日期最晚也就是当前期间的最后一天 employee_hire_date = employee_info ['employee_hire_date'] 计算工龄跨档日,根据使用的工龄类型不同,得到不同的跨档日 当启用混合工龄与天数时, 默认用公司工龄计算跨当日; company_work_age_cross_date, social_work_age_cross_date = self.get_work_age_cross_date(employee_id, period=period_info) if not employee_info ['original_start_date'] : social_work_age_cross_date = company_work_age_cross_date _logger.info("公司跨档日期 %s" % company_work_age_cross_date) _logger.info("社会跨档日期 %s" % social_work_age_cross_date) 计算工龄(公司工龄,社会工龄) social_work_age = 0 inner_work_age = 0 if is_increase_with_work_age: 计算社会工龄和公司工龄 社会工龄, 目前是带小数的 social_work_age = self.work_age_calculate_func(employee_id, work_age_count_rule, "social", company_work_age_cross_date, social_work_age_cross_date, period_start_date, period_end_date) _logger.info("社会工龄 %s" % social_work_age) 公司工龄,目前是带小数的 inner_work_age = self.work_age_calculate_func(employee_id, work_age_count_rule, "inner", company_work_age_cross_date, social_work_age_cross_date, period_start_date, period_end_date) _logger.info("公司工龄 %s" % inner_work_age) 是否当前期间新入职 is_new = True if period_start_date < employee_hire_date < period_end_date else False 获取法定/公司 工龄应发的天数 legal_is_cross_year = False legal_current_num = 0 legal_before_cross_num = 0 company_is_cross_year = False company_current_num = 0 company_before_cross_num = 0 if is_increase_with_work_age: 随工龄增长 根据公司工龄跟社会工龄获取对应档的假期天数 法定年假,如果有跨区间的话:{"is_cross_year":是否跨区间, "last_num":上个区间的假期天数, "current_num":下个期间的假期天数},否则last_num和current_num是一致的 legal_holiday_count = {} company_holiday_count = {} # 公司年假 try: legal_holiday_count = get_days_count(social_work_age, LEGAL) except Exception: legal_holiday_count = {"is_cross_year": False, "last_num": 0, "current_num": 0} company_holiday_count = {"is_cross_year": False, "last_num": 0, "current_num": 0} if legal_holiday_count: legal_is_cross_year = legal_holiday_count ["is_cross_year"] legal_current_num = legal_holiday_count ["current_num"] legal_before_cross_num = legal_holiday_count ["last_num"] if company_holiday_count: company_is_cross_year = company_holiday_count ["is_cross_year"] company_current_num = company_holiday_count ["current_num"] company_before_cross_num = company_holiday_count ["last_num"] day_product_uom = self.data ['uom_info'] [package_info ['product_uom_categ_id'] ] ['day_uom'] # 获得天类型 standard_product_uom_id = self.data ['uom_info'] [package_info ['product_uom_categ_id'] ] ['hour_uom_id'] 处理初始值 init_num = _compute_qty(rule ['product_uom_id'] , init_num, day_product_uom ['id'] , round=False) if growth_type != "normal" and is_increase_with_work_age: legal_current_num = init_num + legal_current_num legal_before_cross_num = init_num + legal_before_cross_num company_current_num = init_num + company_current_num company_before_cross_num = init_num + company_before_cross_num 不影响折算,另存拆假前期间开始日期和结束日期(跳过离职日期) whole_start_date = period_start_date whole_end_date = period_end_date 根据是否入职离职折算,设置其按月或按天拆分的起止日期 if is_entry_convert_enable and is_new: # 是否是当前期间入职 period_start_date = employee_hire_date if is_resignation_convert_enable and leave_date: period_end_date = leave_date is_package_start_convert = is_package_end_convert = False if period_start_date < package_start_date and not self._is_first_package(package_rule_info): # 第一个休假包不做休假包有效期折算 period_start_date = package_start_date 第一个休假包特殊处理 is_package_start_convert = True if package_end_date and period_end_date > package_end_date: period_end_date = package_end_date is_package_end_convert = True 处理发放频率 allot_records = [] if frequency == "year": 按年发的入离职跟按月不一样,这里单独处理 入离职折算 if work_age_count_rule in ["preview", "enough"] : legal_is_cross_year = False company_is_cross_year = False 法定假期天数 legal_temp_result = entry_resignation_converter(legal_before_cross_num, legal_current_num, period_end_date, period_start_date, period_end_date, social_work_age_cross_date, employee_hire_date, legal_is_cross_year, is_new and is_entry_convert_enable or is_package_start_convert, leave_date and is_resignation_convert_enable or is_package_end_convert,is_package_start_convert, is_package_end_convert) _logger.info("法定假期天数 %s" % legal_temp_result) # 公司假期天数 if company_work_age_type == 'social': company_work_age_cross_date = social_work_age_cross_date company_temp_result = 0 emp = env ['hr.employee'] .browse(employee_id) hire_date = emp.hire_date or None today = datetime.date.today() emp = env ['hr.employee'] .browse(employee_id) hire_date = emp.hire_date or None today = datetime.date.today() if hire_date: the_years = relativedelta.relativedelta(today, hire_date).years company_temp_result = min(the_years, 10) _logger.info("公司假期天数 %s" % company_temp_result) 精度处理 if is_enable_legal_annual and not is_enable_company_annual: 只启用法定年假 result = {"social": legal_temp_result, "start_date": period_start_date, "end_date": period_end_date} _logger.info("只启用法定年假 %s" % result) elif not is_enable_legal_annual and is_enable_company_annual: 只启用公司年假 result = {"company": company_temp_result, "start_date": period_start_date, "end_date": period_end_date} _logger.info("只启用公司年假 %s" % result) elif not is_enable_legal_annual and not is_enable_company_annual: result = [] elif is_enable_legal_annual and is_enable_company_annual: 法定跟公司都启用 result = {"social": legal_temp_result, "company": min(15 - precision_round(legal_temp_result, legal_precision, legal_round_rule), company_temp_result), "start_date": period_start_date, "end_date": period_end_date} # 年假获得的假期天数是按天来计算的 if employee_hire_date > period_end_date: # 如果入职日期在区间结束时间之后,则不发假 result = [] if result: 精度处理 if frequency in ['quarter', 'month'] : handle_precision_round_by_month(result, rule_obj, precision_round, company_precision, company_round_rule, legal_precision, legal_round_rule) elif rule ['frequency'] == 'year': if 'social' in result: result ['social'] = precision_round(round(result ['social'] ,1), legal_precision, legal_round_rule) result ['social'] = result ['social'] if 'company' in result: result ['company'] = precision_round(round(result ['company'] ,1), company_precision, company_round_rule)
银科福利年假需按进入银科日期发假