# -*- coding: utf-8 -*- from odoo import api, fields, models, tools from odoo.exceptions import ValidationError, UserError class YuthonFileProcessing(models.Model): _name = 'yuthon.file.processing' _description = '文件处理' _inherit = ['mail.thread.main.attachment', 'mail.activity.mixin', 'soong.workflow.mixin'] _rec_name = 'name' name = fields.Char(string="标题") code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('file_code')) official_type_id = fields.Many2one('official.type', string="文件类型") is_cold = fields.Boolean(string="发文编号") reference_cold = fields.Char(string="发文字号") major_event_category = fields.Integer(string="重大事项所属类别") official_partner_id = fields.Many2one('official.partner', string="来文单位") remarks = fields.Char(string="备注事项") main_text = fields.Text(string='文件内容') come_file_id = fields.Char(string="来文编号") incoming_file_id = fields.Char(string="收文编号") main_flats_ids = fields.Many2many( 'main.flats', relation='yuthon_file_processing_main_flats_rel', column1='yuthon_file_processing_id', column2='main_flats_id', string="主送单位" ) copy_flats_ids = fields.Many2many( 'main.flats', relation='yuthon_file_processing_copy_flats_rel', column1='yuthon_file_processing_id', column2='main_flats_copy_id', string="抄送单位" ) department_ids = fields.Many2many('hr.department', string='部门范围') users_role_ids = fields.Many2many('soong.user.role', string='角色范围') servings_number = fields.Integer(string="份数") urgency_level = fields.Selection([('normal', '一般'), ('urgent', '紧急'), ('extra_urgent', '特急')], string="紧急程度", default='normal') secret_level = fields.Selection([('normal', '一般'), ('urgent', '秘密'), ('secret', '机密'), ('so_secret', '绝密')], string="密级") date = fields.Datetime(string="拟稿日期", default=fields.Datetime.now) official_statu = fields.Selection([('done', '办结'), ('approval', '审核')], string="公文环节") users_id = fields.Many2one('res.users', string="拟稿人", default=lambda self: self.env.user) department_id = fields.Many2one(related='users_id.employee_id.department_id', string="拟稿部门") company_id = fields.Many2one(related='users_id.company_id', string="公司") company_id1 = fields.Many2one('res.company', string="公司前缀", default=lambda self: self.env.company) is_meet = fields.Boolean(string="是否上会") issues_result = fields.Html(string="会议结果") related_issues_id = fields.Many2one('issue.library', string="关联议题") is_official_incoming = fields.Boolean(string="是否收文") active = fields.Boolean('Active', default=True, tracking=True) is_chapter = fields.Selection([('yes', '是'), ('no', '否')], string="是否用章") type_stamp_ids = fields.Many2many('seals.type.setting', string='用章类型', domain="['&', ('start_date', '<=', context_today()), '|', ('end_date', '=', False), ('end_date', '>=', context_today())]") scope_chapter_ids = fields.Many2many('seals.scope.setting', string='用章范围') approve_state = fields.Selection([("start", "草稿"), ("pending", "审批中"), ("end", "结束")], string="审批状态", compute='_compute_workflow') soong_state = fields.Selection([('to_do', '待办'), ('done', '已办'), ('to_active', '待归档'), ('active', '已归档')], string="流程状态", compute='_compute_workflow') red_suit = fields.Char(string="套红") official_documents_ids = fields.Many2many('ir.attachment', string="附件") completion_time = fields.Datetime(string="办结时间") is_supervising = fields.Boolean(string="是否督办") deadline = fields.Datetime(string="办理期限") done_date = fields.Date(string="完成时间") workflow_inspector_ids = fields.One2many('soong.workflow.inspector', 'yuthon_official_id', string="督办事项") room_booking_ids = fields.One2many('room.booking', 'yuthon_official_id', string="会议关联") issue_library_ids = fields.One2many('issue.library', 'yuthon_official_id', string="议题关联") work_end = fields.Boolean(string="结束") official_state = fields.Selection([('to_do', '待转'), ('done', '已转')], string="状态") employee_ids1 = fields.Many2many( 'hr.employee', 'yuthon_file_processing_employee1_rel', 'file_id', 'employee_id', string="经办人" ) employee_ids = fields.Many2many( 'hr.employee', 'yuthon_file_processing_employee_rel', 'file_id', 'employee_id', string='人员范围' ) def _get_default_name_title(self): return self._description if self._description else self._name name_title = fields.Char(default=_get_default_name_title) self_users_ids = fields.Many2many( 'res.users', string="当前经办人", relation='yuthon_file_processing_self_users_rel', column1='processing_id', column2='self_user_id', default=lambda self: [(6, 0, [self.env.user.id])] ) users_ids = fields.Many2many('res.users', string="用户", relation='yuthon_file_processing_users_rel', column1='processing_id', column2='compute_user_id', compute='_compute_workflow', store=True ) is_display = fields.Boolean( string="显示", default=False, compute='_compute_is_display', search='_search_part_of_company' ) def compute_workflow(self): processing_ids = self.env["yuthon.file.processing"].browse( self._context.get('active_ids', self._context.get('active_id'))) for processing in processing_ids: processing._compute_workflow() @api.depends_context('uid') @api.depends('users_ids') def _compute_is_display(self): current_user = self.env.user is_system_admin = current_user.has_group('base.group_system') or current_user.has_group('base.group_admin') current_user = self.env.user for record in self: record._compute_workflow() if is_system_admin: record.is_display = True else: record.is_display = current_user in record.users_ids def _search_part_of_company(self, operator, value): current_user = self.env.user is_system_admin = current_user.has_group('base.group_system') or current_user.has_group('base.group_admin') current_user_id = current_user.id if is_system_admin: return [] if value: if operator == "=": return [("users_ids", "in", [current_user_id])] else: return [("users_ids", "not in", [current_user_id])] else: if operator == "=": return [("users_ids", "not in", [current_user_id])] else: return [("users_ids", "in", [current_user_id])] def get_no_read_count(self): domain = [ ('employee_ids1', 'in', self.env.user.employee_id.id), ] return self.search_count(domain) @api.depends('code') def _compute_workflow(self): for record in self: record.users_ids = False record.approve_state = False record.soong_state = False record.employee_ids1 = False workflow = self.env['soong.workflow.record'].sudo().search( [('code', '=', record.code)], limit=1 ) if workflow: record.employee_ids1 = workflow.employee_ids.ids record.users_ids = workflow.users_ids.ids record.approve_state = workflow.approve_state record.soong_state = workflow.soong_state if record.log_ids: record.completion_time = record.log_ids[-1].lase_click_date else: record.completion_time = False @api.onchange('is_cold') def onchange_is_cold(self): if self.is_cold: self.onchange_company_id1() else: self.reference_cold = False @api.onchange('company_id1') def onchange_company_id1(self): current_year = fields.Date.today().year self.reference_cold = False if self.company_id1 and self.company_id1.name: company_name = self.company_id1.name prefix_map = { '集团本部': '穗天投', '天河粮储': '天粮储司', '天河物管': '穗天物' } prefix = prefix_map.get(company_name) if not prefix: return # 构建查询条件:同公司 + 同一年份的文号 year_str = f"〔{current_year}〕" domain = [ ('company_id1', '=', self.company_id1.id), ('reference_cold', 'like', f"{prefix}{year_str}%") ] last_record = self.search(domain, order='reference_cold desc', limit=1) # 计算下一个序号(格式化为3位数字:001、002...) if last_record and last_record.reference_cold: # 从现有文号中提取数字部分(如从"穗天物【2025】003号"提取"003") try: # 截取序号部分(假设格式固定为"前缀【年份】序号号") seq_str = last_record.reference_cold.split(year_str)[1].rsplit('号', 1)[0] last_seq = int(seq_str) next_seq = last_seq + 1 except (IndexError, ValueError): next_seq = 1 else: next_seq = 1 seq_str = f"{next_seq}" self.reference_cold = f"{prefix}{year_str}{seq_str}号" @api.onchange('is_issues') def _onchange_is_issues(self): if self.is_issues: issue_id = self.env['issue.library'].create({'name': self.name, 'is_invisible_workflow': True}) self.related_issues_id = issue_id.id self.env['issue.library.approval.line'].create({ 'issue_library_id': issue_id.id, 'workflow_name': self.name, 'approval_type': self.workflow_id.name, 'res_model': self._name, 'res_id': self.id, 'code': self.code, 'approval_date': fields.Datetime.now(), }) def supervising_button(self): return { "name": "督查督办", "type": "ir.actions.act_window", "view_mode": "form", "res_model": "soong.workflow.inspector", "views": [[self.env.ref('soong_workflow.soong_workflow_inspector_form').id, "form"]], "context": {'default_name': self.name, 'default_start_data': fields.Date.today(), 'default_end_data': self.done_date, 'default_relevancy_type': 'yuthon_official_incoming_normal', 'default_incoming_normal_id': self.id, }, } def action_print_file_processing(self): report_ref = self.env.ref('yuthon_official.action_file_processing_report') return report_ref.report_action(self.id) # def button_meet(self): # return { # "name": "会议", # "type": "ir.actions.act_window", # "view_mode": "form", # "res_model": "room.booking", # "views": [[self.env.ref('room.room_booking_view_form').id, "form"]], # "context": { # 'default_name': self.name, # 'default_relevancy_type': 'yuthon_official_incoming_normal', # 'default_incoming_normal_id': self.id, # }, # }