- 
    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)
银科福利年假需按进入银科日期发假

