From 744e7a78b37c2b01de65c2f126ec2496f40a0fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Mon, 2 Dec 2024 17:47:06 +0800 Subject: [PATCH] pengyuthon wechat --- attendance_iot/__init__.py | 3 + attendance_iot/__manifest__.py | 25 +++++ attendance_iot/controllers/__init__.py | 6 ++ attendance_iot/controllers/http.py | 19 ++++ attendance_iot/controllers/kaoqin_test.py | 95 +++++++++++++++++++ attendance_iot/models/__init__.py | 4 + .../models/attendance_iot.py | 0 .../models/attendance_iot_datas.py | 0 .../models/attendance_iot_manager.py | 0 .../models/hr_employee.py | 0 attendance_iot/security/ir.mode.access.csv | 5 + .../views/attendance_iot_datas.xml | 0 .../views/attendance_iot_manager_views.xml | 0 .../views/attendance_iot_views.xml | 0 .../views/inherit_hr_employee_views.xml | 0 attendance_iot/wizard/__init__.py | 1 + .../wizard/attendance_iot_manager_wizard.py | 0 .../attendance_iot_manager_wizard_views.xml | 0 soong_workflow/models/soong_workflow_mixin.py | 6 +- soong_workflow/models/soong_workflow_node.py | 6 +- .../wizard/soong_workflow_comment_wizard.py | 16 ++-- yuthon_duty_plan/__init__.py | 2 + yuthon_duty_plan/__manifest__.py | 34 +++++++ .../data/arrangement_time_data.xml | 0 yuthon_duty_plan/models/__init__.py | 8 ++ .../models/yuthon_abnormal_approval.py | 0 .../models/yuthon_abnormal_setting.py | 0 .../models/yuthon_adjustments_approval.py | 0 .../models/yuthon_duty_arrangement.py | 35 +++---- yuthon_duty_plan/models/yuthon_duty_plan.py | 41 ++++++++ .../models/yuthon_duty_setting.py | 0 .../models/yuthon_duty_summary.py | 0 .../models/yuthon_shift_approval.py | 0 yuthon_duty_plan/security/ir.model.access.csv | 16 ++++ .../views/yuthon_abnormal_approval_views.xml | 0 .../views/yuthon_abnormal_setting_views.xml | 0 .../yuthon_adjustments_approval_views.xml | 0 .../views/yuthon_duty_arrangement_views.xml | 30 ++---- .../views/yuthon_duty_plan_views.xml | 3 + .../views/yuthon_duty_setting_views.xml | 0 .../views/yuthon_duty_summary_views.xml | 4 +- .../views/yuthon_shift_approval_views.xml | 0 .../wizard/__init__.py | 0 .../wizard/yuthon_duty_arrangement_wizard.py | 13 ++- .../yuthon_duty_arrangement_wizard_views.xml | 2 +- .../wizard/yuthon_duty_summary_wizard.py | 1 + .../yuthon_duty_summary_wizard_views.xml | 2 +- yuthon_hr_attendance/__init__.py | 1 - yuthon_hr_attendance/__manifest__.py | 21 +--- yuthon_hr_attendance/controllers/__init__.py | 2 - yuthon_hr_attendance/controllers/http.py | 19 ---- .../controllers/kaoqin_test.py | 95 ------------------- yuthon_hr_attendance/models/__init__.py | 21 +--- .../models/yuthon_duty_plan.py | 25 ----- .../security/ir.model.access.csv | 16 +--- .../views/all_attendance_menu.xml | 10 -- yuthon_hr_attendance/views/duty_approval.xml | 1 - yuthon_property/models/property_assess.py | 15 +-- yuthon_will_task/models/yuthon_will_task.py | 2 +- yuthon_work_brand/__manifest__.py | 1 + yuthon_work_brand/views/attendance_menu.xml | 22 +++-- .../views/invisible_sequence.xml | 6 +- 62 files changed, 343 insertions(+), 291 deletions(-) create mode 100644 attendance_iot/__init__.py create mode 100644 attendance_iot/__manifest__.py create mode 100644 attendance_iot/controllers/__init__.py create mode 100644 attendance_iot/controllers/http.py create mode 100644 attendance_iot/controllers/kaoqin_test.py create mode 100644 attendance_iot/models/__init__.py rename {yuthon_hr_attendance => attendance_iot}/models/attendance_iot.py (100%) rename {yuthon_hr_attendance => attendance_iot}/models/attendance_iot_datas.py (100%) rename {yuthon_hr_attendance => attendance_iot}/models/attendance_iot_manager.py (100%) rename {yuthon_hr_attendance => attendance_iot}/models/hr_employee.py (100%) create mode 100644 attendance_iot/security/ir.mode.access.csv rename {yuthon_hr_attendance => attendance_iot}/views/attendance_iot_datas.xml (100%) rename {yuthon_hr_attendance => attendance_iot}/views/attendance_iot_manager_views.xml (100%) rename {yuthon_hr_attendance => attendance_iot}/views/attendance_iot_views.xml (100%) rename {yuthon_hr_attendance => attendance_iot}/views/inherit_hr_employee_views.xml (100%) create mode 100644 attendance_iot/wizard/__init__.py rename {yuthon_hr_attendance => attendance_iot}/wizard/attendance_iot_manager_wizard.py (100%) rename {yuthon_hr_attendance => attendance_iot}/wizard/attendance_iot_manager_wizard_views.xml (100%) create mode 100644 yuthon_duty_plan/__init__.py create mode 100644 yuthon_duty_plan/__manifest__.py rename {yuthon_hr_attendance => yuthon_duty_plan}/data/arrangement_time_data.xml (100%) create mode 100644 yuthon_duty_plan/models/__init__.py rename {yuthon_hr_attendance => yuthon_duty_plan}/models/yuthon_abnormal_approval.py (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/models/yuthon_abnormal_setting.py (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/models/yuthon_adjustments_approval.py (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/models/yuthon_duty_arrangement.py (79%) create mode 100644 yuthon_duty_plan/models/yuthon_duty_plan.py rename {yuthon_hr_attendance => yuthon_duty_plan}/models/yuthon_duty_setting.py (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/models/yuthon_duty_summary.py (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/models/yuthon_shift_approval.py (100%) create mode 100644 yuthon_duty_plan/security/ir.model.access.csv rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_abnormal_approval_views.xml (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_abnormal_setting_views.xml (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_adjustments_approval_views.xml (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_duty_arrangement_views.xml (75%) rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_duty_plan_views.xml (93%) rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_duty_setting_views.xml (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_duty_summary_views.xml (89%) rename {yuthon_hr_attendance => yuthon_duty_plan}/views/yuthon_shift_approval_views.xml (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/wizard/__init__.py (100%) rename {yuthon_hr_attendance => yuthon_duty_plan}/wizard/yuthon_duty_arrangement_wizard.py (83%) rename {yuthon_hr_attendance => yuthon_duty_plan}/wizard/yuthon_duty_arrangement_wizard_views.xml (90%) rename {yuthon_hr_attendance => yuthon_duty_plan}/wizard/yuthon_duty_summary_wizard.py (99%) rename {yuthon_hr_attendance => yuthon_duty_plan}/wizard/yuthon_duty_summary_wizard_views.xml (91%) delete mode 100644 yuthon_hr_attendance/controllers/http.py delete mode 100644 yuthon_hr_attendance/controllers/kaoqin_test.py delete mode 100644 yuthon_hr_attendance/models/yuthon_duty_plan.py diff --git a/attendance_iot/__init__.py b/attendance_iot/__init__.py new file mode 100644 index 000000000..e4f4917ae --- /dev/null +++ b/attendance_iot/__init__.py @@ -0,0 +1,3 @@ +from . import controllers +from . import models +from . import wizard diff --git a/attendance_iot/__manifest__.py b/attendance_iot/__manifest__.py new file mode 100644 index 000000000..7652b0588 --- /dev/null +++ b/attendance_iot/__manifest__.py @@ -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', +} diff --git a/attendance_iot/controllers/__init__.py b/attendance_iot/controllers/__init__.py new file mode 100644 index 000000000..f9e3f1f6b --- /dev/null +++ b/attendance_iot/controllers/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from . import kaoqin_test +from . import http + + diff --git a/attendance_iot/controllers/http.py b/attendance_iot/controllers/http.py new file mode 100644 index 000000000..b13daa378 --- /dev/null +++ b/attendance_iot/controllers/http.py @@ -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) + + diff --git a/attendance_iot/controllers/kaoqin_test.py b/attendance_iot/controllers/kaoqin_test.py new file mode 100644 index 000000000..b772649d0 --- /dev/null +++ b/attendance_iot/controllers/kaoqin_test.py @@ -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": "添加成功"} diff --git a/attendance_iot/models/__init__.py b/attendance_iot/models/__init__.py new file mode 100644 index 000000000..6ecccf0e1 --- /dev/null +++ b/attendance_iot/models/__init__.py @@ -0,0 +1,4 @@ +from . import hr_employee +from . import attendance_iot +from . import attendance_iot_datas +from . import attendance_iot_manager diff --git a/yuthon_hr_attendance/models/attendance_iot.py b/attendance_iot/models/attendance_iot.py similarity index 100% rename from yuthon_hr_attendance/models/attendance_iot.py rename to attendance_iot/models/attendance_iot.py diff --git a/yuthon_hr_attendance/models/attendance_iot_datas.py b/attendance_iot/models/attendance_iot_datas.py similarity index 100% rename from yuthon_hr_attendance/models/attendance_iot_datas.py rename to attendance_iot/models/attendance_iot_datas.py diff --git a/yuthon_hr_attendance/models/attendance_iot_manager.py b/attendance_iot/models/attendance_iot_manager.py similarity index 100% rename from yuthon_hr_attendance/models/attendance_iot_manager.py rename to attendance_iot/models/attendance_iot_manager.py diff --git a/yuthon_hr_attendance/models/hr_employee.py b/attendance_iot/models/hr_employee.py similarity index 100% rename from yuthon_hr_attendance/models/hr_employee.py rename to attendance_iot/models/hr_employee.py diff --git a/attendance_iot/security/ir.mode.access.csv b/attendance_iot/security/ir.mode.access.csv new file mode 100644 index 000000000..091bbb8e9 --- /dev/null +++ b/attendance_iot/security/ir.mode.access.csv @@ -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 \ No newline at end of file diff --git a/yuthon_hr_attendance/views/attendance_iot_datas.xml b/attendance_iot/views/attendance_iot_datas.xml similarity index 100% rename from yuthon_hr_attendance/views/attendance_iot_datas.xml rename to attendance_iot/views/attendance_iot_datas.xml diff --git a/yuthon_hr_attendance/views/attendance_iot_manager_views.xml b/attendance_iot/views/attendance_iot_manager_views.xml similarity index 100% rename from yuthon_hr_attendance/views/attendance_iot_manager_views.xml rename to attendance_iot/views/attendance_iot_manager_views.xml diff --git a/yuthon_hr_attendance/views/attendance_iot_views.xml b/attendance_iot/views/attendance_iot_views.xml similarity index 100% rename from yuthon_hr_attendance/views/attendance_iot_views.xml rename to attendance_iot/views/attendance_iot_views.xml diff --git a/yuthon_hr_attendance/views/inherit_hr_employee_views.xml b/attendance_iot/views/inherit_hr_employee_views.xml similarity index 100% rename from yuthon_hr_attendance/views/inherit_hr_employee_views.xml rename to attendance_iot/views/inherit_hr_employee_views.xml diff --git a/attendance_iot/wizard/__init__.py b/attendance_iot/wizard/__init__.py new file mode 100644 index 000000000..030334691 --- /dev/null +++ b/attendance_iot/wizard/__init__.py @@ -0,0 +1 @@ +from . import attendance_iot_manager_wizard diff --git a/yuthon_hr_attendance/wizard/attendance_iot_manager_wizard.py b/attendance_iot/wizard/attendance_iot_manager_wizard.py similarity index 100% rename from yuthon_hr_attendance/wizard/attendance_iot_manager_wizard.py rename to attendance_iot/wizard/attendance_iot_manager_wizard.py diff --git a/yuthon_hr_attendance/wizard/attendance_iot_manager_wizard_views.xml b/attendance_iot/wizard/attendance_iot_manager_wizard_views.xml similarity index 100% rename from yuthon_hr_attendance/wizard/attendance_iot_manager_wizard_views.xml rename to attendance_iot/wizard/attendance_iot_manager_wizard_views.xml diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 5dd2db6c3..e083273d4 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -220,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): diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py index b556c4359..9f4426ec8 100644 --- a/soong_workflow/models/soong_workflow_node.py +++ b/soong_workflow/models/soong_workflow_node.py @@ -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 diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index 5272c91aa..43476fa0a 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -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}) diff --git a/yuthon_duty_plan/__init__.py b/yuthon_duty_plan/__init__.py new file mode 100644 index 000000000..9b4296142 --- /dev/null +++ b/yuthon_duty_plan/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/yuthon_duty_plan/__manifest__.py b/yuthon_duty_plan/__manifest__.py new file mode 100644 index 000000000..3c9388857 --- /dev/null +++ b/yuthon_duty_plan/__manifest__.py @@ -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', +} diff --git a/yuthon_hr_attendance/data/arrangement_time_data.xml b/yuthon_duty_plan/data/arrangement_time_data.xml similarity index 100% rename from yuthon_hr_attendance/data/arrangement_time_data.xml rename to yuthon_duty_plan/data/arrangement_time_data.xml diff --git a/yuthon_duty_plan/models/__init__.py b/yuthon_duty_plan/models/__init__.py new file mode 100644 index 000000000..9417273df --- /dev/null +++ b/yuthon_duty_plan/models/__init__.py @@ -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 diff --git a/yuthon_hr_attendance/models/yuthon_abnormal_approval.py b/yuthon_duty_plan/models/yuthon_abnormal_approval.py similarity index 100% rename from yuthon_hr_attendance/models/yuthon_abnormal_approval.py rename to yuthon_duty_plan/models/yuthon_abnormal_approval.py diff --git a/yuthon_hr_attendance/models/yuthon_abnormal_setting.py b/yuthon_duty_plan/models/yuthon_abnormal_setting.py similarity index 100% rename from yuthon_hr_attendance/models/yuthon_abnormal_setting.py rename to yuthon_duty_plan/models/yuthon_abnormal_setting.py diff --git a/yuthon_hr_attendance/models/yuthon_adjustments_approval.py b/yuthon_duty_plan/models/yuthon_adjustments_approval.py similarity index 100% rename from yuthon_hr_attendance/models/yuthon_adjustments_approval.py rename to yuthon_duty_plan/models/yuthon_adjustments_approval.py diff --git a/yuthon_hr_attendance/models/yuthon_duty_arrangement.py b/yuthon_duty_plan/models/yuthon_duty_arrangement.py similarity index 79% rename from yuthon_hr_attendance/models/yuthon_duty_arrangement.py rename to yuthon_duty_plan/models/yuthon_duty_arrangement.py index 99c2ff704..9f67b4bab 100644 --- a/yuthon_hr_attendance/models/yuthon_duty_arrangement.py +++ b/yuthon_duty_plan/models/yuthon_duty_arrangement.py @@ -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 \ No newline at end of file diff --git a/yuthon_duty_plan/models/yuthon_duty_plan.py b/yuthon_duty_plan/models/yuthon_duty_plan.py new file mode 100644 index 000000000..d6e1c970e --- /dev/null +++ b/yuthon_duty_plan/models/yuthon_duty_plan.py @@ -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库', + '联安粮库'])]) diff --git a/yuthon_hr_attendance/models/yuthon_duty_setting.py b/yuthon_duty_plan/models/yuthon_duty_setting.py similarity index 100% rename from yuthon_hr_attendance/models/yuthon_duty_setting.py rename to yuthon_duty_plan/models/yuthon_duty_setting.py diff --git a/yuthon_hr_attendance/models/yuthon_duty_summary.py b/yuthon_duty_plan/models/yuthon_duty_summary.py similarity index 100% rename from yuthon_hr_attendance/models/yuthon_duty_summary.py rename to yuthon_duty_plan/models/yuthon_duty_summary.py diff --git a/yuthon_hr_attendance/models/yuthon_shift_approval.py b/yuthon_duty_plan/models/yuthon_shift_approval.py similarity index 100% rename from yuthon_hr_attendance/models/yuthon_shift_approval.py rename to yuthon_duty_plan/models/yuthon_shift_approval.py diff --git a/yuthon_duty_plan/security/ir.model.access.csv b/yuthon_duty_plan/security/ir.model.access.csv new file mode 100644 index 000000000..c698edd4b --- /dev/null +++ b/yuthon_duty_plan/security/ir.model.access.csv @@ -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, \ No newline at end of file diff --git a/yuthon_hr_attendance/views/yuthon_abnormal_approval_views.xml b/yuthon_duty_plan/views/yuthon_abnormal_approval_views.xml similarity index 100% rename from yuthon_hr_attendance/views/yuthon_abnormal_approval_views.xml rename to yuthon_duty_plan/views/yuthon_abnormal_approval_views.xml diff --git a/yuthon_hr_attendance/views/yuthon_abnormal_setting_views.xml b/yuthon_duty_plan/views/yuthon_abnormal_setting_views.xml similarity index 100% rename from yuthon_hr_attendance/views/yuthon_abnormal_setting_views.xml rename to yuthon_duty_plan/views/yuthon_abnormal_setting_views.xml diff --git a/yuthon_hr_attendance/views/yuthon_adjustments_approval_views.xml b/yuthon_duty_plan/views/yuthon_adjustments_approval_views.xml similarity index 100% rename from yuthon_hr_attendance/views/yuthon_adjustments_approval_views.xml rename to yuthon_duty_plan/views/yuthon_adjustments_approval_views.xml diff --git a/yuthon_hr_attendance/views/yuthon_duty_arrangement_views.xml b/yuthon_duty_plan/views/yuthon_duty_arrangement_views.xml similarity index 75% rename from yuthon_hr_attendance/views/yuthon_duty_arrangement_views.xml rename to yuthon_duty_plan/views/yuthon_duty_arrangement_views.xml index 7ffd5009b..4ada78d4c 100644 --- a/yuthon_hr_attendance/views/yuthon_duty_arrangement_views.xml +++ b/yuthon_duty_plan/views/yuthon_duty_arrangement_views.xml @@ -4,8 +4,7 @@ yuthon.duty.arrangement.tree yuthon.duty.arrangement - + @@ -14,9 +13,8 @@ - -