From 4000bff31608f592b0d3aa59a321766f2844a2be Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Tue, 18 Feb 2025 20:59:16 +0800
Subject: [PATCH 1/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../models/yuthon_medical_manage.py | 20 ++++++-
.../models/yuthon_medical_rule.py | 2 +
.../security/ir.model.access.csv | 3 +-
.../views/yuthon_medical_manage_views.xml | 46 ++++++++++++++++
.../views/yuthon_medical_rule_views.xml | 2 +
yuthon_property_approval/__manifest__.py | 1 +
.../models/property_reimbursement_form.py | 52 ++++++++++++++++++-
.../security/ir.model.access.csv | 2 +
.../property_reimbursement_form_views.xml | 14 +++++
yuthon_property_approval/wizard/__init__.py | 3 +-
.../wizard/property_physical_wizard.py | 29 +++++++++++
.../wizard/property_physical_wizard_views.xml | 35 +++++++++++++
12 files changed, 204 insertions(+), 5 deletions(-)
create mode 100644 yuthon_property_approval/wizard/property_physical_wizard.py
create mode 100644 yuthon_property_approval/wizard/property_physical_wizard_views.xml
diff --git a/yuthon_hr_employee/models/yuthon_medical_manage.py b/yuthon_hr_employee/models/yuthon_medical_manage.py
index cc0c83b34..f9b957cbe 100644
--- a/yuthon_hr_employee/models/yuthon_medical_manage.py
+++ b/yuthon_hr_employee/models/yuthon_medical_manage.py
@@ -2,7 +2,6 @@
from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError
from datetime import datetime
-import re
class YuthonMedicalManage(models.Model):
@@ -19,3 +18,22 @@ class YuthonMedicalManage(models.Model):
prev_last_year_balance = fields.Float(string="前年结余")
prev_last_year_used = fields.Float(string="前年使用")
prev_last_year_remaining = fields.Float(string="前年剩余")
+ medical_line_ids = fields.One2many('yuthon.medical.line', 'medical_manage_id', string="体检费明细")
+
+ def button_details(self):
+ form_id = self.env.ref('yuthon_hr_employee.view_yuthon_medical_manage_form').id
+ return {
+ "type": "ir.actions.act_window",
+ "name": "修正申请",
+ "res_model": "yuthon.medical.manage",
+ "views": [[form_id, "form"]],
+ "res_id": self.id,
+ }
+
+class YuthonMedicalLine(models.Model):
+ _name = 'yuthon.medical.line'
+ _description = '体检费明细'
+
+ medical_manage_id = fields.Many2one('yuthon.medical.manage', string="关联体检费管理")
+ medical_date = fields.Date(string="体检日期")
+ medical_fee = fields.Float(string="费用")
diff --git a/yuthon_hr_employee/models/yuthon_medical_rule.py b/yuthon_hr_employee/models/yuthon_medical_rule.py
index 086ba3a8f..6a73bd8d2 100644
--- a/yuthon_hr_employee/models/yuthon_medical_rule.py
+++ b/yuthon_hr_employee/models/yuthon_medical_rule.py
@@ -11,6 +11,8 @@ class YuthonMedicalRule(models.Model):
base_amount = fields.Float(string='基数金额')
starting_age = fields.Integer(string='起始年龄')
+ department_id = fields.Many2one("hr.department", string="部门")
+ extension_years = fields.Selection(selection=[(str(i), str(i)) for i in range(1, 13)], string='延续年限')
increase_interval_years = fields.Integer(string='递增间隔(年)')
increment_amount = fields.Float(string='递增金额')
cap = fields.Float(string='封顶金额')
diff --git a/yuthon_hr_employee/security/ir.model.access.csv b/yuthon_hr_employee/security/ir.model.access.csv
index 6640cc757..c8bc23a97 100644
--- a/yuthon_hr_employee/security/ir.model.access.csv
+++ b/yuthon_hr_employee/security/ir.model.access.csv
@@ -17,4 +17,5 @@ access_yuthon_hr_employee_time_wizard,yuthon_hr_employee_time_wizard,model_yutho
access_hr_job_add_wizard,hr_job_add_wizard,model_hr_job_add_wizard,base.group_user,1,1,1,1
access_yuthon_party_setting,yuthon_party_setting,model_yuthon_party_setting,base.group_user,1,1,1,1
access_yuthon_medical_rule,yuthon_medical_rule,model_yuthon_medical_rule,base.group_user,1,1,1,1
-access_yuthon_medical_manage,yuthon_medical_manage,model_yuthon_medical_manage,base.group_user,1,1,1,1
\ No newline at end of file
+access_yuthon_medical_manage,yuthon_medical_manage,model_yuthon_medical_manage,base.group_user,1,1,1,1
+access_yuthon_medical_line,yuthon_medical_line,model_yuthon_medical_line,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/yuthon_hr_employee/views/yuthon_medical_manage_views.xml b/yuthon_hr_employee/views/yuthon_medical_manage_views.xml
index fecbd88a5..1b4368689 100644
--- a/yuthon_hr_employee/views/yuthon_medical_manage_views.xml
+++ b/yuthon_hr_employee/views/yuthon_medical_manage_views.xml
@@ -15,9 +15,55 @@
+
+
+ yuthon.medical.manage.form
+ yuthon.medical.manage
+
+
+
+
体检费管理
yuthon.medical.manage
diff --git a/yuthon_hr_employee/views/yuthon_medical_rule_views.xml b/yuthon_hr_employee/views/yuthon_medical_rule_views.xml
index 0198447a6..115e88890 100644
--- a/yuthon_hr_employee/views/yuthon_medical_rule_views.xml
+++ b/yuthon_hr_employee/views/yuthon_medical_rule_views.xml
@@ -12,6 +12,8 @@
+
+
diff --git a/yuthon_property_approval/__manifest__.py b/yuthon_property_approval/__manifest__.py
index 8f853947b..d91394923 100644
--- a/yuthon_property_approval/__manifest__.py
+++ b/yuthon_property_approval/__manifest__.py
@@ -63,6 +63,7 @@
'views/property_transaction_confirmed.xml',
'wizard/property_add_wizard_views.xml',
'wizard/property_contract_wizard.xml',
+ 'wizard/property_physical_wizard_views.xml',
'wizard/choose_contract_wizard_views.xml',
'wizard/property_rental_wizard_views.xml',
'views/property_menu_all.xml',
diff --git a/yuthon_property_approval/models/property_reimbursement_form.py b/yuthon_property_approval/models/property_reimbursement_form.py
index f6e70a571..1fc9256ca 100644
--- a/yuthon_property_approval/models/property_reimbursement_form.py
+++ b/yuthon_property_approval/models/property_reimbursement_form.py
@@ -21,7 +21,44 @@ class PropertyReimbursementForm(models.Model):
company_page = fields.Selection([('tz', '天河投资'), ('wg', '天河物管'), ('lc', '天河粮储')], string="公司")
account_id = fields.Many2one('property.account.setting', string="账户")
expense_line_ids = fields.One2many('property.expense.line', 'reimbursement_id', string="费用项目明细")
+ physical_line_ids = fields.One2many('property.physical.line', 'reimbursement_id', string="体检费明细")
+ def put_physical_in(self): # 导入按钮
+ return {
+ "type": "ir.actions.act_window",
+ "name": "导入体检费明细",
+ "res_model": "property.physical.wizard",
+ "view_mode": "form",
+ "target": "new",
+ }
+
+ # 体检费计算方法
+ def compute_reimbursement(self):
+ for record in self:
+ for rec in record.physical_line_ids:
+ rule_id = self.env['yuthon.medical.rule'].search([('department_id', '=', rec.employee_id.department_id.id)])
+ employee_id = self.env['yuthon.medical.manage'].search([('employee_id', '=', rec.employee_id.id)])
+ if not employee_id:
+ years_passed = rec.employee_id.old - rule_id.starting_age
+ decades_passed = years_passed // rule_id.increase_interval_years
+ increased_amount = decades_passed * rule_id.increment_amount
+ total_amount = rule_id.base_amount + increased_amount - rec.fees
+ final_amount = min(total_amount, rule_id.cap)
+ if rec.employee_id.user_sex == 'girl':
+ if rec.employee_id.marital == 'single':
+ final_amount = final_amount + rule_id.allowance_unmarried_women - rec.fees
+ else:
+ final_amount = final_amount + rule_id.allowance_married_women - rec.fees
+ employee_id = self.env['yuthon.medical.manage'].create({
+ 'employee_id': rec.employee_id.id,
+ 'current_year_remaining': final_amount})
+ else:
+ final_amount = employee_id.current_year_remaining - rec.fees
+ employee_id.write({'current_year_remaining': final_amount})
+ self.env['yuthon.medical.line'].create({
+ 'medical_manage_id': employee_id.id,
+ 'medical_date': rec.reimbursement_date,
+ 'medical_fee': rec.fees})
class PropertyExpenseLine(models.Model):
_name = 'property.expense.line'
@@ -29,11 +66,22 @@ class PropertyExpenseLine(models.Model):
reimbursement_id = fields.Many2one('property.reimbursement.form', string='关联报销单')
expense_id = fields.Many2one('property.project.setting', string='费用项目')
- invoice_type = fields.Char(string='发票类型')
+ invoice_type = fields.Selection([('ordinary_invoice', '普通发票'), ('vat_invoice', '增值税发票'), ('air_ticket', '机票'),
+ ('train_ticket', '火车票'), ('other_transport_ticket', '其他运输票'), ('other', '其他')], string='发票类型', default='ordinary_invoice')
expense_amount = fields.Float(string='费用金额')
applied_reimbursement_amount = fields.Float(string='申请报销金额')
expense_department_id = fields.Many2one('hr.department', string='费用承担部门')
invoice_receipt_number = fields.Char(string='收票单号')
applied_payment_amount = fields.Float(string='申请付款金额')
approved_reimbursement_amount = fields.Float(string='核定报销金额')
- approved_payment_amount = fields.Float(string='核定付款金额')
\ No newline at end of file
+ approved_payment_amount = fields.Float(string='核定付款金额')
+
+
+class PropertyPhysicalLine(models.Model):
+ _name = 'property.physical.line'
+ _description = '体检费明细'
+
+ reimbursement_id = fields.Many2one('property.reimbursement.form', string='关联报销单')
+ employee_id = fields.Many2one('hr.employee', string='姓名')
+ reimbursement_date = fields.Date(string='报销日期')
+ fees = fields.Float(string='费用')
diff --git a/yuthon_property_approval/security/ir.model.access.csv b/yuthon_property_approval/security/ir.model.access.csv
index 29ea7b70b..0616ac5d0 100644
--- a/yuthon_property_approval/security/ir.model.access.csv
+++ b/yuthon_property_approval/security/ir.model.access.csv
@@ -82,4 +82,6 @@ access_choose_property_wizard,choose_property_wizard,model_choose_property_wizar
access_property_rental_wizard,property_rental_wizard,model_property_rental_wizard,base.group_user,1,1,1,1
access_property_reimbursement_form,property_reimbursement_form,model_property_reimbursement_form,base.group_user,1,1,1,1
access_property_expense_line,property_expense_line,model_property_expense_line,base.group_user,1,1,1,1
+access_property_physical_line,property_physical_line,model_property_physical_line,base.group_user,1,1,1,1
+access_property_physical_wizard,property_physical_wizard,model_property_physical_wizard,base.group_user,1,1,1,1
diff --git a/yuthon_property_approval/views/property_reimbursement_form_views.xml b/yuthon_property_approval/views/property_reimbursement_form_views.xml
index f203054fd..8bc1548e3 100644
--- a/yuthon_property_approval/views/property_reimbursement_form_views.xml
+++ b/yuthon_property_approval/views/property_reimbursement_form_views.xml
@@ -21,6 +21,7 @@
+
@@ -47,6 +48,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/yuthon_property_approval/wizard/__init__.py b/yuthon_property_approval/wizard/__init__.py
index 3ff98c423..fc4e7ad59 100644
--- a/yuthon_property_approval/wizard/__init__.py
+++ b/yuthon_property_approval/wizard/__init__.py
@@ -1,4 +1,5 @@
from . import property_contract_wizard
from . import choose_property_wizard
from . import property_rental_wizard
-from . import property_add_wizard
\ No newline at end of file
+from . import property_add_wizard
+from . import property_physical_wizard
\ No newline at end of file
diff --git a/yuthon_property_approval/wizard/property_physical_wizard.py b/yuthon_property_approval/wizard/property_physical_wizard.py
new file mode 100644
index 000000000..fbfca01a1
--- /dev/null
+++ b/yuthon_property_approval/wizard/property_physical_wizard.py
@@ -0,0 +1,29 @@
+from odoo import models, fields, api, _, SUPERUSER_ID
+from odoo.exceptions import ValidationError, UserError
+import xlrd
+import base64
+import datetime
+from datetime import datetime
+import pandas as pd
+
+
+class PropertyPhysicalWizard(models.Model):
+ _name = 'property.physical.wizard'
+
+ excel_file = fields.Binary(string="上传Excel表")
+ excel_name = fields.Char(string="文件名")
+
+ def confirm(self):
+ """
+ 导入excel文件,按行读取数据并处理
+ """
+ if not self.excel_file:
+ raise ValidationError('请上传文件。')
+ book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file))
+ sh = book.sheet_by_index(0)
+ for rx in range(1, sh.nrows):
+ row = sh.row(rx)
+ self.yuthon_physical_update(row)
+
+ def yuthon_physical_update(self, row):
+ pass
\ No newline at end of file
diff --git a/yuthon_property_approval/wizard/property_physical_wizard_views.xml b/yuthon_property_approval/wizard/property_physical_wizard_views.xml
new file mode 100644
index 000000000..7cf213c32
--- /dev/null
+++ b/yuthon_property_approval/wizard/property_physical_wizard_views.xml
@@ -0,0 +1,35 @@
+
+
+
+ 体检费模板
+ self
+ ...
+
+
+
+ 体检费导入弹窗
+ property.physical.wizard
+
+
+
+
+
\ No newline at end of file
From ed63c431f4e67ad40d20e224e7ab8198e78d8d3c Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Wed, 19 Feb 2025 15:30:44 +0800
Subject: [PATCH 2/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
yuthon_holiday/models/inherit_hr_leave.py | 8 +-
.../data/attendance_time_data.xml | 39 +++++++
yuthon_hr_attendance/models/hr_attendance.py | 36 +++++++
yuthon_issue/views/menus.xml | 100 +++++++++---------
.../models/property_reimbursement_form.py | 10 +-
.../property_reimbursement_form_views.xml | 5 +
.../wizard/property_physical_wizard.py | 16 ++-
7 files changed, 159 insertions(+), 55 deletions(-)
diff --git a/yuthon_holiday/models/inherit_hr_leave.py b/yuthon_holiday/models/inherit_hr_leave.py
index 01a14f740..87c4c723b 100644
--- a/yuthon_holiday/models/inherit_hr_leave.py
+++ b/yuthon_holiday/models/inherit_hr_leave.py
@@ -58,7 +58,7 @@ class HrLeave(models.Model):
column2='attachment_id'
)
request_hour_from = fields.Selection([
- ('0', '12:00 上午'), ('0.5', '12:30 上午'),
+ ('0', '00:00 上午'), ('0.5', '00:30 上午'),
('1', '1:00 上午'), ('1.5', '1:30 上午'),
('2', '2:00 上午'), ('2.5', '2:30 上午'),
('3', '3:00 上午'), ('3.5', '3:30 上午'),
@@ -83,7 +83,7 @@ class HrLeave(models.Model):
('22', '10:00 下午'), ('22.5', '10:30 下午'),
('23', '11:00 下午'), ('23.5', '11:30 下午')], string='开始时间')
request_hour_to = fields.Selection([
- ('0', '12:00 上午'), ('0.5', '12:30 上午'),
+ ('0', '00:00 上午'), ('0.5', '00:30 上午'),
('1', '1:00 上午'), ('1.5', '1:30 上午'),
('2', '2:00 上午'), ('2.5', '2:30 上午'),
('3', '3:00 上午'), ('3.5', '3:30 上午'),
@@ -156,10 +156,10 @@ class HolidaysRequestBatch(models.Model):
self.leave_ids.action_validate()
self.hour_leave_ids.action_validate()
- @api.onchange('leave_ids', 'hour_leave_ids')
+ @api.onchange('is_day', 'is_hour')
def _onchange_name(self):
employee_name = self.users_id.name
- if self.leave_ids or self.hour_leave_ids:
+ if self.is_day or self.is_hour:
leave_types = []
for leave in self.leave_ids:
if leave.number_of_days_display:
diff --git a/yuthon_hr_attendance/data/attendance_time_data.xml b/yuthon_hr_attendance/data/attendance_time_data.xml
index 56dec9a51..af0079a0e 100644
--- a/yuthon_hr_attendance/data/attendance_time_data.xml
+++ b/yuthon_hr_attendance/data/attendance_time_data.xml
@@ -200,6 +200,45 @@
-1
+
+ 定时任务:客服上班提醒
+
+ code
+ model.card_customer_service_shift_remind_on()
+
+
+ 1
+ days
+
+ -1
+
+
+
+ 定时任务:客服下班提醒
+
+ code
+ model.card_customer_service_shift_remind_out()
+
+
+ 1
+ days
+
+ -1
+
+
+
+ 定时任务:客服值班提醒
+
+ code
+ model.card_customer_service_stand_remind()
+
+
+ 1
+ days
+
+ -1
+
+
diff --git a/yuthon_hr_attendance/models/hr_attendance.py b/yuthon_hr_attendance/models/hr_attendance.py
index d8432bc53..0d12406db 100644
--- a/yuthon_hr_attendance/models/hr_attendance.py
+++ b/yuthon_hr_attendance/models/hr_attendance.py
@@ -469,6 +469,42 @@ class HrAttendance(models.Model):
'department': user.department_id.name, })
self.card_out_comment(user.resource_id.employee_id, user.template_id.planning_name)
+ # 客服上班消息提醒
+ def card_customer_service_shift_remind_on(self):
+ ba_up_users = self.env['planning.slot'].search([('role_id.name', '=', '客服中心'), ('template_id.planning_name', '=', '白班')])
+ for user in ba_up_users:
+ if user.start_datetime.date() == fields.date.today():
+ self.env['card.remind.form'].create({
+ 'name': user.resource_id.employee_id.name,
+ 'start_time': datetime.now(),
+ 'shift': user.template_id.planning_name,
+ 'department': user.department_id.name, })
+ self.card_in_comment(user.resource_id.employee_id, user.template_id.planning_name)
+
+ # 客服下班消息提醒
+ def card_customer_service_shift_remind_out(self):
+ ba_up_users = self.env['planning.slot'].search([('role_id.name', '=', '客服中心'), ('template_id.planning_name', '=', '白班')])
+ for user in ba_up_users:
+ if user.start_datetime.date() == fields.date.today():
+ self.env['card.remind.form'].create({
+ 'name': user.resource_id.employee_id.name,
+ 'start_time': datetime.now(),
+ 'shift': user.template_id.planning_name,
+ 'department': user.department_id.name, })
+ self.card_out_comment(user.resource_id.employee_id, user.template_id.planning_name)
+
+ # 客服值班消息提醒
+ def card_customer_service_stand_remind(self):
+ ba_up_users = self.env['planning.slot'].search([('role_id.name', '=', '客服中心'), ('template_id.planning_name', '=', '值班')])
+ for user in ba_up_users:
+ if user.start_datetime.date() == fields.date.today():
+ self.env['card.remind.form'].create({
+ 'name': user.resource_id.employee_id.name,
+ 'start_time': datetime.now(),
+ 'shift': user.template_id.planning_name,
+ 'department': user.department_id.name, })
+ self.card_duty_remind(user.resource_id.employee_id)
+
def card_in_comment(self, employee_id, planning_name):
data = f"您的班次是{planning_name},还有10分钟上班,记得打卡"
self.sudo().env["wecom.apps"].sync_send_message(category='att', user_id=employee_id.wecom_userid, message=data)
diff --git a/yuthon_issue/views/menus.xml b/yuthon_issue/views/menus.xml
index d01acb392..af4e28544 100644
--- a/yuthon_issue/views/menus.xml
+++ b/yuthon_issue/views/menus.xml
@@ -138,6 +138,38 @@
action="issue_library_action_cancel5"
sequence="9"/>
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-