合并sf代码

This commit is contained in:
gqh
2023-01-11 14:51:59 +08:00
parent aba5a076b1
commit 8e51654f17
23 changed files with 547 additions and 621 deletions

View File

@@ -3,9 +3,10 @@ from odoo.exceptions import ValidationError
import logging
import base64
import os
from OCC.Extend.DataExchange import read_step_file, write_stl_file
# from OCC.Extend.DataExchange import read_step_file, write_stl_file
from odoo.modules import get_resource_path
class ResProductTemplate(models.Model):
_inherit = 'product.template'
@@ -16,11 +17,11 @@ class ResProductTemplate(models.Model):
model_height = fields.Float('模型高[mm]', digits=(16, 3))
model_volume = fields.Float('模型体积[m³]')
model_machining_precision = fields.Selection([
('±0.10mm', '±0.10mm'),
('±0.05mm', '±0.05mm'),
('±0.03mm', '±0.03mm'),
('±0.02mm', '±0.02mm'),
('±0.01mm', '±0.01mm')], string='加工精度')
('0.10', '±0.10mm'),
('0.05', '±0.05mm'),
('0.03', '±0.03mm'),
('0.02', '±0.02mm'),
('0.01', '±0.01mm')], string='加工精度')
model_type_id = fields.Many2one('sf.model.type', string='模型类型')
model_processing_panel = fields.Char('模型加工面板')
model_surface_process_id = fields.Many2one('sf.production.process', string='表面工艺')
@@ -34,6 +35,15 @@ class ResProductTemplate(models.Model):
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号')
single_manufacturing = fields.Boolean(string="单个制造")
upload_model_file = fields.Many2many('ir.attachment', 'upload_model_file_attachment_ref', string='上传模型文件')
model_code = fields.Char('模型编码')
def _get_volume_uom_id_from_ir_config_parameter(self):
product_length_in_feet_param = self.env['ir.config_parameter'].sudo().get_param('product.volume_in_cubic_feet')
if product_length_in_feet_param == '1':
return self.env.ref('uom.product_uom_cubic_foot')
else:
return self.env.ref('sf_dlm.product_uom_cubic_millimeter')
# model_file = fields.Binary('模型文件')
# 胚料的库存路线设置
@@ -70,18 +80,19 @@ class ResProductTemplate(models.Model):
'model_volume': (item['model_long'] + model_type.embryo_tolerance) * (
item['model_width'] + model_type.embryo_tolerance) * (
item['model_height'] + model_type.embryo_tolerance),
'model_type_id': 1,
# 'model_machining_precision': item['model_machining_precision'],
'model_processing_panel': 'A',
'model_machining_precision': '±0.10mm',
'model_type_id': model_type.id,
'model_processing_panel': 'R',
'model_machining_precision': item['model_machining_precision'],
'model_code': item['barcode'],
'length': item['model_long'],
'width': item['model_width'],
'height': item['model_height'],
'volume': item['model_long'] * item['model_width'] * item['model_height'],
'model_file': base64.b64decode(item['model_file']),
'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']),
'model_name': attachment.name,
'upload_model_file': [(6, 0, [attachment.id])],
# 'single_manufacturing': True,
'tracking': 'serial',
'list_price': item['price'],
# 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id,
'materials_id': self.env['sf.production.materials'].search(
@@ -94,26 +105,26 @@ class ResProductTemplate(models.Model):
# [('process_encode', '=', item['process_parameters_code'])]).id,
'model_remark': item['remark'],
'default_code': '%s-%s' % (order_number, i),
#'barcode': item['barcode'],
# 'barcode': item['barcode'],
'active': True,
# 'route_ids': self._get_routes('')
}
copy_product_id.sudo().write(vals)
print(len(copy_product_id.model_file))
product_id.product_tmpl_id.active = False
# product_id.product_tmpl_id.active = False
return copy_product_id
def attachment_create(self, name, data):
attachment = self.env['ir.attachment'].create({
'datas': base64.b64decode(data),
'datas': base64.b64decode(data),
'type': 'binary',
'public': True,
'description': '模型文件',
'name': name
})
return attachment
# 创建胚料
def no_bom_product_create(self, product_id, item, order_id, route_type):
def no_bom_product_create(self, product_id, item, order_id, route_type, i):
no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
no_bom_copy_product_id.product_tmpl_id.active = True
materials_id = self.env['sf.production.materials'].search(
@@ -124,9 +135,10 @@ class ResProductTemplate(models.Model):
supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
vals = {
'name': '%s %s %s %s * %s * %s' % (
order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'],
item['model_height']),
'name': '%s-%s %s %s %s * %s * %s' % (
order_id.name, i, materials_id.name, materials_type_id.name,
item['model_long'] + model_type.embryo_tolerance, item['model_width'] + model_type.embryo_tolerance,
item['model_height'] + model_type.embryo_tolerance),
'length': item['model_long'] + model_type.embryo_tolerance,
'width': item['model_width'] + model_type.embryo_tolerance,
'height': item['model_height'] + model_type.embryo_tolerance,
@@ -150,40 +162,38 @@ class ResProductTemplate(models.Model):
no_bom_copy_product_id.purchase_ok = True
no_bom_copy_product_id.seller_ids = [
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0, 'is_subcontractor': True})]
logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
elif route_type == 'purchase':
no_bom_copy_product_id.purchase_ok = True
no_bom_copy_product_id.seller_ids = [
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
no_bom_copy_product_id.write(vals)
logging.info('no_bom_copy_product_id-vals:%s' % vals)
product_id.product_tmpl_id.active = False
# product_id.product_tmpl_id.active = False
return no_bom_copy_product_id
@api.onchange('upload_model_file')
def onchange_model_file(self):
for item in self:
if len(item.upload_model_file) > 1:
raise ValidationError('只允许上传一个文件')
if item.upload_model_file:
file_attachment_id = item.upload_model_file[0]
item.model_name = file_attachment_id.name
# 附件路径
report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
shapes = read_step_file(report_path)
output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl')
write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
# 转化为glb
output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb')
util_path = get_resource_path('sf_dlm', 'static/util')
cmd = 'python %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
os.system(cmd)
# 转base64
with open(output_glb_file, 'rb') as fileObj:
image_data = fileObj.read()
base64_data = base64.b64encode(image_data)
item.model_file = base64_data
# @api.onchange('upload_model_file')
# def onchange_model_file(self):
# for item in self:
# if len(item.upload_model_file) > 1:
# raise ValidationError('只允许上传一个文件')
# if item.upload_model_file:
# file_attachment_id = item.upload_model_file[0]
# item.model_name = file_attachment_id.name
# # 附件路径
# report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
# shapes = read_step_file(report_path)
# output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl')
# write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
# # 转化为glb
# output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb')
# util_path = get_resource_path('sf_dlm', 'static/util')
# cmd = 'python %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
# os.system(cmd)
# # 转base64
# with open(output_glb_file, 'rb') as fileObj:
# image_data = fileObj.read()
# base64_data = base64.b64encode(image_data)
# item.model_file = base64_data
class ResMrpBom(models.Model):
@@ -244,8 +254,6 @@ class ResMrpBom(models.Model):
# 匹配bom
def get_bom(self, product):
logging.info('get_bom-product:%s' % product)
logging.info('get_bom-product:%s' % product.materials_type_id.id)
embryo_has = self.env['product.product'].search(
[('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id),
('length', '>', product.length), ('width', '>', product.width),
@@ -257,7 +265,7 @@ class ResMrpBom(models.Model):
logging.info('get_bom-vals:%s' % embryo_has)
if embryo_has:
rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100
if rate_of_waste >= 20:
if rate_of_waste <= 20:
return embryo_has
else:
return

View File

@@ -14,7 +14,6 @@
'data': [
# 定义权限组放在最上面
# 权限组
"security/ir.model.access.csv",
'views/compensation.xml',
'views/ftp_button.xml',
'views/SfWorkOrderBarcodes.xml',
@@ -23,6 +22,9 @@
'views/machine_monitor.xml',
],
'assets': {
},
'installable': True,
'application': True,
# 'auto_install': False,

View File

@@ -1,44 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
# ----------------------------------------------------------
# Models for Simulation
# ----------------------------------------------------------
class Simulation(models.Model):
_name = 'simulation'
_description = 'SIMULATION'
name = fields.Char('Name', size=50, readonly=True)
place_value = fields.Boolean(String="位值")
place_value_random = fields.Boolean(String="位值随机")
place_value_ai = fields.Boolean(String="位值自增")
place_value_list = fields.Boolean(String="位值列表")
unsigned_integer_8_DO = fields.Integer(Sting="无符号8位整数D0")
unsigned_integer_8_D1 = fields.Integer(Sting="无符号8位整数D1")
unsigned_integer_8_random = fields.Integer(Sting="无符号8位整数随机")
unsigned_integer_8_ai = fields.Integer(Sting="无符号8位整数自增")
unsigned_integer_8_list = fields.Integer(Sting="无符号8位整数列表")
integer_8 = fields.Integer(String="有符号8位整数")
integer_8_random = fields.Integer(String="有符号8位整数随机")
integer_8_ai = fields.Integer(String="有符号8位整数自增")
integer_8_ad = fields.Integer(String="有符号8位整数自减")
integer_16 = fields.Integer(String="有符号16位整数")
integer_16_random = fields.Integer(String="有符号16位整数随机")
integer_16_list = fields.Integer(String="有符号16位整数列表")
# ----------------------------------------------------------
# Models for Mitsubishi
# ----------------------------------------------------------
class MitsuCnc(models.Model):
_name = 'mitsu.cnc'
_description = 'Mitsubishi CNC'
name = fields.Char('Name', size=50, readonly=True)
status = fields.Boolean(string="状态")

View File

@@ -1,22 +1,21 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import psycopg2
import os
import logging
from zeep.exceptions import ValidationError
from odoo import http
from ftplib import FTP
from odoo.http import request
from odoo import api, fields, models
import json
import hashlib
import time
import requests
from datetime import datetime
from odoo import fields, models, api, _
from odoo.exceptions import ValidationError
from odoo.exceptions import UserError
from odoo.addons.sf_machine_connect.models import py2opcua, ftp_operate
# from .ftp_operate import FtpController
# from .py2opcua import Py2opcua
_logger = logging.getLogger(__name__)
# ----------------------------------------------------------
# Models for client
# ----------------------------------------------------------
@@ -24,8 +23,13 @@ _logger = logging.getLogger(__name__)
class FtpButton(models.Model):
_inherit = 'sf.cnc.processing'
button_state = fields.Boolean(string='是否已经下发')
def pri(self):
print('11111111111111111')
"""
一个测试函数用于检测能否从”获取cnc程序“处获得NC代码文件
:return:
"""
s = self.cnc_id
s1 = self.cnc_id._filestore()
print(s1)
@@ -36,72 +40,115 @@ class FtpButton(models.Model):
ftp_operate.FtpController.prin(self)
def up(self):
# self.env['mrp.workorder'].check_compensation_before_up()
ftp = ftp_operate.FtpController()
# ftp.delAllfile('C://Users//马广威//Desktop//ftp')
a = self.cnc_id
print(a.display_name)
_logger.info(a.display_name)
datas = base64.standard_b64decode(a.datas)
# file_path = '{}\{}\{}'.format(a._filestore(), a.store_fname.split('/'[0]), a.display_name)
"""
此函数用于将NC代码下发到机床
:return:
"""
# 点击下发按钮自动补偿三元检测偏差值
# 此方法不走ftp直接文件写入暂不确定能否写入ftp服务器但可以转成ftp方法只是要把文件暂存到本地再上传
# file_path_local = '{}\{}'.format('C://Users//马广威//Desktop//ftp', a.display_name)
file_path_local = '{}/{}'.format('/nc2machine', a.display_name)
file_path_remote = '{}\{}'.format('//(192,168,2,141)//DS', a.display_name)
try:
try:
if self.sequence_number == '1':
self.check_compensation_before_up()
except Exception:
raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
ftp = ftp_operate.FtpController()
# ftp.delAllfile('C://Users//马广威//Desktop//ftp')
a = self.cnc_id
_logger.info(a.public)
_logger.info(a.display_name)
datas = base64.standard_b64decode(a.datas)
with open(file_path_local, mode='wb+') as file:
file.write(datas)
# file_path = '{}\{}\{}'.format(a._filestore(), a.store_fname.split('/'[0]), a.display_name)
file_path_local = '{}/{}'.format('/nc2machine', a.display_name)
file_path_remote = '{}\{}'.format('//(192,168,2,141)//DS', a.display_name)
# file = open(file_path_local, 'wb+')
# file.write(datas)
# file.close()
with open(file_path_local, mode='wb+') as file:
file.write(datas)
# 存在本地的文件下发到机床
ftp.upload_file(remotepath=file_path_remote, localpath=file_path_local)
except Exception as e:
_logger.info("=====================================", e)
raise UserError('NC下发执行超时, 请检查下发状态')
# 存在本地的文件下发到机床
ftp.upload_file(remotepath=file_path_remote, localpath=file_path_local)
# 补偿下发都执行完毕后按钮标志位变为true
self.button_state = True
# 新增,下发完成返回当前工单位置
# return {
# 'name': _("工单"),
# 'view_mode': 'form',
# 'res_model': 'mrp.workorder',
# 'res_id': self.workorder_id,
# 'type': 'ir.actions.act_window',
# 'target': 'new'
# }
class FtpClient(models.Model):
_name = "ftp.client"
_description = 'Ftp Client'
name = fields.Char('Name', size=50, readonly=True)
description = fields.Char(size=50)
mobile = fields.Char(size=50)
def up(self):
ftp = ftp_operate.FtpController()
# FtpController.__init__(self, host="127.0.0.1", port=2121, username="admin", password="123456")
ftp.upload_file(remotepath='/(192,168,199,2)/DS/02-222.NC', localpath='D:/ftp/up/02-222.NC')
# def delete(self):
# ftp = FtpController()
# ftp.del_file()
#
# def _compute_ip_url(self):
# for box in self:
# if not box.ip:
# box.ip_url = False
# else:
# url = 'https://%s' if box.get_base_url()[:5] == 'https' else 'http://%s:8069'
# box.ip_url = url % box.ip
#
# def _compute_device_count(self):
# for box in self:
# box.device_count = len(box.device_ids)
def check_compensation_before_up(self):
"""
下发NC代码前自动补偿三元检测偏差值
:return:
"""
try:
temp_dict = {}
temp_dict[
'ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang550'] = self.workorder_id.compensation_value_x
temp_dict[
'ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang551'] = self.workorder_id.compensation_value_y
temp = py2opcua.Py2opcua()
# temp.connect()
temp.write(temp_dict)
# temp.disconnect()
except Exception as e:
_logger.info("=====================================", e)
raise UserError('补偿值获取失败,或机床未连接,请检查')
class Machine_ftp(models.Model):
# _name = 'data.collection'
"""
数据采集类
"""
_inherit = 'sf.machine_tool'
timestamp = fields.Datetime('时间戳', readonly=True)
signed = fields.Integer('刷新间隔', readonly=True)
status = fields.Boolean('在线状态', readonly=True)
time_on = fields.Char('总在线时长', readonly=True)
time_on_now = fields.Char('本次在线时长', readonly=True)
tool_num = fields.Integer('当前刀具', readonly=True)
program = fields.Char('当前程序', readonly=True)
run_status = fields.Selection([('0', '空闲中'), ('1', '加工中'), ('2', '加工中'), ('3', '等待中')], string='运行状态',
readonly=True, default='0')
run_time = fields.Char('总运行时长', readonly=True)
cut_time = fields.Char('总切削时长', readonly=True)
cut_status = fields.Selection([('0', '未切削'), ('1', '切削中'), ('2', '切削中'), ('3', '切削中')], string='切削状态',
readonly=True, default='0')
tool_num_process_time1 = fields.Char('刀位1', readonly=True, default='0')
tool_num_process_time2 = fields.Char('刀位2', readonly=True, default='0')
tool_num_process_time3 = fields.Char('刀位3', readonly=True, default='0')
tool_num_process_time4 = fields.Char('刀位4', readonly=True, default='0')
tool_num_process_time5 = fields.Char('刀位5', readonly=True, default='0')
tool_num_process_time6 = fields.Char('刀位6', readonly=True, default='0')
tool_num_process_time7 = fields.Char('刀位7', readonly=True, default='0')
tool_num_process_time8 = fields.Char('刀位8', readonly=True, default='0')
tool_num_process_time9 = fields.Char('刀位9', readonly=True, default='0')
tool_num_process_time10 = fields.Char('刀位10', readonly=True, default='0')
tool_num_process_time11 = fields.Char('刀位11', readonly=True, default='0')
tool_num_process_time12 = fields.Char('刀位12', readonly=True, default='0')
tool_num_process_time13 = fields.Char('刀位13', readonly=True, default='0')
tool_num_process_time14 = fields.Char('刀位14', readonly=True, default='0')
tool_num_process_time15 = fields.Char('刀位15', readonly=True, default='0')
tool_num_process_time16 = fields.Char('刀位16', readonly=True, default='0')
tool_num_process_time17 = fields.Char('刀位17', readonly=True, default='0')
tool_num_process_time18 = fields.Char('刀位18', readonly=True, default='0')
tool_num_process_time19 = fields.Char('刀位19', readonly=True, default='0')
tool_num_process_time20 = fields.Char('刀位20', readonly=True, default='0')
tool_num_process_time21 = fields.Char('刀位21', readonly=True, default='0')
tool_num_process_time22 = fields.Char('刀位22', readonly=True, default='0')
tool_num_process_time23 = fields.Char('刀位23', readonly=True, default='0')
tool_num_process_time24 = fields.Char('刀位24', readonly=True, default='0')
class WorkCenterBarcode(models.Model):
@@ -109,45 +156,56 @@ class WorkCenterBarcode(models.Model):
扫码托盘码可查到制造订单,由制造订单查工单
"""
_inherit = "mrp.workorder"
compensation_value_x = fields.Float(string='X轴补偿值')
compensation_value_y = fields.Float(string='Y轴补偿值')
button_compensation_state = fields.Boolean(string='是否已经补偿')
def compensation(self):
'''
"""
将节点与其值放入字典,字典作为参数传入
:return:
'''
temp_dict = {}
temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang520'] = self.compensation_value_x
temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang521'] = self.compensation_value_y
print("测试补偿能够执行")
temp = py2opcua.Py2opcua()
_logger.info(temp)
temp.connect()
temp.write(temp_dict)
temp.disconnect()
def check_compensation_before_up(self):
temp_value = self.env['mrp.workorder'].getcenter()
_logger.info("====================================================================================")
_logger.info(temp_value)
if temp_value[0] == 0 or temp_value[1] != 0:
"""
try:
temp_dict = {}
# temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang520'] = temp_value[0]
temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang520'] = 111
temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang521'] = 111
# temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang521'] = temp_value[1]
print("测试补偿能够执行")
temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang550'] = self.compensation_value_x
temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang551'] = self.compensation_value_y
temp = py2opcua.Py2opcua()
_logger.info(temp)
temp.connect()
# temp.connect()
temp.write(temp_dict)
temp.disconnect()
self.button_compensation_state = True
# temp.disconnect()
except Exception as e:
_logger.info("=====================================", e)
raise UserError('补偿值获取失败,或机床未连接,请检查')
def get__state(self):
pay_time = str(datetime.now())
json = {
'params': {
'model_name': 'jikimo.process.order',
'field_name': 'name',
'default_code': 'PO-2022-1207-0020',
'state': '待付款',
# 'pay_time': pay_time,
# 'get_order_sf': 21,
},
}
# res_str = json.dumps(vals)
url = 'https://bfm.cs.jikimo.com/api/get/state'
requests.post(url, json=json, data=None)
def process_control(self):
def test(self, barcode):
# 托盘对象
tray = self.env('sf.tray').search("code", "=", barcode)
product = tray.product_id
if self.routing_type == '获取CNC加工程序' and self.state == '进行中':
json = {
'params': {
'model_name': 'jikimo.process.order',
'field_name': 'name',
'default_code': 'PO-2022-1123-0014',
'state': '加工中',
},
}
url = 'https://bfm.cs.jikimo.com/api/get/state'
requests.post(url, json=json, data=None)

View File

@@ -2,13 +2,18 @@
import os
from ftplib import FTP
class FTP_P(FTP):
"""
重写FTP类重写dirs方法
"""
def dirs(self, *args):
'''List a directory in long form.
"""List a directory in long form.
By default list current directory to stdout.
Optional last argument is callback function; all
non-empty arguments before it are concatenated to the
LIST command. (This *should* only be used for a pathname.)'''
LIST command. (This *should* only be used for a pathname.)"""
cmd = 'LIST'
templist = []
tempdic = {}
@@ -19,7 +24,6 @@ class FTP_P(FTP):
if arg:
cmd = cmd + (' ' + arg)
self.retrlines(cmd, templist.append)
# print(templist)
# 处理返回结果,只需要目录名称
r_files = [file.split(" ")[-1] for file in templist]
tempdic['name'] = [file for file in r_files if file != "." and file != ".."]
@@ -27,13 +31,14 @@ class FTP_P(FTP):
return tempdic
# return [file for file in r_files if file != "." and file != ".."]
# FTP接口类
class FtpController():
'''
# FTP接口类
class FtpController:
"""
这是ftp接口类在类初始化的时候就连接了ftp服务器能否成功连接有反馈。
类中定义了两个接口:上传接口和删除接口
'''
"""
# 三菱机床连接
def __init__(self, host="192.168.2.158", port=8080, username="MITSUBISHI", password="CNC"):
self.host = host
@@ -42,47 +47,41 @@ class FtpController():
self.password = password
ftp = FTP_P()
# self.ftp.set_debuglevel(2) #打开调试级别2显示详细信息
ftp.set_pasv(0) #0主动模式 1 #被动模式
ftp.set_pasv(0) # 0主动模式 1 #被动模式
try:
ftp.connect(self.host, self.port)
ftp.login(self.username, self.password)
print("连接成功")
self.ftp = ftp
except:
print("连接失败")
except Exception as e:
print("连接失败" + str(e))
# 试验接口
def prin(self):
print("这是试验接口")
# 试验ftp服务器连接
# def connect(self, host="127.0.0.1", port=2121, username="admin", password="123456"):
# ftp = FTP_P()
# try:
# ftp.connect(host, port)
# ftp.login(username, password)
# print("连接成功")
# ftp1 = ftp
# return ftp1
# except:
# print("连接失败")
# 三菱代码下发
def upload_file(self, remotepath='/(192,168,199,2)/DS/Z4.5.NC', localpath='D:/ftp/up/Z4.5.NC'):
'''
"""
第一个是要上传到ftp服务器路径下的文件第二个是本地要上传的的路径文件
:param remotepath: 上传和下载都需要设置工作目录,注意只能使用文件名,不能有路径中的冒号
:param localpath:
:return:
'''
"""
bufsize = 1024
fp = open(localpath, 'rb')
self.ftp.storbinary('STOR ' + remotepath, fp, bufsize)
fp.close()
# return "上传成功"
# fp = open(localpath, 'rb')
# self.ftp.storbinary('STOR ' + remotepath, fp, bufsize)
# fp.close()
with open(localpath, mode='rb') as file:
self.ftp.storbinary('STOR ' + remotepath, file, bufsize)
def delAllfile(self, ftppath):
"""
删除ftp服务器端全部文件
:param ftppath:
:return:
"""
dir_res = []
try:
print(ftppath)
@@ -106,13 +105,13 @@ class FtpController():
# print("删除FTP目录" + ftppath + "下存在文件:" + f)
# ftp.delete(f)
except Exception as e:
raise e
print("删除失败" + str(e))
# 删除远端ftp文件
# 出现550 not found file是路径不对
# def del_file(self, delpath='./YIN.NC'):
def del_file(self, delpath='/(192,168,199,2)/DS/Z4.5.NC'):
self.ftp.delete(delpath) # 删除远程文件
"""
删除ftp服务器端指定文件
:param delpath:
:return:
"""
self.ftp.delete(delpath)

View File

@@ -2,22 +2,35 @@ from opcua import ua, Client
class Py2opcua:
"""
将三元检测补偿值写入opcua服务器
"""
def __init__(self, url='opc.tcp://192.168.2.99:4840'):
self.client = Client(url)
def connect(self):
try:
# 连接客户端
self.client.connect()
print("opcua服务器连接成功可以写入")
return self.client
except:
print("opcua服务器连接失败请检查")
# 连接客户端
# def connect(self):
# try:
# self.client.connect()
# print("opcua服务器连接成功可以写入")
# return self.client
# except Exception as e:
# print("opcua服务器连接失败请检查" + str(e))
def write(self, temp_dict):
temp_dict = temp_dict
"""
补偿值写入方法,参数是一个字典,键是节点名,值是补偿值
:param temp_dict:
:return:
"""
# try:
self.client.connect()
# print("opcua服务器连接成功可以写入")
# return self.client
# except Exception as e:
# print("opcua服务器连接失败请检查" + str(e))
# temp_dict = temp_dict
temp_list = list(temp_dict.items())
for i in range(len(temp_list)):
# 寻找节点上的变量
@@ -25,8 +38,9 @@ class Py2opcua:
# var.set_value(ua.Variant(1.234, ua.VariantType.Float))
# 通过set_value写值
var.set_value(ua.Variant(temp_list[i][1], ua.VariantType.Double))
print("%s 已写入" % var.get_value())
def disconnect(self):
# 断开连接
# print("%s 已写入" % var.get_value())
self.client.disconnect()
# 断开连接
# def disconnect(self):
# self.client.disconnect()

View File

@@ -0,0 +1,13 @@
.o_form_view:not(.o_field_highlight) {
.o_field_many2one_selection {
.o_external_button, .o_dropdown_button {
visibility: hidden;
}
&:hover, &:focus-within {
.o_external_button, .o_dropdown_button {
visibility: visible;
}
}
}
}

View File

@@ -0,0 +1,82 @@
/** @odoo-module **/
import { browser } from "@web/core/browser/browser";
import { Dialog } from "@web/core/dialog/dialog";
import { _lt } from "@web/core/l10n/translation";
import { useChildRef, useOwnedDialogs, useService } from "@web/core/utils/hooks";
import { sprintf } from "@web/core/utils/strings";
import { isMobileOS } from "@web/core/browser/feature_detection";
import * as BarcodeScanner from "@web/webclient/barcode/barcode_scanner";
const {xml, Component} = owl;
import { standardFieldProps } from "@web/views/fields/standard_field_props";
// Import the registry
import {registry} from "@web/core/registry";
export class CodeField extends Component {
setup() {
super.setup();
}
async onBarcodeBtnClick() {
const barcode = await BarcodeScanner.scanBarcode();
if (barcode) {
await this.onBarcodeScanned(barcode);
if ("vibrate" in browser.navigator) {
browser.navigator.vibrate(100);
}
} else {
this.notification.add(this.env._t("Please, scan again !"), {
type: "warning",
});
}
}
async search(barcode) {
const results = await this.orm.call("sf.tray", "name_search", [code], {
name: barcode,
args: this.getDomain(),
operator: "ilike",
limit: 2, // If one result we set directly and if more than one we use normal flow so no need to search more
context: this.context,
});
return results.map((result) => {
const [id, displayName] = result;
return {
id,
name: displayName,
};
});
}
async onBarcodeScanned(barcode) {
const results = await this.search(barcode);
const records = results.filter((r) => !!r.id);
if (records.length === 1) {
this.update([{ id: records[0].id, name: records[0].name }]);
} else {
const searchInput = this.autocompleteContainerRef.el.querySelector("input");
searchInput.value = barcode;
searchInput.dispatchEvent(new Event("input"));
if (this.env.isSmall) {
searchInput.click();
}
}
}
}
CodeField.template = xml`
<button
t-on-click="onBarcodeBtnClick"
type="button"
class="btn ms-3 o_barcode"
tabindex="-1"
draggable="false"
aria-label="Scan barcode"
title="Scan barcode"
data-tooltip="Scan barcode"
/>
`;
// CodeField.template = 'sf_machine_connect.CodeField';
CodeField.props = standardFieldProps;
// Add the field to the correct category
registry.category("fields").add("code", CodeField);

View File

@@ -1,17 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="web.Many2OneField" owl="1">
<button
t-on-click="onBarcodeBtnClick"
type="button"
class="btn ms-3 o_barcode"
tabindex="-1"
draggable="false"
aria-label="Scan barcode"
title="Scan barcode"
data-tooltip="Scan barcode"
/>
</t>
<t t-name="sf_machine_connect.CodeField" owl="1">
<div class="o_field_many2one_selection">
<button
t-on-click="onBarcodeBtnClick"
type="button"
class="btn ms-3 o_barcode"
tabindex="-1"
draggable="false"
aria-label="Scan barcode"
title="Scan barcode"
data-tooltip="Scan barcode"
/>
</div>
</t>
</templates>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<odoo>
<record id="view_order_form_scan_barcode" model="ir.ui.view">
<field name="name">sale.order.form.scan.barcode</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="partner_id" position="after">
<!-- invisible="1" -->
<field name="_barcode_scanned" widget="barcode_handler"/>
</field>
</field>
</record>
</odoo>

View File

@@ -8,6 +8,7 @@
<xpath expr="//page//field[@name='tray_code']" position="before">
<!-- invisible="1" -->
<field name="_barcode_scanned" widget="barcode_handler"/>
<field name="tray_code" widget="code"/>
</xpath>
</field>

View File

@@ -11,12 +11,13 @@
<field name="compensation_value_y"/>
</group>
<div>
<field name="button_compensation_state"/>
<button string="一键补偿" name="compensation" type="object" confirm="是否确认下发补偿" class="btn-primary"/>
<!-- <button string="显示补偿" name="compensation1" type="object" confirm="是否确认下发补偿" class="btn-primary"/>-->
<!-- <button string="修改状态" name="get__state" type="object" class="btn-primary"/>-->
</div>
</xpath>
<!-- attrs='{"invisible": [("routing_type","!=","CNC加工")]}'-->
</field>
</record>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="flush">
&lt;!DOCTYPE html&gt;
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>World Map</title>
<script type="text/javascript">
$(function () {
setInterval(function () {
$("#map").load(location.href + " #map>*", "");//注意后面DIV的ID前面的空格跟 id 后的>*,很重要!
}, 1000);//8秒自动刷新
})
</script>
</head>
<body>
</body>
</html>
</template>
</odoo>

View File

@@ -9,8 +9,9 @@
<field name="inherit_id" ref="sf_manufacturing.view_mrp_production_workorder_tray_form_inherit_sf"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='remark']" position="after">
<button string="测试按钮" name="pri" type="object" class="btn-primary"/>
<button string="下发按钮" name="up" type="object" confirm="是否确认下发此程序" class="btn-primary"/>
<!-- <button string="测试按钮" name="pri" type="object" class="btn-primary"/>-->
<field name="button_state"/>
<button string="下发按钮" name="up" type="object" class="btn-primary" confirm="是否确认下发此程序"/>
</xpath>
</field>

View File

@@ -4,40 +4,99 @@
<field name="name">sf_base_extension</field>
<field name="model">sf.machine_tool</field>
<field name="inherit_id" ref="sf_base.sf_machine_tool_form"/>
<!-- <field name="inherit_id" ref="sf_base.form_mrs_machine_tool_type"/>-->
<field eval="20" name="priority"/>
<field name="arch" type="xml">
<!-- <xpath expr="//field[@name='knife_type']" position="before">-->
<xpath expr="//form//notebook//page[1]" position="inside">
<!-- <xpath expr="//page[@name='other']" position="before">-->
<!-- <page string="监控页面">-->
<group string="监控">
<field name="timestamp"/>
<field name="signed"/>
<field name="status"/>
<!-- <field name="tool_num"/>-->
<field name="time_on"/>
<field name="time_on_now"/>
<field name="run_status"/>
<field name="run_time"/>
<field name="cut_status"/>
<!-- <field name="cut_time"/>-->
<field name="program"/>
<field name="tool_num"/>
<!-- <div class="o_address_format">-->
<!-- <label for="tool_num_process_time1" string="刀位1"/>-->
<!-- <field name="tool_num_process_time1" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time2" string="刀位1"/>-->
<!-- <field name="tool_num_process_time2" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time3" string="刀位1"/>-->
<!-- <field name="tool_num_process_time3" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time4" string="刀位1"/>-->
<!-- <field name="tool_num_process_time4" class="o_form_label"/>-->
<!-- <div></div>-->
<!-- <label for="tool_num_process_time5" string="刀位1"/>-->
<!-- <field name="tool_num_process_time5" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time6" string="刀位1"/>-->
<!-- <field name="tool_num_process_time6" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time7" string="刀位1"/>-->
<!-- <field name="tool_num_process_time7" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time8" string="刀位1"/>-->
<!-- <field name="tool_num_process_time8" class="o_form_label"/>-->
<!-- <div></div>-->
<!-- <label for="tool_num_process_time9" string="刀位1"/>-->
<!-- <field name="tool_num_process_time9" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time10" string="刀位1"/>-->
<!-- <field name="tool_num_process_time10" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time11" string="刀位1"/>-->
<!-- <field name="tool_num_process_time11" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time12" string="刀位1"/>-->
<!-- <field name="tool_num_process_time12" class="o_form_label"/>-->
<!-- <div></div>-->
<!-- <label for="tool_num_process_time13" string="刀位1"/>-->
<!-- <field name="tool_num_process_time13" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time14" string="刀位1"/>-->
<!-- <field name="tool_num_process_time14" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time15" string="刀位1"/>-->
<!-- <field name="tool_num_process_time15" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time16" string="刀位1"/>-->
<!-- <field name="tool_num_process_time16" class="o_form_label"/>-->
<!-- <div></div>-->
<!-- <label for="tool_num_process_time17" string="刀位1"/>-->
<!-- <field name="tool_num_process_time17" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time18" string="刀位1"/>-->
<!-- <field name="tool_num_process_time18" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time19" string="刀位1"/>-->
<!-- <field name="tool_num_process_time19" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time20" string="刀位1"/>-->
<!-- <field name="tool_num_process_time20" class="o_form_label"/>-->
<!-- <div></div>-->
<!-- <label for="tool_num_process_time21" string="刀位1"/>-->
<!-- <field name="tool_num_process_time21" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time22" string="刀位1"/>-->
<!-- <field name="tool_num_process_time22" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time23" string="刀位1"/>-->
<!-- <field name="tool_num_process_time23" class="o_form_label"/>-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="tool_num_process_time24" string="刀位1"/>-->
<!-- <field name="tool_num_process_time24" class="o_form_label"/>-->
<!-- </div>-->
</group>
<!-- </page>-->
</xpath>
</field>
</record>
</odoo>
<!--&lt;!&ndash;继承了本模块的视图&ndash;&gt;-->
<!--<?xml version="1.0" encoding="utf-8"?>-->
<!--<odoo>-->
<!-- <record id="view_tree_mrs_machine_tool_inherited" model="ir.ui.view">-->
<!-- <field name="name">sf_base_extension</field>-->
<!-- <field name="model">ftp.client</field>-->
<!-- <field name="inherit_id" ref="ftp_form"/>-->
<!-- <field eval="20" name="priority"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//field[@name='name']" position="before">-->
<!-- <field name="count_books"/>-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<!--</odoo>-->

View File

@@ -1,25 +0,0 @@
<record id="view_purchase_order_barcode_inherit_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<form position="inside">
<field name="_barcode_scanned" widget="purchaseorder_barcode_handler"/>
</form>
<xpath expr="//field[@name='order_line']/tree" position="inside">
<field name="product_barcode" invisible="1"/>
</xpath>
<xpath expr="//field[@name='order_line']/kanban" position="inside">
<field name="product_barcode" invisible="1"/>
</xpath>
<xpath expr="//field[@name='order_line']//field[@name='product_qty']" position="attributes">
<attribute name="options">{'barcode_events': True}</attribute>
<attribute name="widget">field_float_scannable</attribute>
</xpath>
<xpath expr="//button[@name='button_confirm']" position="attributes">
<attribute name="barcode_trigger">validate</attribute>
</xpath>
</field>
</record>

View File

@@ -1,176 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Menus -->
<menuitem
id="ftp_menu_root"
name="sf2machine"
web_icon="iot,static/description/icon.png"
groups="base.group_system"
/>
IoT Boxes
<record model="ir.ui.view" id="data_list">
<field name="model">ftp.client</field>
<field name="arch" type="xml">
<!-- <div id="map">-->
<tree string="目标">
<field name="name"/>
<field name="mobile"/>
<field name="description"/>
</tree>
<!-- </div>-->
</field>
</record>
<record model="ir.ui.view" id="barcode_list">
<field name="model">mrp.production</field>
<field name="arch" type="xml">
<!-- <div id="map">-->
<tree string="目标">
<field name="_barcode_scanned" widget="barcode_handler"/>
<field name="aa"/>
</tree>
<!-- </div>-->
</field>
</record>
<record model="ir.ui.view" id="ftp_form">
<field name="model">ftp.client</field>
<field name="arch" type="xml">
<form string="数据采集">
<group string="基本信息">
<group>
<field name="name"/>
<field name="mobile"/>
<field name="description"/>
<field name="_barcode_scanned" widget="barcode_handler"/>
<!-- <button string="测试按钮" name="pri" type="object"/>-->
<button string="下发程序" name="up" type="object" data-hotkey="enter"/>
<button string="扫码" name="on_barcode_scanned" type="object"/>
<!-- <button string="删除程序" name="delete" type="object"/>-->
<templates xml:space="preserve">
<t t-name="web.Many2OneField" owl="1">
<button t-on-click="onBarcodeBtnClick"
type="button"
class="btn ms-3 o_barcode"
tabindex="-1"
draggable="false"
aria-label="Scan barcode"
title="Scan barcode"
data-tooltip="Scan barcode"
>saomiao</button>
</t>
</templates>
</group>
</group>
</form>
</field>
</record>
<record model="ir.ui.view" id="barcode_form">
<field name="model">mrp.production</field>
<field name="arch" type="xml">
<form string="扫码">
<group string="基本信息">
<field name="_barcode_scanned" widget="barcode_handler"/>
<field name="aa"/>
</group>
</form>
</field>
</record>
<record id="ftp_action" model="ir.actions.act_window">
<field name="name">数据采集</field>
<field name="res_model">ftp.client</field>
<field name="view_mode">list,form,kanban</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
这是我们的数据采集与程序管理页面!
</p>
</field>
</record>
<record id="barcode_action" model="ir.actions.act_window">
<field name="name">扫码</field>
<field name="res_model">mrp.production</field>
<field name="view_mode">list,form,kanban</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
这是我们的扫码页面!
</p>
</field>
</record>
<menuitem
id="ftp_data_menu_action"
name="数据采集"
action="ftp_action"
parent="ftp_menu_root"
sequence="1"/>
<menuitem
id="ftp_cnc_data_menu_action"
name="CNC"
action="ftp_action"
parent="ftp_data_menu_action"
sequence="1"/>
<!-- <menuitem-->
<!-- id="ftp_mit_cnc_data_menu_action"-->
<!-- name="三菱CNC"-->
<!-- action="ftp_action"-->
<!-- parent="ftp_cnc_data_menu_action"-->
<!-- sequence="1"/>-->
<!-- <menuitem-->
<!-- id="ftp_sim_cnc_data_menu_action"-->
<!-- name="西门子CNC"-->
<!-- action="ftp_action"-->
<!-- parent="ftp_cnc_data_menu_action"-->
<!-- sequence="1"/>-->
<!-- <menuitem-->
<!-- id="ftp_fan_cnc_data_menu_action"-->
<!-- name="发那科CNC"-->
<!-- action="ftp_action"-->
<!-- parent="ftp_cnc_data_menu_action"-->
<!-- sequence="1"/>-->
<menuitem
id="ftp_plc_data_menu_action"
name="PLC"
action="ftp_action"
parent="ftp_data_menu_action"
sequence="3"/>
<menuitem
id="ftp_instrument_data_menu_action"
name="仪器仪表"
action="ftp_action"
parent="ftp_data_menu_action"
sequence="9"/>
<menuitem
id="ftp_procedure_menu_action"
name="程序管理"
action="barcode_action"
parent="ftp_menu_root"
sequence="2"/>
<menuitem
id="ftp_up_menu_action"
name="本地代码"
action="ftp_action"
parent="ftp_procedure_menu_action"
sequence="2"/>
<menuitem
id="ftp_down_menu_action"
name="机床代码"
action="ftp_action"
parent="ftp_procedure_menu_action"
sequence="6"/>
</odoo>

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sale_order_form_inherit" model="ir.ui.view">
<field name="name">sale.order.form.inherit</field>
<field name="model">sf.machine_tool</field>
<field name="inherit_id" ref="sf_base.sf_machine_tool_form"/>
<field name="arch" type="xml">
<xpath expr="//form//notebook//page[1]" position="inside">
<group string="监控">
<field name="timestamp"/>
<field name="signed"/>
<field name="signed16"/>
<field name="pulse2"/>
<field name="tool_num"/>
<field name="program"/>
</group>
<!-- </page>-->
<div class="o_partner_order_summary" colspan="2"/>
</xpath>
<!-- <field name="payment_term_id" position="after">-->
<!-- <field name="create_date" widget="show_units" options="{'units':'UTC'}"/>-->
<!-- -->
<!-- </field>-->
</field>
</record>
</odoo>
<!--<?xml version="1.0" encoding="utf-8"?>-->
<!--<odoo>-->
<!-- <record id="sale_order_form_inherit" model="ir.ui.view">-->
<!-- <field name="name">sale.order.form.inherit</field>-->
<!-- <field name="model">sale.order</field>-->
<!-- <field name="inherit_id" ref="sale.view_order_form"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <field name="payment_term_id" position="after">-->
<!-- <field name="create_date" widget="show_units" options="{'units':'UTC'}"/>-->
<!-- <div class="o_partner_order_summary" colspan="2"/>-->
<!-- </field>-->
<!-- </field>-->
<!-- </record>-->
<!--</odoo>-->

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sf_install_the_tray_workorder_form_view_inherit" model="ir.ui.view">
<field name="name">sale.order.form.inherit</field>
<field name="model">mrp.workorder</field>
<field name="inherit_id" ref="sf_manufacturing.view_mrp_production_workorder_tray_form_inherit_sf"/>
<field name="arch" type="xml">
<field name="tray_code" position="before">
<!-- <field name="create_date" widget="show_units" options="{'units':'UTC'}"/>-->
<div class="o_partner_order_summary" colspan="2"/>
<!-- <field name="aa"/>-->
</field>
</field>
</record>
</odoo>

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="mrp_workcenter_view_kanban_inherit_workorder_inherit" model="ir.ui.view">
<field name="name">mrp.workcenter.view.kanban.inherit.mrpworkorder</field>
<field name="model">mrp.workcenter</field>
<!-- <field name="model">cnc.processing</field>-->
<field name="inherit_id" ref="mrp.mrp_workcenter_kanban"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_work_order']" position="after">
<!-- <field name="aaaa"/>-->
<button string="扫码查询" name="search_order" type="object" class="btn-primary"/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -47,6 +47,9 @@ class ResMrpWorkOrder(models.Model):
workorder.user_permissions = False
user_permissions = fields.Boolean('用户权限', compute='get_user_permissions')
programming_no = fields.Char('编程单号')
work_state = fields.Char('业务状态')
programming_state = fields.Char('编程状态')
cnc_worksheet = fields.Binary(
'工作指令', readonly=True)
material_center_point = fields.Char(string='胚料中心点')
@@ -85,8 +88,7 @@ class ResMrpWorkOrder(models.Model):
string="检测结果")
cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工")
tray_code = fields.Char(string="托盘")
programming_no = fields.Char('编程单号')
is_programming = fields.Boolean('是否编程', default=False)
# 计算配料中心点和与x轴倾斜度方法
def getcenter(self):
@@ -125,7 +127,11 @@ class ResMrpWorkOrder(models.Model):
print("(%.2f,%.2f)" % (x, y))
self.material_center_point = ("(%.2f,%.2f,%.2f)" % (x, y, z))
self.X_deviation_angle = jdz
return self.material_center_point
# 将补偿值写入CNC加工工单
workorder = self.env['mrp.workorder'].browse(self.ids)
work = workorder.production_id.workorder_ids
work.compensation_value_x = eval(self.material_center_point)[0]
work.compensation_value_y = eval(self.material_center_point)[1]
except:
raise UserError("参数计算有误")
@@ -138,6 +144,7 @@ class ResMrpWorkOrder(models.Model):
'name': route.route_workcenter_id.name,
'processing_panel': k,
'routing_type': route.routing_type,
'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起',
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids),
'date_planned_start': False,
'date_planned_finished': False,
@@ -362,6 +369,7 @@ class ResMrpWorkOrder(models.Model):
'name': route.route_workcenter_id.name,
'processing_panel': k,
'routing_type': route.routing_type,
'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起',
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids),
'date_planned_start': False,
'date_planned_finished': False,
@@ -440,27 +448,53 @@ class CNCprocessing(models.Model):
workorder_id = fields.Many2one('mrp.workorder', string="工单")
# mrs下发编程单创建CNC加工
def cnc_processing_create(self, obj):
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', obj['production_order_no']),
('processing_panel', '=', obj['processing_panel']),
('routing_type', '=', 'CNC加工')])
vals = {
'workorder_id': workorder.id,
'sequence_number': obj['sequence_number'],
'program_name': obj['program_name'],
'cutting_tool_name': obj['cutting_tool_name'],
'cutting_tool_no': obj['cutting_tool_no'],
'processing_type': obj['processing_type'],
'margin_x_y': obj['margin_x_y'],
'margin_z': obj['margin_z'],
'depth_of_processing_z': obj['depth_of_processing_z'],
'cutting_tool_extension_length': obj['cutting_tool_extension_length'],
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
'estimated_processing_time': obj['estimated_processing_time'],
'remark': obj['remark']
}
return self.env['sf.cnc.processing'].create(vals)
def cnc_processing_create(self, cnc_workorder, ret):
logging.info('ret:%s' % ret)
for obj in ret['programming_list']:
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']),
('processing_panel', '=', obj['processing_panel']),
('routing_type', '=', 'CNC加工')])
cnc_processing = self.env['sf.cnc.processing'].create({
'workorder_id': workorder.id,
'sequence_number': obj['sequence_number'],
'program_name': obj['program_name'],
'cutting_tool_name': obj['cutting_tool_name'],
'cutting_tool_no': obj['cutting_tool_no'],
'processing_type': obj['processing_type'],
'margin_x_y': obj['margin_x_y'],
'margin_z': obj['margin_z'],
'depth_of_processing_z': obj['depth_of_processing_z'],
'cutting_tool_extension_length': obj['cutting_tool_extension_length'],
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
'estimated_processing_time': obj['estimated_processing_time'],
'remark': obj['remark']
})
self.get_cnc_processing_file(ret['folder_name'], cnc_processing, workorder.processing_panel)
cnc_workorder.state = 'done'
cnc_workorder.work_state = '已编程'
cnc_workorder.programming_state = '已编程'
cnc_workorder.time_ids.date_end = datetime.now()
cnc_workorder.button_finish()
def get_cnc_processing_file(self, folder_name, cnc_processing, processing_panel):
logging.info('folder_name:%s' % folder_name)
serverdir = os.path.join('/tmp', folder_name, 'return', processing_panel)
logging.info('serverdir:%s' % serverdir)
for root, dirs, files in os.walk(serverdir):
for f in files:
logging.info('f:%s' % f)
if os.path.splitext(f)[1] == ".pdf":
full_path = os.path.join(serverdir, root, f)
logging.info('pdf:%s' % full_path)
if full_path != False:
if not cnc_processing.workorder_id.cnc_worksheet:
cnc_processing.workorder_id.cnc_worksheet = base64.b64encode(
open(full_path, 'rb').read())
else:
if cnc_processing.program_name == f.split('.')[0]:
cnc_file_path = os.path.join(serverdir, root, f)
logging.info('cnc_file_path:%s' % cnc_file_path)
self.write_file(cnc_file_path, cnc_processing)
# 创建附件(nc文件)
def attachment_create(self, name, data):
attachment = self.env['ir.attachment'].create({
@@ -472,12 +506,15 @@ class CNCprocessing(models.Model):
return attachment
# 将FTP的nc文件下载到临时目录
def download_file_tmp(self, model_code, processing_panel):
remotepath = os.path.join('/', model_code, 'return', processing_panel)
serverdir = os.path.join('/tmp', model_code, 'return', processing_panel)
ftp = FtpController()
ftp.download_file_tree(remotepath, serverdir)
return serverdir
def download_file_tmp(self, production_no, processing_panel):
remotepath = os.path.join('/', production_no, 'return', processing_panel)
serverdir = os.path.join('/tmp', production_no, 'return', processing_panel)
ftp_resconfig = self.env['res.config.settings'].get_values()
ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'],
ftp_resconfig['ftp_password'])
download_state = ftp.download_file_tree(remotepath, serverdir)
return download_state
# 将nc文件存到attach的datas里
def write_file(self, nc_file_path, cnc):

View File

@@ -95,11 +95,20 @@
<xpath expr="//page[last()]" position="after">
<page string="获取CNC加工程序" attrs='{"invisible": [("routing_type","!=","获取CNC加工程序")]}'>
<div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码"
attrs='{"invisible": ["|",("state","!=","progress"),("user_permissions","=",False)]}'/>
<group>
<field name="programming_no" readonly="1"
attrs='{"invisible": [("programming_no","=",False)]}'/>
<field name="programming_state" readonly="1"
attrs='{"invisible": [("programming_no","=",False)]}'/>
</group>
<group>
<div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码"
attrs='{"invisible": ["|", "|", ("state","!=","progress"),("user_permissions","=",False),("programming_no","!=",False)]}'/>
</div>
</group>
</page>
</xpath>

View File

@@ -44,7 +44,6 @@ class ReSaleOrder(models.Model):
product.model_machining_precision,
product.materials_id.name),
'price_unit': product.list_price,
'route_id': product.route_ids,
'product_uom_qty': item['number']
}
return self.env['sale.order.line'].create(vals)