624 lines
31 KiB
Python
624 lines
31 KiB
Python
# -*- coding: utf-8 -*-
|
||
import base64
|
||
|
||
from odoo import api, fields, models, SUPERUSER_ID, _
|
||
from odoo.exceptions import UserError
|
||
import logging
|
||
from datetime import date, datetime, timedelta
|
||
import requests
|
||
import json
|
||
from odoo.addons.sf_base.commons.common import Common
|
||
|
||
|
||
class SfMaintenanceEquipmentCategory(models.Model):
|
||
_inherit = 'maintenance.equipment.category'
|
||
_description = '设备类别'
|
||
|
||
equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'), ('检测设备', '检测设备')], string='类型', default='机床')
|
||
|
||
|
||
class SfMaintenanceEquipment(models.Model):
|
||
_inherit = 'maintenance.equipment'
|
||
_description = '设备'
|
||
|
||
crea_url = "/api/machine_tool/create"
|
||
|
||
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','=','保养')]")
|
||
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','=','检修')]")
|
||
|
||
@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("编码", default=get_no)
|
||
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('名称')
|
||
knife_type = fields.Selection(
|
||
[("BT40", "BT40"), ("BT30", "BT30"), ("BT50", "BT50")],
|
||
default="", string="刀把类型")
|
||
number_of_knife_library = fields.Integer('刀库数量(把)')
|
||
rotate_speed = fields.Integer('转速')
|
||
number_of_axles = fields.Selection(
|
||
[("三轴", "三轴"), ("四轴", "四轴"), ("五轴", "五轴")],
|
||
default="", string="轴数")
|
||
# 加工进程
|
||
x_axis = fields.Integer('X轴')
|
||
y_axis = fields.Integer('Y轴')
|
||
z_axis = fields.Integer('Z轴')
|
||
b_axis = fields.Integer('B轴')
|
||
c_axis = fields.Integer('C轴')
|
||
remark = fields.Char('备注')
|
||
is_binding = fields.Boolean('是否绑定机床', default=False)
|
||
precision_min = fields.Float('X轴定位精度min(mm)', digits=(12, 3))
|
||
precision_max = fields.Float('X轴定位精度max(mm)', digits=(12, 3))
|
||
control_system_id = fields.Many2one('sf.machine.control_system',
|
||
string="控制系统")
|
||
# 多个机床型号对应一个机床
|
||
brand_id = fields.Many2one('sf.machine.brand', string='品牌')
|
||
type_id = fields.Many2one('sf.machine_tool.type', '型号')
|
||
|
||
state = fields.Selection(
|
||
[("正常", "正常"), ("故障", "故障"), ("不可用", "不可用")],
|
||
default='正常', string="机床状态")
|
||
# 0606新增字段
|
||
machine_tool_picture = fields.Binary('图片')
|
||
heightened_way = fields.Selection([
|
||
('sifudianji', '伺服电机驱动'),
|
||
('youyagang', '油压缸驱动'),
|
||
('chilunjia', '齿轮架驱动')
|
||
], string="主轴加高方式", default='sifudianji')
|
||
workpiece_load = fields.Char('工件最大负载(kg)')
|
||
lead_screw = fields.Char('丝杆')
|
||
workbench_L = fields.Char('工作台长度(mm)')
|
||
workbench_W = fields.Char('工作台宽度(mm)')
|
||
guide_rail = fields.Char('导轨')
|
||
machine_tool_L = fields.Char('机床长度(mm)')
|
||
machine_tool_W = fields.Char('机床宽度(mm)')
|
||
machine_tool_H = fields.Char('机床高度(mm)')
|
||
feed_speed = fields.Char('进给速度(mm/min)')
|
||
tool_speed = fields.Char('刀具速度(m/min)')
|
||
distance_min = fields.Char('主轴端面至工作台面距离MIN(mm)')
|
||
distance_max = fields.Char('主轴端面至工作台面距离MAX(mm)')
|
||
taper = fields.Char('主轴锥度(°)')
|
||
torque = fields.Char('主轴电机扭矩(n/m)')
|
||
motor_power = fields.Char('主轴电机功率(kw)')
|
||
tool_quality_max = fields.Char('刀具最大质量(kg)')
|
||
tool_long_max = fields.Char('刀具最大长度(mm)')
|
||
tool_diameter_max = fields.Char('刀具刀径max(mm)')
|
||
tool_diameter_min = fields.Char('刀具刀径min(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', '设备故障日志')
|
||
|
||
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.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.precision <= 0.00:
|
||
raise UserError("加工精度不能为0")
|
||
|
||
@api.constrains('number_of_knife_library')
|
||
def _check_number_of_knife_library(self):
|
||
if self.number_of_knife_library <= 0:
|
||
raise UserError("刀库数量不能为0")
|
||
|
||
@api.constrains('x_axis')
|
||
def _check_x_axis(self):
|
||
if self.x_axis <= 0:
|
||
raise UserError("加工行程里x轴不能为0")
|
||
|
||
@api.constrains('y_axis')
|
||
def _check_y_axis(self):
|
||
if self.y_axis <= 0:
|
||
raise UserError("加工行程里y轴不能为0")
|
||
|
||
@api.constrains('z_axis')
|
||
def _check_z_axis(self):
|
||
if self.z_axis <= 0:
|
||
raise UserError("加工行程里z轴不能为0")
|
||
|
||
@api.constrains('b_axis')
|
||
def _check_b_axis(self):
|
||
if 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.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
|
||
|
||
# AGV小车设备参数
|
||
AGV_L = fields.Char('设备尺寸(长)')
|
||
AGV_W = fields.Char('设备尺寸(宽)')
|
||
AGV_H = fields.Char('设备尺寸(高)')
|
||
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_weight = fields.Char('本体总重量')
|
||
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_navigation_mode = fields.Char('导航方式')
|
||
AGV_communication_mode = fields.Char('通讯方式')
|
||
AGV_direction_travel = fields.Char('行走方向')
|
||
AGV_power_requirements = fields.Char('电源要求')
|
||
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('环境湿度')
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
# 注册同步机床
|
||
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([('MTcode', '=', self.MTcode)])
|
||
machine_tool_list = []
|
||
if objs_all:
|
||
for item in objs_all:
|
||
if item.machine_tool_picture != False:
|
||
image = base64.b64encode(item.machine_tool_picture).decode('utf-8')
|
||
else:
|
||
image = False
|
||
val = {
|
||
'MTcode': item.MTcode,
|
||
'factory_token': token,
|
||
'id': item.id,
|
||
'name': item.name,
|
||
'code': item.code,
|
||
'precision': item.precision,
|
||
'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': self.env['sf.machine.control_system'].search(
|
||
[('id', '=', item.control_system_id.id)]).code,
|
||
'type_id': self.env['sf.machine_tool.type'].search([('id', '=', item.type_id.id)]).code,
|
||
'brand_id': self.env['sf.machine.brand'].search([('id', '=', 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,
|
||
'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,
|
||
'distance': item.distance,
|
||
'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,
|
||
'machine_tool_category': item.machine_tool_category.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['message']
|
||
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),
|
||
('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),
|
||
('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.effective_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),
|
||
('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),
|
||
('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.effective_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'),
|
||
('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'),
|
||
('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', string='设备图文')
|
||
|
||
|
||
class MaintenanceStandardImage(models.Model):
|
||
_name = 'maintenance.equipment.image'
|
||
_description = '能力特征库'
|
||
|
||
active = fields.Boolean('有效', default=True)
|
||
name = fields.Char('名称')
|
||
image = fields.Binary(string='图文')
|
||
type = fields.Selection(
|
||
[('加工能力', '加工能力'), ('刀尖特征', '刀尖特征'), ('柄部类型', '柄部类型'), ('走刀方向', '走刀方向'), ('冷却液', '冷却液')],
|
||
string='特征')
|
||
equipment_id = fields.Many2many('maintenance.equipment', 'image_id', string='设备')
|
||
|
||
@api.model
|
||
def name_search(self, name='', args=None, operator='ilike', limit=100):
|
||
# 调用父类的name_search方法,获取原始的结果列表
|
||
res = super().name_search(name, args, operator, limit)
|
||
# 定义一个空字典用来存储id和name的映射关系
|
||
name_dict = {}
|
||
# 遍历结果列表,将id和name存入字典中
|
||
for item in res:
|
||
id = item[0]
|
||
name = item[1]
|
||
name_dict[id] = name
|
||
# 根据id列表搜索符合条件的记录
|
||
records = self.browse(name_dict.keys())
|
||
# 定义一个新的结果列表用来存储修改后的结果
|
||
new_res = []
|
||
# 遍历每条记录
|
||
for record in records:
|
||
# 获取记录的id,name和image属性
|
||
id = record.id
|
||
name = name_dict[id]
|
||
image = record.image
|
||
# 如果image不为空,将其转换为data URI scheme
|
||
if image:
|
||
data_uri = f"data:image/png;base64,{image.decode('utf-8')}"
|
||
else:
|
||
data_uri = ""
|
||
# 将这三个属性组成一个数组,并添加到结果列表中 result.append([id, name, data_uri]) # 返回结果列表 return result
|
||
new_res.append([id, name, data_uri])
|
||
# 返回新的结果列表
|
||
return new_res
|
||
|
||
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', '=', '机器人')]")
|