+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -153,6 +172,9 @@
+
+
+
diff --git a/soong_workflow/wizard/soong_bounced_wizard.py b/soong_workflow/wizard/soong_bounced_wizard.py
index 9c1267d09..7c1bec996 100644
--- a/soong_workflow/wizard/soong_bounced_wizard.py
+++ b/soong_workflow/wizard/soong_bounced_wizard.py
@@ -24,15 +24,13 @@ class SoongBouncedWizard(models.Model):
if invalid_logs:
raise UserError('当前状态不可以收回')
- related_record = self.env[self.res_model].browse(self.res_id)
prev_log = None
- if hasattr(related_record, 'self_users_ids'):
- total_log_count = len(log_ids)
- deleted_log_count = len(log_to_delete)
- prev_log_index = (total_log_count - deleted_log_count) - 1
- if prev_log_index < 0 or prev_log_index >= len(log_ids):
- raise UserError('无有效的上一级审批明细行,无法执行收回操作')
- prev_log = log_ids[prev_log_index]
+ total_log_count = len(log_ids)
+ deleted_log_count = len(log_to_delete)
+ prev_log_index = (total_log_count - deleted_log_count) - 1
+ if prev_log_index < 0 or prev_log_index >= len(log_ids):
+ raise UserError('无有效的上一级审批明细行,无法执行收回操作')
+ prev_log = log_ids[prev_log_index]
related_record = self.env[self.res_model].browse(self.res_id)
if hasattr(related_record, 'self_users_ids'):
diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py
index e3b25bd65..a2faccf4c 100644
--- a/soong_workflow/wizard/soong_workflow_comment_wizard.py
+++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py
@@ -440,7 +440,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
fields.Datetime.now() + timedelta(
hours=8)),
url=url, btntxt="查看详情")
- next_node_employee_log.msg_id = result_data[1]['msgid']
+ # next_node_employee_log.msg_id = result_data[1]['msgid']
else: # 串审模式 (沿用原有逻辑)
# 查找下一个节点
@@ -719,7 +719,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
# recall_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/recall?access_token={access_token}'
record = self.env[self.res_model].search([('id', '=', self.res_id)])
log_ids = record.log_ids.sorted('sequence')
- if self.env.user.name != ['Administrator', '叶华锋']:
+ if self.env.user.name not in ['Administrator', '叶华锋']:
if log_ids[-1].approval_state in ['1', '2']:
raise UserError('当前状态不可以收回')
related_record = self.env[self.res_model].browse(self.res_id)
@@ -736,7 +736,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
record.write({'state': 'draft', 'work_end': False})
else:
record.write({'state': log_ids[-2].name, 'work_end': False})
- return self.node_btn_id.with_context(cx).run()
+ return self.node_btn_id.with_context(cx).run()
def update_self_users_ids(self):
diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
index 883a75ee0..d7eec3b17 100644
--- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py
+++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
@@ -1,7 +1,6 @@
from datetime import datetime, timedelta, time
from email.policy import default
from operator import index
-
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
import calendar
@@ -724,6 +723,7 @@ class YuthonVacationReports(models.Model):
record.statutory_leave = legal_total/8
record.cop_leave = total_add2 / 8
+
@api.depends('meal_fee_ids.update_lines', 'meal_fee_ids.update_type', 'meal_fee_ids.is_void')
def _compute_meal_fee(self):
for record in self:
@@ -962,6 +962,35 @@ class VacationOverline(models.Model):
vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id'])
if vacation_main.vacation_state == 'confirmed':
vals['is_confirm'] = True
+
+ if vals.get('update_type') == 'reduce' and vals.get('vacation_id'):
+ vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id'])
+ deduct_workday = vals.get('workday', 0.0)
+ deduct_public = vals.get('public_holidays', 0.0)
+ if vacation_main:
+ vacation_deduct_vals = {
+ 'year_workday': vacation_main.year_workday - deduct_workday/8,
+ 'year_holiday': vacation_main.year_holiday - deduct_public/8,
+ }
+ vacation_main.write(vacation_deduct_vals)
+
+ if vacation_main.vacation_date:
+ current_vacation_date = vacation_main.vacation_date
+ next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
+ # 必须是跨年才写入上年工作日
+ is_cross_year = current_vacation_date.year != next_month_first_day.year
+ next_month_vacation = self.env['yuthon.vacation.reports'].search([
+ ('employee_id', '=', vacation_main.employee_id.id),
+ ('vacation_date', '=', next_month_first_day),
+ ('vacation_state', 'in', ['not_sent', 'pending']),
+ ], limit=1)
+ if is_cross_year:
+ next_month_deduct_vals = {
+ 'last_workday': next_month_vacation.last_workday - deduct_workday/8,
+ 'last_holiday': next_month_vacation.last_holiday - deduct_public/8,
+ }
+ next_month_vacation.write(next_month_deduct_vals)
+
return super(VacationOverline, self).create(vals)
# def unlink(self):
diff --git a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
index 5fb48122e..aab82d4f2 100644
--- a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
+++ b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
@@ -72,6 +72,9 @@
+
+
+
diff --git a/yuthon_issue/models/inherit_room_booking.py b/yuthon_issue/models/inherit_room_booking.py
index a53606139..e8ff7dbb1 100644
--- a/yuthon_issue/models/inherit_room_booking.py
+++ b/yuthon_issue/models/inherit_room_booking.py
@@ -11,16 +11,17 @@ class RoomBooking(models.Model):
number_of_meetings = fields.Integer(string='会议次数')
minutes_id = fields.Many2one('issue.meeting.minutes', string='会议纪要流程')
- @api.constrains('start_datetime')
- def _check_start_datetime(self):
+ def end_approval(self):
+ self.write({'work_end': True})
for meet in self.issue_meeting_line_ids:
if meet.issue_library_id:
- if meet.issue_library_id.is_party == True:
- meet.issue_library_id.party_date = self.start_datetime + timedelta(hours=8)
- if meet.issue_library_id.is_class == True:
- meet.issue_library_id.class_date = self.start_datetime + timedelta(hours=8)
- if meet.issue_library_id.is_boss == True:
- meet.issue_library_id.boss_date = self.start_datetime + timedelta(hours=8)
+ meeting_type_name = str(self.meeting_type_id.name).strip()
+ if '党' in meeting_type_name:
+ meet.issue_library_id.party_char = str(self.start_datetime.date()) + self.meeting_type_id.name
+ if '班子' in meeting_type_name:
+ meet.issue_library_id.class_char = str(self.start_datetime.date()) + f'第{self.number_of_meetings}' + self.meeting_type_id.name
+ if '董事' in meeting_type_name:
+ meet.issue_library_id.boss_char = str(self.start_datetime.date()) + self.meeting_type_id.name
def bottom_meeting_approval(self):
@@ -51,17 +52,27 @@ class RoomBooking(models.Model):
@api.model_create_multi
def create(self, vals_list):
+ # 步骤1:先调用父类create方法,批量创建主记录,获取有效记录集
res = super().create(vals_list)
- for vals in vals_list:
- if vals['issue_meeting_line_ids']:
- for line in vals['issue_meeting_line_ids']:
- self.env['issue.library.room.line'].create({
- 'issue_library_id': line[2]['issue_library_id'],
- 'room_booking_id': res.id,
- 'room_id': vals['room_id'],
- 'meeting_type_id': vals['meeting_type_id'],
- 'approval_date': vals['start_datetime'],
- })
+ if not res:
+ return res
+ for idx, (main_record, vals) in enumerate(zip(res, vals_list)):
+ issue_meeting_lines = vals.get('issue_meeting_line_ids', [])
+ for line_triple in issue_meeting_lines:
+ line_state, line_id, line_vals = line_triple
+ issue_library_id = line_vals.get('issue_library_id')
+ room_id = vals.get('room_id')
+ meeting_type_id = vals.get('meeting_type_id')
+ approval_date = vals.get('start_datetime')
+ if not (issue_library_id and main_record.id and room_id and meeting_type_id):
+ continue
+ self.env['issue.library.room.line'].create({
+ 'issue_library_id': issue_library_id,
+ 'room_booking_id': main_record.id,
+ 'room_id': room_id,
+ 'meeting_type_id': meeting_type_id,
+ 'approval_date': approval_date,
+ })
return res
@@ -77,5 +88,31 @@ class IssueMeetingLine(models.Model):
employee_id = fields.Many2one('hr.employee', string='传达人')
attendees = fields.Char(string='列席人员')
is_sanda = fields.Boolean(string="三重一大")
- decision_results = fields.Selection([('agree', '通过'), ('disagree', '未通过')], string="决策结果")
+ decision_results = fields.Selection([('agree', '通过'), ('disagree', '重新上会'), ('rejected', '驳回')], string="决策结果")
decision_details = fields.Text(string="决策详情")
+
+ @api.onchange('decision_results', 'meeting_booking_id')
+ def _onchange_decision_results(self):
+ if not self.meeting_booking_id.meeting_type_id:
+ return
+ meeting_type_name = str(self.meeting_booking_id.meeting_type_id.name).strip()
+ if self.decision_results == 'agree':
+ is_agree = 'pass'
+ agree_name = '通过'
+ else:
+ is_agree = 'reject'
+ agree_name = '未通过'
+ if '党' in meeting_type_name:
+ self.issue_library_id.is_party_passed = is_agree
+ original_party_char = self.issue_library_id.party_char or ""
+ self.issue_library_id.party_char = original_party_char + (agree_name)
+
+ if '班子' in meeting_type_name:
+ self.issue_library_id.is_class_passed = is_agree
+ original_class_char = self.issue_library_id.class_char or ""
+ self.issue_library_id.class_char = original_class_char + (agree_name)
+
+ if '董事' in meeting_type_name:
+ self.issue_library_id.is_boss_passed = is_agree
+ original_boss_char = self.issue_library_id.boss_char or ""
+ self.issue_library_id.boss_char = original_boss_char + (agree_name)
diff --git a/yuthon_issue/models/issue_approval.py b/yuthon_issue/models/issue_approval.py
index a6b77cda0..0b75b344c 100644
--- a/yuthon_issue/models/issue_approval.py
+++ b/yuthon_issue/models/issue_approval.py
@@ -59,6 +59,12 @@ class IssueApproval(models.Model):
else:
rec.issue_display = ""
+ def end_approval(self):
+ for rec in self:
+ if rec.issue_approval_ids:
+ for issue_library in rec.issue_approval_ids:
+ issue_library.issue_library_id.write({'issue_state': 'will'})
+
class IssueApprovalLine(models.Model):
_name = 'issue.approval.line'
_description = '关联议题明细'
@@ -81,3 +87,6 @@ class IssueApprovalLine(models.Model):
'view_mode': 'form',
'target': 'current',
}
+
+class IssueRoomApproval(models.Model):
+ _name = 'issue.room.approval'
diff --git a/yuthon_issue/models/issue_library.py b/yuthon_issue/models/issue_library.py
index d7801718e..f7f8e8a1f 100644
--- a/yuthon_issue/models/issue_library.py
+++ b/yuthon_issue/models/issue_library.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, tools
from odoo.exceptions import UserError, ValidationError
+from datetime import datetime, timedelta, date
class IssueLibrary(models.Model):
@@ -23,11 +24,11 @@ class IssueLibrary(models.Model):
('will', '待上会'), ('on_meet', '已上会'), ('cancel', '已取消')],
default='draft', string="议题状态")
is_party = fields.Boolean(string="党总支", store=True)
- party_date = fields.Datetime(string=' ')
+ party_char = fields.Char(string=' ')
is_class = fields.Boolean(string="班子会", store=True)
- class_date = fields.Datetime(string=' ')
+ class_char = fields.Char(string=' ')
is_boss = fields.Boolean(string="董事会", store=True)
- boss_date = fields.Datetime(string=' ')
+ boss_char = fields.Char(string=' ')
is_note = fields.Boolean(string="上级单位", compute='_compute_issue_library_line_ids', store=True)
is_district_state = fields.Boolean(string="区国资局", compute='_compute_issue_library_line_ids', store=True)
is_district_government = fields.Boolean(string="区政府", compute='_compute_issue_library_line_ids', store=True)
@@ -64,7 +65,9 @@ class IssueLibrary(models.Model):
member_of_department = fields.Boolean("是否是本部门数据", compute='_compute_part_of_department',
search='_search_part_of_department')
- is_passed = fields.Selection([('',''), ('pass', '通过'), ('reject', '未通过')])
+ is_party_passed = fields.Selection([('',''), ('pass', '通过'), ('reject', '未通过')])
+ is_class_passed = fields.Selection([('',''), ('pass', '通过'), ('reject', '未通过')])
+ is_boss_passed = fields.Selection([('',''), ('pass', '通过'), ('reject', '未通过')])
is_push_party = fields.Boolean(string="党推送")
is_push_class = fields.Boolean(string="班子推送")
is_push_boss = fields.Boolean(string="董事推送")
@@ -95,21 +98,21 @@ class IssueLibrary(models.Model):
def library_push(self):
for rec in self:
- if rec.is_passed != 'pass':
- raise UserError("当前状态不允许推送")
-
push_update_vals = {}
- if rec.is_party and rec.is_passed:
+ if rec.is_party and rec.is_party_passed == 'reject' or not rec.is_party_passed:
push_update_vals['is_push_party'] = True
- if rec.is_class and rec.is_passed:
+ elif rec.is_class and rec.is_class_passed == 'reject' or not rec.is_class_passed:
push_update_vals['is_push_class'] = True
- if rec.is_boss and rec.is_passed:
+ elif rec.is_boss and rec.is_boss_passed == 'reject' or not rec.is_boss_passed:
push_update_vals['is_push_boss'] = True
if push_update_vals:
rec.write(push_update_vals)
+ rec.write({
+ 'issue_state': 'will'
+ })
@api.onchange('is_legal_trial')
def _onchange_is_legal_trial(self):
@@ -294,8 +297,6 @@ class IssueLibrary(models.Model):
# for record in issue_active_ids:
# if record.state != 'will':
# raise UserError("当前状态不允许上会")
- for meet in self:
- meet.write({"issue_state": "on_meet"})
issue_details = []
for issue in issue_active_ids:
issue_details.append((0, 0, {
@@ -309,6 +310,7 @@ class IssueLibrary(models.Model):
"views": [[form_id, "form"]],
"context": {
'default_is_issue': True,
+ 'default_start_datetime': fields.Datetime.now() + timedelta(hours=8),
'default_issue_meeting_line_ids': issue_details,
}
}
@@ -317,7 +319,6 @@ class IssueLibrary(models.Model):
issue = self.env["issue.library"].browse(self.id)
if issue.issue_state != 'will':
raise UserError("当前状态不允许上会")
- self.write({"issue_state": "on_meet"})
issue_details = [(0, 0, {
'issue_library_id': issue.id,
})]
diff --git a/yuthon_issue/views/inherit_room_booking.xml b/yuthon_issue/views/inherit_room_booking.xml
index cb9d4684d..ff2bcfe4a 100644
--- a/yuthon_issue/views/inherit_room_booking.xml
+++ b/yuthon_issue/views/inherit_room_booking.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/yuthon_issue/views/issue_library_views.xml b/yuthon_issue/views/issue_library_views.xml
index a8d4a572a..05ed4664b 100644
--- a/yuthon_issue/views/issue_library_views.xml
+++ b/yuthon_issue/views/issue_library_views.xml
@@ -12,11 +12,11 @@
-
+
-
+
-
+
@@ -45,18 +45,18 @@
decoration-info="issue_state == 'will'"
decoration-success="issue_state == 'done'"
decoration-muted="issue_state == 'cancel'">
-
+
+
+
-
+
-
+
-
+
@@ -67,7 +67,7 @@
-
+
@@ -206,6 +206,7 @@
issue.library
+
@@ -219,6 +220,10 @@
+
@@ -251,7 +256,7 @@
-
+
@@ -407,7 +412,7 @@
-
+
@@ -551,7 +556,7 @@
-
+
diff --git a/yuthon_issue/views/menus.xml b/yuthon_issue/views/menus.xml
index 0a4fa0f1d..0b507d3cf 100644
--- a/yuthon_issue/views/menus.xml
+++ b/yuthon_issue/views/menus.xml
@@ -22,7 +22,7 @@
sequence="5"/>