Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化agv和ftp
This commit is contained in:
@@ -128,8 +128,7 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
|
||||
this.allColumns.forEach(_ => {
|
||||
if( tableRequiredList.indexOf(_.name) >= 0 ) {
|
||||
const dom = $(`th[data-name=${_.name}]`)
|
||||
let t = dom.html()
|
||||
dom.html('<i style="color: red;margin-left: -4px;position: absolute;left: 0">*</i>' + t)
|
||||
dom.addClass('addRequired')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -478,4 +478,14 @@ div:has(.o_required_modifier) > label::before {
|
||||
width: auto !important;
|
||||
flex: unset;
|
||||
}
|
||||
|
||||
.addRequired {
|
||||
padding-left: calc(0.3rem + 2px)!important;
|
||||
}
|
||||
.addRequired:before {
|
||||
content: '*';
|
||||
color: red;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
@@ -316,6 +316,7 @@ class ToolInventory(models.Model):
|
||||
|
||||
name = fields.Char('功能刀具名称', required=True)
|
||||
type = fields.Char('类型')
|
||||
functional_cutting_tool_model_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
|
||||
prefix = fields.Char('前缀')
|
||||
postfix = fields.Char('后缀')
|
||||
diameter = fields.Float('直径(mm)')
|
||||
@@ -326,5 +327,9 @@ class ToolInventory(models.Model):
|
||||
cutter_number = fields.Char('刀号')
|
||||
blade_number = fields.Integer('刃数(个)')
|
||||
extension = fields.Float('伸出长度(mm)')
|
||||
work_material = fields.Selection([('钢', '钢'), ('铝', '铝')], string='加工材料')
|
||||
life_span = fields.Float('寿命(h)')
|
||||
|
||||
tool_groups_id = fields.Many2one('sf.tool.groups', string='刀具组')
|
||||
|
||||
active = fields.Boolean('已归档', default=True)
|
||||
|
||||
@@ -556,19 +556,23 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="功能刀具清单" create="1" edit="1" delete="0" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="prefix"/>
|
||||
<field name="postfix"/>
|
||||
<field name="functional_cutting_tool_model_id"/>
|
||||
<field name="tool_groups_id"/>
|
||||
<field name="work_material"/>
|
||||
<field name="life_span"/>
|
||||
<field name="prefix" optional="hide"/>
|
||||
<field name="postfix" optional="hide"/>
|
||||
<field name="diameter"/>
|
||||
<field name="angle"/>
|
||||
<field name="tool_length"/>
|
||||
<field name="blade_length"/>
|
||||
<field name="knife_head_name"/>
|
||||
<field name="knife_head_name" optional="hide"/>
|
||||
<field name="cutter_number"/>
|
||||
<field name="blade_number"/>
|
||||
<field name="extension"/>
|
||||
<field name="create_uid" string="创建人" optional="hide"/>
|
||||
<field name="create_date" string="创建时间" optional="hide"/>
|
||||
<field name="type" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -579,7 +583,10 @@
|
||||
<field name="arch" type="xml">
|
||||
<search string="功能刀具清单">
|
||||
<field name="name" string="名称搜索" filter_domain="[('name','ilike',self)]"/>
|
||||
<field name="type"/>
|
||||
<field name="functional_cutting_tool_model_id"/>
|
||||
<field name="tool_groups_id"/>
|
||||
<field name="work_material"/>
|
||||
<field name="life_span"/>
|
||||
<field name="prefix"/>
|
||||
<field name="postfix"/>
|
||||
<field name="diameter"/>
|
||||
|
||||
@@ -8,6 +8,7 @@ from datetime import datetime, timedelta
|
||||
import requests
|
||||
import os
|
||||
import math
|
||||
from lxml import etree
|
||||
from dateutil.relativedelta import relativedelta
|
||||
# import subprocess
|
||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||
@@ -115,6 +116,19 @@ class ResMrpWorkOrder(models.Model):
|
||||
processing_user_id = fields.Many2one('res.users', string='加工人')
|
||||
# 检测人
|
||||
inspection_user_id = fields.Many2one('res.users', string='检测人')
|
||||
# 保存名称
|
||||
save_name = fields.Char(string='检测文件保存名称', compute='_compute_save_name')
|
||||
# 获取数据状态
|
||||
data_state = fields.Boolean(string='获取数据状态', default=False)
|
||||
|
||||
@api.depends('production_id')
|
||||
def _compute_save_name(self):
|
||||
"""
|
||||
保存名称
|
||||
"""
|
||||
for record in self:
|
||||
record.save_name = record.production_id.name.replace('/', '_')
|
||||
|
||||
schedule_state = fields.Selection(related='production_id.schedule_state', store=True)
|
||||
# 工件装夹信息
|
||||
functional_fixture_code = fields.Char(string="功能夹具编码", readonly=True)
|
||||
@@ -187,6 +201,149 @@ class ResMrpWorkOrder(models.Model):
|
||||
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_id)])
|
||||
return process_parameter_workorder
|
||||
|
||||
# 获取三次元检测点数据
|
||||
def get_three_check_datas(self):
|
||||
factory_nick_name = 'XT'
|
||||
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'])
|
||||
# ftp.connect()
|
||||
|
||||
local_dir_path = '/ftp/before'
|
||||
os.makedirs(local_dir_path, exist_ok=True)
|
||||
local_filename = self.save_name + '.xls'
|
||||
local_file_path = os.path.join(local_dir_path, local_filename)
|
||||
logging.info('local_file_path:%s' % local_file_path)
|
||||
remote_path = '/home/ftp/ftp_root/ThreeTest/XT/Before/' + local_filename
|
||||
logging.info('remote_path:%s' % remote_path)
|
||||
|
||||
if not ftp.file_exists(remote_path):
|
||||
raise UserError(f"文件不存在: {remote_path}")
|
||||
|
||||
with open(local_file_path, 'wb') as local_file:
|
||||
ftp.ftp.retrbinary('RETR ' + remote_path, local_file.write)
|
||||
logging.info('下载文件成功')
|
||||
# 解析本地文件
|
||||
# file_path = 'WH_MO_00099.xls' # 使用下载的实际文件路径
|
||||
parser = etree.XMLParser(recover=True) # Using recover to handle errors
|
||||
tree = etree.parse(local_file_path, parser)
|
||||
logging.info('tree:%s' % tree)
|
||||
root = tree.getroot()
|
||||
logging.info('root:%s' % root)
|
||||
|
||||
# 准备一个外部字典来存储以PT为键的坐标字典
|
||||
pt_coordinates = {}
|
||||
# 遍历每个工作表和行
|
||||
for worksheet in root.iterfind('.//{urn:schemas-microsoft-com:office:spreadsheet}Worksheet'):
|
||||
sheet_name = worksheet.attrib.get('{urn:schemas-microsoft-com:office:spreadsheet}Name')
|
||||
logging.info('sheet_name:%s' % sheet_name)
|
||||
if sheet_name == "Sheet1": # 确保我们只查看包含数据的工作表
|
||||
current_pt = None
|
||||
for row in worksheet.iterfind('.//{urn:schemas-microsoft-com:office:spreadsheet}Row'):
|
||||
cells = list(row.iterfind('.//{urn:schemas-microsoft-com:office:spreadsheet}Cell'))
|
||||
for i, cell in enumerate(cells):
|
||||
data_cell = cell.find('.//{urn:schemas-microsoft-com:office:spreadsheet}Data')
|
||||
if data_cell is not None and data_cell.text is not None: # 添加检查以确保data_cell.text不为空
|
||||
# 检查是否是PT标识
|
||||
logging.info(f"Data in cell: {data_cell.text}") # 输出单元格数据
|
||||
if "PT" in data_cell.text:
|
||||
current_pt = data_cell.text
|
||||
pt_coordinates[current_pt] = []
|
||||
elif data_cell.text in ["X", "Y", "Z"] and current_pt is not None:
|
||||
# 确保当前单元格后面还有单元格存在,以获取理论值
|
||||
if i + 1 < len(cells):
|
||||
next_cell = cells[i + 1]
|
||||
theory_value = next_cell.find(
|
||||
'.//{urn:schemas-microsoft-com:office:spreadsheet}Data')
|
||||
if theory_value is not None:
|
||||
# 为当前PT键添加坐标数据
|
||||
pt_coordinates[current_pt].append({
|
||||
data_cell.text: float(theory_value.text)
|
||||
})
|
||||
logging.info(f"PT: {current_pt} - {data_cell.text}: {theory_value.text}")
|
||||
logging.info('pt_coordinates=====%s' % pt_coordinates)
|
||||
# pt_coordinates:{'PT1': [{'X': 38.9221}, {'Y': -18.7304}, {'Z': 128.0783}],
|
||||
# 'PT2': [{'X': 39.2456}, {'Y': -76.9169}, {'Z': 123.7541}]}
|
||||
|
||||
# 检查是否存在PT1等键
|
||||
if 'PT1' in pt_coordinates and pt_coordinates['PT1']:
|
||||
self.X1_axis = pt_coordinates['PT3'][0]['X']
|
||||
self.Y1_axis = pt_coordinates['PT3'][1]['Y']
|
||||
self.Z1_axis = pt_coordinates['PT3'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT1点未测或数据错误')
|
||||
if 'PT2' in pt_coordinates and pt_coordinates['PT2']:
|
||||
self.X2_axis = pt_coordinates['PT4'][0]['X']
|
||||
self.Y2_axis = pt_coordinates['PT4'][1]['Y']
|
||||
self.Z2_axis = pt_coordinates['PT4'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT2点未测或数据错误')
|
||||
if 'PT3' in pt_coordinates and pt_coordinates['PT3']:
|
||||
self.X3_axis = pt_coordinates['PT5'][0]['X']
|
||||
self.Y3_axis = pt_coordinates['PT5'][1]['Y']
|
||||
self.Z3_axis = pt_coordinates['PT5'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT3点未测或数据错误')
|
||||
if 'PT4' in pt_coordinates and pt_coordinates['PT4']:
|
||||
self.X4_axis = pt_coordinates['PT6'][0]['X']
|
||||
self.Y4_axis = pt_coordinates['PT6'][1]['Y']
|
||||
self.Z4_axis = pt_coordinates['PT6'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT4点未测或数据错误')
|
||||
if 'PT5' in pt_coordinates and pt_coordinates['PT5']:
|
||||
self.X5_axis = pt_coordinates['PT7'][0]['X']
|
||||
self.Y5_axis = pt_coordinates['PT7'][1]['Y']
|
||||
self.Z5_axis = pt_coordinates['PT7'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT5点未测或数据错误')
|
||||
if 'PT6' in pt_coordinates and pt_coordinates['PT6']:
|
||||
self.X6_axis = pt_coordinates['PT8'][0]['X']
|
||||
self.Y6_axis = pt_coordinates['PT8'][1]['Y']
|
||||
self.Z6_axis = pt_coordinates['PT8'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT6点未测或数据错误')
|
||||
if 'PT7' in pt_coordinates and pt_coordinates['PT7']:
|
||||
self.X7_axis = pt_coordinates['PT9'][0]['X']
|
||||
self.Y7_axis = pt_coordinates['PT9'][1]['Y']
|
||||
self.Z7_axis = pt_coordinates['PT9'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT7点未测或数据错误')
|
||||
if 'PT8' in pt_coordinates and pt_coordinates['PT8']:
|
||||
self.X8_axis = pt_coordinates['PT10'][0]['X']
|
||||
self.Y8_axis = pt_coordinates['PT10'][1]['Y']
|
||||
self.Z8_axis = pt_coordinates['PT10'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT8点未测或数据错误')
|
||||
if 'PT9' in pt_coordinates and pt_coordinates['PT9']:
|
||||
self.X9_axis = pt_coordinates['PT1'][0]['X']
|
||||
self.Y9_axis = pt_coordinates['PT1'][1]['Y']
|
||||
self.Z9_axis = pt_coordinates['PT1'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT9点未测或数据错误')
|
||||
if 'PT10' in pt_coordinates and pt_coordinates['PT10']:
|
||||
self.X10_axis = pt_coordinates['PT2'][0]['X']
|
||||
self.Y10_axis = pt_coordinates['PT2'][1]['Y']
|
||||
self.Z10_axis = pt_coordinates['PT2'][2]['Z']
|
||||
else:
|
||||
raise UserError('PT10点未测或数据错误')
|
||||
|
||||
self.data_state = True
|
||||
|
||||
return True
|
||||
|
||||
# ftp.download_file('three_check_datas.xls', '/home/ftpuser/three_check_datas.xls')
|
||||
# ftp.close()
|
||||
# data = xlrd.open_workbook('/home/ftpuser/three_check_datas.xls')
|
||||
# table = data.sheets()[0]
|
||||
# nrows = table.nrows
|
||||
# # 点坐标列表
|
||||
# point_list = []
|
||||
# datas = []
|
||||
# for i in range(1, nrows):
|
||||
# datas.append(table.row_values(i))
|
||||
# return datas
|
||||
|
||||
# 计算配料中心点和与x轴倾斜度方法
|
||||
def getcenter(self):
|
||||
try:
|
||||
@@ -230,8 +387,9 @@ class ResMrpWorkOrder(models.Model):
|
||||
work.compensation_value_x = eval(self.material_center_point)[0]
|
||||
work.compensation_value_y = eval(self.material_center_point)[1]
|
||||
workorder.button_finish()
|
||||
except:
|
||||
raise UserError("参数计算有误")
|
||||
except Exception as e:
|
||||
# 重新抛出捕获到的异常信息
|
||||
raise UserError(str(e))
|
||||
|
||||
def button_workpiece_delivery(self):
|
||||
if self.routing_type == '装夹预调':
|
||||
|
||||
@@ -403,8 +403,11 @@
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<field name="data_state" invisible="1"/>
|
||||
<button type="object" class="oe_highlight" name="get_three_check_datas" string="获取数据"
|
||||
attrs='{"invisible": ["|", "|", "|", ("material_center_point","!=",False),("state","!=","progress"),("user_permissions","=",False), ("data_state", "=", True)]}'/>
|
||||
<button type="object" class="oe_highlight" name="getcenter" string="计算定位"
|
||||
attrs='{"invisible": ["|","|",("material_center_point","!=",False),("state","!=","progress"),("user_permissions","=",False)]}'/>
|
||||
attrs='{"invisible": ["|","|", "|",("material_center_point","!=",False),("state","!=","progress"),("user_permissions","=",False), ("data_state", "=", False)]}'/>
|
||||
</div>
|
||||
|
||||
<group>
|
||||
@@ -518,6 +521,7 @@
|
||||
<field name="is_ok"/>
|
||||
<field name="processing_user_id"/>
|
||||
<field name="inspection_user_id"/>
|
||||
<field name="save_name" widget="CopyClipboardChar"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -21,6 +21,16 @@ class FtpController():
|
||||
except Exception:
|
||||
logging.info("ftp连接失败")
|
||||
|
||||
def file_exists(self, path):
|
||||
# 检查文件是否存在于FTP服务器上
|
||||
try:
|
||||
self.ftp.cwd(os.path.dirname(path))
|
||||
files = self.ftp.nlst()
|
||||
return os.path.basename(path) in files
|
||||
except Exception as e:
|
||||
logging.error(f"Error checking file: {e}")
|
||||
return False
|
||||
|
||||
# 下载目录下的文件
|
||||
def download_file_tree(self, target_dir, serverdir):
|
||||
if not os.path.exists(serverdir):
|
||||
|
||||
@@ -52,8 +52,6 @@ class MrStaticResourceDataSync(models.Model):
|
||||
logging.info("夹具型号已每日同步成功")
|
||||
self.env['sf.fixture.materials.basic.parameters'].sync_fixture_materials_basic_parameters_yesterday()
|
||||
logging.info("夹具型号基本参数已每日同步成功")
|
||||
self.env['sf.functional.fixture.type'].sync_fixture_materials_basic_parameters_yesterday()
|
||||
logging.info("夹具型号基本参数已每日同步成功")
|
||||
self.env['sf.functional.fixture.type'].sync_functional_fixture_type_yesterday()
|
||||
logging.info("功能夹具类型已每日同步成功")
|
||||
self.env['sf.cutting.tool.material'].sync_cutting_tool_material_yesterday()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</field>
|
||||
<field name="email" position="replace">
|
||||
<field name="email"
|
||||
attrs="{'required' : [('customer_rank','>', 0)],'readonly': [('id','!=', False)]}"/>
|
||||
attrs="{'readonly': [('id','!=', False)]}"/>
|
||||
</field>
|
||||
<field name="mobile" position="attributes">
|
||||
<attribute name="attrs">{'required': [('phone', '=', False)],'readonly': [('id','!=', False)]}
|
||||
@@ -37,19 +37,19 @@
|
||||
</attribute>
|
||||
</field>
|
||||
<field name="street" position="attributes">
|
||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
||||
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||
</attribute>
|
||||
</field>
|
||||
<field name="street2" position="attributes">
|
||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
||||
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||
</attribute>
|
||||
</field>
|
||||
<field name="city" position="attributes">
|
||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
||||
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||
</attribute>
|
||||
</field>
|
||||
<field name="country_id" position="attributes">
|
||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
||||
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||
</attribute>
|
||||
</field>
|
||||
<xpath expr="//group[@name='sale']/field[@name='user_id']" position="replace">
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
'views/menu_view.xml',
|
||||
'views/tool_material_search.xml',
|
||||
'views/fixture_material_search_views.xml',
|
||||
'data/tool_data.xml',
|
||||
],
|
||||
'demo': [
|
||||
],
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- <record model="sf.machine.table.tool.changing.apply" id="sf_create_tool_change_application">-->
|
||||
|
||||
<!-- </record>-->
|
||||
</data>
|
||||
<record model="ir.cron" id="ir_cron_sf_tool_datasync">
|
||||
<field name="name">定时同步刀具物料、功能刀具信息到cloud</field>
|
||||
<field name="model_id" ref="model_sf_tool_datasync"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model._cron_tool_datasync_all()</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="numbercall">-1</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,9 +1,10 @@
|
||||
import json
|
||||
import base64
|
||||
import requests
|
||||
import logging
|
||||
from odoo import models, api
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
def get_suitable_machining_method_names(item):
|
||||
@@ -30,6 +31,30 @@ def get_suitable_coolant_names(item):
|
||||
return suitable_coolant_names
|
||||
|
||||
|
||||
class ToolDatasync(models.Model):
|
||||
_name = 'sf.tool.datasync'
|
||||
_description = '定时同步所有刀具'
|
||||
|
||||
def _cron_tool_datasync_all(self):
|
||||
try:
|
||||
self.env['stock.lot'].sudo().sync_enroll_tool_material_stock_all()
|
||||
logging.info("刀具物料序列号每日同步成功")
|
||||
self.env['sf.tool.material.search'].sudo().sync_enroll_tool_material_all()
|
||||
logging.info("刀具物料每日同步成功")
|
||||
self.env['sf.functional.cutting.tool.entity'].sudo().esync_enroll_functional_tool_entity_all()
|
||||
logging.info("功能刀具列表每日同步成功")
|
||||
self.env['sf.functional.tool.warning'].sudo().sync_enroll_functional_tool_warning_all()
|
||||
logging.info("功能刀具预警每日同步成功")
|
||||
self.env['stock.move.line'].sudo().sync_enroll_functional_tool_move_all()
|
||||
logging.info("功能刀具出入库记录每日同步成功")
|
||||
self.env[
|
||||
'sf.real.time.distribution.of.functional.tools'].sudo().sync_enroll_functional_tool_real_time_distribution_all()
|
||||
logging.info("功能刀具安全库存每日同步成功")
|
||||
except Exception as e:
|
||||
logging.info("捕获错误信息:%s" % e)
|
||||
raise ValidationError("数据错误导致同步失败,请联系管理员")
|
||||
|
||||
|
||||
class StockLot(models.Model):
|
||||
_inherit = 'stock.lot'
|
||||
_description = '刀具物料序列号注册'
|
||||
@@ -41,6 +66,18 @@ class StockLot(models.Model):
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
str_url = sf_sync_config['sf_url'] + "/api/tool_material_stock/create"
|
||||
objs_all = self.env['stock.lot'].search([('id', '=', self.id), ('active', 'in', [True, False])])
|
||||
self._get_sync_stock_lot(objs_all, str_url, token, headers)
|
||||
|
||||
def sync_enroll_tool_material_stock_all(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)
|
||||
str_url = sf_sync_config['sf_url'] + "/api/tool_material_stock/create"
|
||||
objs_all = self.env['stock.lot'].search([('rfid', '!=', False)])
|
||||
self._get_sync_stock_lot(objs_all, str_url, token, headers)
|
||||
|
||||
def _get_sync_stock_lot(self, objs_all, str_url, token, headers):
|
||||
tool_material_stock_list = []
|
||||
if objs_all:
|
||||
for item in objs_all:
|
||||
@@ -57,7 +94,7 @@ class StockLot(models.Model):
|
||||
if ret.get('code') == 200:
|
||||
return '刀具物料序列号注册成功'
|
||||
else:
|
||||
raise UserError("没有注册刀具物料序列号信息")
|
||||
logging.info("没有注册刀具物料序列号信息")
|
||||
|
||||
|
||||
class ToolMaterial(models.Model):
|
||||
@@ -73,6 +110,18 @@ class ToolMaterial(models.Model):
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.search([('id', '=', self.id)])
|
||||
self._get_sync_tool_material_search(objs_all, str_url, token, headers)
|
||||
|
||||
def sync_enroll_tool_material_all(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)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.search([])
|
||||
self._get_sync_tool_material_search(objs_all, str_url, token, headers)
|
||||
|
||||
def _get_sync_tool_material_search(self, objs_all, str_url, token, headers):
|
||||
tool_material_list = []
|
||||
if objs_all:
|
||||
for item in objs_all:
|
||||
@@ -95,7 +144,7 @@ class ToolMaterial(models.Model):
|
||||
if ret.get('code') == 200:
|
||||
return '刀具物料注册成功'
|
||||
else:
|
||||
raise UserError("没有注册刀具物料信息")
|
||||
logging.info('没有注册刀具物料信息')
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
@@ -120,6 +169,18 @@ class FunctionalCuttingToolEntity(models.Model):
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['sf.functional.cutting.tool.entity'].search([('id', '=', self.id)])
|
||||
self._get_sync_functional_cutting_tool_entity(objs_all, str_url, token, headers)
|
||||
|
||||
def esync_enroll_functional_tool_entity_all(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)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['sf.functional.cutting.tool.entity'].search([])
|
||||
self._get_sync_functional_cutting_tool_entity(objs_all, str_url, token, headers)
|
||||
|
||||
def _get_sync_functional_cutting_tool_entity(self, objs_all, str_url, token, headers):
|
||||
functional_tool_list = []
|
||||
if objs_all:
|
||||
for item in objs_all:
|
||||
@@ -170,7 +231,7 @@ class FunctionalCuttingToolEntity(models.Model):
|
||||
if ret.get('code') == 200:
|
||||
return "功能刀具注册成功"
|
||||
else:
|
||||
raise UserError("没有注册功能刀具信息")
|
||||
logging.info('没有注册功能刀具信息')
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
@@ -201,6 +262,18 @@ class FunctionalToolWarning(models.Model):
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['sf.functional.tool.warning'].search([('id', '=', self.id)])
|
||||
self.get_sync_functional_tool_warning(objs_all, str_url, token, headers)
|
||||
|
||||
def sync_enroll_functional_tool_warning_all(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)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['sf.functional.tool.warning'].search([])
|
||||
self.get_sync_functional_tool_warning(objs_all, str_url, token, headers)
|
||||
|
||||
def get_sync_functional_tool_warning(self, objs_all, str_url, token, headers):
|
||||
tool_warning_list = []
|
||||
if objs_all:
|
||||
for item in objs_all:
|
||||
@@ -237,7 +310,7 @@ class FunctionalToolWarning(models.Model):
|
||||
if ret.get('code') == 200:
|
||||
return "功能刀具预警注册成功"
|
||||
else:
|
||||
raise UserError("没有注册功能刀具预警信息")
|
||||
logging.info('没有注册功能刀具预警信息')
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
@@ -262,6 +335,18 @@ class StockMoveLine(models.Model):
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['stock.move.line'].search([('id', '=', self.id), ('functional_tool_name_id', '!=', False)])
|
||||
self.get_sync_stock_move_line(objs_all, str_url, token, headers)
|
||||
|
||||
def sync_enroll_functional_tool_move_all(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)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['stock.move.line'].search([('functional_tool_name_id', '!=', False)])
|
||||
self.get_sync_stock_move_line(objs_all, str_url, token, headers)
|
||||
|
||||
def get_sync_stock_move_line(self, objs_all, str_url, token, headers):
|
||||
tool_stock_list = []
|
||||
if objs_all:
|
||||
for item in objs_all:
|
||||
@@ -289,7 +374,7 @@ class StockMoveLine(models.Model):
|
||||
if ret.get('code') == 200:
|
||||
return "功能刀具出入库记录注册成功"
|
||||
else:
|
||||
raise UserError("没有注册功能刀具出入库记录信息")
|
||||
logging.info('没有注册功能刀具出入库记录信息')
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
@@ -314,6 +399,18 @@ class RealTimeDistributionFunctionalTools(models.Model):
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['sf.real.time.distribution.of.functional.tools'].search([('id', '=', self.id)])
|
||||
self.get_sync_real_time_distribution_functional_tools(objs_all, str_url, token, headers)
|
||||
|
||||
def sync_enroll_functional_tool_real_time_distribution_all(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)
|
||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||
objs_all = self.env['sf.real.time.distribution.of.functional.tools'].search([])
|
||||
self.get_sync_real_time_distribution_functional_tools(objs_all, str_url, token, headers)
|
||||
|
||||
def get_sync_real_time_distribution_functional_tools(self, objs_all, str_url, token, headers):
|
||||
tool_distribution_list = []
|
||||
if objs_all:
|
||||
for item in objs_all:
|
||||
@@ -353,7 +450,7 @@ class RealTimeDistributionFunctionalTools(models.Model):
|
||||
if ret.get('code') == 200:
|
||||
return "功能刀具出入库记录注册成功"
|
||||
else:
|
||||
raise UserError("没有注册功能刀具出入库记录信息")
|
||||
logging.info('没有注册功能刀具出入库记录信息')
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
|
||||
@@ -222,132 +222,147 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
||||
image = fields.Binary('图片')
|
||||
|
||||
# 功能刀具组装信息
|
||||
# 整体式刀具型号
|
||||
# ===============整体式刀具型号=================
|
||||
integral_freight_barcode = fields.Char('整体式刀具货位')
|
||||
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号',
|
||||
domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具'),
|
||||
('tool_material_status', '=', '可用')])
|
||||
integral_product_id = fields.Many2one('product.product', string='整体式刀具名称',
|
||||
compute='_compute_integral_product_id', store=True)
|
||||
cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号',
|
||||
related='integral_code_id.product_id.cutting_tool_model_id')
|
||||
integral_name = fields.Char('整体式刀具名称', related='integral_code_id.product_id.name')
|
||||
related='integral_product_id.cutting_tool_model_id')
|
||||
integral_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='整体式刀具规格',
|
||||
related='integral_code_id.product_id.specification_id')
|
||||
related='integral_product_id.specification_id')
|
||||
sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌',
|
||||
related='integral_code_id.product_id.brand_id')
|
||||
related='integral_product_id.brand_id')
|
||||
|
||||
# 刀片型号
|
||||
@api.depends('integral_freight_barcode')
|
||||
def _compute_integral_product_id(self):
|
||||
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.integral_freight_barcode)])
|
||||
if location:
|
||||
self.integral_product_id = location.product_id.id
|
||||
|
||||
# ===============刀片型号====================
|
||||
blade_freight_barcode = fields.Char('刀片货位')
|
||||
blade_code_id = fields.Many2one('stock.lot', '刀片序列号',
|
||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀片'),
|
||||
('tool_material_status', '=', '可用')])
|
||||
blade_product_id = fields.Many2one('product.product', string='刀片名称', compute='_compute_blade_product_id',
|
||||
store=True)
|
||||
cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号',
|
||||
related='blade_code_id.product_id.cutting_tool_model_id')
|
||||
blade_name = fields.Char('刀片名称', related='blade_code_id.product_id.name')
|
||||
related='blade_product_id.cutting_tool_model_id')
|
||||
blade_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀片规格',
|
||||
related='blade_code_id.product_id.specification_id')
|
||||
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_code_id.product_id.brand_id')
|
||||
related='blade_product_id.specification_id')
|
||||
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_product_id.brand_id')
|
||||
|
||||
# 刀杆型号
|
||||
@api.depends('blade_freight_barcode')
|
||||
def _compute_blade_product_id(self):
|
||||
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.blade_freight_barcode)])
|
||||
if location:
|
||||
self.blade_product_id = location.product_id.id
|
||||
|
||||
# ====================刀杆型号==================
|
||||
bar_freight_barcode = fields.Char('刀杆货位')
|
||||
bar_code_id = fields.Many2one('stock.lot', '刀杆序列号',
|
||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆'),
|
||||
('tool_material_status', '=', '可用')])
|
||||
bar_product_id = fields.Many2one('product.product', string='刀杆名称', compute='_compute_bar_product_id',
|
||||
store=True)
|
||||
cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号',
|
||||
related='bar_code_id.product_id.cutting_tool_model_id')
|
||||
bar_name = fields.Char('刀杆名称', related='bar_code_id.product_id.name')
|
||||
related='bar_product_id.cutting_tool_model_id')
|
||||
bar_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀杆规格',
|
||||
related='bar_code_id.product_id.specification_id')
|
||||
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_code_id.product_id.brand_id')
|
||||
related='bar_product_id.specification_id')
|
||||
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_product_id.brand_id')
|
||||
|
||||
# 刀盘型号
|
||||
@api.depends('bar_freight_barcode')
|
||||
def _compute_bar_product_id(self):
|
||||
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.bar_freight_barcode)])
|
||||
if location:
|
||||
self.bar_product_id = location.product_id.id
|
||||
|
||||
# ===============刀盘型号===================
|
||||
pad_freight_barcode = fields.Char('刀盘货位')
|
||||
pad_code_id = fields.Many2one('stock.lot', '刀盘序列号',
|
||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘'),
|
||||
('tool_material_status', '=', '可用')])
|
||||
pad_product_id = fields.Many2one('product.product', string='刀盘名称', compute='_compute_pad_product_id',
|
||||
store=True)
|
||||
cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号',
|
||||
related='pad_code_id.product_id.cutting_tool_model_id')
|
||||
pad_name = fields.Char('刀盘名称', related='pad_code_id.product_id.name')
|
||||
related='pad_product_id.cutting_tool_model_id')
|
||||
pad_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀盘规格',
|
||||
related='pad_code_id.product_id.specification_id')
|
||||
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_code_id.product_id.brand_id')
|
||||
related='pad_product_id.specification_id')
|
||||
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_product_id.brand_id')
|
||||
|
||||
# 刀柄型号
|
||||
@api.depends('pad_freight_barcode')
|
||||
def _compute_pad_product_id(self):
|
||||
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.pad_freight_barcode)])
|
||||
if location:
|
||||
self.pad_product_id = location.product_id.id
|
||||
|
||||
# ================刀柄型号===============
|
||||
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True,
|
||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'),
|
||||
('tool_material_status', '=', '可用')])
|
||||
handle_product_id = fields.Many2one('product.product', string='刀柄名称', related='handle_code_id.product_id')
|
||||
cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号',
|
||||
related='handle_code_id.product_id.cutting_tool_model_id')
|
||||
handle_name = fields.Char('刀柄名称', related='handle_code_id.product_id.name')
|
||||
handle_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀柄规格',
|
||||
related='handle_code_id.product_id.specification_id')
|
||||
sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', related='handle_code_id.product_id.brand_id')
|
||||
|
||||
# 夹头型号
|
||||
chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', required=True,
|
||||
# =================夹头型号==============
|
||||
chuck_freight_barcode = fields.Char('夹头货位', required=True)
|
||||
chuck_code_id = fields.Many2one('stock.lot', '夹头序列号',
|
||||
domain=[('product_id.cutting_tool_material_id.name', '=', '夹头'),
|
||||
('tool_material_status', '=', '可用')])
|
||||
chuck_product_id = fields.Many2one('product.product', string='夹头名称', compute='_compute_chuck_product_id',
|
||||
store=True)
|
||||
cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号',
|
||||
related='chuck_code_id.product_id.cutting_tool_model_id')
|
||||
chuck_name = fields.Char('夹头名称', related='chuck_code_id.product_id.name')
|
||||
related='chuck_product_id.cutting_tool_model_id')
|
||||
chuck_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='夹头规格',
|
||||
related='chuck_code_id.product_id.specification_id')
|
||||
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_code_id.product_id.brand_id')
|
||||
related='chuck_product_id.specification_id')
|
||||
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_product_id.brand_id')
|
||||
|
||||
@api.depends('chuck_freight_barcode')
|
||||
def _compute_chuck_product_id(self):
|
||||
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.chuck_freight_barcode)])
|
||||
if location:
|
||||
self.chuck_product_id = location.product_id.id
|
||||
|
||||
# ========================================
|
||||
|
||||
def on_barcode_scanned(self, barcode):
|
||||
"""
|
||||
智能工厂组装单处扫码绑定刀具物料')
|
||||
智能工厂组装单处扫码绑定刀具物料
|
||||
"""
|
||||
for record in self:
|
||||
if 'DJWL' in barcode:
|
||||
lot_ids = record.env['stock.lot'].sudo().search([('name', '=', barcode)])
|
||||
if not lot_ids:
|
||||
raise ValidationError('扫描的条形码数据不存在,请重新扫描!')
|
||||
for lot_id in lot_ids:
|
||||
if lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
|
||||
raise ValidationError('该刀具物料已使用,请重新扫描!!!')
|
||||
elif lot_id.quant_ids[-1].location_id.name not in '刀具房':
|
||||
raise ValidationError('该刀具物料未入库,请重新扫描!!!')
|
||||
tool_material_name = lot_id.product_id.cutting_tool_material_id.name
|
||||
if tool_material_name == '整体式刀具':
|
||||
record.integral_code_id = lot_id.id
|
||||
elif tool_material_name == '刀片':
|
||||
record.blade_code_id = lot_id.id
|
||||
elif tool_material_name == '刀杆':
|
||||
record.bar_code_id = lot_id.id
|
||||
elif tool_material_name == '刀盘':
|
||||
record.pad_code_id = lot_id.id
|
||||
elif tool_material_name == '刀柄':
|
||||
record.handle_code_id = lot_id.id
|
||||
record.chuck_code_id = record.get_chuck_code_id(lot_id).id or False
|
||||
elif tool_material_name == '夹头':
|
||||
record.chuck_code_id = lot_id.id
|
||||
else:
|
||||
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
|
||||
else:
|
||||
lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
|
||||
if not lot_ids:
|
||||
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
|
||||
lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
|
||||
if lot_ids:
|
||||
for lot_id in lot_ids:
|
||||
if lot_id.quant_ids[-1].location_id.name in '刀具房':
|
||||
record.handle_code_id = lot_id.id
|
||||
record.chuck_code_id = record.get_chuck_code_id(lot_id).id or False
|
||||
elif lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
|
||||
raise ValidationError('该刀柄已使用,请重新扫描!!!')
|
||||
else:
|
||||
raise ValidationError('该刀柄未入库,请重新扫描!!!')
|
||||
|
||||
def get_chuck_code_id(self, lot_id):
|
||||
# 适用夹头型号
|
||||
cutting_tool_chuck_id = lot_id.product_id.cutting_tool_chuck_id
|
||||
# 适用夹头尺寸
|
||||
fit_chuck_size = lot_id.product_id.cutting_tool_fit_chuck_size
|
||||
# 适用夹头产品
|
||||
chuck_product_id = self.env['product.product'].sudo().search(
|
||||
[('cutting_tool_model_id', '=', cutting_tool_chuck_id.id),
|
||||
('cutting_tool_er_size_model', '=', fit_chuck_size)])
|
||||
# 适用夹头产品序列号
|
||||
chuck_product_lot_ids = self.env['stock.lot'].sudo().search(
|
||||
[('product_id', '=', chuck_product_id.id), ('tool_material_status', '=', '可用')])
|
||||
for chuck_product_lot_id in chuck_product_lot_ids:
|
||||
if chuck_product_lot_id.quant_ids[-1].location_id.name in '刀具房':
|
||||
return chuck_product_lot_id
|
||||
return False
|
||||
else:
|
||||
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', barcode)])
|
||||
if location:
|
||||
material_name = location.product_id.cutting_tool_material_id.name
|
||||
if material_name == '整体式刀具':
|
||||
record.integral_freight_barcode = barcode
|
||||
elif material_name == '刀片':
|
||||
record.blade_freight_barcode = barcode
|
||||
elif material_name == '刀杆':
|
||||
record.bar_freight_barcode = barcode
|
||||
elif material_name == '刀盘':
|
||||
record.pad_freight_barcode = barcode
|
||||
elif material_name == '夹头':
|
||||
record.chuck_freight_barcode = barcode
|
||||
else:
|
||||
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
|
||||
else:
|
||||
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
|
||||
|
||||
@api.depends('handle_code_id')
|
||||
def _compute_rfid(self):
|
||||
@@ -437,7 +452,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
||||
else:
|
||||
obj.after_assembly_functional_tool_name = ''
|
||||
|
||||
@api.onchange('integral_code_id')
|
||||
@api.onchange('integral_freight_barcode')
|
||||
def _onchange_after_assembly_functional_tool_diameter(self):
|
||||
for obj in self:
|
||||
if obj.integral_code_id:
|
||||
@@ -573,12 +588,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
||||
'name': self.after_assembly_functional_tool_name,
|
||||
'rfid': self.rfid,
|
||||
'tool_groups_id': self.tool_groups_id.id,
|
||||
'integral_code_id': self.integral_code_id.id,
|
||||
'blade_code_id': self.blade_code_id.id,
|
||||
'bar_code_id': self.bar_code_id.id,
|
||||
'pad_code_id': self.pad_code_id.id,
|
||||
'integral_product_id': self.integral_product_id.id,
|
||||
'blade_product_id': self.blade_product_id.id,
|
||||
'bar_product_id': self.bar_product_id.id,
|
||||
'pad_product_id': self.pad_product_id.id,
|
||||
'handle_code_id': self.handle_code_id.id,
|
||||
'chuck_code_id': self.chuck_code_id.id,
|
||||
'chuck_product_id': self.chuck_product_id.id,
|
||||
|
||||
'after_assembly_functional_tool_name': self.after_assembly_functional_tool_name,
|
||||
'after_assembly_functional_tool_type_id': self.after_assembly_functional_tool_type_id.id,
|
||||
@@ -613,12 +628,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
||||
'tool_groups_id': self.tool_groups_id.id,
|
||||
'functional_tool_name_id': functional_tool_assembly_id.id,
|
||||
'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id,
|
||||
'cutting_tool_integral_model_id': self.integral_code_id.product_id.id,
|
||||
'cutting_tool_blade_model_id': self.blade_code_id.product_id.id,
|
||||
'cutting_tool_cutterbar_model_id': self.bar_code_id.product_id.id,
|
||||
'cutting_tool_cutterpad_model_id': self.pad_code_id.product_id.id,
|
||||
'cutting_tool_cutterhandle_model_id': self.handle_code_id.product_id.id,
|
||||
'cutting_tool_cutterhead_model_id': self.chuck_code_id.product_id.id,
|
||||
'cutting_tool_integral_model_id': self.integral_product_id.id,
|
||||
'cutting_tool_blade_model_id': self.blade_product_id.id,
|
||||
'cutting_tool_cutterbar_model_id': self.bar_product_id.id,
|
||||
'cutting_tool_cutterpad_model_id': self.pad_product_id.id,
|
||||
'cutting_tool_cutterhandle_model_id': self.handle_product_id.id,
|
||||
'cutting_tool_cutterhead_model_id': self.chuck_product_id.id,
|
||||
|
||||
'functional_tool_diameter': self.after_assembly_functional_tool_diameter,
|
||||
'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,
|
||||
|
||||
@@ -201,20 +201,18 @@
|
||||
<group string="组装物料信息" col="1">
|
||||
<field name="_barcode_scanned" widget="barcode_handler"/>
|
||||
<group col="1"
|
||||
attrs="{'invisible': ['|','|',('blade_code_id', '!=', False),('bar_code_id', '!=', False),('pad_code_id', '!=', False)]}">
|
||||
attrs="{'invisible': ['|','|',('blade_freight_barcode', '!=', False),('bar_freight_barcode', '!=', False),('pad_freight_barcode', '!=', False)]}">
|
||||
<div>
|
||||
<separator string="整体式刀具:" style="font-size: 13px;"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="integral_code_id" placeholder="请选择" string="序列号"
|
||||
class="custom_required"
|
||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
||||
<field name="integral_freight_barcode" string="货位"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="integral_name" string="名称"/>
|
||||
<field name="integral_product_id" string="名称"/>
|
||||
<field name="integral_specification_id" string="规格"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -223,20 +221,18 @@
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group col="1" attrs="{'invisible': [('integral_code_id', '!=', False)]}">
|
||||
<group col="1" attrs="{'invisible': [('integral_freight_barcode', '!=', False)]}">
|
||||
<div>
|
||||
<separator string="刀片:" style="font-size: 13px;"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="blade_code_id" placeholder="请选择" string="序列号"
|
||||
class="custom_required"
|
||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
||||
<field name="blade_freight_barcode" string="货位"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="blade_name" string="名称"/>
|
||||
<field name="blade_product_id" string="名称"/>
|
||||
<field name="blade_specification_id" string="规格"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -246,20 +242,18 @@
|
||||
</group>
|
||||
</group>
|
||||
<group col="1"
|
||||
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('pad_code_id', '!=', False)]}">
|
||||
attrs="{'invisible': ['|',('integral_freight_barcode', '!=', False),('pad_freight_barcode', '!=', False)]}">
|
||||
<div>
|
||||
<separator string="刀杆:" style="font-size: 13px;"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="bar_code_id" placeholder="请选择" string="序列号"
|
||||
class="custom_required"
|
||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
||||
<field name="bar_freight_barcode" string="货位"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="bar_name" string="名称"/>
|
||||
<field name="bar_product_id" string="名称"/>
|
||||
<field name="bar_specification_id" string="规格"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -269,20 +263,18 @@
|
||||
</group>
|
||||
</group>
|
||||
<group col="1"
|
||||
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('bar_code_id', '!=', False)]}">
|
||||
attrs="{'invisible': ['|',('bar_freight_barcode', '!=', False),('bar_freight_barcode', '!=', False)]}">
|
||||
<div>
|
||||
<separator string="刀盘:" style="font-size: 13px;"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="pad_code_id" placeholder="请选择" string="序列号"
|
||||
class="custom_required"
|
||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
||||
<field name="pad_freight_barcode" string="货位"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="pad_name" string="名称"/>
|
||||
<field name="pad_product_id" string="名称"/>
|
||||
<field name="pad_specification_id" string="规格"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -304,7 +296,7 @@
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="handle_name" string="名称"/>
|
||||
<field name="handle_product_id" string="名称"/>
|
||||
<field name="handle_specification_id" string="规格"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -319,14 +311,12 @@
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="chuck_code_id" string="序列号" placeholder="请选择"
|
||||
class="custom_required"
|
||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
||||
<field name="chuck_freight_barcode" string="货位"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="chuck_name" string="名称"/>
|
||||
<field name="chuck_product_id" string="名称"/>
|
||||
<field name="chuck_specification_id" string="规格"/>
|
||||
</group>
|
||||
<group>
|
||||
|
||||
@@ -21,7 +21,6 @@ class SfLocation(models.Model):
|
||||
name = fields.Char('Location Name', required=True, size=20)
|
||||
barcode = fields.Char('Barcode', copy=False, size=15)
|
||||
|
||||
|
||||
# 仓库类别(selection:库区、库位、货位)
|
||||
# location_type = fields.Selection([
|
||||
# ('库区', '库区'),
|
||||
@@ -127,7 +126,7 @@ class SfLocation(models.Model):
|
||||
for record in self:
|
||||
if record.product_sn_id:
|
||||
record.product_id = record.product_sn_id.product_id
|
||||
record.location_status = '占用'
|
||||
# record.location_status = '占用'
|
||||
else:
|
||||
record.product_id = False
|
||||
# record.location_status = '空闲'
|
||||
@@ -305,7 +304,7 @@ class SfShelf(models.Model):
|
||||
class ShelfLocation(models.Model):
|
||||
_name = 'sf.shelf.location'
|
||||
_description = '货位'
|
||||
_order = 'create_date desc'
|
||||
_order = 'id asc, create_date asc'
|
||||
|
||||
# current_location_id = fields.Many2one('sf.shelf.location', string='当前位置')
|
||||
# # 目的位置
|
||||
@@ -356,10 +355,20 @@ class ShelfLocation(models.Model):
|
||||
('空闲', '空闲'),
|
||||
('占用', '占用'),
|
||||
('禁用', '禁用')
|
||||
], string='货位状态', default='空闲', readonly=True)
|
||||
], string='货位状态', default='空闲', compute='_compute_product_num', store=True)
|
||||
# product_id = fields.Many2one('product.template', string='产品')
|
||||
product_id = fields.Many2one('product.product', string='产品', readonly=True)
|
||||
product_id = fields.Many2one('product.product', string='产品', compute='_compute_product_id', store=True)
|
||||
product_sn_id = fields.Many2one('stock.lot', string='产品序列号')
|
||||
# 产品数量
|
||||
product_num = fields.Integer('数量')
|
||||
|
||||
@api.depends('product_num')
|
||||
def _compute_product_num(self):
|
||||
for record in self:
|
||||
if record.product_num > 0:
|
||||
record.location_status = '占用'
|
||||
elif record.product_num == 0:
|
||||
record.location_status = '空闲'
|
||||
|
||||
# 修改货位状态为禁用
|
||||
def action_location_status_disable(self):
|
||||
@@ -376,12 +385,20 @@ class ShelfLocation(models.Model):
|
||||
"""
|
||||
for record in self:
|
||||
if record.product_sn_id:
|
||||
record.sudo().product_id = record.product_sn_id.product_id
|
||||
record.sudo().location_status = '占用'
|
||||
try:
|
||||
record.sudo().product_id = record.product_sn_id.product_id
|
||||
# record.sudo().location_status = '占用'
|
||||
record.sudo().product_num = 1
|
||||
except Exception as e:
|
||||
print('eeeeeee占用', e)
|
||||
|
||||
else:
|
||||
record.product_id = False
|
||||
# record.location_status = '空闲'
|
||||
try:
|
||||
record.sudo().product_id = False
|
||||
# record.sudo().location_status = '空闲'
|
||||
record.sudo().product_num = 0
|
||||
except Exception as e:
|
||||
print('eeeeeee空闲', e)
|
||||
|
||||
# 调取获取货位信息接口
|
||||
def get_sf_shelf_location_info(self):
|
||||
@@ -418,6 +435,8 @@ class Sf_stock_move_line(models.Model):
|
||||
location_dest_id_value = fields.Integer(compute='_compute_location_dest_id_value', store=True)
|
||||
# lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True)
|
||||
lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True)
|
||||
current_product_id = fields.Integer(compute='_compute_location_dest_id_value', store=True)
|
||||
there_is_no_sn = fields.Boolean('是否有序列号', default=False)
|
||||
|
||||
rfid = fields.Char('Rfid', readonly=True)
|
||||
|
||||
@@ -689,6 +708,7 @@ class Sf_stock_move_line(models.Model):
|
||||
def _compute_location_dest_id_value(self):
|
||||
for record in self:
|
||||
record.location_dest_id_value = record.location_dest_id.id if record.location_dest_id else False
|
||||
record.current_product_id = record.product_id.id if record.product_id else False
|
||||
|
||||
destination_location_id = fields.Many2one(
|
||||
'sf.shelf.location', string='目标货位')
|
||||
@@ -696,23 +716,31 @@ class Sf_stock_move_line(models.Model):
|
||||
@api.onchange('destination_location_id')
|
||||
def _compute_destination_location_id(self):
|
||||
for record in self:
|
||||
shelf_location_obj = self.env['sf.shelf.location'].search(
|
||||
[('product_sn_id', '=', record.lot_id.id)])
|
||||
if shelf_location_obj:
|
||||
shelf_location_obj.product_sn_id = False
|
||||
# obj = self.env['sf.shelf.location'].search([('location_id', '=',
|
||||
# self.destination_location_id.id)])
|
||||
obj = self.env['sf.shelf.location'].search([('name', '=',
|
||||
self.destination_location_id.name)])
|
||||
if obj:
|
||||
obj.product_sn_id = record.lot_id.id
|
||||
if record.lot_id:
|
||||
shelf_location_obj = self.env['sf.shelf.location'].search(
|
||||
[('product_sn_id', '=', record.lot_id.id)])
|
||||
if shelf_location_obj:
|
||||
shelf_location_obj.product_sn_id = False
|
||||
# obj = self.env['sf.shelf.location'].search([('location_id', '=',
|
||||
# self.destination_location_id.id)])
|
||||
obj = self.env['sf.shelf.location'].search([('name', '=',
|
||||
self.destination_location_id.name)])
|
||||
if obj:
|
||||
obj.product_sn_id = record.lot_id.id
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
obj = self.env['sf.shelf.location'].search([('name', '=',
|
||||
self.destination_location_id.name)])
|
||||
if obj:
|
||||
obj.product_sn_id = record.lot_id.id
|
||||
else:
|
||||
obj = self.env['sf.shelf.location'].search([('name', '=',
|
||||
self.destination_location_id.name)])
|
||||
if obj:
|
||||
obj.product_sn_id = record.lot_id.id
|
||||
obj.product_id = record.product_id.id
|
||||
# obj.location_status = '占用'
|
||||
obj.product_num += record.reserved_uom_qty
|
||||
|
||||
|
||||
class SfStockPicking(models.Model):
|
||||
@@ -737,8 +765,10 @@ class SfStockPicking(models.Model):
|
||||
for line in self.move_line_ids:
|
||||
if line:
|
||||
if line.current_location_id:
|
||||
line.current_location_id.product_sn_id = False
|
||||
line.current_location_id.location_status = '空闲'
|
||||
if line.current_location_id.product_sn_id:
|
||||
line.current_location_id.product_sn_id = False
|
||||
# line.current_location_id.location_status = '空闲'
|
||||
line.current_location_id.product_num = 0
|
||||
|
||||
for move in self.move_ids:
|
||||
if move and move.product_id.cutting_tool_material_id.name == '刀柄' or '托盘' in (
|
||||
@@ -750,19 +780,20 @@ class SfStockPicking(models.Model):
|
||||
self.env['stock.lot'].search([('name', '=', item.lot_name)]).write({'rfid': item.rfid})
|
||||
return res
|
||||
|
||||
# def print_all_barcode(self):
|
||||
# """
|
||||
# 打印所有编码
|
||||
# """
|
||||
# print('================')
|
||||
# for record in self.move_ids_without_package:
|
||||
# print('record', record)
|
||||
# print('record.move_line_ids', record.move_line_ids)
|
||||
#
|
||||
# # record.move_line_ids.print_qr_code()
|
||||
#
|
||||
# print('record.move_line_ids.lot_id', record.move_line_ids.lot_id)
|
||||
# print('record.move_line_ids.lot_id.name', record.move_line_ids.lot_id.name)
|
||||
|
||||
# def print_all_barcode(self):
|
||||
# """
|
||||
# 打印所有编码
|
||||
# """
|
||||
# print('================')
|
||||
# for record in self.move_ids_without_package:
|
||||
# print('record', record)
|
||||
# print('record.move_line_ids', record.move_line_ids)
|
||||
#
|
||||
# # record.move_line_ids.print_qr_code()
|
||||
#
|
||||
# print('record.move_line_ids.lot_id', record.move_line_ids.lot_id)
|
||||
# print('record.move_line_ids.lot_id.name', record.move_line_ids.lot_id.name)
|
||||
|
||||
|
||||
class SfProcurementGroup(models.Model):
|
||||
|
||||
@@ -10,10 +10,18 @@
|
||||
<field name="current_location_id" force_save="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='location_dest_id'][2]" position="after">
|
||||
<field name="destination_location_id" domain="[
|
||||
('location_id', '=', location_dest_id_value),
|
||||
('location_status', '=', '空闲')
|
||||
]"/>
|
||||
<field name="current_product_id" invisible="1"/>
|
||||
<field name="there_is_no_sn" invisible="1"/>
|
||||
<!-- <field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), -->
|
||||
<!-- '|', -->
|
||||
<!-- ('location_status', '=', '空闲'), -->
|
||||
<!-- ('location_status', '=', '占用'), ('product_id', '=', current_product_id) -->
|
||||
<!-- ]"/> -->
|
||||
<field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), '|',
|
||||
('location_status', '=', '空闲'), ('product_id', '=', current_product_id), ('product_sn_id',
|
||||
'=', there_is_no_sn)]"/>
|
||||
|
||||
|
||||
<!-- <field name="location_dest_id_product_type"/> -->
|
||||
<!-- <field name="location_dest_id"/> -->
|
||||
<field name="location_dest_id_value" invisible="1"/>
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
<field name="location_id"/>
|
||||
<field name="product_sn_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="product_num" readonly="1"/>
|
||||
<field name="location_status"/>
|
||||
<field name="storage_time" widget="datetime"/>
|
||||
<field name="production_id" readonly="1"/>
|
||||
|
||||
Reference in New Issue
Block a user