diff --git a/yuthon_salary/__init__.py b/yuthon_salary/__init__.py index cde864bae..35e7c9600 100644 --- a/yuthon_salary/__init__.py +++ b/yuthon_salary/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import models +from . import wizard diff --git a/yuthon_salary/__manifest__.py b/yuthon_salary/__manifest__.py index 03e58889b..fb136cee8 100644 --- a/yuthon_salary/__manifest__.py +++ b/yuthon_salary/__manifest__.py @@ -15,6 +15,8 @@ 'security/ir.model.access.csv', 'security/yuthon_salary_company.xml', 'views/inherit_hr_payroll_structure_views.xml', + 'views/inherit_hr_salary_rule_views.xml', + 'wizard/yuthon_salary_wizard_views.xml', ], 'installable': True, 'application': True, diff --git a/yuthon_salary/models/inherit_hr_payroll_structure.py b/yuthon_salary/models/inherit_hr_payroll_structure.py index 6ceb0a7ec..ad050f45e 100644 --- a/yuthon_salary/models/inherit_hr_payroll_structure.py +++ b/yuthon_salary/models/inherit_hr_payroll_structure.py @@ -33,4 +33,4 @@ class HrPayrollStructure(models.Model): return (False, 0) return (False, 0) # 首位非0的放前面 res.sort(key=sort_by_sequence_number) - return res \ No newline at end of file + return res diff --git a/yuthon_salary/models/inherit_hr_salary_rule.py b/yuthon_salary/models/inherit_hr_salary_rule.py index 9d4be9d93..ff70f157c 100644 --- a/yuthon_salary/models/inherit_hr_salary_rule.py +++ b/yuthon_salary/models/inherit_hr_salary_rule.py @@ -3,5 +3,17 @@ import re class InheritHrSalaryRule(models.Model): _inherit = 'hr.salary.rule' + _order = 'sequence asc' - category_id = fields.Many2one('hr.salary.rule.category', required=False) + category_id = fields.Many2one('hr.salary.rule.category', required=False, string='类别') + yuthon_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'), ('thlc', '天河粮储')], + string='所属公司') + + def action_yuthon_salary_wizard(self): + return { + "type": "ir.actions.act_window", + "name": "批量更新工资项", + "res_model": "yuthon.salary.wizard", + "view_mode": "form", + "target": "new", + } \ No newline at end of file diff --git a/yuthon_salary/security/ir.model.access.csv b/yuthon_salary/security/ir.model.access.csv index 58262d444..9ad83f062 100644 --- a/yuthon_salary/security/ir.model.access.csv +++ b/yuthon_salary/security/ir.model.access.csv @@ -1 +1,2 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink \ No newline at end of file +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_yuthon_salary_wizard,access_yuthon_salary_wizard,model_yuthon_salary_wizard,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/yuthon_salary/static/others/salary_template.xlsx b/yuthon_salary/static/others/salary_template.xlsx new file mode 100644 index 000000000..98392725a Binary files /dev/null and b/yuthon_salary/static/others/salary_template.xlsx differ diff --git a/yuthon_salary/views/inherit_hr_salary_rule_views.xml b/yuthon_salary/views/inherit_hr_salary_rule_views.xml new file mode 100644 index 000000000..6d87df537 --- /dev/null +++ b/yuthon_salary/views/inherit_hr_salary_rule_views.xml @@ -0,0 +1,40 @@ + + + + hr.salary.rule.inherit + hr.salary.rule + + + + + + + 1 + + + 1 + + + + + + + + hr.salary.rule.inherit.form + hr.salary.rule + + + + + + + + + + 批量导入职级 + + + code + action = model.action_yuthon_salary_wizard() + + diff --git a/yuthon_salary/wizard/__init__.py b/yuthon_salary/wizard/__init__.py new file mode 100644 index 000000000..48a07b98d --- /dev/null +++ b/yuthon_salary/wizard/__init__.py @@ -0,0 +1 @@ +from . import yuthon_salary_wizard \ No newline at end of file diff --git a/yuthon_salary/wizard/yuthon_salary_wizard.py b/yuthon_salary/wizard/yuthon_salary_wizard.py new file mode 100644 index 000000000..129c614c0 --- /dev/null +++ b/yuthon_salary/wizard/yuthon_salary_wizard.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api, _, SUPERUSER_ID +from odoo.exceptions import ValidationError, UserError +from pypinyin import pinyin, Style +import xlrd +import base64 +import datetime +from datetime import datetime + + +class YuthonSalaryWizard(models.Model): + _name = 'yuthon.salary.wizard' + + excel_file = fields.Binary(string="上传Excel表") + excel_name = fields.Char(string="文件名") + + def confirm(self): + """ + 导入excel文件,按行读取数据并处理 + """ + if not self.excel_file: + raise ValidationError('请上传文件。') + book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file)) + sh = book.sheet_by_index(0) + for rx in range(1, sh.nrows): + row = sh.row(rx) + self.salary_user_data(row) + return { + 'name': '批量更新工资项', + 'type': 'ir.actions.act_window', + 'view_mode': 'tree', + 'res_model': 'hr.salary.rule', + } + + def salary_user_data(self,row): + name_pinyin = pinyin(row[1].value, style=Style.FIRST_LETTER) + abbreviation = "".join([p[0][0] for p in name_pinyin]).upper() + salary_name = self.env['hr.salary.rule'].search([('name', '=', row[1].value)]) + text = row[2].value + struct_id = self.env['hr.payroll.structure'].search([('name', '=', text)]) + yuthon_company_dict = {'天河投资集团': 'thtz', '天河物管': 'thwg', '天河粮储': 'thlc', '': ''} + yuthon_company_dict2 = {'天河投资集团': 'TT', '天河物管': 'TW', '天河粮储': 'TL', '': ''} + yuthon_company = yuthon_company_dict.get(row[3].value) + yuthon_company2 = yuthon_company_dict2.get(row[3].value) + salary_date = { + 'sequence': row[0].value, + 'code':yuthon_company2+abbreviation, + 'name': row[1].value, # 姓名 + 'struct_id': struct_id.id, # 部门 + 'yuthon_company': yuthon_company, + 'amount_fix' : row[4].value, # 固定金额 + } + salary_name.create(salary_date) diff --git a/yuthon_salary/wizard/yuthon_salary_wizard_views.xml b/yuthon_salary/wizard/yuthon_salary_wizard_views.xml new file mode 100644 index 000000000..cd8a9fc1b --- /dev/null +++ b/yuthon_salary/wizard/yuthon_salary_wizard_views.xml @@ -0,0 +1,34 @@ + + + + 工资项模板 下载 + self + /yuthon_salary/static/others/salary_template.xlsx + + + 审批意见弹窗 + yuthon.salary.wizard + +
+ +
+
+ + + + + + + + +
+ +
+
+
+
\ No newline at end of file diff --git a/yuthon_will_task/data/will_task_time_data.xml b/yuthon_will_task/data/will_task_time_data.xml index 8059874c7..18e5f33ed 100644 --- a/yuthon_will_task/data/will_task_time_data.xml +++ b/yuthon_will_task/data/will_task_time_data.xml @@ -8,7 +8,7 @@ model.will_task_time() - 2 + 1 minutes -1 diff --git a/yuthon_will_task/models/yuthon_task_time.py b/yuthon_will_task/models/yuthon_task_time.py index 9eb742512..536155849 100644 --- a/yuthon_will_task/models/yuthon_task_time.py +++ b/yuthon_will_task/models/yuthon_task_time.py @@ -18,4 +18,5 @@ class YuthonTaskTime(models.Model): 'day': '天', } for n in self: - n.name = str(n.number) + task_unit_dict[n.task_unit] + if n.number and n.task_unit: + n.name = str(n.number) + task_unit_dict[n.task_unit] diff --git a/yuthon_will_task/models/yuthon_will_task.py b/yuthon_will_task/models/yuthon_will_task.py index 0d1f271f8..175f9d45b 100644 --- a/yuthon_will_task/models/yuthon_will_task.py +++ b/yuthon_will_task/models/yuthon_will_task.py @@ -21,20 +21,25 @@ class YuthonWillTask(models.Model): start_time = fields.Datetime(string='开始时间', default=fields.Date.today()) end_time = fields.Datetime(string='结束时间', default=lambda self: datetime.combine(datetime.now().date(), time(11, 0, 0))) - remind_mapping = { - 'fifteen': timedelta(minutes=15), - 'thirty': timedelta(minutes=30), - 'one_hour': timedelta(hours=1), - 'two_hour': timedelta(hours=2), - 'one_day': timedelta(days=1), - } - def will_task_time(self): - for task in self.env['yuthon.will.task'].search([]): - time_difference = task.end_time - datetime.now() - for remind, duration in self.remind_mapping.items(): - if task.remind == remind and time_difference <= duration: - task.add_comment() + tasks = self.env['yuthon.will.task'].search([]) + for task in tasks: + for task_time in task.task_time_ids: + time_difference = task.end_time - datetime.now() + duration = self._compute_duration(task_time) + if time_difference <= duration: + task.add_comment() # 将task_time对象传递给add_comment方法 + break # 触发一个提醒后就跳出内循环 + + def _compute_duration(self, task_time): + if task_time.task_unit == 'min': + return timedelta(minutes=task_time.number) + elif task_time.task_unit == 'hour': + return timedelta(hours=task_time.number) + elif task_time.task_unit == 'day': + return timedelta(days=task_time.number) + else: + return timedelta.max def add_comment(self): self.ensure_one()