Files
jikimo_sf/sf_route_workcenter/models/workcenter.py
2022-11-15 16:16:21 +08:00

337 lines
14 KiB
Python

# -*- coding: utf-8 -*-
# Part of SmartGo. See LICENSE file for full copyright and licensing details.
import base64
import logging
import math
from io import BytesIO
from odoo import api, fields, models, SUPERUSER_ID
from pystrich.code128 import Code128Encoder
from odoo.exceptions import ValidationError
_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 ""
def fetchCNC(self):
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.is_repeat == True:
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('模型名称')