添加功能

This commit is contained in:
李鹏宇
2026-03-26 12:03:53 +08:00
parent 2ad6dac317
commit 5c4e48b82a
3 changed files with 100 additions and 119 deletions
+95 -79
View File
@@ -576,24 +576,20 @@ class IssueLibrary(models.Model):
self.write({"issue_state": "cancel"})
def all_meeting_issue(self):
issue_active_ids = self.env["issue.library"].browse(self._context.get('active_ids', self._context.get('active_id', [])))
issue_active_ids = self.env["issue.library"].browse(
self._context.get('active_ids', self._context.get('active_id', [])))
current_user = self.env.user
user_company_name = current_user.company_id.name if current_user.company_id else ""
action_id = self._context.get('from_action')
for ras in issue_active_ids:
# if action_id == 'issue_library_action3' and ras.issue_state_party != 'will':
# raise UserError(f"议题为{ras.name}不可上会",)
# elif action_id == 'issue_library_action4' and ras.issue_state_class != 'will':
# raise UserError(f"议题为{ras.name}不可上会",)
# elif action_id == 'issue_library_action5' and ras.issue_state_boss != 'will':
# raise UserError(f"议题为{ras.name}不可上会",)
issue_details = []
target_meeting_type_id = False
meeting_priority = [
('is_party', 'is_party_passed', None), # 党总支:动态匹配名称(集团本部=党总支/其他=党支委)
('is_class', 'is_class_passed', '班子'), # 班子会:匹配含「班子」的名称
('is_boss', 'is_boss_passed', '董事'), # 董事会:匹配含「董事」的名称
('is_party', 'is_party_passed', None),
('is_class', 'is_class_passed', '班子'),
('is_boss', 'is_boss_passed', '董事'),
]
def get_all_sub_departments(department):
dept_ids = [department.id]
sub_depts = self.env['hr.department'].search([('parent_id', '=', department.id)])
@@ -606,6 +602,58 @@ class IssueLibrary(models.Model):
('department_id', 'in', all_dept_ids),
('active', '=', True)
])
# 先匹配出最终会议类型(原有逻辑)
for issue in issue_active_ids:
if target_meeting_type_id:
continue
# 按「党→班子→董事」优先级匹配
for idx, (field_flag, field_passed, keyword) in enumerate(meeting_priority):
if not getattr(issue, field_flag, False):
continue
passed_result = getattr(issue, field_passed, '')
if passed_result in (False, 'reject'):
if idx == 0:
party_meeting_name = "党总支" if user_company_name == "集团本部" else "党支委"
meeting_type = self.env['room.meeting.type'].search([('name', 'ilike', party_meeting_name)],
limit=1)
else:
meeting_type = self.env['room.meeting.type'].search([('name', 'ilike', keyword)], limit=1)
if meeting_type:
target_meeting_type_id = meeting_type.id
break
elif passed_result == 'pass':
continue
# 天河粮储 套会逻辑
if len(issue_active_ids) == 2 and all(ras.company_id.name == "天河粮储" for ras in issue_active_ids):
record_a, record_b = issue_active_ids
condition = ((getattr(record_a, 'is_party', False) and not getattr(record_b, 'is_party',
False) and getattr(record_b,
'is_class',
False))
or (getattr(record_b, 'is_party', False) and not getattr(record_a, 'is_party',
False) and getattr(record_a,
'is_class',
False)))
all_char_empty = (
not getattr(record_a, 'party_char', '') and not getattr(record_a, 'class_char', '')
and not getattr(record_b, 'party_char', '') and not getattr(record_b, 'class_char', ''))
if condition and all_char_empty:
meeting_type_with_tao = self.env['room.meeting.type'].search([('name', 'ilike', '套')], limit=1)
if meeting_type_with_tao:
target_meeting_type_id = meeting_type_with_tao.id
# ====================== 核心新增:判断会议名称是否含「党」 ======================
meeting_type_has_dang = False
if target_meeting_type_id:
meeting_type = self.env['room.meeting.type'].browse(target_meeting_type_id)
# 判断会议类型名称是否包含 "党" 字
if meeting_type.name and '党' in meeting_type.name:
meeting_type_has_dang = True
# 生成议题明细,根据是否含党字设置 is_sanda
for issue in issue_active_ids:
dept_manager = self.env['hr.employee'].search([
('active', '=', True),
@@ -614,73 +662,29 @@ class IssueLibrary(models.Model):
('department_id', '=', issue.department_id.id),
('department_ids', 'in', [issue.department_id.id])
], limit=1)
# 关键:会议名称含党 → is_sanda=True,否则 False
issue_details.append((0, 0, {
'issue_library_id': issue.id,
'employee_id': dept_manager.id if dept_manager else False,
'designated_person_ids': [(6, 0, target_employees.ids)],
'is_sanda': meeting_type_has_dang, # 自动赋值
}))
if target_meeting_type_id:
continue
# 按「党→班子→董事」优先级匹配
for idx, (field_flag, field_passed, keyword) in enumerate(meeting_priority):
# 跳过未勾选的会议类型
if not getattr(issue, field_flag, False):
continue
passed_result = getattr(issue, field_passed, '')
# 逻辑:空/未通过 → 匹配对应会议类型;已通过 → 继续匹配下一级
if passed_result in (False, 'reject'):
if idx == 0:
if user_company_name == "集团本部":
party_meeting_name = "党总支"
else:
party_meeting_name = "党支委"
meeting_type = self.env['room.meeting.type'].search([
('name', 'ilike', party_meeting_name)
], limit=1)
else:
meeting_type = self.env['room.meeting.type'].search([
('name', 'ilike', keyword)
], limit=1)
if meeting_type:
target_meeting_type_id = meeting_type.id
break
elif passed_result == 'pass':
continue
if len(issue_active_ids) == 2 and all(ras.company_id.name == "天河粮储" for ras in issue_active_ids):
record_a, record_b = issue_active_ids
# 定义核心判断条件:
# 场景1:A党勾 + B党未勾且班子勾 OR 场景2:B党勾 + A党未勾且班子勾
condition = ((getattr(record_a, 'is_party', False) and not getattr(record_b, 'is_party', False) and getattr(record_b, 'is_class', False))
or
(getattr(record_b, 'is_party', False) and not getattr(record_a, 'is_party',False) and getattr(record_a,'is_class', False)))
all_char_empty = (
not getattr(record_a, 'party_char', '') and not getattr(record_a, 'class_char', '')
and
not getattr(record_b, 'party_char', '') and not getattr(record_b, 'class_char', '')
)
if condition and all_char_empty:
meeting_type_with_tao = self.env['room.meeting.type'].search([
('name', 'ilike', '套')# 模糊匹配含「套」的会议类型
], limit=1)
if meeting_type_with_tao:
target_meeting_type_id = meeting_type_with_tao.id
form_id = self.env.ref("room.room_booking_view_form", raise_if_not_found=False)
return {
"type": "ir.actions.act_window",
"name": "批量上会",
"res_model": "room.booking",
"views": [[form_id.id, "form"]],
"context": {
'default_is_issue': True,
'default_state': '申请人',
'default_meeting_type_id': target_meeting_type_id,
'default_start_datetime': fields.Datetime.now() + timedelta(hours=8),
'default_issue_meeting_line_ids': issue_details,
}
}
form_id = self.env.ref("room.room_booking_view_form", raise_if_not_found=False)
return {
"type": "ir.actions.act_window",
"name": "批量上会",
"res_model": "room.booking",
"views": [[form_id.id, "form"]],
"context": {
'default_is_issue': True,
'default_state': '申请人',
'default_meeting_type_id': target_meeting_type_id,
'default_start_datetime': fields.Datetime.now() + timedelta(hours=8),
'default_issue_meeting_line_ids': issue_details,
},
}
def single_meeting_issue(self):
issue = self.env["issue.library"].browse(self.id)
@@ -693,12 +697,14 @@ class IssueLibrary(models.Model):
('is_class', 'is_class_passed', '班子'), # 班子会:匹配含「班子」的名称
('is_boss', 'is_boss_passed', '董事'), # 董事会:匹配含「董事」的名称
]
def get_all_sub_departments(department):
dept_ids = [department.id]
sub_depts = self.env['hr.department'].search([('parent_id', '=', department.id)])
for sub_dept in sub_depts:
dept_ids += get_all_sub_departments(sub_dept)
return dept_ids
all_dept_ids = get_all_sub_departments(self.department_id)
target_employees = self.env['hr.employee'].search([
('department_id', 'in', all_dept_ids),
@@ -722,23 +728,17 @@ class IssueLibrary(models.Model):
attendees_ids = target_managers.filtered(lambda emp: emp.id != manager_employee.id).ids
elif target_managers:
attendees_ids = target_managers.id
# 先匹配会议类型
for issue in self:
issue_details.append((0, 0, {
'issue_library_id': issue.id,
'employee_id': manager_employee.id,
'designated_person_ids': [(6, 0, target_employees.ids)],
'attendees_ids': [(6, 0, attendees_ids)],
}))
if target_meeting_type_id:
continue
# 按「党→班子→董事」优先级匹配
for idx, (field_flag, field_passed, keyword) in enumerate(meeting_priority):
# 跳过未勾选的会议类型
if not getattr(issue, field_flag, False):
continue
passed_result = getattr(issue, field_passed, '')
# 逻辑:空/未通过 → 匹配对应会议类型;已通过 → 继续匹配下一级
if passed_result in (False, 'reject'):
if idx == 0:
if user_company_name == "集团本部":
@@ -757,6 +757,22 @@ class IssueLibrary(models.Model):
break
elif passed_result == 'pass':
continue
meeting_type_has_dang = False
if target_meeting_type_id:
meeting_type = self.env['room.meeting.type'].browse(target_meeting_type_id)
if meeting_type.name and '党' in meeting_type.name:
meeting_type_has_dang = True
for issue in self:
issue_details.append((0, 0, {
'issue_library_id': issue.id,
'employee_id': manager_employee.id if manager_employee else False,
'designated_person_ids': [(6, 0, target_employees.ids)],
'attendees_ids': [(6, 0, attendees_ids)],
'is_sanda': meeting_type_has_dang,
}))
form_id = self.env.ref("room.room_booking_view_form").id
return {
"type": "ir.actions.act_window",
@@ -23,6 +23,7 @@
<field name="issue_meeting_line_ids">
<tree editable="bottom">
<button name="open_record" type="object" string="详情" class="oe_highlight"/>
<field name="sequence" widget="handle"/>
<field name="meeting_booking_id" column_invisible="1"/>
<field name="issue_library_id"/>
<field name="employee_id" options="{'no_create': True}" domain="[('id', 'in', designated_person_ids)]"/>
@@ -13,7 +13,7 @@ class PropertyStatementsWizard(models.Model):
_name = 'property.statements.wizard'
_description = '银行流水向导弹窗'
selection_bank = fields.Selection([('js', '建设银行'), ('gs', '工商银行'), ('sh', '农商'), ('ms', '民生'), ('zc', '广州银行(中城)'), ('dj', '农商行(东进)'), ('xy', '工商银行(兴源)')], string="选择银行")
selection_bank = fields.Selection([('js', '建设银行'), ('gs', '工商银行'), ('sh', '农商'), ('ms', '民生'), ('zc', '广州银行(中城)'), ('dj', '农商行(东进)')], string="选择银行")
excel_file = fields.Binary(string="上传Excel表")
excel_name = fields.Char(string="文件名")
@@ -62,8 +62,6 @@ class PropertyStatementsWizard(models.Model):
self.property_bank_statements_ms_data(row)
elif self.selection_bank == 'gs':
self.property_bank_statements_gc_data(row)
elif self.selection_bank == 'xy':
self.property_bank_statements_xy_data(row)
count_after = self.env['property.bank.statements'].search_count([])
_logger.info('[银行流水导入] 银行=%s 导入前总条数=%d 导入后总条数=%d 新增=%d', self.selection_bank, count_before, count_after, count_after - count_before)
@@ -360,7 +358,7 @@ class PropertyStatementsWizard(models.Model):
existing_record.write(bank_data)
def property_bank_statements_xy_data(self, row):
def property_bank_statements_gc_data(self, row):
"""工商银行(兴源)解析:数据从第2行开始,列结构(共34列):
0:交易时间, 1:对方单位, 2:摘要, 4:转入金额(贷时取), 7:借贷标志,
8:发生额(借时取), 9:对方账号, 16:本方账号, 22:对方行名, 31:顺序号
@@ -431,41 +429,6 @@ class PropertyStatementsWizard(models.Model):
else:
existing_record.write(bank_data)
def property_bank_statements_gc_data(self, row):
"""工商银行(原始格式)解析"""
if row[0].value:
start_time = datetime.strptime(row[0].value, '%Y-%m-%d %H:%M:%S')
else:
start_time = None
name = row[4].value
name_account = row[1].value
remake = row[2].value
original_amount = row[3].value
your_own_account = row[6].value
cleaned_amount = str(original_amount).replace(',', '')
float_amount = float(cleaned_amount)
your_own_unit = self.classify_by_last_four(your_own_account)
company_id = self._get_company_by_unit(your_own_unit)
if not company_id:
return
sequence_number = row[5].value
bank_data = {
'name': name,
'your_own_unit': your_own_unit,
'original_amount': float_amount,
'company_id': company_id.id,
'sequence_number': sequence_number,
'start_time': start_time - timedelta(hours=8) if start_time else False,
'your_own_account': your_own_account,
'name_account': name_account,
'remake': remake,
}
existing_record = self.env['property.bank.statements'].search(
[('sequence_number', '=', sequence_number)], limit=1
)
if not existing_record:
self.env['property.bank.statements'].create(bank_data)
def _get_company_by_unit(self, unit_name):
"""根据账号单位返回对应公司"""
if unit_name in ['天河投资', '天投城建']:
@@ -478,7 +441,7 @@ class PropertyStatementsWizard(models.Model):
def classify_by_last_four(self, input_str):
if not isinstance(input_str, str) or len(input_str) < 4:
return "天投城建" # 输入不是字符串或长度不足4,默认为天投城建
return "天投城建"
last_four = input_str[-4:] # 获取后四位字符
@@ -489,4 +452,5 @@ class PropertyStatementsWizard(models.Model):
elif last_four == "9661":
return "天河粮储"
else:
last_four == ""
return "天投城建"