# -*- coding: utf-8 -*- import json import base64 import logging from datetime import timedelta import requests from odoo.addons.sf_base.commons.common import Common from odoo import api, fields, models, _ from odoo.exceptions import UserError, ValidationError class SfMaintenanceEquipmentCategory(models.Model): _inherit = 'maintenance.equipment.category' _description = '设备类别' equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'), ('检测设备', '检测设备'), ('其他', '其他')], string='类型', default='机床') equipment_type_code = fields.Char('简写') class SfMaintenanceEquipmentAGVLog(models.Model): _name = 'maintenance.equipment.agv.log' _description = 'AGV运行日志' run_type = fields.Char('任务类型') run_code = fields.Char('任务指令代码') run_first = fields.Char('任务起点') production_line = fields.Char('目的生产线') run_last = fields.Char('任务终点') workorder = fields.Char('工件编码/任务单号') time = fields.Datetime('日期/事件') state = fields.Char('事件/状体') equipment_id = fields.Many2one('maintenance.equipment', '设备') class SfMaintenanceEquipment(models.Model): _inherit = 'maintenance.equipment' _description = '设备' crea_url = "/api/machine_tool/create" run_status = fields.Char('机床运行状态', readonly=True) # AGV运行日志 agv_logs = fields.One2many('maintenance.equipment.agv.log', 'equipment_id', string='AGV运行日志') # 1212修改后的字段 number_of_axles = fields.Selection( [("三轴", "三轴"), ("四轴", "四轴"), ("五轴", "五轴"), ("六轴", "六轴")], default="", string="轴数") # 1212新增字段 function_type = fields.Selection( [("ZXJGZX", "钻铣加工中心"), ("CXJGZX", "车削加工中心"), ("FHJGZX", "复合加工中心")], default="", string="功能类型") T_trough_num = fields.Integer('槽数') T_trough_wide = fields.Float('槽宽(mm)') T_trough_distance = fields.Float('槽距(mm)') taper_type_id = fields.Many2one('spindle.taper.type', string='主轴锥孔型号') spindle_center_distance = fields.Float('主轴中心至立柱滑轨面距离(mm)') spindle_continuous_power = fields.Float('主轴持续功率(kw)') spindle_peak_power = fields.Float('主轴峰值功率(kw)') spindle_sustained_torque = fields.Float('主轴持续扭矩(n/m)') spindle_peak_torque = fields.Float('主轴峰值扭矩(n/m)') linear_axis_guides_type = fields.Char('直线轴导轨类型') axis_driven_type = fields.Char('坐标轴驱动类型') X_axis_rapid_traverse_speed = fields.Char('X轴快速进给速度(mm/min)') Y_axis_rapid_traverse_speed = fields.Char('Y轴快速进给速度(mm/min)') Z_axis_rapid_traverse_speed = fields.Char('Z轴快速进给速度(mm/min)') a_axis_rapid_traverse_speed = fields.Char('a轴快速进给速度(mm/min)') b_axis_rapid_traverse_speed = fields.Char('b轴快速进给速度(mm/min)') c_axis_rapid_traverse_speed = fields.Char('c轴快速进给速度(mm/min)') straight_cutting_feed_rate = fields.Char('直线切削进给速度(mm/min)') rotary_cutting_feed_rate = fields.Char('回转切削进给速度(mm/min)') X_precision = fields.Char('X轴定位精度(mm)') X_precision_repeat = fields.Char('X轴重复定位精度(mm)') Y_precision = fields.Char('Y轴定位精度(mm)') Y_precision_repeat = fields.Char('Y轴重复定位精度(mm)') Z_precision = fields.Char('Z轴定位精度(mm)') Z_precision_repeat = fields.Char('Z轴重复定位精度(mm)') a_precision = fields.Char('a轴定位精度(mm)') a_precision_repeat = fields.Char('a轴重复定位精度(mm)') b_precision = fields.Char('b轴定位精度(mm)') b_precision_repeat = fields.Char('b轴重复定位精度(mm)') c_precision = fields.Char('c轴定位精度(mm)') c_precision_repeat = fields.Char('c轴重复定位精度(mm)') tool_full_diameter_max = fields.Float('刀具满刀最大直径(mm)') tool_perimeter_diameter_max = fields.Float('刀具邻空刀最大直径(mm)') T_tool_time = fields.Float('T-T换刀时间(s)', digits=(12, 1)) C_tool_time = fields.Float('C-C换刀时间(s)', digits=(12, 1)) # 待删除字段 precision_min = fields.Float('X轴定位精度min(mm)', digits=(12, 3)) precision_max = fields.Float('X轴定位精度max(mm)', digits=(12, 3)) lead_screw = fields.Char('丝杆') guide_rail = fields.Char('导轨') feed_speed = fields.Char('进给速度(mm/min)') tool_speed = fields.Char('刀具速度(m/min)') torque = fields.Char('主轴点击扭矩(n/m)') motor_power = fields.Char('主轴电机功率(kw)') taper = fields.Char('主轴锥度(°)') tool_diameter_max = fields.Char('刀具刀径max(mm)') tool_diameter_min = fields.Char('刀具刀径min(mm)') # def get_no(self): # partner = self.env['maintenance.equipment'].sudo().search( # [('MTcode', '!=', '')], # limit=1, # order="id desc") # if not partner: # num = "%04d" % 1 # # else: # m = int(partner.MTcode) + 1 # num = "%04d" % m # return num equipment_maintenance_standards_ids = fields.Many2many('equipment.maintenance.standards', 'sf_maintenance_equipment_ids', string='设备维保标准') eq_maintenance_id = fields.Many2one('equipment.maintenance.standards', string='设备保养标准', domain="[('maintenance_type','=','保养')]") initial_action_date = fields.Date(string='重置保养日期') initial_action_date_old = fields.Date(string='重置保养日期(旧)') next_action_date = fields.Date(string='下次预防保养') initial_overhaul_date = fields.Date(string='重置维修日期') initial_overhaul_date_old = fields.Date(string='重置维修日期(旧)') overhaul_date = fields.Date(string='下次预防检修') overhaul_period = fields.Integer(string='预防检修频次') overhaul_duration = fields.Float(string='检修时长') overhaul_id = fields.Many2one('equipment.maintenance.standards', string='设备检修标准', domain="[('maintenance_type','=','检修')]") def confirm_maintenance(self): """ 确认保养/检修 """ context = self.env.context if context['type'] == '保养': if not self.initial_action_date: raise ValidationError('重置保养日期不能为空!!') elif self.initial_action_date < fields.Date.today(): raise ValidationError('重置保养日期不能小于当前日期!!') elif context['type'] == '检修': if not self.initial_overhaul_date: raise ValidationError('重置检修日期不能为空!!') elif self.initial_overhaul_date < fields.Date.today(): raise ValidationError('重置检修日期不能小于当前日期!!') request_ids = self.env['maintenance.request'].search([('stage_id.done', '=', False), ('equipment_id', '=', self.id), ('maintenance_type', '=', 'preventive'), ('sf_maintenance_type', '=', context['type'])]) if not request_ids: return self.create_maintenance_request(context['type']) else: return { "type": "ir.actions.act_window", "res_model": "maintenance.request.wizard", "views": [[False, "form"]], "target": "new", 'context': { 'equipment_id': self.id } } def create_maintenance_request(self, maintenance_request_type): """ 根据条件创建维保计划 """ if maintenance_request_type == '保养': self._create_new_request(self.initial_action_date + timedelta(days=self.period)) self.initial_action_date_old = self.initial_action_date elif maintenance_request_type == '检修': self._create_new_request1(self.initial_overhaul_date + timedelta(days=self.overhaul_period)) self.initial_overhaul_date_old = self.initial_overhaul_date return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': f'创建{maintenance_request_type}计划', 'message': f'新{maintenance_request_type}维保计划创建成功', 'type': 'success', 'next': {'type': 'ir.actions.act_window_close'}, } } @api.onchange('eq_maintenance_id', 'overhaul_id') def _compute_equipment_maintenance_standards_ids(self): for record in self: if record.eq_maintenance_id and record.overhaul_id: record.equipment_maintenance_standards_ids = [ (6, 0, [record.eq_maintenance_id.id, record.overhaul_id.id])] break if record.eq_maintenance_id: record.equipment_maintenance_standards_ids = [(6, 0, [record.eq_maintenance_id.id])] break if record.overhaul_id: record.equipment_maintenance_standards_ids = [(6, 0, [record.overhaul_id.id])] break else: record.equipment_maintenance_standards_ids = False MTcode = fields.Char("机台编码") created_user = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user) equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'), ('检测设备', '检测设备'), ('其他', '其他')], compute='_compute_category_id') @api.depends('category_id') def _compute_category_id(self): for record in self: if record: record.equipment_type = record.category_id.equipment_type code = fields.Char('行业编码') name = fields.Char('机台号', required=False) knife_type = fields.Selection( [("BT40", "BT40"), ("BT30", "BT30"), ("BT50", "BT50")], default="", string="刀把类型") number_of_knife_library = fields.Integer('刀库数量(把)') rotate_speed = fields.Integer('转速') # 加工进程 a_axis = fields.Char('a轴') x_axis = fields.Integer('X轴') y_axis = fields.Integer('Y轴') z_axis = fields.Integer('Z轴') b_axis = fields.Char('B轴') c_axis = fields.Char('C轴') remark = fields.Char('备注') is_binding = fields.Boolean('是否绑定机床', default=False) control_system_id = fields.Many2one('sf.machine.control_system', string="控制系统") # 多个机床型号对应一个机床 brand_id = fields.Many2one('sf.machine.brand', string='品牌', domain="[('tag_ids.name', 'ilike', equipment_type)]") type_id = fields.Many2one('sf.machine_tool.type', '型号') state = fields.Selection( [("正常", "正常"), ("故障停机", "故障停机"), ("计划维保", "计划维保"), ("空闲", "空闲"), ("封存(报废)", "封存(报废)")], default='正常', string="机床状态") run_time = fields.Char('总运行时长') # 0606新增字段 machine_tool_picture = fields.Binary('图片') heightened_way = fields.Selection([ ('sifudianji', '伺服电机驱动'), ('youyagang', '油压缸驱动'), ('chilunjia', '齿轮架驱动') ], string="主轴加高方式", default='sifudianji') workpiece_load = fields.Char('工件最大负载(kg)') workbench_L = fields.Char('工作台长度(mm)') workbench_W = fields.Char('工作台宽度(mm)') workbench_H = fields.Char('工作台高度(mm)') machine_tool_L = fields.Char('机床长度(mm)') machine_tool_W = fields.Char('机床宽度(mm)') machine_tool_H = fields.Char('机床高度(mm)') distance_min = fields.Char('主轴端面至工作台面距离MIN(mm)') distance_max = fields.Char('主轴端面至工作台面距离MAX(mm)') tool_quality_max = fields.Char('刀具最大质量(kg)') tool_long_max = fields.Char('刀具最大长度(mm)') machine_tool_category = fields.Many2one('sf.machine_tool.category', string='机床类型') # 一个机床对应一個加工工厂,一个加工工厂对应多个机床 factory_id = fields.Many2one('res.partner', string='所属工厂', domain="[('is_factory', '=', True)]") # 一个机床对应一个供应商,一个供应商对应多个机床 supplier_id = fields.Many2one('res.partner', string='制造商', domain="[('is_vendor', '=', True)]") registration_date = fields.Date('注册日期') state_zc = fields.Selection([("已注册", "已注册"), ("未注册", "未注册")], string="注册状态", default='未注册', tracking=True) active = fields.Boolean('有效', default=True) # 多个型号对应一个机床 machine_tool_id = fields.Many2one('sf.machine_tool', '机床') sf_maintenance_logs_ids = fields.One2many('sf.maintenance.logs', 'maintenance_equipment_id', '设备故障日志') equipment_oee_ids = fields.One2many('maintenance.equipment.oee', 'equipment_id', '设备OEE') # def name_get(self): # result = [] # for parameter in self: # if parameter.code: # name = parameter.name + '-' + parameter.code # else: # name = parameter.name # result.append((parameter.id, name)) # return result @api.model def create(self, vals): # 在创建设备之前执行一些自定义逻辑 equipment = super(SfMaintenanceEquipment, self).create(vals) if equipment.category_id: equipment.name = "%s%s" % (equipment.MTcode, equipment.category_id.name) if equipment.category_id.equipment_type == '机床': equipment_id = self.env['maintenance.equipment.oee'].search([('equipment_id', '=', equipment.id)]) if not equipment_id: self.env['maintenance.equipment.oee'].sudo().create({ 'equipment_id': equipment.id, 'name': equipment.name, }) # 在创建设备之后执行一些自定义逻辑 # ... return equipment # @api.constrains('rotate_speed') # def _check_rotate_speed(self): # if self.rotate_speed <= 0: # raise UserError("转速不能为0") # # @api.constrains('precision') # def _check_precision(self): # if self.equipment_type == '机床' and self.precision <= 0.00: # raise UserError("加工精度不能为0") # # @api.constrains('number_of_knife_library') # def _check_number_of_knife_library(self): # if self.equipment_type == '机床' and self.number_of_knife_library <= 0: # raise UserError("刀库数量不能为0") # # @api.constrains('x_axis') # def _check_x_axis(self): # if self.equipment_type == '机床' and self.x_axis <= 0: # raise UserError("加工行程里x轴不能为0") # # @api.constrains('y_axis') # def _check_y_axis(self): # if self.equipment_type == '机床' and self.y_axis <= 0: # raise UserError("加工行程里y轴不能为0") # # @api.constrains('z_axis') # def _check_z_axis(self): # if self.equipment_type == '机床' and self.z_axis <= 0: # raise UserError("加工行程里z轴不能为0") # # @api.constrains('b_axis') # def _check_b_axis(self): # if self.equipment_type == '机床' and self.number_of_axles == '四轴': # print(self.number_of_axles) # if self.b_axis <= 0: # raise UserError("加工行程里b轴不能为0") # # @api.constrains('c_axis') # def _check_c_axis(self): # if self.equipment_type == '机床' and self.number_of_axles == '五轴': # if self.c_axis <= 0: # raise UserError("加工行程里c轴不能为0") @api.onchange('type_id') def get_type_info(self): for item in self: item.knife_type = item.type_id.knife_type item.number_of_knife_library = item.type_id.number_of_knife_library item.number_of_axles = item.type_id.number_of_axles item.rotate_speed = item.type_id.rotate_speed item.precision_min = item.type_id.precision_min item.precision_max = item.type_id.precision_max item.control_system_id = item.type_id.control_system_id item.x_axis = item.type_id.x_axis item.y_axis = item.type_id.y_axis item.z_axis = item.type_id.z_axis item.b_axis = item.type_id.b_axis item.c_axis = item.type_id.c_axis item.machine_tool_picture = item.type_id.machine_tool_picture item.heightened_way = item.type_id.heightened_way item.workpiece_load = item.type_id.workpiece_load item.lead_screw = item.type_id.lead_screw item.workbench_L = item.type_id.workbench_L item.workbench_W = item.type_id.workbench_W item.guide_rail = item.type_id.guide_rail item.machine_tool_L = item.type_id.machine_tool_L item.machine_tool_W = item.type_id.machine_tool_W item.machine_tool_H = item.type_id.machine_tool_H item.feed_speed = item.type_id.feed_speed item.tool_speed = item.type_id.tool_speed item.distance_min = item.type_id.distance_min item.distance_max = item.type_id.distance_max item.taper = item.type_id.taper item.torque = item.type_id.torque item.motor_power = item.type_id.motor_power item.tool_quality_max = item.type_id.tool_quality_max item.tool_long_max = item.type_id.tool_long_max item.tool_diameter_max = item.type_id.tool_diameter_max item.tool_diameter_min = item.type_id.tool_diameter_min item.machine_tool_category = item.type_id.machine_tool_category.id item.brand_id = item.type_id.brand_id.id # 新增修改字段 item.taper_type_id = item.type_id.taper_type_id.id item.function_type = item.type_id.function_type item.a_axis = item.type_id.a_axis item.T_trough_num = item.type_id.T_trough_num item.T_trough_wide = item.type_id.T_trough_wide item.T_trough_distance = item.type_id.T_trough_distance item.spindle_center_distance = item.type_id.spindle_center_distance item.spindle_continuous_power = item.type_id.spindle_continuous_power item.spindle_peak_power = item.type_id.spindle_peak_power item.spindle_sustained_torque = item.type_id.spindle_sustained_torque item.spindle_peak_torque = item.type_id.spindle_peak_torque item.linear_axis_guides_type = item.type_id.linear_axis_guides_type item.axis_driven_type = item.type_id.axis_driven_type item.X_axis_rapid_traverse_speed = item.type_id.X_axis_rapid_traverse_speed item.Y_axis_rapid_traverse_speed = item.type_id.Y_axis_rapid_traverse_speed item.Z_axis_rapid_traverse_speed = item.type_id.Z_axis_rapid_traverse_speed item.a_axis_rapid_traverse_speed = item.type_id.a_axis_rapid_traverse_speed item.b_axis_rapid_traverse_speed = item.type_id.b_axis_rapid_traverse_speed item.c_axis_rapid_traverse_speed = item.type_id.c_axis_rapid_traverse_speed item.straight_cutting_feed_rate = item.type_id.straight_cutting_feed_rate item.rotary_cutting_feed_rate = item.type_id.rotary_cutting_feed_rate item.X_precision = item.type_id.X_precision item.X_precision_repeat = item.type_id.X_precision_repeat item.Y_precision = item.type_id.Y_precision item.Y_precision_repeat = item.type_id.Y_precision_repeat item.Z_precision = item.type_id.Z_precision item.Z_precision_repeat = item.type_id.Z_precision_repeat item.a_precision = item.type_id.a_precision item.a_precision_repeat = item.type_id.a_precision_repeat item.b_precision = item.type_id.b_precision item.b_precision_repeat = item.type_id.b_precision_repeat item.c_precision = item.type_id.c_precision item.c_precision_repeat = item.type_id.c_precision_repeat item.tool_full_diameter_max = item.type_id.tool_full_diameter_max item.tool_perimeter_diameter_max = item.type_id.tool_perimeter_diameter_max item.T_tool_time = item.type_id.T_tool_time item.C_tool_time = item.type_id.C_tool_time item.C_tool_time = item.type_id.C_tool_time item.image_id = item.type_id.jg_image_id.ids item.image_lq_id = item.type_id.lq_image_id.ids # AGV小车设备参数 AGV_L = fields.Char('AGV尺寸(长)') AGV_W = fields.Char('AGV尺寸(宽)') AGV_H = fields.Char('AGV尺寸(高)') AGV_goods_L = fields.Char('载货尺寸(长)') AGV_goods_W = fields.Char('载货尺寸(宽)') AGV_goods_H = fields.Char('载货尺寸(高)') AGV_velocity = fields.Char('标准速度') AGV_velocity_min = fields.Char('标准速度(最小)') AGV_velocity_max = fields.Char('标准速度(最大)') AGV_Lifting_height = fields.Char('升降高度(max)') AGV_ground_clearance = fields.Char('最小离地高度') AGV_turning_radius = fields.Char('最小转弯半径') AGV_gradeability_max = fields.Integer('最大爬坡度') AGV_parking_accuracy = fields.Char('停车精度') AGV_load_weight_max = fields.Char('AGV最大负载重量') AGV_weight = fields.Char('AGV本体总重量') AGV_job_duration = fields.Char('连续作业时长') AGV_transfer_mode = fields.Char('移载方式') AGV_drive_motor_power = fields.Char('驱动电机功率') AGV_hoist_motor_power = fields.Char('提升电机功率') AGV_drive_motor_speed_ratio = fields.Char('驱动电机速比') AGV_veer_motor_power = fields.Char('转向电机功率') AGV_veer_motor_speed_ratio = fields.Char('转向电机速比') AGV_move_motor_power = fields.Char('前移电机功率') AGV_move_motor_speed_ratio = fields.Char('前移电机速比') AGV_drive_mode = fields.Char('AGV驱动方式') AGV_navigation_mode = fields.Char('导航方式') AGV_communication_mode = fields.Char('通讯方式') AGV_direction_travel = fields.Char('行走方向') AGV_power_requirements = fields.Char('AGV电源要求') AGV_charge_mode = fields.Selection([('手动', '手动'), ('自动', '自动')], string='充电方式') AGV_security = fields.Char('安全防护') AGV_operating_temperature = fields.Char('环境温度') AGV_operating_humidity = fields.Char('环境湿度') # 三元检测设备参数 detect_L = fields.Char('设备尺寸(长)') detect_W = fields.Char('设备尺寸(宽)') detect_H = fields.Char('设备尺寸(高)') detect_x_axis = fields.Char('检测X轴') detect_y_axis = fields.Char('检测Y轴') detect_z_axis = fields.Char('检测Z轴') detect_precision = fields.Char('测量精度') detect_measurement_mode = fields.Selection([('光栅尺', '光栅尺'), ('容栅', '容栅'), ('磁栅', '磁栅'), ('激光干涉仪', '激光干涉仪')], string='测量方式') detect_resolution = fields.Char('分辨率') detect_load_weight_max = fields.Char('检测设备最大负载重量') detect_weight = fields.Char('检测设备本体总重量') detect_measurement_length = fields.Char('深孔测量长度(max)') detect_control_mode = fields.Char('控制方式') detect_balance_mode_for_Z = fields.Char('Z轴平衡方式') detect_zoom_objective_magnification = fields.Char('变焦物镜倍率') detect_magnification = fields.Char('放大倍率') detect_working_distance = fields.Char('工作距离') detect_locking_mode = fields.Char('锁紧方式') detect_pressurized_air = fields.Char('压缩空气') detect_object_field_of_view_max = fields.Char('物方视场(最大)') detect_object_field_of_view_min = fields.Char('物方视场(最小)') detect_power_requirements = fields.Char('电源要求') detect_operating_temperature = fields.Char('检测设备环境温度') detect_operating_humidity = fields.Char('检测设备环境湿度') # 机器人设备参数 robot_gripping_of_workpieces_L = fields.Char('可抓取工件(长)') robot_gripping_of_workpieces_W = fields.Char('可抓取工件(宽)') robot_gripping_of_workpieces_H = fields.Char('可抓取工件(高)') robot_radius_of_the_boom = fields.Char('展臂半径') robot_load_weight_max = fields.Char('机械臂最大负载重量') robot_weight = fields.Char('机械臂本体总重量') robot_repeatable_positioning_accuracy = fields.Char('重复定位精度') robot_axis_num = fields.Selection([('2轴', '2轴'), ('3轴', '3轴'), ('4轴', '4轴'), ('5轴', '5轴'), ('6轴', '6轴'), ('7轴', '7轴'), ('8轴', '8轴')], string='机械臂轴数') axis_ids = fields.One2many('sf.robot.axis.num', 'equipment_id', string='动作范围') robot_track_dimensions_L = fields.Char('轨道尺寸(长)') robot_track_dimensions_W = fields.Char('轨道尺寸(宽)') robot_track_dimensions_H = fields.Char('轨道尺寸(高)') robot_drive_mode = fields.Char('驱动方式') robot_installation_method = fields.Selection([('置地式', '置地式'), ('壁挂式', '壁挂式'), ('倒挂式', '倒挂式')], string='安装方式') robot_operating_temperature = fields.Char('机器人环境温度') robot_operating_humidity = fields.Char('机器人环境湿度') # 其他参数(所有设备) date_of_purchase = fields.Date('采购日期') date_of_manufacture = fields.Date('出厂日期') date_of_warranty = fields.Date('质保截至日期') original_value = fields.Char('原值') incomplete_value = fields.Char('残值') # 注册同步机床 def enroll_machine_tool(self): sf_sync_config = self.env['res.config.settings'].get_values() token = sf_sync_config['token'] sf_secret_key = sf_sync_config['sf_secret_key'] headers = Common.get_headers(self, token, sf_secret_key) strurl = sf_sync_config['sf_url'] + self.crea_url objs_all = self.env['maintenance.equipment'].search([('id', '=', self.id)]) machine_tool_list = [] if objs_all: for item in objs_all: images_ids_names = [] for a in self.env['maintenance.equipment.image'].search([('id', 'in', item.image_id.ids)]): images_ids_names.append(a.name) if item.machine_tool_picture: image = base64.b64encode(item.machine_tool_picture).decode('utf-8') else: image = False control_system_id = self.env['sf.machine.control_system'].sudo().browse(item.control_system_id.id).code val = { 'MTcode': item.MTcode, 'factory_token': token, 'id': item.id, 'name': item.name, 'code': item.code, 'knife_type': item.knife_type, 'number_of_knife_library': item.number_of_knife_library, 'rotate_speed': item.rotate_speed, 'number_of_axles': item.number_of_axles, 'control_system_id': control_system_id, 'type_id': self.env['sf.machine_tool.type'].sudo().browse(item.type_id.id).code, 'brand_id': self.env['sf.machine.brand'].sudo().browse(item.brand_id.id).code, 'supplier_id': item.supplier_id.id, 'x_axis': item.x_axis, 'y_axis': item.y_axis, 'z_axis': item.z_axis, 'b_axis': item.b_axis, 'c_axis': item.c_axis, 'state': item.state, 'active': item.active, 'machine_tool_picture': image, 'heightened_way': item.heightened_way, 'workpiece_load': item.workpiece_load, 'lead_screw': item.lead_screw, 'workbench_L': item.workbench_L, 'workbench_W': item.workbench_W, 'workbench_H': item.workbench_H, 'guide_rail': item.guide_rail, 'machine_tool_L': item.machine_tool_L, 'machine_tool_W': item.machine_tool_W, 'machine_tool_H': item.machine_tool_H, 'feed_speed': item.feed_speed, 'tool_speed': item.tool_speed, 'taper': item.taper, 'torque': item.torque, 'motor_power': item.motor_power, 'tool_quality_max': item.tool_quality_max, 'tool_long_max': item.tool_long_max, 'tool_diameter_max': item.tool_diameter_max, 'precision_min': item.precision_min, 'precision_max': item.precision_max, 'distance_min': item.distance_min, 'distance_max': item.distance_max, 'tool_diameter_min': item.tool_diameter_min, 'machine_tool_category': item.machine_tool_category.code, 'image_id': images_ids_names, 'taper_type_id': item.taper_type_id.name, 'function_type': item.function_type, 'a_axis': item.a_axis, 'T_trough_num': item.T_trough_num, 'T_trough_wide': item.T_trough_wide, 'T_trough_distance': item.T_trough_distance, 'spindle_center_distance': item.spindle_center_distance, 'spindle_continuous_power': item.spindle_continuous_power, 'spindle_peak_power': item.spindle_peak_power, 'spindle_sustained_torque': item.spindle_sustained_torque, 'spindle_peak_torque': item.spindle_peak_torque, 'linear_axis_guides_type': item.linear_axis_guides_type, 'axis_driven_type': item.axis_driven_type, 'X_axis_rapid_traverse_speed': item.X_axis_rapid_traverse_speed, 'Y_axis_rapid_traverse_speed': item.Y_axis_rapid_traverse_speed, 'Z_axis_rapid_traverse_speed': item.Z_axis_rapid_traverse_speed, 'a_axis_rapid_traverse_speed': item.a_axis_rapid_traverse_speed, 'b_axis_rapid_traverse_speed': item.b_axis_rapid_traverse_speed, 'c_axis_rapid_traverse_speed': item.c_axis_rapid_traverse_speed, 'straight_cutting_feed_rate': item.straight_cutting_feed_rate, 'rotary_cutting_feed_rate': item.rotary_cutting_feed_rate, 'X_precision': item.X_precision, 'X_precision_repeat': item.X_precision_repeat, 'Y_precision': item.X_precision, 'Y_precision_repeat': item.X_precision_repeat, 'Z_precision': item.X_precision, 'Z_precision_repeat': item.X_precision_repeat, 'a_precision': item.X_precision, 'a_precision_repeat': item.X_precision_repeat, 'b_precision': item.X_precision, 'b_precision_repeat': item.X_precision_repeat, 'c_precision': item.X_precision, 'c_precision_repeat': item.X_precision_repeat, 'tool_full_diameter_max': item.tool_full_diameter_max, 'tool_perimeter_diameter_max': item.tool_perimeter_diameter_max, 'T_tool_time': item.T_tool_time, 'C_tool_time': item.C_tool_time, 'jiancheng': item.category_id.equipment_type_code, } machine_tool_list.append(val) # kw = machine_tool_list kw = json.dumps(machine_tool_list, ensure_ascii=False) r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers) ret = r.json() self.code = ret['data'] self.state_zc = "已注册" if r == 200: return "机床注册成功" else: raise UserError("没有注册机床信息") # 修改原生方法,生成维保日期 @api.depends('effective_date', 'period', 'maintenance_ids.request_date', 'maintenance_ids.close_date', 'overhaul_period') def _compute_next_maintenance(self): date_now = fields.Date.context_today(self) equipments = self.filtered(lambda x: x.period > 0) if equipments: for equipment in equipments: next_maintenance_todo = self.env['maintenance.request'].search([ ('equipment_id', '=', equipment.id), ('sf_maintenance_type', '=', '保养'), ('stage_id.done', '!=', True), ('active', '!=', False), ('close_date', '=', False)], order="request_date asc", limit=1) last_maintenance_done = self.env['maintenance.request'].search([ ('equipment_id', '=', equipment.id), ('sf_maintenance_type', '=', '保养'), ('stage_id.done', '=', True), ('active', '!=', False), ('close_date', '!=', False)], order="close_date desc", limit=1) if next_maintenance_todo and last_maintenance_done: next_date = next_maintenance_todo.request_date date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_date # If the gap between the last_maintenance_done and the next_maintenance_todo one is bigger than # 2 times the period and next request is in the future # We use 2 times the period to avoid creation too closed request from a manually one created if date_gap > timedelta(0) and date_gap > timedelta( days=equipment.period) * 2 and next_maintenance_todo.request_date > date_now: # If the new date still in the past, we set it for today if last_maintenance_done.close_date + timedelta(days=equipment.period) < date_now: next_date = date_now else: next_date = last_maintenance_done.close_date + timedelta(days=equipment.period) elif next_maintenance_todo: next_date = next_maintenance_todo.request_date date_gap = next_maintenance_todo.request_date - date_now # If next maintenance to do is in the future, and in more than 2 times the period, we insert # an new request # We use 2 times the period to avoid creation too closed request from a manually one created if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.period) * 2: next_date = date_now + timedelta(days=equipment.period) elif last_maintenance_done: next_date = last_maintenance_done.close_date + timedelta(days=equipment.period) # If when we add the period to the last maintenance done and we still in past, we plan it for today if next_date < date_now: next_date = date_now else: next_date = equipment.initial_action_date + timedelta(days=equipment.period) equipment.next_action_date = next_date else: self.next_action_date = False overhaul_equipments = self.filtered(lambda x: x.overhaul_period > 0) if overhaul_equipments: for equipment in overhaul_equipments: next_maintenance_todo = self.env['maintenance.request'].search([ ('equipment_id', '=', equipment.id), ('sf_maintenance_type', '=', '检修'), ('stage_id.done', '!=', True), ('active', '!=', False), ('close_date', '=', False)], order="request_date asc", limit=1) last_maintenance_done = self.env['maintenance.request'].search([ ('equipment_id', '=', equipment.id), ('sf_maintenance_type', '=', '检修'), ('stage_id.done', '=', True), ('active', '!=', False), ('close_date', '!=', False)], order="close_date desc", limit=1) if next_maintenance_todo and last_maintenance_done: next_date = next_maintenance_todo.request_date date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_date # If the gap between the last_maintenance_done and the next_maintenance_todo one is bigger than 2 # times the period and next request is in the future # We use 2 times the period to avoid creation too closed request from a manually one created if date_gap > timedelta(0) and date_gap > timedelta( days=equipment.overhaul_period) * 2 and next_maintenance_todo.request_date > date_now: # If the new date still in the past, we set it for today if last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period) < date_now: next_date = date_now else: next_date = last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period) elif next_maintenance_todo: next_date = next_maintenance_todo.request_date date_gap = next_maintenance_todo.request_date - date_now # If next maintenance to do is in the future, and in more than 2 times the period, we insert # an new request # We use 2 times the period to avoid creation too closed request from a manually one created if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.overhaul_period) * 2: next_date = date_now + timedelta(days=equipment.overhaul_period) elif last_maintenance_done: next_date = last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period) # If when we add the period to the last maintenance done and we still in past, we plan it for today if next_date < date_now: next_date = date_now else: next_date = equipment.initial_overhaul_date + timedelta(days=equipment.overhaul_period) equipment.overhaul_date = next_date else: self.overhaul_date = False # 拼接维保请求字符串 def _prepare_maintenance_request_vals(self, date): self.ensure_one() return { 'name': _('Preventive Maintenance - %s', self.name), 'request_date': date, 'schedule_date': date, 'category_id': self.category_id.id, 'equipment_id': self.id, 'maintenance_type': 'preventive', 'owner_user_id': self.owner_user_id.id, 'user_id': self.technician_user_id.id, 'maintenance_team_id': self.maintenance_team_id.id, 'duration': self.maintenance_duration, 'company_id': self.company_id.id or self.env.company.id, 'equipment_maintenance_id': self.eq_maintenance_id.id, 'sf_maintenance_type': '保养' } # 拼接维保请求字符串 def _prepare_maintenance_request_vals1(self, date): self.ensure_one() return { 'name': _('Preventive Maintenance - %s', self.name), 'request_date': date, 'schedule_date': date, 'category_id': self.category_id.id, 'equipment_id': self.id, 'maintenance_type': 'preventive', 'owner_user_id': self.owner_user_id.id, 'user_id': self.technician_user_id.id, 'maintenance_team_id': self.maintenance_team_id.id, 'duration': self.overhaul_duration, 'company_id': self.company_id.id or self.env.company.id, 'equipment_maintenance_id': self.overhaul_id.id, 'sf_maintenance_type': '检修' } # 创建维保请求 def _create_new_request(self, date): self.ensure_one() vals = self._prepare_maintenance_request_vals(date) maintenance_requests = self.env['maintenance.request'].create(vals) return maintenance_requests def _create_new_request1(self, date): self.ensure_one() vals = self._prepare_maintenance_request_vals1(date) maintenance_requests = self.env['maintenance.request'].create(vals) return maintenance_requests # 生成维保请求定时器 @api.model def _cron_generate_requests(self): """ Generates maintenance request on the next_action_date or today if none exists """ for equipment in self.search([('period', '>', 0)]): next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False), ('equipment_id', '=', equipment.id), ('maintenance_type', '=', 'preventive'), ('active', '=', True), ('request_date', '=', equipment.next_action_date), ('sf_maintenance_type', '=', '保养')]) if not next_requests: equipment._create_new_request(equipment.next_action_date) for equipment in self.search([('overhaul_period', '>', 0)]): next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False), ('equipment_id', '=', equipment.id), ('maintenance_type', '=', 'preventive'), ('active', '=', True), ('request_date', '=', equipment.overhaul_date), ('sf_maintenance_type', '=', '检修')]) if not next_requests: equipment._create_new_request1(equipment.overhaul_date) image_id = fields.Many2many('maintenance.equipment.image', 'equipment_id', domain="[('type', '=', '加工能力')]") image_lq_id = fields.Many2many('maintenance.equipment.image', 'equipment_lq_id', string='冷却方式', domain="[('type', '=', '冷却方式')]") class SfRobotAxisNum(models.Model): _name = 'sf.robot.axis.num' _description = '机器人轴参数' name = fields.Char('*轴') angle_min = fields.Char('最小角度-(°)') angle_max = fields.Char('最大角度+(°)') velocity = fields.Char('最大速度(°/s)') weight = fields.Char('最大负载(kg)') permissible_load_torque = fields.Char('允许负载扭矩(N-m)') permissible_inertial_torque = fields.Char('允许惯性扭矩(kg-m²)') equipment_id = fields.Many2one('maintenance.equipment', string='机器人', domain="[('equipment_type', '=', '机器人')]")