diff --git a/sun_badge_menu/models/ir_ui_menu.py b/sun_badge_menu/models/ir_ui_menu.py
index 0325632ec..49975e359 100644
--- a/sun_badge_menu/models/ir_ui_menu.py
+++ b/sun_badge_menu/models/ir_ui_menu.py
@@ -3,7 +3,8 @@
import re
-from odoo import models, fields
+from odoo import models, fields, api, tools
+from odoo.osv import expression
def compute_badge_count_recursive(web_menus, menu_id):
@@ -31,6 +32,93 @@ class IrUiMenu(models.Model):
_inherit = "ir.ui.menu"
show_badge_count = fields.Boolean(string="显示菜单角标",default=True)
+ is_phone = fields.Boolean(string="手机菜单",default=False)
+ is_pc = fields.Boolean(string="PC菜单",default=True)
+
+ @api.model
+ @tools.ormcache_context('self._uid', 'debug', keys=('lang',))
+ def load_menus(self, debug):
+ """ Loads all menu items (all applications and their sub-menus).
+
+ :return: the menu root
+ :rtype: dict('children': menu_nodes)
+ """
+ fields = ['name', 'sequence', 'parent_id', 'action', 'web_icon','show_badge_count']
+ menu_roots = self.get_user_roots()
+ menu_roots_data = menu_roots.read(fields) if menu_roots else []
+ menu_root = {
+ 'id': False,
+ 'name': 'root',
+ 'parent_id': [-1, ''],
+ 'children': [menu['id'] for menu in menu_roots_data],
+ }
+
+ all_menus = {'root': menu_root}
+
+ if not menu_roots_data:
+ return all_menus
+
+ # menus are loaded fully unlike a regular tree view, cause there are a
+ # limited number of items (752 when all 6.1 addons are installed)
+ menus_domain = [('id', 'child_of', menu_roots.ids)]
+ blacklisted_menu_ids = self._load_menus_blacklist()
+ if blacklisted_menu_ids:
+ menus_domain = expression.AND([menus_domain, [('id', 'not in', blacklisted_menu_ids)]])
+ menus = self.search(menus_domain)
+ menu_items = menus.read(fields)
+ xmlids = (menu_roots + menus)._get_menuitems_xmlids()
+
+ # add roots at the end of the sequence, so that they will overwrite
+ # equivalent menu items from full menu read when put into id:item
+ # mapping, resulting in children being correctly set on the roots.
+ menu_items.extend(menu_roots_data)
+
+ mi_attachments = self.env['ir.attachment'].sudo().search_read(
+ domain=[('res_model', '=', 'ir.ui.menu'),
+ ('res_id', 'in', [menu_item['id'] for menu_item in menu_items if menu_item['id']]),
+ ('res_field', '=', 'web_icon_data')],
+ fields=['res_id', 'datas', 'mimetype'])
+
+ mi_attachment_by_res_id = {attachment['res_id']: attachment for attachment in mi_attachments}
+
+ # set children ids and xmlids
+ menu_items_map = {menu_item["id"]: menu_item for menu_item in menu_items}
+ for menu_item in menu_items:
+ menu_item.setdefault('children', [])
+ parent = menu_item['parent_id'] and menu_item['parent_id'][0]
+ menu_item['xmlid'] = xmlids.get(menu_item['id'], "")
+ if parent in menu_items_map:
+ menu_items_map[parent].setdefault(
+ 'children', []).append(menu_item['id'])
+ attachment = mi_attachment_by_res_id.get(menu_item['id'])
+ if attachment:
+ menu_item['web_icon_data'] = attachment['datas']
+ menu_item['web_icon_data_mimetype'] = attachment['mimetype']
+ else:
+ menu_item['web_icon_data'] = False
+ menu_item['web_icon_data_mimetype'] = False
+ all_menus.update(menu_items_map)
+
+ # sort by sequence
+ for menu_id in all_menus:
+ all_menus[menu_id]['children'].sort(key=lambda id: all_menus[id]['sequence'])
+
+ # recursively set app ids to related children
+ def _set_app_id(app_id, menu):
+ menu['app_id'] = app_id
+ for child_id in menu['children']:
+ _set_app_id(app_id, all_menus[child_id])
+
+ for app in menu_roots_data:
+ app_id = app['id']
+ _set_app_id(app_id, all_menus[app_id])
+
+ # filter out menus not related to an app (+ keep root menu)
+ all_menus = {menu['id']: menu for menu in all_menus.values() if menu.get('app_id')}
+ all_menus['root'] = menu_root
+
+ return all_menus
+
def load_web_menus(self, debug):
""" Loads all menu items (all applications and their sub-menus) and
@@ -75,7 +163,8 @@ class IrUiMenu(models.Model):
action_id = int(action_id) if action_id else False
badge_count = 0
res_model = False
- if action_model and action_id:
+ # 增加 show_badge_count 限制是否显示"角标".
+ if action_model and action_id and menu['show_badge_count']:
action_record = self.env[action_model].browse(action_id).sudo()
if action_model == 'ir.actions.act_window' and action_record.view_mode != 'form':
diff --git a/yuthon_hr_employee_approval/models/__init__.py b/yuthon_hr_employee_approval/models/__init__.py
index de509b22a..900eecc9f 100644
--- a/yuthon_hr_employee_approval/models/__init__.py
+++ b/yuthon_hr_employee_approval/models/__init__.py
@@ -27,4 +27,5 @@ from . import yuthon_department_change
from . import yuthon_renewal_approval
from . import contract_review_approval
from . import yuthon_employee_add
-from . import yuthon_pre_examination
\ No newline at end of file
+from . import yuthon_pre_examination
+from . import yuthon_employee_setting
\ No newline at end of file
diff --git a/yuthon_hr_employee_approval/models/yuthon_employee_setting.py b/yuthon_hr_employee_approval/models/yuthon_employee_setting.py
new file mode 100644
index 000000000..591a681c8
--- /dev/null
+++ b/yuthon_hr_employee_approval/models/yuthon_employee_setting.py
@@ -0,0 +1,9 @@
+from odoo import models, fields, api
+from dateutil.relativedelta import relativedelta
+
+
+class YuthonServiceType(models.Model):
+ _name = 'yuthon.service.type'
+ _description = '服务类型'
+
+ name = fields.Char(string="名称")
diff --git a/yuthon_hr_employee_approval/models/yuthon_service_approval.py b/yuthon_hr_employee_approval/models/yuthon_service_approval.py
index 5efac9fc1..6ee4a26bb 100644
--- a/yuthon_hr_employee_approval/models/yuthon_service_approval.py
+++ b/yuthon_hr_employee_approval/models/yuthon_service_approval.py
@@ -10,20 +10,22 @@ class YuthonServiceApproval(models.Model):
name = fields.Char(string='标题')
code = fields.Char(string="编号",
default=lambda self: self.env['ir.sequence'].next_by_code('yuthon_service_approval_code'))
- service_type = fields.Selection([('done', '在职证明'), ('leaving', '离职证明'), ('income', '收入证明')], string="服务类型")
+ service_type_id = fields.Many2one('yuthon.service.type', string="服务类型")
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
documents_ids = fields.Many2many('ir.attachment', string="附件")
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门", store=True)
- employee_id = fields.Many2one('hr.employee', string="员工姓名")
+ employee_id = fields.Many2one('hr.employee', string="员工姓名", default=lambda self: self.env.user.employee_id.id)
company_id = fields.Many2one(related="users_id.employee_id.company_id", string="公司", store=True)
tenant_user_card = fields.Many2one('ir.attachment', string="身份证")
- onboarding_time = fields.Date(related='employee_id.open_start_time', string="入职时间")
+ onboarding_time = fields.Date(related='employee_id.open_start_time', string="入职日期")
job_id = fields.Many2one(related='employee_id.job_id', string="岗位")
+ is_turnover = fields.Boolean()
reason_issuance = fields.Char(string="开证原因")
is_issues = fields.Boolean(string='是否上会')
issues_result = fields.Html(string="会议结果")
related_issues_id = fields.Many2one('issue.library', string="关联议题")
+ separation_date = fields.Date(string="离职日期")
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
default='normal')
active = fields.Boolean('Active', default=True, tracking=True)
@@ -50,14 +52,13 @@ class YuthonServiceApproval(models.Model):
'approval_date': fields.Datetime.now(),
})
- @api.onchange('service_type')
+ @api.onchange('service_type_id')
def _onchange_service_type(self):
- if self.service_type and self.users_id.name:
- # 创建一个映射表,将技术值映射到显示文本
- service_type_map = {
- 'done': '在职证明',
- 'leaving': '离职证明',
- 'income': '收入证明'
- }
- service_display = service_type_map.get(self.service_type, self.service_type)
- self.name = f"{self.users_id.name}的{service_display}"
\ No newline at end of file
+ if self.service_type_id and self.users_id.name:
+ self.name = f"{self.users_id.name}的{self.service_type_id.name}"
+
+ if self.service_type_id.name == '离职证明':
+ self.is_turnover = True
+ else:
+ self.is_turnover = False
+
diff --git a/yuthon_hr_employee_approval/security/ir.model.access.csv b/yuthon_hr_employee_approval/security/ir.model.access.csv
index 9bea8f0e7..c22a515ef 100644
--- a/yuthon_hr_employee_approval/security/ir.model.access.csv
+++ b/yuthon_hr_employee_approval/security/ir.model.access.csv
@@ -56,3 +56,4 @@ access_contract_review_approval,contract_review_approval,model_contract_review_a
access_awards_line, awards_line,model_awards_line,base.group_user,1,1,1,1
access_yuthon_employee_add,yuthon_employee_add,model_yuthon_employee_add,base.group_user,1,1,1,1
access_yuthon_pre_examination,yuthon_pre_examination,model_yuthon_pre_examination,base.group_user,1,1,1,1
+access_yuthon_service_type,yuthon_service_type,model_yuthon_service_type,base.group_user,1,1,1,1
diff --git a/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml
index 10aa4fb62..a63fd49b8 100644
--- a/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml
+++ b/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml
@@ -52,11 +52,13 @@