@@ -0,0 +1,3 @@
|
||||
from . import controllers
|
||||
from . import models
|
||||
from . import wizard
|
||||
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# email:pengyuthon@163.com
|
||||
{
|
||||
'name': 'Yuthon Iot Attendance',
|
||||
'summary': '',
|
||||
'description': '''
|
||||
''',
|
||||
'author': 'pengyuthon',
|
||||
'version': '17.0.1.2.1',
|
||||
'category': 'Human Resources/Attendances',
|
||||
'sequence': 240,
|
||||
'website': 'https://www.pengyuthon.com',
|
||||
'depends': ['hr_attendance', 'base', 'hr'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'views/attendance_iot_datas.xml',
|
||||
'views/attendance_iot_manager_views.xml',
|
||||
'views/attendance_iot_views.xml',
|
||||
'views/inherit_hr_employee_views.xml',
|
||||
'wizard/attendance_iot_manager_wizard_views.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import kaoqin_test
|
||||
from . import http
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
from odoo.http import JsonRPCDispatcher
|
||||
|
||||
|
||||
class CustomJsonRPCDispatcher(JsonRPCDispatcher):
|
||||
"""
|
||||
继承odoo底层源码http.py
|
||||
因为odoo本身会给对应的接口请求进行自动包装,通过判断做设备区分
|
||||
"""
|
||||
def _response(self, result=None, error=None):
|
||||
if 'api/v1' in self.request.httprequest.headers.environ.get('PATH_INFO'):
|
||||
return self.request.make_json_response(result)
|
||||
response = {'jsonrpc': '2.0', 'id': self.request_id}
|
||||
if error is not None:
|
||||
response['error'] = error
|
||||
if result is not None:
|
||||
response['result'] = result
|
||||
return self.request.make_json_response(response)
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
from odoo.http import Controller, request, route
|
||||
from datetime import datetime
|
||||
from odoo import models, fields, api, http, SUPERUSER_ID, _
|
||||
|
||||
|
||||
class BusController(Controller):
|
||||
def get_equipment_company(self, sn):
|
||||
sn_address = {
|
||||
'RLM-00111018': '地址1',
|
||||
}
|
||||
return sn_address[sn]
|
||||
|
||||
@route('/api/v1/record/face', methods=['POST'], type='json', auth='none', csrf=False)
|
||||
def get_model_definitions(self):
|
||||
"""
|
||||
用户通过考勤机识别,写入考勤数据
|
||||
:return:
|
||||
"""
|
||||
data = request.httprequest.json['logs'][0]
|
||||
user_name = data.get('user_name')
|
||||
employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('name', '=', user_name)])
|
||||
request.env(user=SUPERUSER_ID)["hr.attendance"].create({
|
||||
'employee_id': employee_id.id,
|
||||
'check_in': datetime.strptime(data.get('recog_time'), '%Y-%m-%d %H:%M:%S')
|
||||
})
|
||||
print("---------------------------------------------测试成功---------------------------------------")
|
||||
return {"Result": 0, "Msg": "添加成功"}
|
||||
|
||||
@route('/api/v1/user/inf_photo', methods=['POST'], type='json', auth='public')
|
||||
def get_model_definitions(self):
|
||||
name = request.jsonrequest.get('sn') # 姓名
|
||||
phone = request.jsonrequest.get('content') # 电话
|
||||
print(name, phone)
|
||||
return {
|
||||
"Result": 0,
|
||||
"Msg": "更新成功"
|
||||
}
|
||||
|
||||
# 员工识别接口
|
||||
@route('/api/v1/stranger', methods=['POST'], type='json', auth='none')
|
||||
def get_model_definitions(self):
|
||||
data = request.httprequest.json.get('logs')[0]
|
||||
user_name = data['user_name']
|
||||
request.env["hr.employee"].create({
|
||||
'name': user_name + 'stranger',
|
||||
})
|
||||
print("---------------------------------------------测试成功---------------------------------------")
|
||||
return {
|
||||
"Result": 0,
|
||||
"Msg": "更新成功"
|
||||
}
|
||||
|
||||
@route('/api/v1/addFace', methods=['POST'], type='json', auth='none', csrf=False)
|
||||
def get_model_kaoqin(self):
|
||||
"""
|
||||
获取用户录入考勤机数据,和系统内用户绑定关联
|
||||
:return:
|
||||
"""
|
||||
data = request.httprequest.json
|
||||
user_name = data.get('name')
|
||||
# validity_period = datetime.strptime(data.get('validity_period'), '%Y-%m-%d').date()
|
||||
employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('name', '=', user_name)])
|
||||
attendance_iot = request.env(user=SUPERUSER_ID)["attendance.iot.manager"]
|
||||
if not attendance_iot.search([('employee_id', '=', employee_id.id), ('attendance_number', '=', data.get('sn'))]):
|
||||
employee_id.write({
|
||||
'image_1920': data.get('photo'),
|
||||
})
|
||||
attendance_iot.create({
|
||||
'data_selection': "api",
|
||||
'attendance_number': data.get('sn'),
|
||||
'attendance_address': self.get_equipment_company(data.get('sn')),
|
||||
'employee_id': employee_id.id,
|
||||
})
|
||||
print("---------------------------------------------测试成功---------------------------------------")
|
||||
return {"Result": 0, "Msg": "添加成功"}
|
||||
|
||||
@route('/api/v1/record/face', methods=['POST'], type='json', auth='none', csrf=False)
|
||||
def get_model_identify(self):
|
||||
"""
|
||||
获取上传识别成功记录
|
||||
:return:
|
||||
"""
|
||||
data = request.httprequest.json
|
||||
user_name = data.get('logs').get('user_id')
|
||||
employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('user_id', '=', user_name.id)])
|
||||
attendance_iot = request.env(user=SUPERUSER_ID)["attendance.iot.datas"]
|
||||
if not attendance_iot.search(
|
||||
[('employee_id', '=', employee_id.id), ('attendance_number', '=', data.get('sn'))]):
|
||||
attendance_iot.create({
|
||||
'attendance_number': data.get('sn'),
|
||||
'attendance_date': data.get('logs').get('recog_time'),
|
||||
'employee_id': employee_id.id,
|
||||
})
|
||||
print("---------------------------------------------测试成功---------------------------------------")
|
||||
return {"Result": 0, "Msg": "添加成功"}
|
||||
@@ -0,0 +1,4 @@
|
||||
from . import hr_employee
|
||||
from . import attendance_iot
|
||||
from . import attendance_iot_datas
|
||||
from . import attendance_iot_manager
|
||||
@@ -0,0 +1,5 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_attendance_iot_manager,attendance_iot_manager,model_attendance_iot_manager,base.group_user,1,1,1,1
|
||||
access_attendance_iot_manager_wizard,attendance_iot_manager_wizard,model_attendance_iot_manager_wizard,base.group_user,1,1,1,1
|
||||
access_attendance_iot_datas,attendance_iot_datas,model_attendance_iot_datas,base.group_user,1,1,1,1
|
||||
access_attendance_iot,attendance_iot,model_attendance_iot,base.group_user,1,1,1,1
|
||||
|
@@ -0,0 +1 @@
|
||||
from . import attendance_iot_manager_wizard
|
||||
@@ -100,7 +100,10 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
}
|
||||
)
|
||||
log_ids.append(record_obj.id)
|
||||
rec.workflow_approver_ids = log_ids
|
||||
if log_ids:
|
||||
rec.workflow_approver_ids = log_ids
|
||||
else:
|
||||
rec.workflow_approver_ids = None
|
||||
|
||||
@api.depends("state")
|
||||
def _compute_workflow_id(self):
|
||||
@@ -217,9 +220,9 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
fields.Datetime.now() + timedelta(
|
||||
hours=8)),
|
||||
url=url, btntxt="查看详情")
|
||||
partner_ids = employee_ids.user_id.partner_id.ids
|
||||
self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids,
|
||||
'soong_workflow.message_soong_workflow_users_data')
|
||||
# partner_ids = employee_ids.user_id.partner_id.ids
|
||||
# self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids,
|
||||
# 'soong_workflow.message_soong_workflow_users_data')
|
||||
return btn_rec.with_context(cx).run()
|
||||
|
||||
def _add_comment(self, logs, btn_rec):
|
||||
|
||||
@@ -401,9 +401,9 @@ class SoongWorkflowNodeButton(models.Model):
|
||||
elif button_id.review_type == "user_role":
|
||||
user_role_id = self.env['res.users'].search([('employee_id.user_role_id', '=', button_id.users_role_id.id)])
|
||||
user_ids += user_role_id.ids
|
||||
# 发送信息提醒
|
||||
partner_ids = self.sudo().env['res.users'].search([('id', 'in', user_ids)]).mapped('partner_id').ids
|
||||
self.sudo().with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_yuthon_workflow_btn_approval_data')
|
||||
# # 发送信息提醒
|
||||
# partner_ids = self.sudo().env['res.users'].search([('id', 'in', user_ids)]).mapped('partner_id').ids
|
||||
# self.sudo().with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_yuthon_workflow_btn_approval_data')
|
||||
except Exception as e:
|
||||
pass
|
||||
return func_result
|
||||
|
||||
@@ -133,8 +133,8 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
record_id.name) + self.env.user.name + ' ' + str(
|
||||
fields.Datetime.now() + timedelta(hours=8)),
|
||||
url=url, btntxt="查看详情")
|
||||
partner_ids = self_node_id.employee_ids.user_id.partner_id.ids
|
||||
self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_soong_workflow_distribute')
|
||||
# partner_ids = self_node_id.employee_ids.user_id.partner_id.ids
|
||||
# self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_soong_workflow_distribute')
|
||||
# 转交逻辑--单线
|
||||
if not self.node_link_len:
|
||||
state = self.node_btn_id.node_id.out_link_ids.name.split('-> ')[-1]
|
||||
@@ -152,8 +152,8 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
fields.Datetime.now() + timedelta(
|
||||
hours=8)),
|
||||
url=url, btntxt="查看详情")
|
||||
partner_ids = self.employee_ids.user_id.partner_id.ids
|
||||
self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_soong_workflow_distribute')
|
||||
# partner_ids = self.employee_ids.user_id.partner_id.ids
|
||||
# self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_soong_workflow_distribute')
|
||||
return self.node_btn_id.with_context(cx).run()
|
||||
if self.node_btn_name == '退回':
|
||||
record_id.write({'state': 'start' if self.return_link_id.name == '拟办' else self.return_link_id.name})
|
||||
@@ -167,8 +167,8 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
fields.Datetime.now() + timedelta(
|
||||
hours=8)),
|
||||
url=url, btntxt="查看详情")
|
||||
partner_ids = self.employee_ids.user_id.partner_id.ids
|
||||
self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_soong_workflow_distribute')
|
||||
# partner_ids = self.employee_ids.user_id.partner_id.ids
|
||||
# self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_soong_workflow_distribute')
|
||||
return self.node_btn_id.with_context(cx).run()
|
||||
# 填写审批记录
|
||||
if self.node_btn_name != '加签':
|
||||
@@ -187,8 +187,8 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
record_id.name) + self.env.user.name + ' ' + str(
|
||||
fields.Datetime.now() + timedelta(hours=8)),
|
||||
url=url, btntxt="查看详情")
|
||||
partner_ids = self.circulated_employee_ids.user_id.partner_id.ids
|
||||
self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids,'soong_workflow.message_soong_workflow_distribute')
|
||||
# partner_ids = self.circulated_employee_ids.user_id.partner_id.ids
|
||||
# self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids,'soong_workflow.message_soong_workflow_distribute')
|
||||
if self.employee_ids:
|
||||
state = self.node_btn_id.node_id.out_link_ids.name.split('-> ')[-1]
|
||||
record_id.write({'state': 'end' if state == '结束' else state})
|
||||
|
||||
@@ -8,9 +8,23 @@ class HrContract(models.Model):
|
||||
_description = "员工合同拓展"
|
||||
|
||||
code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('contract_code'))
|
||||
name = fields.Char(string="合同名称", compute='_compute_name')
|
||||
resource_calendar_id = fields.Many2one('resource.calendar', string='考勤时间表')
|
||||
date_of_entry = fields.Date(string="入职时间", default=lambda self: self._default_date_of_entry())
|
||||
|
||||
work_entry_source = fields.Selection([
|
||||
('calendar', '考勤安排'),
|
||||
('attendance', 'Attendances'),
|
||||
('planning', '特殊排版')])
|
||||
('planning', '特殊排版')])
|
||||
|
||||
@api.model
|
||||
def _default_date_of_entry(self):
|
||||
return self.date_start or fields.Date.today()
|
||||
|
||||
@api.depends('contract_type_id')
|
||||
def _compute_name(self):
|
||||
for record in self:
|
||||
if record.contract_type_id:
|
||||
record.name = record.contract_type_id.name
|
||||
else:
|
||||
record.name = ' '
|
||||
@@ -1,5 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="inherit_hr_contract_yuthon_tree" model="ir.ui.view">
|
||||
<field name="name">inherit.hr.contract.yuthon.tree</field>
|
||||
<field name="model">hr.contract</field>
|
||||
<field name="inherit_id" ref="hr_contract.hr_contract_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='date_end']" position="after">
|
||||
<field name="date_of_entry"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='contract_type_id']" position="attributes">
|
||||
<attribute name="column_invisible">1</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='name']" position="attributes">
|
||||
<attribute name="string">合同名称</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="inherit_hr_contract_yuthon_form" model="ir.ui.view">
|
||||
<field name="name">inherit.hr.contract.yuthon.form</field>
|
||||
<field name="model">hr.contract</field>
|
||||
@@ -8,6 +24,9 @@
|
||||
<xpath expr="//field[@name='employee_id']" position="after">
|
||||
<field name="code"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='structure_type_id']" position="attributes">
|
||||
<attribute name="string">职级</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//page[@name='information']" position="replace">
|
||||
<page name="information2" string="工资信息">
|
||||
<group>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
from . import models
|
||||
from . import wizard
|
||||
@@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# email:pengyuthon@163.com
|
||||
{
|
||||
'name': 'Yuthon duty plan',
|
||||
'summary': '联安粮库值班',
|
||||
'description': '''
|
||||
''',
|
||||
'author': 'pengyuthon',
|
||||
'version': '17.0.1.2.1',
|
||||
'category': 'Human Resources/Attendances',
|
||||
'sequence': 240,
|
||||
'website': 'https://www.pengyuthon.com',
|
||||
'depends': ['hr_attendance', 'resource', 'base', 'hr', 'mail',
|
||||
'soong_workflow', 'yuthon_issue', 'planning', 'calendar'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'data/arrangement_time_data.xml',
|
||||
|
||||
'views/yuthon_duty_arrangement_views.xml',
|
||||
'views/yuthon_duty_summary_views.xml',
|
||||
'views/yuthon_duty_setting_views.xml',
|
||||
'views/yuthon_duty_plan_views.xml',
|
||||
|
||||
'views/yuthon_abnormal_approval_views.xml',
|
||||
'views/yuthon_abnormal_setting_views.xml',
|
||||
'views/yuthon_adjustments_approval_views.xml',
|
||||
'views/yuthon_shift_approval_views.xml',
|
||||
'wizard/yuthon_duty_arrangement_wizard_views.xml',
|
||||
'wizard/yuthon_duty_summary_wizard_views.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
from . import yuthon_duty_arrangement
|
||||
from . import yuthon_duty_plan
|
||||
from . import yuthon_duty_setting
|
||||
from . import yuthon_duty_summary
|
||||
from . import yuthon_adjustments_approval
|
||||
from . import yuthon_abnormal_approval
|
||||
from . import yuthon_abnormal_setting
|
||||
from . import yuthon_shift_approval
|
||||
+15
-20
@@ -23,10 +23,11 @@ class YuthonDutyArrangement(models.Model):
|
||||
duration = fields.Datetime(string='时长1')
|
||||
duration_two = fields.Datetime(string='时长2')
|
||||
duration_three = fields.Datetime(string='时长3')
|
||||
is_abnormal = fields.Boolean(string='异常', compute='_compute_is_abnormal')
|
||||
is_abnormal = fields.Boolean(string='异常', compute='_compute_is_abnormal', store=True)
|
||||
weekday_count = fields.Float(string='值班次数')
|
||||
week = fields.Char(string='星期', compute='_compute_week')
|
||||
is_weekend = fields.Boolean(string='是否周末', compute='_compute_is_weekend')
|
||||
week = fields.Selection([('one', '星期一'), ('two', '星期二'), ('three', '星期三'),
|
||||
('four', '星期四'), ('five', '星期五'), ('six', '星期六'),
|
||||
('seven', '星期日')], string='星期', compute='_compute_week', store=True)
|
||||
|
||||
@api.depends('duration', 'duration_two', 'duration_three')
|
||||
def _compute_is_photo(self):
|
||||
@@ -38,21 +39,14 @@ class YuthonDutyArrangement(models.Model):
|
||||
@api.depends('duration', 'duration_two', 'duration_three')
|
||||
def _compute_is_abnormal(self):
|
||||
for record in self:
|
||||
record.is_abnormal = not all([record.duration, record.duration_two, record.duration_three])
|
||||
|
||||
@api.depends('start_time')
|
||||
def _compute_is_weekend(self):
|
||||
for record in self:
|
||||
if record.start_time:
|
||||
weekday = record.start_time.weekday()
|
||||
record.is_weekend = weekday in (5, 6)
|
||||
else:
|
||||
record.is_weekend = False
|
||||
record.is_abnormal = False
|
||||
if record.start_time < fields.Date.today():
|
||||
record.is_abnormal = not all([record.duration, record.duration_two, record.duration_three])
|
||||
|
||||
def bottom_adjustment(self):
|
||||
for record in self:
|
||||
if date.today() < record.start_time:
|
||||
form_id = self.env.ref("yuthon_hr_attendance.view_yuthon_adjustments_approval_form").id
|
||||
form_id = self.env.ref("yuthon_duty_plan.view_yuthon_adjustments_approval_form").id
|
||||
use_id = self.employee_id.user_id.id
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
@@ -70,14 +64,14 @@ class YuthonDutyArrangement(models.Model):
|
||||
def button_abnormal(self):
|
||||
for record in self:
|
||||
if record.is_abnormal:
|
||||
form_id = self.env.ref("yuthon_hr_attendance.view_yuthon_abnormal_approval_form").id
|
||||
form_id = self.env.ref("yuthon_duty_plan.view_yuthon_abnormal_approval_form").id
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': '异常申请',
|
||||
'res_model': 'yuthon.abnormal.approval',
|
||||
"views": [[form_id, "form"]],
|
||||
"context": {
|
||||
'default_users_id':self.employee_id.user_id.id,
|
||||
'default_users_id': self.employee_id.user_id.id,
|
||||
}
|
||||
}
|
||||
else:
|
||||
@@ -87,11 +81,13 @@ class YuthonDutyArrangement(models.Model):
|
||||
def _compute_week(self):
|
||||
for record in self:
|
||||
if record.start_time:
|
||||
weekday = record.start_time.weekday()
|
||||
weekdays_cn = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
|
||||
weekday = (record.start_time + timedelta(hours=8)).weekday()
|
||||
weekdays_cn = {0: 'one', 1: 'two', 2: 'three',
|
||||
3: 'four', 4: 'five', 5: 'six',
|
||||
6: 'seven'}
|
||||
record.week = weekdays_cn[weekday]
|
||||
else:
|
||||
record.weed = False
|
||||
record.week = False
|
||||
|
||||
def duty_publish(self):
|
||||
employee_ids = self.search([]).mapped('employee_id.id')
|
||||
@@ -105,4 +101,3 @@ class YuthonDutyArrangement(models.Model):
|
||||
title="值班安排",
|
||||
description='本月的值班表已确认,请查看',
|
||||
url=str, btntxt="详细信息")
|
||||
e
|
||||
@@ -0,0 +1,41 @@
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, time, timedelta, date
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class YuthonDutyPlan(models.Model):
|
||||
_name = 'yuthon.duty.plan'
|
||||
_description = '值班计划'
|
||||
|
||||
name = fields.Char(string='计划名称', required=True)
|
||||
start_index_time = fields.Date(string='生效时间', default=fields.Date.today())
|
||||
end_index_time = fields.Date(string='失效时间')
|
||||
is_enable = fields.Boolean(string="启用", default=True)
|
||||
plan_line_ids = fields.One2many('duty.plan.line', 'duty_plan_id', string='关联计划明细')
|
||||
|
||||
def auto_duty_plan(self):
|
||||
employee_ids = self.env['hr.employee'].search([('department_id.name', 'in', ['仓储组', '综合组', '保管组', '机安组',
|
||||
'1库', '2库', '3库', '联安粮库'])])
|
||||
self.plan_line_ids.unlink()
|
||||
sequence = 1
|
||||
for employee in employee_ids:
|
||||
self.env['duty.plan.line'].create({
|
||||
'duty_plan_id': self.id,
|
||||
'sequence': sequence,
|
||||
'employee_id': employee.id
|
||||
})
|
||||
sequence += 1
|
||||
|
||||
|
||||
class DutyPlanLine(models.Model):
|
||||
_name = 'duty.plan.line'
|
||||
_description = '值班计划明细行'
|
||||
_order = 'sequence asc'
|
||||
|
||||
duty_plan_id = fields.Many2one('yuthon.duty.plan', string='关联计划名称')
|
||||
sequence = fields.Integer(string='序号')
|
||||
employee_id = fields.Many2one('hr.employee', string='员工',
|
||||
domain=lambda self: [('department_id.name', 'in', ['仓储组', '综合组',
|
||||
'保管组', '机安组',
|
||||
'1库', '2库', '3库',
|
||||
'联安粮库'])])
|
||||
@@ -0,0 +1,16 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_yuthon_duty_arrangement,yuthon.duty.arrangement,model_yuthon_duty_arrangement,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_arrangement_wizard,yuthon.duty.arrangement.wizard,model_yuthon_duty_arrangement_wizard,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_plan,yuthon.duty.plan,model_yuthon_duty_plan,base.group_user,1,1,1,1
|
||||
access_duty_plan_line,duty.plan.line,model_duty_plan_line,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_setting,yuthon.duty.setting,model_yuthon_duty_setting,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_summary,yuthon.duty.summary,model_yuthon_duty_summary,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_summary_wizard,yuthon.duty.summary.wizard,model_yuthon_duty_summary_wizard,base.group_user,1,1,1,1
|
||||
|
||||
|
||||
access_duty_approval_line,duty.approval.line,model_duty_approval_line,base.group_user,1,1,1,1
|
||||
|
||||
access_yuthon_adjustments_approval,yuthon.adjustments.approval,model_yuthon_adjustments_approval,base.group_user,1,1,1,1
|
||||
access_yuthon_abnormal_approval,yuthon.abnormal.approval,model_yuthon_abnormal_approval,base.group_user,1,1,1,1
|
||||
access_yuthon_abnormal_setting,yuthon.abnormal.setting,model_yuthon_abnormal_setting,base.group_user,1,1,1,1
|
||||
access_yuthon_shift_approval,yuthon.shift.approval,model_yuthon_shift_approval,base.group_user,1,1,1,
|
||||
|
+6
-24
@@ -4,8 +4,7 @@
|
||||
<field name="name">yuthon.duty.arrangement.tree</field>
|
||||
<field name="model">yuthon.duty.arrangement</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="值班安排"
|
||||
decoration-danger="is_abnormal">
|
||||
<tree string="值班安排" decoration-danger="is_abnormal">
|
||||
<field name="employee_id"/>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
@@ -14,9 +13,8 @@
|
||||
<field name="is_photo_two"/>
|
||||
<field name="is_photo_three"/>
|
||||
<field name="is_abnormal"/>
|
||||
<field name="is_weekend" optional="hide"/>
|
||||
<button name="bottom_adjustment" type="object" string="调休" class="btn btn-primary" column_invisible="not is_weekend"/>
|
||||
<button name="button_abnormal" type="object" string="异常申请" class="btn btn-primary"/>
|
||||
<button name="bottom_adjustment" type="object" string="调休" class="btn btn-primary"/>
|
||||
<button name="button_abnormal" type="object" string="补卡" class="btn btn-primary"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -39,7 +37,6 @@
|
||||
</group>
|
||||
<group>
|
||||
<field name="end_time" required="1"/>
|
||||
<field name="is_weekend" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
@@ -78,31 +75,16 @@
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_duty_calendar_event_calendar" model="ir.ui.view">
|
||||
<field name="name">yuthon.duty.arrangement.calendar</field>
|
||||
<field name="model">yuthon.duty.arrangement</field>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="arch" type="xml">
|
||||
<calendar string="待办事项"
|
||||
date_start="start_time"
|
||||
date_stop="end_time"
|
||||
event_open_popup="true"
|
||||
event_limit="5"
|
||||
quick_create="false"
|
||||
quick_create_view_id="%(yuthon_hr_attendance.view_yuthon_duty_arrangement_form)d">
|
||||
</calendar>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_yuthon_duty_arrangement_action" model="ir.actions.act_window">
|
||||
<field name="name">值班安排</field>
|
||||
<field name="res_model">yuthon.duty.arrangement</field>
|
||||
<field name="view_mode">tree,form,calendar,search</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_current_month': 1}</field>
|
||||
</record>
|
||||
<record id="all_duty_write_user" model="ir.actions.server">
|
||||
<field name="name">发送员工值班消息提醒</field>
|
||||
<field name="model_id" ref="yuthon_hr_attendance.model_yuthon_duty_arrangement"/>
|
||||
<field name="binding_model_id" ref="yuthon_hr_attendance.model_yuthon_duty_arrangement"/>
|
||||
<field name="model_id" ref="yuthon_duty_plan.model_yuthon_duty_arrangement"/>
|
||||
<field name="binding_model_id" ref="yuthon_duty_plan.model_yuthon_duty_arrangement"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.duty_publish()</field>
|
||||
</record>
|
||||
+3
@@ -17,6 +17,9 @@
|
||||
<field name="model">yuthon.duty.plan</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="值班计划">
|
||||
<header>
|
||||
<button name="auto_duty_plan" type="object" string="自动排列" class="oe_highlight"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
+2
-2
@@ -23,8 +23,8 @@
|
||||
<field name="name">值班汇总打印</field>
|
||||
<field name="model">yuthon.duty.summary</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">yuthon_hr_attendance.yuthon_duty_summary_report_template</field>
|
||||
<field name="report_file">yuthon_hr_attendance.yuthon_duty_summary_report_template</field>
|
||||
<field name="report_name">yuthon_duty_plan.yuthon_duty_summary_report_template</field>
|
||||
<field name="report_file">yuthon_duty_plan.yuthon_duty_summary_report_template</field>
|
||||
<field name="print_report_name">'%s-值班汇总'%</field>
|
||||
<field name="binding_model_id" ref="model_yuthon_duty_summary"/>
|
||||
<field name="binding_type">report</field>
|
||||
+11
-2
@@ -3,11 +3,12 @@ from odoo.exceptions import ValidationError, UserError
|
||||
from datetime import date, timedelta
|
||||
import random
|
||||
|
||||
|
||||
class YuthonDutyArrangementWizard(models.TransientModel):
|
||||
_name = 'yuthon.duty.arrangement.wizard'
|
||||
_description = '自动安排值班弹窗'
|
||||
|
||||
number_personnel = fields.Integer(string='人数')
|
||||
number_personnel = fields.Integer(string='人数', help="多少人一循环")
|
||||
remake = fields.Text(string='备注', default='一次只能排当月的,注意会清空当月数据随机生成。')
|
||||
|
||||
def confirm(self):
|
||||
@@ -27,7 +28,7 @@ class YuthonDutyArrangementWizard(models.TransientModel):
|
||||
]).unlink()
|
||||
today = date.today()
|
||||
next_month = (today.replace(day=1) + timedelta(days=32)).replace(day=1)
|
||||
current_date = today
|
||||
current_date = today
|
||||
while current_date < next_month:
|
||||
for employee in selected_people:
|
||||
self.env['yuthon.duty.arrangement'].create({
|
||||
@@ -37,6 +38,14 @@ class YuthonDutyArrangementWizard(models.TransientModel):
|
||||
})
|
||||
current_date += timedelta(days=1)
|
||||
|
||||
tree_id = self.env.ref("yuthon_duty_plan.view_yuthon_duty_arrangement_tree").id
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"name": "值班安排",
|
||||
"res_model": "yuthon.duty.arrangement",
|
||||
"views": [[tree_id, "tree"]],
|
||||
}
|
||||
|
||||
@api.model
|
||||
def action_hr_employee(self):
|
||||
return {
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
</record>
|
||||
<record id="yuthon_duty_arrangement_wizard_action" model="ir.actions.server">
|
||||
<field name="name">自动安排</field>
|
||||
<field name="model_id" ref="yuthon_hr_attendance.model_yuthon_duty_arrangement_wizard"/>
|
||||
<field name="model_id" ref="yuthon_duty_plan.model_yuthon_duty_arrangement_wizard"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.action_hr_employee()
|
||||
</field>
|
||||
+1
@@ -3,6 +3,7 @@ from dateutil.relativedelta import relativedelta
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import date, timedelta, datetime
|
||||
|
||||
|
||||
class YuthonDutySummaryWizard(models.TransientModel):
|
||||
_name = 'yuthon.duty.summary.wizard'
|
||||
_description = '值班汇总计算'
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
</record>
|
||||
<record id="yuthon_duty_summary_wizard_action" model="ir.actions.server">
|
||||
<field name="name">值班汇总计算</field>
|
||||
<field name="model_id" ref="yuthon_hr_attendance.model_yuthon_duty_summary_wizard"/>
|
||||
<field name="model_id" ref="yuthon_duty_plan.model_yuthon_duty_summary_wizard"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.action_duty_summary_wizard()
|
||||
</field>
|
||||
@@ -17,7 +17,7 @@
|
||||
'wizard/yuthon_fixes_wizard_views.xml',
|
||||
],
|
||||
'demo': [],
|
||||
'depends': ['hr_holidays', 'planning', 'hr', 'yuthon_hr_employee', 'base', 'yuthon_issue', 'documents', 'mail'],
|
||||
'depends': ['hr_holidays', 'planning', 'hr', 'yuthon_hr_employee', 'base', 'yuthon_issue', 'documents', 'mail', 'soong_workflow'],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
}
|
||||
|
||||
@@ -2,4 +2,3 @@
|
||||
|
||||
from . import models
|
||||
from . import controllers
|
||||
from . import wizard
|
||||
|
||||
@@ -16,45 +16,26 @@
|
||||
'soong_workflow', 'yuthon_issue', 'planning', 'calendar'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
# 'security/approval_attendance.xml',
|
||||
'data/attendance_code_data.xml',
|
||||
'data/attendance_time_data.xml',
|
||||
'data/arrangement_time_data.xml',
|
||||
# 'views/inherit_hr_employee_views.xml',
|
||||
'views/hr_attendance_views.xml',
|
||||
'views/resource_calendar_leaves_views.xml',
|
||||
'views/yuthon_adjustments_approval_views.xml',
|
||||
'views/yuthon_duty_arrangement_views.xml',
|
||||
'views/inherit_planning_role_views.xml',
|
||||
'views/inherit_planning_slot_views.xml',
|
||||
'views/inherit_planning_slot_template_views.xml',
|
||||
'views/yuthon_shift_planning_views.xml',
|
||||
'views/yuthon_duty_summary_views.xml',
|
||||
'views/yuthon_hv_planning_views.xml',
|
||||
'views/yuthon_overall_planning_views.xml',
|
||||
'views/yuthon_run_planning_views.xml',
|
||||
'views/yuthon_duty_setting_views.xml',
|
||||
'views/yuthon_shift_approval_views.xml',
|
||||
'views/yuthon_abnormal_setting_views.xml',
|
||||
'views/yuthon_duty_plan_views.xml',
|
||||
'views/yuthon_abnormal_approval_views.xml',
|
||||
# 'views/attendance_iot_datas.xml',
|
||||
# 'views/attendance_iot_manager_views.xml',
|
||||
# 'views/attendance_iot_views.xml',
|
||||
# 'views/attendance_iot_datas.xml',
|
||||
'views/overtime_approval.xml',
|
||||
'views/go_approval.xml',
|
||||
'views/duty_approval.xml',
|
||||
'views/leave_approval.xml',
|
||||
'views/overtime_page_views.xml',
|
||||
'views/remove_holiday_approval.xml',
|
||||
'views/card_approval.xml',
|
||||
'views/attendance_scheme.xml',
|
||||
'views/duty_approval.xml',
|
||||
'views/all_attendance_menu.xml',
|
||||
# 'views/attendance_iot_datas.xml',
|
||||
'wizard/yuthon_duty_arrangement_wizard_views.xml',
|
||||
'wizard/yuthon_duty_summary_wizard_views.xml',
|
||||
# 'wizard/attendance_iot_manager_wizard_views.xml',
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# from . import kaoqin_test
|
||||
# from . import http
|
||||
from . import attendance_banner_route
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
from odoo.http import JsonRPCDispatcher
|
||||
|
||||
|
||||
# class CustomJsonRPCDispatcher(JsonRPCDispatcher):
|
||||
# """
|
||||
# 继承odoo底层源码http.py
|
||||
# 因为odoo本身会给对应的接口请求进行自动包装,通过判断做设备区分
|
||||
# """
|
||||
# def _response(self, result=None, error=None):
|
||||
# if 'api/v1' in self.request.httprequest.headers.environ.get('PATH_INFO'):
|
||||
# return self.request.make_json_response(result)
|
||||
# response = {'jsonrpc': '2.0', 'id': self.request_id}
|
||||
# if error is not None:
|
||||
# response['error'] = error
|
||||
# if result is not None:
|
||||
# response['result'] = result
|
||||
# return self.request.make_json_response(response)
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
from odoo.http import Controller, request, route
|
||||
from datetime import datetime
|
||||
from odoo import models, fields, api, http, SUPERUSER_ID, _
|
||||
|
||||
|
||||
# class BusController(Controller):
|
||||
# def get_equipment_company(self, sn):
|
||||
# sn_address = {
|
||||
# 'RLM-00111018': '地址1',
|
||||
# }
|
||||
# return sn_address[sn]
|
||||
|
||||
# @route('/api/v1/record/face', methods=['POST'], type='json', auth='none', csrf=False)
|
||||
# def get_model_definitions(self):
|
||||
# """
|
||||
# 用户通过考勤机识别,写入考勤数据
|
||||
# :return:
|
||||
# """
|
||||
# data = request.httprequest.json['logs'][0]
|
||||
# user_name = data.get('user_name')
|
||||
# employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('name', '=', user_name)])
|
||||
# request.env(user=SUPERUSER_ID)["hr.attendance"].create({
|
||||
# 'employee_id': employee_id.id,
|
||||
# 'check_in': datetime.strptime(data.get('recog_time'), '%Y-%m-%d %H:%M:%S')
|
||||
# })
|
||||
# print("---------------------------------------------测试成功---------------------------------------")
|
||||
# return {"Result": 0, "Msg": "添加成功"}
|
||||
|
||||
# @route('/api/v1/user/inf_photo', methods=['POST'], type='json', auth='public')
|
||||
# def get_model_definitions(self):
|
||||
# name = request.jsonrequest.get('sn') # 姓名
|
||||
# phone = request.jsonrequest.get('content') # 电话
|
||||
# print(name, phone)
|
||||
# return {
|
||||
# "Result": 0,
|
||||
# "Msg": "更新成功"
|
||||
# }
|
||||
#
|
||||
# # 员工识别接口
|
||||
# @route('/api/v1/stranger', methods=['POST'], type='json', auth='none')
|
||||
# def get_model_definitions(self):
|
||||
# data = request.httprequest.json.get('logs')[0]
|
||||
# user_name = data['user_name']
|
||||
# request.env["hr.employee"].create({
|
||||
# 'name': user_name + 'stranger',
|
||||
# })
|
||||
# print("---------------------------------------------测试成功---------------------------------------")
|
||||
# return {
|
||||
# "Result": 0,
|
||||
# "Msg": "更新成功"
|
||||
# }
|
||||
|
||||
# @route('/api/v1/addFace', methods=['POST'], type='json', auth='none', csrf=False)
|
||||
# def get_model_kaoqin(self):
|
||||
# """
|
||||
# 获取用户录入考勤机数据,和系统内用户绑定关联
|
||||
# :return:
|
||||
# """
|
||||
# data = request.httprequest.json
|
||||
# user_name = data.get('name')
|
||||
# # validity_period = datetime.strptime(data.get('validity_period'), '%Y-%m-%d').date()
|
||||
# employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('name', '=', user_name)])
|
||||
# attendance_iot = request.env(user=SUPERUSER_ID)["attendance.iot.manager"]
|
||||
# if not attendance_iot.search([('employee_id', '=', employee_id.id), ('attendance_number', '=', data.get('sn'))]):
|
||||
# employee_id.write({
|
||||
# 'image_1920': data.get('photo'),
|
||||
# })
|
||||
# attendance_iot.create({
|
||||
# 'data_selection': "api",
|
||||
# 'attendance_number': data.get('sn'),
|
||||
# 'attendance_address': self.get_equipment_company(data.get('sn')),
|
||||
# 'employee_id': employee_id.id,
|
||||
# })
|
||||
# print("---------------------------------------------测试成功---------------------------------------")
|
||||
# return {"Result": 0, "Msg": "添加成功"}
|
||||
|
||||
# @route('/api/v1/record/face', methods=['POST'], type='json', auth='none', csrf=False)
|
||||
# def get_model_identify(self):
|
||||
# """
|
||||
# 获取上传识别成功记录
|
||||
# :return:
|
||||
# """
|
||||
# data = request.httprequest.json
|
||||
# user_name = data.get('logs').get('user_id')
|
||||
# employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('user_id', '=', user_name.id)])
|
||||
# attendance_iot = request.env(user=SUPERUSER_ID)["attendance.iot.datas"]
|
||||
# if not attendance_iot.search(
|
||||
# [('employee_id', '=', employee_id.id), ('attendance_number', '=', data.get('sn'))]):
|
||||
# attendance_iot.create({
|
||||
# 'attendance_number': data.get('sn'),
|
||||
# 'attendance_date': data.get('logs').get('recog_time'),
|
||||
# 'employee_id': employee_id.id,
|
||||
# })
|
||||
# print("---------------------------------------------测试成功---------------------------------------")
|
||||
# return {"Result": 0, "Msg": "添加成功"}
|
||||
@@ -1,38 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 硬件相关
|
||||
# from . import attendance_iot
|
||||
# from . import attendance_iot_manager
|
||||
# from . import attendance_iot_datas
|
||||
# access_attendance_iot_manager,attendance_iot_manager,model_attendance_iot_manager,base.group_user,1,1,1,1
|
||||
# access_attendance_iot_manager_wizard,attendance_iot_manager_wizard,model_attendance_iot_manager_wizard,base.group_user,1,1,1,1
|
||||
# access_attendance_iot_datas,attendance_iot_datas,model_attendance_iot_datas,base.group_user,1,1,1,1
|
||||
# access_attendance_iot,attendance_iot,model_attendance_iot,base.group_user,1,1,1,1
|
||||
# from . import hr_employee
|
||||
|
||||
from . import attendance_scheme
|
||||
from . import hr_attendance
|
||||
from . import resource_calendar_leaves
|
||||
from . import overtime_approval
|
||||
from . import go_approval
|
||||
from . import duty_approval
|
||||
from . import leave_approval
|
||||
from . import remove_holiday_approval
|
||||
from . import card_approval
|
||||
from . import planning_template_inherit
|
||||
from . import overtime_page
|
||||
from . import inherit_planning_role
|
||||
from . import yuthon_duty_summary
|
||||
from . import yuthon_adjustments_approval
|
||||
from . import yuthon_duty_arrangement
|
||||
from . import yuthon_duty_setting
|
||||
from . import yuthon_abnormal_approval
|
||||
from . import yuthon_shift_approval
|
||||
from . import yuthon_abnormal_setting
|
||||
from . import yuthon_duty_plan
|
||||
from . import inherit_planning_slot_template
|
||||
from . import inherit_planning_slot
|
||||
from . import yuthon_shift_planning
|
||||
from . import yuthon_hv_planning
|
||||
from . import yuthon_overall_planning
|
||||
from . import yuthon_run_planning
|
||||
from . import duty_approval
|
||||
|
||||
@@ -27,7 +27,17 @@ class GoApprovals(models.Model):
|
||||
if rec.go_approval_ids:
|
||||
first_line = rec.go_approval_ids[0]
|
||||
if first_line.date_start and first_line.date_end:
|
||||
rec.duration = (first_line.date_end - first_line.date_start).total_seconds() / 3600
|
||||
start_date = first_line.date_start
|
||||
end_date = first_line.date_end
|
||||
total_duration = end_date - start_date
|
||||
current_date = start_date
|
||||
while current_date < end_date:
|
||||
if current_date.weekday() == 5:
|
||||
total_duration -= timedelta(days=2)
|
||||
current_date += timedelta(days=2)
|
||||
else:
|
||||
current_date += timedelta(days=1)
|
||||
rec.duration = total_duration.total_seconds() / 3600
|
||||
else:
|
||||
rec.duration = 0.0
|
||||
else:
|
||||
|
||||
@@ -139,7 +139,6 @@ class HrAttendance(models.Model):
|
||||
'default_actual_punch': self.current_data,
|
||||
'default_replacement_time': replacement_time,
|
||||
'default_users_id': self.employee_id.user_id.id,
|
||||
'default_replacement_time': replacement_time,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, time, timedelta,date
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class YuthonDutyPlan(models.Model):
|
||||
_name = 'yuthon.duty.plan'
|
||||
_description = '值班计划'
|
||||
|
||||
name = fields.Char(string='计划名称', required=True)
|
||||
start_index_time = fields.Date(string='生效时间', default=fields.Date.today())
|
||||
end_index_time = fields.Date(string='失效时间')
|
||||
is_enable = fields.Boolean(string="启用", default=True)
|
||||
plan_line_ids = fields.One2many('duty.plan.line', 'duty_plan_id', string='关联计划明细')
|
||||
|
||||
|
||||
class DutyPlanLine(models.Model):
|
||||
_name = 'duty.plan.line'
|
||||
_description = '值班计划明细行'
|
||||
_order = 'sequence asc'
|
||||
|
||||
duty_plan_id = fields.Many2one('yuthon.duty.plan', string='关联计划名称')
|
||||
sequence = fields.Integer(string='序号')
|
||||
employee_id = fields.Many2one('hr.employee', string='员工',
|
||||
domain=lambda self: [('department_id.name', '=', '仓储组')])
|
||||
@@ -11,6 +11,39 @@ class YuthonRunPlanning(models.Model):
|
||||
illustrate = fields.Char(string='排班说明', default='默认轮排到下个月')
|
||||
engineering_run_ids = fields.One2many('yuthon.engineering.run.line', 'engineering_planning_id', string='关联运行班排班明细')
|
||||
|
||||
def confirm(self):
|
||||
start_date = datetime.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0) # 获取本月第一天零点
|
||||
end_date = (start_date + timedelta(days=32)).replace(day=1) # 获取下个月第一天零点
|
||||
role_a = self.env['planning.role'].search([('name', '=', '运行班白班')], limit=1)
|
||||
role_b = self.env['planning.role'].search([('name', '=', '运行班中值夜班')], limit=1)
|
||||
department_id = self.env['hr.department'].search([('name', '=', '运行班')])
|
||||
if department_id:
|
||||
employee_ids = self.env['hr.employee'].search([('department_id', '=', department_id.id)])
|
||||
else:
|
||||
employee_ids = self.env['hr.employee']
|
||||
if not role_a:
|
||||
resource_list = []
|
||||
for employee in employee_ids:
|
||||
resource_id = self.env['resource.resource'].search([('name', '=', employee.name)],
|
||||
limit=1)
|
||||
resource_list.append(resource_id.id)
|
||||
role_a = self.env['planning.role'].create({
|
||||
'resource_ids': resource_list,
|
||||
'name': '运行班白班',
|
||||
'department_id': department_id.id
|
||||
})
|
||||
|
||||
if not role_b:
|
||||
resource_list = []
|
||||
for employee in employee_ids:
|
||||
resource_ids = self.env['resource.resource'].search([('name', '=', employee.name)],
|
||||
limit=1)
|
||||
resource_list.append(resource_ids.id)
|
||||
role_b = self.env['planning.role'].create({
|
||||
'resource_ids': resource_list,
|
||||
'name': '运行班中值夜班',
|
||||
'department_id': department_id.id
|
||||
})
|
||||
|
||||
class YuthonEngineeringRunLine(models.Model):
|
||||
_name = 'yuthon.engineering.run.line'
|
||||
@@ -19,4 +52,4 @@ class YuthonEngineeringRunLine(models.Model):
|
||||
employee_id = fields.Many2one('hr.employee', string='人员',
|
||||
domain=lambda self: [('department_id.name', '=', '运行班')])
|
||||
sequence = fields.Integer(string='序号')
|
||||
engineering_planning_id = fields.Many2one('yuthon.engineering.planning', string='关联运行班排班计划')
|
||||
engineering_planning_id = fields.Many2one('yuthon.run.planning', string='关联运行班排班计划')
|
||||
|
||||
@@ -8,19 +8,108 @@ class YuthonShiftPlanning(models.Model):
|
||||
|
||||
name = fields.Char(string='排班名称', required=True)
|
||||
illustrate = fields.Char(string='排班说明', default='默认按ABC三组轮排到下个月')
|
||||
number_of_shifts = fields.Integer(string='轮班次数', default=0)
|
||||
planning_a_ids = fields.One2many('yuthon.shift.planning.a.line', 'shift_planning_id', string='关联A组')
|
||||
planning_b_ids = fields.One2many('yuthon.shift.planning.b.line', 'shift_planning_id', string='关联B组')
|
||||
planning_c_ids = fields.One2many('yuthon.shift.planning.c.line', 'shift_planning_id', string='关联C组')
|
||||
|
||||
def confirm(self):
|
||||
pass
|
||||
start_date = datetime.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0) # 获取本月第一天零点
|
||||
end_date = (start_date + timedelta(days=32)).replace(day=1) # 获取下个月第一天零点
|
||||
role_a = self.env['planning.role'].search([('name', '=', '保安部白班')], limit=1)
|
||||
role_b = self.env['planning.role'].search([('name', '=', '保安部中班')], limit=1)
|
||||
role_c = self.env['planning.role'].search([('name', '=', '保安部夜班')], limit=1)
|
||||
department_id = self.env['hr.department'].search([('name', '=', '保安部')], limit=1)
|
||||
department_ids = self.env['hr.department'].search([('name', 'in', ['保安部', '班组A', '班组B', '班组C'])])
|
||||
if department_ids:
|
||||
employee_ids = self.env['hr.employee'].search([('department_id', 'in', department_ids.ids)])
|
||||
else:
|
||||
employee_ids = self.env['hr.employee']
|
||||
if not role_a:
|
||||
resource_list = []
|
||||
for employee in employee_ids:
|
||||
resource_id = self.env['resource.resource'].search([('name', '=', employee.name)],
|
||||
limit=1)
|
||||
resource_list.append(resource_id.id)
|
||||
role_a = self.env['planning.role'].create({
|
||||
'resource_ids': resource_list,
|
||||
'name':'保安部白班',
|
||||
'department_id':department_id.id
|
||||
})
|
||||
|
||||
if not role_b:
|
||||
resource_list = []
|
||||
for employee in employee_ids:
|
||||
resource_ids = self.env['resource.resource'].search([('name', '=', employee.name)],
|
||||
limit=1)
|
||||
resource_list.append(resource_ids.id)
|
||||
role_b = self.env['planning.role'].create({
|
||||
'resource_ids': resource_list,
|
||||
'name': '保安部中班',
|
||||
'department_id': department_id.id
|
||||
})
|
||||
|
||||
if not role_c:
|
||||
resource_list = []
|
||||
for employee in employee_ids:
|
||||
resource_ids = self.env['resource.resource'].search([('name', '=', employee.name)],
|
||||
limit=1)
|
||||
resource_list.append(resource_ids.id)
|
||||
role_c = self.env['planning.role'].create({
|
||||
'resource_ids': resource_list,
|
||||
'name': '保安部夜班',
|
||||
'department_id': department_id.id
|
||||
})
|
||||
|
||||
role = [role_a, role_b, role_c]
|
||||
planning_groups = {
|
||||
'planning_a_ids': range(len(role)), # 默认顺序: 早 -> 中 -> 夜
|
||||
'planning_b_ids': [1, 2, 0], # 中 -> 夜 -> 早
|
||||
'planning_c_ids': [2, 1, 0] # 夜 -> 中 -> 早
|
||||
}
|
||||
|
||||
for planning_group, role_order in planning_groups.items():
|
||||
for record in getattr(self, planning_group):
|
||||
current_date = start_date
|
||||
while current_date < end_date:
|
||||
for role_index in role_order:
|
||||
for _ in range(self.number_of_shifts):
|
||||
role_template = self.env['planning.slot.template'].search(
|
||||
[('role_id', '=', role[role_index].id)], limit=1)
|
||||
self.create_planning_slot(record, role[role_index].id, role_template, current_date)
|
||||
current_date += timedelta(days=1)
|
||||
if current_date >= end_date: # 防止超出 end_date
|
||||
break
|
||||
if current_date >= end_date:
|
||||
break
|
||||
|
||||
def create_planning_slot(self, record,role,role_template,current_date):
|
||||
start_hour = int(role_template.start_time)
|
||||
start_minute = int(round((role_template.start_time - start_hour) * 60))
|
||||
end_hour = int(role_template.end_time)
|
||||
end_minute = int(round((role_template.end_time - end_hour) * 60))
|
||||
|
||||
start_time = current_date.replace(hour=start_hour, minute=start_minute, second=0, microsecond=0)+ timedelta(hours=16)
|
||||
if role_template.end_time < role_template.start_time:
|
||||
end_time = (current_date + timedelta(days=1)).replace(hour=end_hour, minute=end_minute, second=0,
|
||||
microsecond=0)+ timedelta(hours=16)
|
||||
else:
|
||||
end_time = current_date.replace(hour=end_hour, minute=end_minute, second=0, microsecond=0)+ timedelta(hours=16)
|
||||
|
||||
self.env['planning.slot'].create({
|
||||
'resource_id': record.employee_id.resource_id.id,
|
||||
'role_id':role,
|
||||
'start_datetime': start_time,
|
||||
'end_datetime': end_time,
|
||||
'allocated_hours':8,
|
||||
})
|
||||
|
||||
class YuthonShiftPlanningALine(models.Model):
|
||||
_name = 'yuthon.shift.planning.a.line'
|
||||
_description = '排班安排A组'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string='人员',
|
||||
domain=lambda self: [('department_id.name', '=', '保安部')])
|
||||
domain=lambda self: [('department_id.name', 'in', ['保安部', '班组A', '班组B','班组C'])])
|
||||
sequence = fields.Integer(string='序号')
|
||||
shift_planning_id = fields.Many2one('yuthon.shift.planning', string='关联排班安排')
|
||||
|
||||
@@ -30,7 +119,7 @@ class YuthonShiftPlanningBLine(models.Model):
|
||||
_description = '排班安排B组'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string='人员',
|
||||
domain=lambda self: [('department_id.name', '=', '保安部')])
|
||||
domain=lambda self: [('department_id.name', 'in', ['保安部', '班组A', '班组B','班组C'])])
|
||||
sequence = fields.Integer(string='序号')
|
||||
shift_planning_id = fields.Many2one('yuthon.shift.planning', string='关联排班安排')
|
||||
|
||||
@@ -40,7 +129,7 @@ class YuthonShiftPlanningCLine(models.Model):
|
||||
_description = '排班安排C组'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string='人员',
|
||||
domain=lambda self: [('department_id.name', '=', '保安部')])
|
||||
domain=lambda self: [('department_id.name', 'in', ['保安部', '班组A', '班组B','班组C'])])
|
||||
sequence = fields.Integer(string='序号')
|
||||
shift_planning_id = fields.Many2one('yuthon.shift.planning', string='关联排班安排')
|
||||
|
||||
|
||||
@@ -2,25 +2,12 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_resource_calendar_holiday,resource.calendar.holiday,model_resource_calendar_holiday,base.group_user,1,1,1,1
|
||||
access_overtime_approval,overtime.approval,model_overtime_approval,base.group_user,1,1,1,1
|
||||
access_go_approval,go.approval,model_go_approval,base.group_user,1,1,1,1
|
||||
access_duty_approval,duty.approval,model_duty_approval,base.group_user,1,1,1,1
|
||||
access_remove_holiday_approval,remove.holiday.approval,model_remove_holiday_approval,base.group_user,1,1,1,1
|
||||
access_card_approval,card.approval,model_card_approval,base.group_user,1,1,1,1
|
||||
access_attendance_scheme,attendance_scheme,model_attendance_scheme,base.group_user,1,1,1,1
|
||||
access_go_approvals_line,go.approvals.line,model_go_approvals_line,base.group_user,1,1,1,1
|
||||
access_overtime_user_line,overtime.user.line,model_overtime_user_line,base.group_user,1,1,1,1
|
||||
access_duty_approval_line,duty.approval.line,model_duty_approval_line,base.group_user,1,1,1,1
|
||||
access_overtime_page,overtime.page,model_overtime_page,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_summary,yuthon.duty.summary,model_yuthon_duty_summary,base.group_user,1,1,1,1
|
||||
access_yuthon_adjustments_approval,yuthon.adjustments.approval,model_yuthon_adjustments_approval,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_arrangement,yuthon.duty.arrangement,model_yuthon_duty_arrangement,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_setting,yuthon.duty.setting,model_yuthon_duty_setting,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_arrangement_wizard,yuthon.duty.arrangement.wizard,model_yuthon_duty_arrangement_wizard,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_summary_wizard,yuthon.duty.summary.wizard,model_yuthon_duty_summary_wizard,base.group_user,1,1,1,1
|
||||
access_yuthon_abnormal_approval,yuthon.abnormal.approval,model_yuthon_abnormal_approval,base.group_user,1,1,1,1
|
||||
access_yuthon_shift_approval,yuthon.shift.approval,model_yuthon_shift_approval,base.group_user,1,1,1,
|
||||
access_yuthon_abnormal_setting,yuthon.abnormal.setting,model_yuthon_abnormal_setting,base.group_user,1,1,1,1
|
||||
access_yuthon_duty_plan,yuthon.duty.plan,model_yuthon_duty_plan,base.group_user,1,1,1,1
|
||||
access_duty_plan_line,duty.plan.line,model_duty_plan_line,base.group_user,1,1,1,1
|
||||
access_yuthon_shift_planning,yuthon.shift.planning,model_yuthon_shift_planning,base.group_user,1,1,1,1
|
||||
access_yuthon_shift_planning_a_line,yuthon.shift.planning.a.line,model_yuthon_shift_planning_a_line,base.group_user,1,1,1,1
|
||||
access_yuthon_shift_planning_b_line,yuthon.shift.planning.b.line,model_yuthon_shift_planning_b_line,base.group_user,1,1,1,1
|
||||
@@ -30,4 +17,5 @@ access_yuthon_engineering_hv_line,yuthon.engineering.hv.line,model_yuthon_engine
|
||||
access_yuthon_yuthon_overall_planning,yuthon.overall.planning,model_yuthon_overall_planning,base.group_user,1,1,1,1
|
||||
access_yuthon_engineering_overall_planning,engineering.overall.planning,model_yuthon_engineering_overall_planning,base.group_user,1,1,1,1
|
||||
access_yuthon_run_planning,yuthon.run.planning,model_yuthon_run_planning,base.group_user,1,1,1,1
|
||||
access_yuthon_engineering_run_line,engineering.run.line,model_yuthon_engineering_run_line,base.group_user,1,1,1,1
|
||||
access_yuthon_engineering_run_line,engineering.run.line,model_yuthon_engineering_run_line,base.group_user,1,1,1,1
|
||||
access_duty_approval,duty.approval,model_duty_approval,base.group_user,1,1,1,1
|
||||
|
@@ -10,20 +10,10 @@
|
||||
parent="menu_hr_attendance_approval_request" sequence="3" action="approval_request_overtime"/>
|
||||
<menuitem id="menu_hr_attendance_going" name="外出申请"
|
||||
parent="menu_hr_attendance_approval_request" sequence="4" action="approval_request_going"/>
|
||||
<menuitem id="menu_hr_attendance_duty" name="值班申请" parent="menu_hr_attendance_approval_request"
|
||||
sequence="5" action="approval_request_duty"/>
|
||||
<menuitem id="menu_hr_attendance_leave" name="调休申请"
|
||||
parent="menu_hr_attendance_approval_request" sequence="6" action="approval_request_leave"/>
|
||||
<menuitem id="menu_hr_attendance_remove_holiday" name="销假申请"
|
||||
parent="menu_hr_attendance_approval_request" sequence="10" action="approval_request_remove_holiday"/>
|
||||
<menuitem id="menu_hr_attendance_remove_card" name="补卡申请"
|
||||
parent="menu_hr_attendance_approval_request" sequence="12" action="approval_request_card"/>
|
||||
<!-- <menuitem id="attendance_iot_manager_views" name="考勤机人员信息管理" parent="hr_attendance.menu_hr_attendance_root"-->
|
||||
<!-- sequence="15" action="attendance_iot_manager_action"/>-->
|
||||
<!-- <menuitem id="attendance_iot_views" name="考勤机设备管理" parent="hr_attendance.menu_hr_attendance_root"-->
|
||||
<!-- sequence="17" action="attendance_iot_action"/>-->
|
||||
<!-- <menuitem id="menu_hr_attendance_work" name="考勤时间表配置" parent="hr_attendance.menu_hr_attendance_root"-->
|
||||
<!-- sequence="18" action="resource.action_resource_calendar_form"/>-->
|
||||
<!-- <menuitem id="menu_hr_attendance_lot_datas" name="上传识别记录" parent="hr_attendance.menu_hr_attendance_root"-->
|
||||
<!-- sequence="21" action="attendance_iot_datas_action"/>-->
|
||||
</odoo>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="duty_approval_tree" model="ir.ui.view">
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
<odoo>
|
||||
<record id="hr_planning_slot_inherit" model="ir.ui.view">
|
||||
<record id="hr_planning_slot_template_tree_inherit" model="ir.ui.view">
|
||||
<field name="name">planning.slot.template.tree.inherit</field>
|
||||
<field name="model">planning.slot.template</field>
|
||||
<field name="inherit_id" ref="planning.planning_slot_template_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='role_id']" position="after">
|
||||
<field name="department_id" string="部门"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_planning_slot_template_inherit_form" model="ir.ui.view">
|
||||
<field name="name">planning.slot.template.form.inherit</field>
|
||||
<field name="model">planning.slot.template</field>
|
||||
<field name="inherit_id" ref="planning.planning_slot_template_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='role_id']" position="after">
|
||||
@@ -12,25 +22,25 @@
|
||||
<record id="action_planning_slot_template_form1" model="ir.actions.act_window">
|
||||
<field name="name">班次模板</field>
|
||||
<field name="res_model">planning.slot.template</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('department_id.name', '=', '保安部')]</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('department_id.name','in',['保安部', '班组A', '班组B','班组C'])]</field>
|
||||
</record>
|
||||
<record id="action_planning_slot_template_form2" model="ir.actions.act_window">
|
||||
<field name="name">班次模板</field>
|
||||
<field name="res_model">planning.slot.template</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('department_id.name', '=', '运行班')]</field>
|
||||
</record>
|
||||
<record id="action_planning_slot_template_form3" model="ir.actions.act_window">
|
||||
<field name="name">班次模板</field>
|
||||
<field name="res_model">planning.slot.template</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('department_id.name', '=', '高压班')]</field>
|
||||
</record>
|
||||
<record id="action_planning_slot_template_form4" model="ir.actions.act_window">
|
||||
<field name="name">班次模板</field>
|
||||
<field name="res_model">planning.slot.template</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('department_id.name', '=', '综合班')]</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -14,7 +14,7 @@
|
||||
<field name="res_model">planning.slot</field>
|
||||
<field name="view_mode">gantt,calendar,tree,form,kanban,pivot,graph</field>
|
||||
<field name="context">{'planning_expand_resource': 1, 'planning_expand_role': 1}</field>
|
||||
<field name="domain">[('department_id.name','=','保安部')]</field>
|
||||
<field name="domain">[('department_id.name','in',['保安部', '班组A', '班组B','班组C'])]</field>
|
||||
</record>
|
||||
<record id="action_planning_slot_form2" model="ir.actions.act_window">
|
||||
<field name="name">排班计划</field>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<tree string="排班安排">
|
||||
<field name="name"/>
|
||||
<field name="illustrate"/>
|
||||
<field name="number_of_shifts"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -22,11 +23,12 @@
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="illustrate"/>
|
||||
<field name="number_of_shifts"/>
|
||||
</group>
|
||||
<group string="排班安排A组(8:00-17:00)">
|
||||
<field name="planning_a_ids" string=" ">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence"/>
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="employee_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -34,15 +36,15 @@
|
||||
<group string="排班安排B组(14:00-22:00)">
|
||||
<field name="planning_b_ids" string=" ">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence"/>
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="employee_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group string="排班安排C组(22:00-06=8:00)">
|
||||
<group string="排班安排C组(22:00-8:00)">
|
||||
<field name="planning_c_ids" string=" ">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence"/>
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="employee_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
@@ -11,7 +11,7 @@ class EmployeeBannerRoute(Controller):
|
||||
all_hired_count = employees.search_count([]) # 全职
|
||||
return {
|
||||
'html': f"""
|
||||
<div style="display: flex; justify-content: space-around; align-items: center; text-align: center; padding: 20px; width: 100%;">
|
||||
<div style="display: flex; justify-content: space-around; align-items: center; text-align: center; padding: 20px; width: 100%;margin-top:25px;margin-bottom:25px;">
|
||||
<div style="flex: 1; padding: 20px;">
|
||||
<h2>正式</h2>
|
||||
<p style="font-size: 24px; color: #4CAF50;">{hired_count}</p>
|
||||
|
||||
@@ -30,7 +30,8 @@ class YuthonHrEmployee(models.Model):
|
||||
|
||||
number = fields.Char(string="序号", store=True)
|
||||
user_number = fields.Char(string="员工编号", default=lambda self: self.env['ir.sequence'].next_by_code('employee_code'))
|
||||
use_user_type = fields.Selection([('formal', '正式合同'), ('labor', '劳务协议'),
|
||||
use_user_type = fields.Selection([('formal_one', '正式合同(一签)'), ('labor', '劳务协议'), ('formal_two', '正式合同(二签)'),
|
||||
('formal_none', '正式合同(无固定)'),
|
||||
('part_time', '兼职协议'), ('employment', '用工协议'), ('internship', '实习协议')], string="用工形式")
|
||||
|
||||
contract_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'),
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<attribute name="column_invisible">1</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='department_id']" position="after">
|
||||
<field name="job_type_id"/>
|
||||
<field name="job_personnel"/>
|
||||
<field name="yuthon_company"/>
|
||||
<field name="establishment_quotas"/>
|
||||
<field name="no_of_employee" string="在编人数"/>
|
||||
|
||||
@@ -2,19 +2,22 @@ from odoo import models, fields, api
|
||||
|
||||
|
||||
class PropertyAssess(models.Model):
|
||||
_name = 'property.assess'
|
||||
_name = 'property.assess'
|
||||
|
||||
name = fields.Char(string="Name")
|
||||
|
||||
name = fields.Char(string="Name")
|
||||
|
||||
class PropertyAssessLine(models.Model):
|
||||
_name = 'property.assess.line'
|
||||
_name = 'property.assess.line'
|
||||
|
||||
|
||||
class PropertyProspectiveCcustomers(models.Model):
|
||||
_name = 'property.prospective.customers'
|
||||
_name = 'property.prospective.customers'
|
||||
|
||||
|
||||
class PropertyType(models.Model):
|
||||
_name = 'property.type'
|
||||
_name = 'property.type'
|
||||
|
||||
|
||||
class PropertyProspectiveCustomers(models.Model):
|
||||
_name = 'property.prospective.customers'
|
||||
_name = 'property.prospective.customers'
|
||||
|
||||
@@ -62,7 +62,7 @@ class YuthonWillTask(models.Model):
|
||||
raise UserError("请同步{}的企业微信".format(employee_id.name))
|
||||
url = "https://oa.thtzjt.com/mail/view?model={}&res_id={}".format(self._name, self.id)
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='task', user_id=employee_id.wecom_userid,
|
||||
title="日程事项提醒", description="事项名称: " + self.task_content + '\t' + self.start_time,
|
||||
title="日程事项提醒", description="事项名称: " + self.task_content + '\t' + str(self.start_time),
|
||||
url=url, btntxt="详细信息")
|
||||
for record in self:
|
||||
partner_ids = record.employee_ids.user_id.partner_id.ids
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
'payment', 'purchase', 'stock',
|
||||
'resource', 'yuthon_hr_employee_approval',
|
||||
'planning', 'ks_dashboard_ninja',
|
||||
'yuthon_duty_plan',
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
|
||||
@@ -215,6 +215,7 @@
|
||||
parent="hr_attendance_record_root_board"
|
||||
action="yuthon_hr_attendance.action_attendance_yuthon_company_form3"
|
||||
sequence="7"/>
|
||||
|
||||
<!-- 值班相关 -->
|
||||
<menuitem id="menu_hr_attendance_duty_summary_menu_board"
|
||||
name="粮库值班管理"
|
||||
@@ -223,27 +224,27 @@
|
||||
<menuitem id="menu_hr_attendance_duty_plan_board"
|
||||
name="值班计划"
|
||||
parent="menu_hr_attendance_duty_summary_menu_board"
|
||||
action="yuthon_hr_attendance.view_yuthon_duty_plan_action"
|
||||
action="yuthon_duty_plan.view_yuthon_duty_plan_action"
|
||||
sequence="1"/>
|
||||
<menuitem id="menu_hr_attendance_duty_automatically_scheduled"
|
||||
name="自动排班"
|
||||
parent="menu_hr_attendance_duty_summary_menu_board"
|
||||
action="yuthon_hr_attendance.yuthon_duty_arrangement_wizard_action"
|
||||
action="yuthon_duty_plan.yuthon_duty_arrangement_wizard_action"
|
||||
sequence="3"/>
|
||||
<menuitem id="menu_hr_attendance_duty_summary_board"
|
||||
name="值班安排"
|
||||
parent="menu_hr_attendance_duty_summary_menu_board"
|
||||
action="yuthon_hr_attendance.view_yuthon_duty_arrangement_action"
|
||||
action="yuthon_duty_plan.view_yuthon_duty_arrangement_action"
|
||||
sequence="5"/>
|
||||
<menuitem id="menu_hr_attendance_summary_root_board"
|
||||
name="值班汇总"
|
||||
parent="menu_hr_attendance_duty_summary_menu_board"
|
||||
action="yuthon_hr_attendance.view_yuthon_duty_summary_action"
|
||||
action="yuthon_duty_plan.view_yuthon_duty_summary_action"
|
||||
sequence="7"/>
|
||||
<menuitem id="menu_hr_attendance_duty_summary_compute_board"
|
||||
name="值班汇总计算"
|
||||
parent="menu_hr_attendance_duty_summary_menu_board"
|
||||
action="yuthon_hr_attendance.yuthon_duty_summary_wizard_action"
|
||||
action="yuthon_duty_plan.yuthon_duty_summary_wizard_action"
|
||||
sequence="9"/>
|
||||
<menuitem id="menu_hr_attendance_duty_summary_flow_board"
|
||||
name="流程"
|
||||
@@ -253,17 +254,17 @@
|
||||
name="值班调休"
|
||||
parent="menu_hr_attendance_duty_summary_flow_board"
|
||||
sequence="1"
|
||||
action="yuthon_hr_attendance.view_yuthon_adjustments_approval_action"/>
|
||||
action="yuthon_duty_plan.view_yuthon_adjustments_approval_action"/>
|
||||
<menuitem id="menu_yuthon_abnormal_approval_board"
|
||||
name="值班补卡"
|
||||
parent="menu_hr_attendance_duty_summary_flow_board"
|
||||
sequence="3"
|
||||
action="yuthon_hr_attendance.view_yuthon_abnormal_approval_action"/>
|
||||
action="yuthon_duty_plan.view_yuthon_abnormal_approval_action"/>
|
||||
<menuitem id="menu_yuthon_shift_approval_board"
|
||||
name="值班换班"
|
||||
parent="menu_hr_attendance_duty_summary_flow_board"
|
||||
sequence="5"
|
||||
action="yuthon_hr_attendance.view_yuthon_shift_approval_action"/>
|
||||
action="yuthon_duty_plan.view_yuthon_shift_approval_action"/>
|
||||
<menuitem id="menu_yuthon_duty_summary_setting"
|
||||
name="配置"
|
||||
parent="menu_hr_attendance_duty_summary_menu_board"
|
||||
@@ -272,12 +273,13 @@
|
||||
name="值班说明"
|
||||
parent="menu_yuthon_duty_summary_setting"
|
||||
sequence="1"
|
||||
action="yuthon_hr_attendance.action_yuthon_duty_setting"/>
|
||||
action="yuthon_duty_plan.action_yuthon_duty_setting"/>
|
||||
<menuitem id="menu_yuthon_abnormal_setting_board"
|
||||
name="值班补卡次数"
|
||||
parent="menu_yuthon_duty_summary_setting"
|
||||
sequence="3"
|
||||
action="yuthon_hr_attendance.view_yuthon_abnormal_setting_action"/>
|
||||
action="yuthon_duty_plan.view_yuthon_abnormal_setting_action"/>
|
||||
|
||||
<!-- 计划相关 -->
|
||||
<menuitem id="menu_hr_attendance_approval_request_board"
|
||||
name="流程"
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
<field name="active">False</field>
|
||||
</record>
|
||||
<!-- 讨论 -->
|
||||
<record id="mail.menu_root_discuss" model="ir.ui.menu">
|
||||
<field name="active">False</field>
|
||||
</record>
|
||||
<!-- <record id="mail.menu_root_discuss" model="ir.ui.menu">-->
|
||||
<!-- <field name="active">False</field>-->
|
||||
<!-- </record>-->
|
||||
<!-- 发票 -->
|
||||
<record id="account.menu_finance" model="ir.ui.menu">
|
||||
<field name="active">False</field>
|
||||
|
||||
Reference in New Issue
Block a user