Files
test/sf_route_workcenter/models/workcenter.py

376 lines
16 KiB
Python

# -*- coding: utf-8 -*-
# Part of SmartGo. See LICENSE file for full copyright and licensing details.
import base64
import logging
import math
import json
import requests
from io import BytesIO
from odoo import api, fields, models, SUPERUSER_ID
from pystrich.code128 import Code128Encoder
from odoo.exceptions import ValidationError
from odoo.addons.sf_base.commons.common import Common
_logger = logging.getLogger(__name__)
class CNCprocessing(models.Model):
_inherit = 'cnc.processing'
_description = "CNC加工"
workorder_id = fields.Many2one('mrp.workorder', string="工单")
class Tray(models.Model):
_inherit = 'sf.tray'
_description = '托盘'
qr_image = fields.Binary(string="托盘二维码", compute='compute_qr_image')
production_id = fields.Many2one('mrp.production', string='制造订单',
related='workorder_id.production_id'
)
workorder_id = fields.Many2one('mrp.workorder', string="工单"
)
@api.onchange('production_id')
def updateTrayState(self):
if self.workorder_id != False:
self.state = '占用'
else:
self.state = '空闲'
def unclamp(self):
self.workorder_id = False
self.production_id = False
self.state = '空闲'
@api.depends('code')
def compute_qr_image(self):
for item in self:
if not item.code:
item.qr_image = False
continue
# 根据code动态生成二维码图片
# qr = qrcode.QRCode(
# version=1,
# error_correction=qrcode.constants.ERROR_CORRECT_L,
# box_size=10,
# border=4,
# )
# qr.add_data(item.code)
# qr.make(fit=True)
# img = qr.make_image()
# 生成条形码文件
# bar = barcode.get("ean13", "123456789102", writer=ImageWriter())
# a = bar.get_fullcode()
# b = bar.save('occ')
# 生成条形码图片
partner_encoder = Code128Encoder(item.code)
# 转换bytes流
temp = BytesIO()
partner_encoder.save(temp)
# img.save(temp, format='PNG')
qr_image = base64.b64encode(temp.getvalue())
item.qr_image = qr_image
'''
工单绑定托盘信息
'''
class MrpWorkOrder(models.Model):
_inherit = 'mrp.workorder'
_description = '工单'
tray_ids = fields.One2many('sf.tray', 'workorder_id', string='托盘')
# def get_tray_info(self):
# @api.onchange('X_axis', 'Y_axis', 'Z_axis')
# def get_center_point(self):
# return 'X:%s,Y:%s,Z:%s' % (self.X_axis, self.Y_axis, self.Z_axis)
# 加工面
# surface = fields.Selection([("前面", "前面"), ("后面", "后面"), ("左面", "左面"), ("右面", "右面"),
# ("上面", "上面")], string="加工面1")
material_center_point = fields.Char(string='配料中心点')
X1_axis = fields.Float(string='Lx1', default=0)
Y1_axis = fields.Float(string='Ly1', default=0)
Z1_axis = fields.Float(string='Lz1', default=0)
X2_axis = fields.Float(string='Lx2', default=0)
Y2_axis = fields.Float(string='Ly2', default=0)
Z2_axis = fields.Float(string='Lz2', default=0)
X3_axis = fields.Float(string='Fx3', default=0)
Y3_axis = fields.Float(string='Fy3', default=0)
Z3_axis = fields.Float(string='Fz3', default=0)
X4_axis = fields.Float(string='Fx4', default=0)
Y4_axis = fields.Float(string='Fy4', default=0)
Z4_axis = fields.Float(string='Fz4', default=0)
X5_axis = fields.Float(string='Rx5', default=0)
Y5_axis = fields.Float(string='Ry5', default=0)
Z5_axis = fields.Float(string='Rz5', default=0)
X6_axis = fields.Float(string='Rx6', default=0)
Y6_axis = fields.Float(string='Ry6', default=0)
Z6_axis = fields.Float(string='Rz6', default=0)
X7_axis = fields.Float(string='Bx7', default=0)
Y7_axis = fields.Float(string='By7', default=0)
Z7_axis = fields.Float(string='Bz7', default=0)
X8_axis = fields.Float(string='Bx8', default=0)
Y8_axis = fields.Float(string='By8', default=0)
Z8_axis = fields.Float(string='Bz8', default=0)
X9_axis = fields.Float(string='Uz9', default=0)
Y9_axis = fields.Float(string='Uz9', default=0)
Z9_axis = fields.Float(string='Uz9', default=0)
X10_axis = fields.Float(string='Uz10', default=0)
Y10_axis = fields.Float(string='Uz10', default=0)
Z10_axis = fields.Float(string='Uz10', default=0)
# 计算配料中心点和与x轴倾斜度方法
def getcenter(self):
x1 = self.X1_axis
x2 = self.X2_axis
x3 = self.X3_axis
x4 = self.X4_axis
x5 = self.X5_axis
x6 = self.X6_axis
x7 = self.X7_axis
x8 = self.X8_axis
y1 = self.Y1_axis
y2 = self.Y2_axis
y3 = self.Y3_axis
y4 = self.Y4_axis
y5 = self.Y5_axis
y6 = self.Y6_axis
y7 = self.Y7_axis
y8 = self.Y8_axis
z1 = self.Z9_axis
x0 = ((x3 - x4) * (x2 * y1 - x1 * y2) - (x1 - x2) * (x4 * y3 - x3 * y4)) / (
(x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4))
y0 = ((y3 - y4) * (y2 * x1 - y1 * x2) - (y1 - y2) * (y4 * x3 - y3 * x4)) / (
(y3 - y4) * (x1 - x2) - (y1 - y2) * (x3 - x4))
x1 = ((x7 - x8) * (x6 * y5 - x5 * y7) - (x5 - x6) * (x8 * y7 - x7 * y8)) / (
(x7 - x8) * (y5 - y6) - (x5 - x6) * (y7 - y8));
y1 = ((y7 - y8) * (y6 * x5 - y5 * x7) - (y5 - y6) * (y8 * x7 - y7 * x8)) / (
(y7 - y8) * (x5 - x6) - (y5 - y6) * (x7 - x8))
x = (x0 + x1) / 2
y = (y0 + y1) / 2
z = z1 / 2
jd = math.atan2((x7 - x8), (y7 - y8))
jdz = jd * 180 / math.pi
print("(%s,%s)" % (x, y))
self.material_center_point = ("(%s,%s,%s)" % (x, y, z))
self.X_deviation_angle = jdz
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], string="检测结果")
cnc_ids = fields.One2many("cnc.processing", 'workorder_id', string="CNC加工")
tray_code = fields.Char(string="托盘")
# 扫码绑定托盘方法
def gettray(self):
if self.tray_code != False:
values = self.env['sf.tray'].search([("code", "=", self.tray_code)])
if values:
if values.state == "占用":
raise ValidationError('该托盘已占用')
if values.state == "报损":
raise ValidationError('该托盘已损坏')
else:
values.update({
'workorder_id': self,
'production_id': self.production_id,
'state': '占用',
})
else:
raise ValidationError('该托盘编码已失效')
else:return ""
# 解除托盘绑定
def unbindtray(self):
tray = self.env['sf.tray'].search([("production_id", "=", self.production_id.id)])
if tray:
tray.unclamp()
return ""
def recreateManufacturing(self):
"""
重新生成制造订单
"""
values = self.env['mrp.production'].create_production1_values(self.production_id)
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(
self.production_id.company_id).create(
values)
self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
productions._create_workorder()
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
(
p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm()
for production in productions:
origin_production = production.move_dest_ids and production.move_dest_ids[
0].raw_material_production_id or False
orderpoint = production.orderpoint_id
if orderpoint and orderpoint.create_uid.id == SUPERUSER_ID and orderpoint.trigger == 'manual':
production.message_post(
body=_('This production order has been created from Replenishment Report.'),
message_type='comment',
subtype_xmlid='mail.mt_note')
elif orderpoint:
production.message_post_with_view(
'mail.message_origin_link',
values={'self': production, 'origin': orderpoint},
subtype_id=self.env.ref('mail.mt_note').id)
elif origin_production:
production.message_post_with_view(
'mail.message_origin_link',
values={'self': production, 'origin': origin_production},
subtype_id=self.env.ref('mail.mt_note').id)
# print(productions)
return ""
def recreateWorkerOrder(self):
"""
返工重新生成工单
"""
productions = self.production_id
self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
productions.create_workorder1(self.processing_panel)
return ""
# cnc程序获取
def fetchCNC(self):
cnc_process = self.env['mrp.workorder'].search(
[("routing_type", '=', 'CNC加工'),
("production_id", '=', self.production_id.id)],
limit=1,
order='id asc'
)
vals = {
'model_long': cnc_process.product_id.model_long,
'model_width': cnc_process.product_id.model_width,
'model_height': cnc_process.product_id.model_height,
'model_volume': cnc_process.product_id.model_volume,
'model_price': cnc_process.product_id.model_price,
'model_total_amount': cnc_process.product_id.model_total_amount,
'model_materials_code': cnc_process.product_id.materials_id.materials_no,
'model_materials_type_code': cnc_process.product_id.materials_type_id.materials_no,
'model_surface_process_code': cnc_process.product_id.model_surface_process_id.process_encode,
'model_process_parameters_code': cnc_process.product_id.model_process_parameters_id.process_encode,
'model_remark': cnc_process.product_id.model_remark
}
res = [{'order_no': self.product_id.barcode, 'production_no': self.production_id.name,
'intelligent_programming_str': vals,
'machine_tool_code': cnc_process.workcenter_id.machine_tool_id.code}]
configsettings = self.env['res.config.settings'].get_values()
token = configsettings['token']
mrs_secret_key = configsettings['mrs_secret_key']
config_header = Common.get_headers(self, token, mrs_secret_key)
url = '/api/intelligent_programming/create'
config_url = configsettings['mrs_url'] + url
res_str = json.dumps(res)
ret = requests.post(config_url, json={"result": res_str}, data=None, headers=config_header)
return ""
'''
制造订单绑定托盘信息
'''
class MrpProduction(models.Model):
_inherit = 'mrp.production'
_description = "制造订单"
tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘")
def create_production1_values(self, production):
production_values_str = {'origin': production.origin,
'product_id': production.product_id.id,
'product_description_variants': production.product_description_variants,
'product_qty': production.product_qty,
'product_uom_id': production.product_uom_id.id,
'location_src_id': production.location_src_id.id,
'location_dest_id': production.location_dest_id.id,
'bom_id': production.bom_id.id,
'date_deadline': production.date_deadline,
'date_planned_start': production.date_planned_start,
'date_planned_finished': production.date_planned_finished,
'procurement_group_id': False,
'propagate_cancel': production.propagate_cancel,
'orderpoint_id': production.orderpoint_id.id,
'picking_type_id': production.picking_type_id.id,
'company_id': production.company_id.id,
'move_dest_ids': production.move_dest_ids.ids,
'user_id': production.user_id.id}
return production_values_str
def create_workorder1(self, k):
for production in self:
if not production.bom_id or not production.product_id:
continue
workorders_values = []
product_qty = production.product_uom_id._compute_quantity(production.product_qty,
production.bom_id.product_uom_id)
exploded_boms, dummy = production.bom_id.explode(production.product_id,
product_qty / production.bom_id.product_qty,
picking_type=production.bom_id.picking_type_id)
for bom, bom_data in exploded_boms:
# If the operations of the parent BoM and phantom BoM are the same, don't recreate work orders.
if not (bom.operation_ids and (not bom_data['parent_line'] or bom_data[
'parent_line'].bom_id.operation_ids != bom.operation_ids)):
continue
for operation in bom.operation_ids:
if operation._skip_operation_line(bom_data['product']):
continue
workorders_values += [{
'name': operation.name,
'production_id': production.id,
'workcenter_id': operation.workcenter_id.id,
'product_uom_id': production.product_uom_id.id,
'operation_id': operation.id,
'state': 'pending',
}]
# 根据加工面板的面数及对应的工序模板生成工单
i = 0
production.product_id.model_processing_panel = k
processing_panel_len = len(k)
for k in (production.product_id.model_processing_panel.split(',')):
routingworkcenter = self.env['sf.model.type.routing.sort'].search(
[('model_type_id', '=', production.product_id.model_type_id.id)],
order='sequence asc'
)
i += 1
for route in routingworkcenter:
if route.routing_type == 'CNC加工':
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(k, production, route))
if route.routing_type == '后置三元质量检测':
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(k, production, route))
production.workorder_ids = workorders_values
for workorder in production.workorder_ids:
workorder.duration_expected = workorder._get_duration_expected()
class Attachment(models.Model):
_inherit = 'ir.attachment'
cnc_model = fields.Binary('cnc文件', attachment=False)
model_name = fields.Char('模型名称')