from odoo import models, fields, api from datetime import datetime import logging _logger = logging.getLogger(__name__) class JikimoDataCleanWizard(models.TransientModel): _name = 'jikimo.data.clean.wizard' _description = '业务数据清理' date = fields.Date(string='截止日期', required=True, default=fields.Date.context_today) model_ids = fields.Many2many('ir.model', string='业务模型', domain=[ ('model', 'in', [ 'sale.order', # 销售订单 'purchase.order', # 采购订单 'mrp.production', # 生产订单 'stock.picking', # 库存调拨 'account.move', # 会计凭证 ]) ]) def action_clean_data(self): self.ensure_one() model_list = self.model_ids.mapped('model') # 销售订单清理(排除已交付,已锁定,已取消) if 'sale.order' in model_list: self.model_cancel('sale.order', except_states=['delivered', 'done', 'cancel']) # 采购订单清理(排除采购订单,已锁定,已取消) if 'purchase.order' in model_list: self.model_cancel('purchase.order', except_states=['purchase', 'done', 'cancel']) # 生产订单清理(排除返工,报废,完成,已取消) if 'mrp.production' in model_list: self.model_cancel('mrp.production', except_states=['rework', 'scrap', 'done', 'cancel']) # 工单清理 (排除返工,完成,已取消) if 'mrp.workorder' in model_list: self.model_cancel('mrp.production', except_states=['rework', 'done', 'cancel']) # 排程单清理 (排除已完成,已取消) if 'mrp.workorder' in model_list: self.model_cancel('mrp.production', except_states=['finished', 'cancel']) # 工单库存移动 (排除完成,已取消) if 'stock.move' in model_list: self.model_cancel('stock.move') # 库存调拨清理 (排除完成,已取消) if 'stock.picking' in model_list: self.model_cancel('stock.picking') # 会计凭证清理 (排除已过账,已取消) if 'account.move' in model_list: self.model_cancel('account.move', except_states=['posted', 'cancel']) return True def model_cancel(self, model_name, state_field='state', to_state='cancel',except_states=('done', 'cancel')): table = self.env[model_name]._table if isinstance(except_states, list): except_states = tuple(except_states) sql = """ UPDATE %s SET %s = '%s' WHERE create_date < '%s' AND state NOT IN %s """ % (table, state_field, to_state, self.date.strftime('%Y-%m-%d'), except_states) self.env.cr.execute(sql) self.env.cr.commit() @api.model def get_confirm_message(self): date_str = self.date.strftime('%Y-%m-%d') if self.date else '' model_names = ', '.join([model.name for model in self.model_ids]) return { 'date': date_str, 'model_names': model_names } def action_clean_data_confirm(self): model_names = self.model_ids.mapped('display_name') return { 'type': 'ir.actions.client', 'tag': 'action_clean_data_confirm', 'params': { 'model_names': model_names, 'date': self.date, 'active_id': self.id, 'context': self.env.context } }