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(_ => {
|
this.allColumns.forEach(_ => {
|
||||||
if( tableRequiredList.indexOf(_.name) >= 0 ) {
|
if( tableRequiredList.indexOf(_.name) >= 0 ) {
|
||||||
const dom = $(`th[data-name=${_.name}]`)
|
const dom = $(`th[data-name=${_.name}]`)
|
||||||
let t = dom.html()
|
dom.addClass('addRequired')
|
||||||
dom.html('<i style="color: red;margin-left: -4px;position: absolute;left: 0">*</i>' + t)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -478,4 +478,14 @@ div:has(.o_required_modifier) > label::before {
|
|||||||
width: auto !important;
|
width: auto !important;
|
||||||
flex: unset;
|
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)
|
name = fields.Char('功能刀具名称', required=True)
|
||||||
type = fields.Char('类型')
|
type = fields.Char('类型')
|
||||||
|
functional_cutting_tool_model_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
|
||||||
prefix = fields.Char('前缀')
|
prefix = fields.Char('前缀')
|
||||||
postfix = fields.Char('后缀')
|
postfix = fields.Char('后缀')
|
||||||
diameter = fields.Float('直径(mm)')
|
diameter = fields.Float('直径(mm)')
|
||||||
@@ -326,5 +327,9 @@ class ToolInventory(models.Model):
|
|||||||
cutter_number = fields.Char('刀号')
|
cutter_number = fields.Char('刀号')
|
||||||
blade_number = fields.Integer('刃数(个)')
|
blade_number = fields.Integer('刃数(个)')
|
||||||
extension = fields.Float('伸出长度(mm)')
|
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)
|
active = fields.Boolean('已归档', default=True)
|
||||||
|
|||||||
@@ -556,19 +556,23 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="功能刀具清单" create="1" edit="1" delete="0" editable="bottom">
|
<tree string="功能刀具清单" create="1" edit="1" delete="0" editable="bottom">
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="type"/>
|
<field name="functional_cutting_tool_model_id"/>
|
||||||
<field name="prefix"/>
|
<field name="tool_groups_id"/>
|
||||||
<field name="postfix"/>
|
<field name="work_material"/>
|
||||||
|
<field name="life_span"/>
|
||||||
|
<field name="prefix" optional="hide"/>
|
||||||
|
<field name="postfix" optional="hide"/>
|
||||||
<field name="diameter"/>
|
<field name="diameter"/>
|
||||||
<field name="angle"/>
|
<field name="angle"/>
|
||||||
<field name="tool_length"/>
|
<field name="tool_length"/>
|
||||||
<field name="blade_length"/>
|
<field name="blade_length"/>
|
||||||
<field name="knife_head_name"/>
|
<field name="knife_head_name" optional="hide"/>
|
||||||
<field name="cutter_number"/>
|
<field name="cutter_number"/>
|
||||||
<field name="blade_number"/>
|
<field name="blade_number"/>
|
||||||
<field name="extension"/>
|
<field name="extension"/>
|
||||||
<field name="create_uid" string="创建人" optional="hide"/>
|
<field name="create_uid" string="创建人" optional="hide"/>
|
||||||
<field name="create_date" string="创建时间" optional="hide"/>
|
<field name="create_date" string="创建时间" optional="hide"/>
|
||||||
|
<field name="type" invisible="1"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
@@ -579,7 +583,10 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="功能刀具清单">
|
<search string="功能刀具清单">
|
||||||
<field name="name" string="名称搜索" filter_domain="[('name','ilike',self)]"/>
|
<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="prefix"/>
|
||||||
<field name="postfix"/>
|
<field name="postfix"/>
|
||||||
<field name="diameter"/>
|
<field name="diameter"/>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from datetime import datetime, timedelta
|
|||||||
import requests
|
import requests
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
|
from lxml import etree
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
# import subprocess
|
# import subprocess
|
||||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
@@ -115,6 +116,19 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
processing_user_id = fields.Many2one('res.users', string='加工人')
|
processing_user_id = fields.Many2one('res.users', string='加工人')
|
||||||
# 检测人
|
# 检测人
|
||||||
inspection_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)
|
schedule_state = fields.Selection(related='production_id.schedule_state', store=True)
|
||||||
# 工件装夹信息
|
# 工件装夹信息
|
||||||
functional_fixture_code = fields.Char(string="功能夹具编码", readonly=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)])
|
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_id)])
|
||||||
return process_parameter_workorder
|
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轴倾斜度方法
|
# 计算配料中心点和与x轴倾斜度方法
|
||||||
def getcenter(self):
|
def getcenter(self):
|
||||||
try:
|
try:
|
||||||
@@ -230,8 +387,9 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
work.compensation_value_x = eval(self.material_center_point)[0]
|
work.compensation_value_x = eval(self.material_center_point)[0]
|
||||||
work.compensation_value_y = eval(self.material_center_point)[1]
|
work.compensation_value_y = eval(self.material_center_point)[1]
|
||||||
workorder.button_finish()
|
workorder.button_finish()
|
||||||
except:
|
except Exception as e:
|
||||||
raise UserError("参数计算有误")
|
# 重新抛出捕获到的异常信息
|
||||||
|
raise UserError(str(e))
|
||||||
|
|
||||||
def button_workpiece_delivery(self):
|
def button_workpiece_delivery(self):
|
||||||
if self.routing_type == '装夹预调':
|
if self.routing_type == '装夹预调':
|
||||||
|
|||||||
@@ -403,8 +403,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-lg-6 o_setting_box">
|
<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="计算定位"
|
<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>
|
</div>
|
||||||
|
|
||||||
<group>
|
<group>
|
||||||
@@ -518,6 +521,7 @@
|
|||||||
<field name="is_ok"/>
|
<field name="is_ok"/>
|
||||||
<field name="processing_user_id"/>
|
<field name="processing_user_id"/>
|
||||||
<field name="inspection_user_id"/>
|
<field name="inspection_user_id"/>
|
||||||
|
<field name="save_name" widget="CopyClipboardChar"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ class FtpController():
|
|||||||
except Exception:
|
except Exception:
|
||||||
logging.info("ftp连接失败")
|
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):
|
def download_file_tree(self, target_dir, serverdir):
|
||||||
if not os.path.exists(serverdir):
|
if not os.path.exists(serverdir):
|
||||||
|
|||||||
@@ -52,8 +52,6 @@ class MrStaticResourceDataSync(models.Model):
|
|||||||
logging.info("夹具型号已每日同步成功")
|
logging.info("夹具型号已每日同步成功")
|
||||||
self.env['sf.fixture.materials.basic.parameters'].sync_fixture_materials_basic_parameters_yesterday()
|
self.env['sf.fixture.materials.basic.parameters'].sync_fixture_materials_basic_parameters_yesterday()
|
||||||
logging.info("夹具型号基本参数已每日同步成功")
|
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()
|
self.env['sf.functional.fixture.type'].sync_functional_fixture_type_yesterday()
|
||||||
logging.info("功能夹具类型已每日同步成功")
|
logging.info("功能夹具类型已每日同步成功")
|
||||||
self.env['sf.cutting.tool.material'].sync_cutting_tool_material_yesterday()
|
self.env['sf.cutting.tool.material'].sync_cutting_tool_material_yesterday()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
</field>
|
</field>
|
||||||
<field name="email" position="replace">
|
<field name="email" position="replace">
|
||||||
<field name="email"
|
<field name="email"
|
||||||
attrs="{'required' : [('customer_rank','>', 0)],'readonly': [('id','!=', False)]}"/>
|
attrs="{'readonly': [('id','!=', False)]}"/>
|
||||||
</field>
|
</field>
|
||||||
<field name="mobile" position="attributes">
|
<field name="mobile" position="attributes">
|
||||||
<attribute name="attrs">{'required': [('phone', '=', False)],'readonly': [('id','!=', False)]}
|
<attribute name="attrs">{'required': [('phone', '=', False)],'readonly': [('id','!=', False)]}
|
||||||
@@ -37,19 +37,19 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
</field>
|
</field>
|
||||||
<field name="street" position="attributes">
|
<field name="street" position="attributes">
|
||||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||||
</attribute>
|
</attribute>
|
||||||
</field>
|
</field>
|
||||||
<field name="street2" position="attributes">
|
<field name="street2" position="attributes">
|
||||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||||
</attribute>
|
</attribute>
|
||||||
</field>
|
</field>
|
||||||
<field name="city" position="attributes">
|
<field name="city" position="attributes">
|
||||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||||
</attribute>
|
</attribute>
|
||||||
</field>
|
</field>
|
||||||
<field name="country_id" position="attributes">
|
<field name="country_id" position="attributes">
|
||||||
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
|
<attribute name="attrs">{'readonly': [('id','!=', False)]}
|
||||||
</attribute>
|
</attribute>
|
||||||
</field>
|
</field>
|
||||||
<xpath expr="//group[@name='sale']/field[@name='user_id']" position="replace">
|
<xpath expr="//group[@name='sale']/field[@name='user_id']" position="replace">
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
'views/menu_view.xml',
|
'views/menu_view.xml',
|
||||||
'views/tool_material_search.xml',
|
'views/tool_material_search.xml',
|
||||||
'views/fixture_material_search_views.xml',
|
'views/fixture_material_search_views.xml',
|
||||||
|
'data/tool_data.xml',
|
||||||
],
|
],
|
||||||
'demo': [
|
'demo': [
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<data>
|
<record model="ir.cron" id="ir_cron_sf_tool_datasync">
|
||||||
<!-- <record model="sf.machine.table.tool.changing.apply" id="sf_create_tool_change_application">-->
|
<field name="name">定时同步刀具物料、功能刀具信息到cloud</field>
|
||||||
|
<field name="model_id" ref="model_sf_tool_datasync"/>
|
||||||
<!-- </record>-->
|
<field name="state">code</field>
|
||||||
</data>
|
<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>
|
</odoo>
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
import base64
|
import base64
|
||||||
import requests
|
import requests
|
||||||
|
import logging
|
||||||
from odoo import models, api
|
from odoo import models, api
|
||||||
from odoo.addons.sf_base.commons.common import Common
|
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):
|
def get_suitable_machining_method_names(item):
|
||||||
@@ -30,6 +31,30 @@ def get_suitable_coolant_names(item):
|
|||||||
return suitable_coolant_names
|
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):
|
class StockLot(models.Model):
|
||||||
_inherit = 'stock.lot'
|
_inherit = 'stock.lot'
|
||||||
_description = '刀具物料序列号注册'
|
_description = '刀具物料序列号注册'
|
||||||
@@ -41,6 +66,18 @@ class StockLot(models.Model):
|
|||||||
headers = Common.get_headers(self, token, sf_secret_key)
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
str_url = sf_sync_config['sf_url'] + "/api/tool_material_stock/create"
|
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])])
|
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 = []
|
tool_material_stock_list = []
|
||||||
if objs_all:
|
if objs_all:
|
||||||
for item in objs_all:
|
for item in objs_all:
|
||||||
@@ -57,7 +94,7 @@ class StockLot(models.Model):
|
|||||||
if ret.get('code') == 200:
|
if ret.get('code') == 200:
|
||||||
return '刀具物料序列号注册成功'
|
return '刀具物料序列号注册成功'
|
||||||
else:
|
else:
|
||||||
raise UserError("没有注册刀具物料序列号信息")
|
logging.info("没有注册刀具物料序列号信息")
|
||||||
|
|
||||||
|
|
||||||
class ToolMaterial(models.Model):
|
class ToolMaterial(models.Model):
|
||||||
@@ -73,6 +110,18 @@ class ToolMaterial(models.Model):
|
|||||||
headers = Common.get_headers(self, token, sf_secret_key)
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||||
objs_all = self.search([('id', '=', self.id)])
|
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 = []
|
tool_material_list = []
|
||||||
if objs_all:
|
if objs_all:
|
||||||
for item in objs_all:
|
for item in objs_all:
|
||||||
@@ -95,7 +144,7 @@ class ToolMaterial(models.Model):
|
|||||||
if ret.get('code') == 200:
|
if ret.get('code') == 200:
|
||||||
return '刀具物料注册成功'
|
return '刀具物料注册成功'
|
||||||
else:
|
else:
|
||||||
raise UserError("没有注册刀具物料信息")
|
logging.info('没有注册刀具物料信息')
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
@@ -120,6 +169,18 @@ class FunctionalCuttingToolEntity(models.Model):
|
|||||||
headers = Common.get_headers(self, token, sf_secret_key)
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||||
objs_all = self.env['sf.functional.cutting.tool.entity'].search([('id', '=', self.id)])
|
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 = []
|
functional_tool_list = []
|
||||||
if objs_all:
|
if objs_all:
|
||||||
for item in objs_all:
|
for item in objs_all:
|
||||||
@@ -170,7 +231,7 @@ class FunctionalCuttingToolEntity(models.Model):
|
|||||||
if ret.get('code') == 200:
|
if ret.get('code') == 200:
|
||||||
return "功能刀具注册成功"
|
return "功能刀具注册成功"
|
||||||
else:
|
else:
|
||||||
raise UserError("没有注册功能刀具信息")
|
logging.info('没有注册功能刀具信息')
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
@@ -201,6 +262,18 @@ class FunctionalToolWarning(models.Model):
|
|||||||
headers = Common.get_headers(self, token, sf_secret_key)
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
str_url = sf_sync_config['sf_url'] + self.crea_url
|
||||||
objs_all = self.env['sf.functional.tool.warning'].search([('id', '=', self.id)])
|
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 = []
|
tool_warning_list = []
|
||||||
if objs_all:
|
if objs_all:
|
||||||
for item in objs_all:
|
for item in objs_all:
|
||||||
@@ -237,7 +310,7 @@ class FunctionalToolWarning(models.Model):
|
|||||||
if ret.get('code') == 200:
|
if ret.get('code') == 200:
|
||||||
return "功能刀具预警注册成功"
|
return "功能刀具预警注册成功"
|
||||||
else:
|
else:
|
||||||
raise UserError("没有注册功能刀具预警信息")
|
logging.info('没有注册功能刀具预警信息')
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
@@ -262,6 +335,18 @@ class StockMoveLine(models.Model):
|
|||||||
headers = Common.get_headers(self, token, sf_secret_key)
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
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)])
|
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 = []
|
tool_stock_list = []
|
||||||
if objs_all:
|
if objs_all:
|
||||||
for item in objs_all:
|
for item in objs_all:
|
||||||
@@ -289,7 +374,7 @@ class StockMoveLine(models.Model):
|
|||||||
if ret.get('code') == 200:
|
if ret.get('code') == 200:
|
||||||
return "功能刀具出入库记录注册成功"
|
return "功能刀具出入库记录注册成功"
|
||||||
else:
|
else:
|
||||||
raise UserError("没有注册功能刀具出入库记录信息")
|
logging.info('没有注册功能刀具出入库记录信息')
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
@@ -314,6 +399,18 @@ class RealTimeDistributionFunctionalTools(models.Model):
|
|||||||
headers = Common.get_headers(self, token, sf_secret_key)
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
str_url = sf_sync_config['sf_url'] + self.crea_url
|
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)])
|
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 = []
|
tool_distribution_list = []
|
||||||
if objs_all:
|
if objs_all:
|
||||||
for item in objs_all:
|
for item in objs_all:
|
||||||
@@ -353,7 +450,7 @@ class RealTimeDistributionFunctionalTools(models.Model):
|
|||||||
if ret.get('code') == 200:
|
if ret.get('code') == 200:
|
||||||
return "功能刀具出入库记录注册成功"
|
return "功能刀具出入库记录注册成功"
|
||||||
else:
|
else:
|
||||||
raise UserError("没有注册功能刀具出入库记录信息")
|
logging.info('没有注册功能刀具出入库记录信息')
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
|
|||||||
@@ -222,132 +222,147 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
|||||||
image = fields.Binary('图片')
|
image = fields.Binary('图片')
|
||||||
|
|
||||||
# 功能刀具组装信息
|
# 功能刀具组装信息
|
||||||
# 整体式刀具型号
|
# ===============整体式刀具型号=================
|
||||||
|
integral_freight_barcode = fields.Char('整体式刀具货位')
|
||||||
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号',
|
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号',
|
||||||
domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具'),
|
domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具'),
|
||||||
('tool_material_status', '=', '可用')])
|
('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='整体式刀具型号',
|
cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号',
|
||||||
related='integral_code_id.product_id.cutting_tool_model_id')
|
related='integral_product_id.cutting_tool_model_id')
|
||||||
integral_name = fields.Char('整体式刀具名称', related='integral_code_id.product_id.name')
|
|
||||||
integral_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='整体式刀具规格',
|
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='整体式刀具品牌',
|
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', '刀片序列号',
|
blade_code_id = fields.Many2one('stock.lot', '刀片序列号',
|
||||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀片'),
|
domain=[('product_id.cutting_tool_material_id.name', '=', '刀片'),
|
||||||
('tool_material_status', '=', '可用')])
|
('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='刀片型号',
|
cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号',
|
||||||
related='blade_code_id.product_id.cutting_tool_model_id')
|
related='blade_product_id.cutting_tool_model_id')
|
||||||
blade_name = fields.Char('刀片名称', related='blade_code_id.product_id.name')
|
|
||||||
blade_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀片规格',
|
blade_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀片规格',
|
||||||
related='blade_code_id.product_id.specification_id')
|
related='blade_product_id.specification_id')
|
||||||
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_code_id.product_id.brand_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', '刀杆序列号',
|
bar_code_id = fields.Many2one('stock.lot', '刀杆序列号',
|
||||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆'),
|
domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆'),
|
||||||
('tool_material_status', '=', '可用')])
|
('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='刀杆型号',
|
cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号',
|
||||||
related='bar_code_id.product_id.cutting_tool_model_id')
|
related='bar_product_id.cutting_tool_model_id')
|
||||||
bar_name = fields.Char('刀杆名称', related='bar_code_id.product_id.name')
|
|
||||||
bar_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀杆规格',
|
bar_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀杆规格',
|
||||||
related='bar_code_id.product_id.specification_id')
|
related='bar_product_id.specification_id')
|
||||||
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_code_id.product_id.brand_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', '刀盘序列号',
|
pad_code_id = fields.Many2one('stock.lot', '刀盘序列号',
|
||||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘'),
|
domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘'),
|
||||||
('tool_material_status', '=', '可用')])
|
('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='刀盘型号',
|
cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号',
|
||||||
related='pad_code_id.product_id.cutting_tool_model_id')
|
related='pad_product_id.cutting_tool_model_id')
|
||||||
pad_name = fields.Char('刀盘名称', related='pad_code_id.product_id.name')
|
|
||||||
pad_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀盘规格',
|
pad_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀盘规格',
|
||||||
related='pad_code_id.product_id.specification_id')
|
related='pad_product_id.specification_id')
|
||||||
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_code_id.product_id.brand_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,
|
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True,
|
||||||
domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'),
|
domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'),
|
||||||
('tool_material_status', '=', '可用')])
|
('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='刀柄型号',
|
cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号',
|
||||||
related='handle_code_id.product_id.cutting_tool_model_id')
|
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='刀柄规格',
|
handle_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀柄规格',
|
||||||
related='handle_code_id.product_id.specification_id')
|
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')
|
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', '=', '夹头'),
|
domain=[('product_id.cutting_tool_material_id.name', '=', '夹头'),
|
||||||
('tool_material_status', '=', '可用')])
|
('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='夹头型号',
|
cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号',
|
||||||
related='chuck_code_id.product_id.cutting_tool_model_id')
|
related='chuck_product_id.cutting_tool_model_id')
|
||||||
chuck_name = fields.Char('夹头名称', related='chuck_code_id.product_id.name')
|
|
||||||
chuck_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='夹头规格',
|
chuck_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='夹头规格',
|
||||||
related='chuck_code_id.product_id.specification_id')
|
related='chuck_product_id.specification_id')
|
||||||
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_code_id.product_id.brand_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):
|
def on_barcode_scanned(self, barcode):
|
||||||
"""
|
"""
|
||||||
智能工厂组装单处扫码绑定刀具物料')
|
智能工厂组装单处扫码绑定刀具物料
|
||||||
"""
|
"""
|
||||||
for record in self:
|
for record in self:
|
||||||
if 'DJWL' in barcode:
|
lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
|
||||||
lot_ids = record.env['stock.lot'].sudo().search([('name', '=', barcode)])
|
if lot_ids:
|
||||||
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('扫描的刀具物料不存在,请重新扫描!')
|
|
||||||
for lot_id in lot_ids:
|
for lot_id in lot_ids:
|
||||||
if lot_id.quant_ids[-1].location_id.name in '刀具房':
|
if lot_id.quant_ids[-1].location_id.name in '刀具房':
|
||||||
record.handle_code_id = lot_id.id
|
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 == '刀具组装位置':
|
elif lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
|
||||||
raise ValidationError('该刀柄已使用,请重新扫描!!!')
|
raise ValidationError('该刀柄已使用,请重新扫描!!!')
|
||||||
else:
|
else:
|
||||||
raise ValidationError('该刀柄未入库,请重新扫描!!!')
|
raise ValidationError('该刀柄未入库,请重新扫描!!!')
|
||||||
|
else:
|
||||||
def get_chuck_code_id(self, lot_id):
|
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', barcode)])
|
||||||
# 适用夹头型号
|
if location:
|
||||||
cutting_tool_chuck_id = lot_id.product_id.cutting_tool_chuck_id
|
material_name = location.product_id.cutting_tool_material_id.name
|
||||||
# 适用夹头尺寸
|
if material_name == '整体式刀具':
|
||||||
fit_chuck_size = lot_id.product_id.cutting_tool_fit_chuck_size
|
record.integral_freight_barcode = barcode
|
||||||
# 适用夹头产品
|
elif material_name == '刀片':
|
||||||
chuck_product_id = self.env['product.product'].sudo().search(
|
record.blade_freight_barcode = barcode
|
||||||
[('cutting_tool_model_id', '=', cutting_tool_chuck_id.id),
|
elif material_name == '刀杆':
|
||||||
('cutting_tool_er_size_model', '=', fit_chuck_size)])
|
record.bar_freight_barcode = barcode
|
||||||
# 适用夹头产品序列号
|
elif material_name == '刀盘':
|
||||||
chuck_product_lot_ids = self.env['stock.lot'].sudo().search(
|
record.pad_freight_barcode = barcode
|
||||||
[('product_id', '=', chuck_product_id.id), ('tool_material_status', '=', '可用')])
|
elif material_name == '夹头':
|
||||||
for chuck_product_lot_id in chuck_product_lot_ids:
|
record.chuck_freight_barcode = barcode
|
||||||
if chuck_product_lot_id.quant_ids[-1].location_id.name in '刀具房':
|
else:
|
||||||
return chuck_product_lot_id
|
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
|
||||||
return False
|
else:
|
||||||
|
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
|
||||||
|
|
||||||
@api.depends('handle_code_id')
|
@api.depends('handle_code_id')
|
||||||
def _compute_rfid(self):
|
def _compute_rfid(self):
|
||||||
@@ -437,7 +452,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
|||||||
else:
|
else:
|
||||||
obj.after_assembly_functional_tool_name = ''
|
obj.after_assembly_functional_tool_name = ''
|
||||||
|
|
||||||
@api.onchange('integral_code_id')
|
@api.onchange('integral_freight_barcode')
|
||||||
def _onchange_after_assembly_functional_tool_diameter(self):
|
def _onchange_after_assembly_functional_tool_diameter(self):
|
||||||
for obj in self:
|
for obj in self:
|
||||||
if obj.integral_code_id:
|
if obj.integral_code_id:
|
||||||
@@ -573,12 +588,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
|||||||
'name': self.after_assembly_functional_tool_name,
|
'name': self.after_assembly_functional_tool_name,
|
||||||
'rfid': self.rfid,
|
'rfid': self.rfid,
|
||||||
'tool_groups_id': self.tool_groups_id.id,
|
'tool_groups_id': self.tool_groups_id.id,
|
||||||
'integral_code_id': self.integral_code_id.id,
|
'integral_product_id': self.integral_product_id.id,
|
||||||
'blade_code_id': self.blade_code_id.id,
|
'blade_product_id': self.blade_product_id.id,
|
||||||
'bar_code_id': self.bar_code_id.id,
|
'bar_product_id': self.bar_product_id.id,
|
||||||
'pad_code_id': self.pad_code_id.id,
|
'pad_product_id': self.pad_product_id.id,
|
||||||
'handle_code_id': self.handle_code_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_name': self.after_assembly_functional_tool_name,
|
||||||
'after_assembly_functional_tool_type_id': self.after_assembly_functional_tool_type_id.id,
|
'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,
|
'tool_groups_id': self.tool_groups_id.id,
|
||||||
'functional_tool_name_id': functional_tool_assembly_id.id,
|
'functional_tool_name_id': functional_tool_assembly_id.id,
|
||||||
'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_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_integral_model_id': self.integral_product_id.id,
|
||||||
'cutting_tool_blade_model_id': self.blade_code_id.product_id.id,
|
'cutting_tool_blade_model_id': self.blade_product_id.id,
|
||||||
'cutting_tool_cutterbar_model_id': self.bar_code_id.product_id.id,
|
'cutting_tool_cutterbar_model_id': self.bar_product_id.id,
|
||||||
'cutting_tool_cutterpad_model_id': self.pad_code_id.product_id.id,
|
'cutting_tool_cutterpad_model_id': self.pad_product_id.id,
|
||||||
'cutting_tool_cutterhandle_model_id': self.handle_code_id.product_id.id,
|
'cutting_tool_cutterhandle_model_id': self.handle_product_id.id,
|
||||||
'cutting_tool_cutterhead_model_id': self.chuck_code_id.product_id.id,
|
'cutting_tool_cutterhead_model_id': self.chuck_product_id.id,
|
||||||
|
|
||||||
'functional_tool_diameter': self.after_assembly_functional_tool_diameter,
|
'functional_tool_diameter': self.after_assembly_functional_tool_diameter,
|
||||||
'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,
|
'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,
|
||||||
|
|||||||
@@ -201,20 +201,18 @@
|
|||||||
<group string="组装物料信息" col="1">
|
<group string="组装物料信息" col="1">
|
||||||
<field name="_barcode_scanned" widget="barcode_handler"/>
|
<field name="_barcode_scanned" widget="barcode_handler"/>
|
||||||
<group col="1"
|
<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>
|
<div>
|
||||||
<separator string="整体式刀具:" style="font-size: 13px;"/>
|
<separator string="整体式刀具:" style="font-size: 13px;"/>
|
||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="integral_code_id" placeholder="请选择" string="序列号"
|
<field name="integral_freight_barcode" string="货位"/>
|
||||||
class="custom_required"
|
|
||||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="2">
|
<group col="2">
|
||||||
<group>
|
<group>
|
||||||
<field name="integral_name" string="名称"/>
|
<field name="integral_product_id" string="名称"/>
|
||||||
<field name="integral_specification_id" string="规格"/>
|
<field name="integral_specification_id" string="规格"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
@@ -223,20 +221,18 @@
|
|||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="1" attrs="{'invisible': [('integral_code_id', '!=', False)]}">
|
<group col="1" attrs="{'invisible': [('integral_freight_barcode', '!=', False)]}">
|
||||||
<div>
|
<div>
|
||||||
<separator string="刀片:" style="font-size: 13px;"/>
|
<separator string="刀片:" style="font-size: 13px;"/>
|
||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="blade_code_id" placeholder="请选择" string="序列号"
|
<field name="blade_freight_barcode" string="货位"/>
|
||||||
class="custom_required"
|
|
||||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="2">
|
<group col="2">
|
||||||
<group>
|
<group>
|
||||||
<field name="blade_name" string="名称"/>
|
<field name="blade_product_id" string="名称"/>
|
||||||
<field name="blade_specification_id" string="规格"/>
|
<field name="blade_specification_id" string="规格"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
@@ -246,20 +242,18 @@
|
|||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="1"
|
<group col="1"
|
||||||
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('pad_code_id', '!=', False)]}">
|
attrs="{'invisible': ['|',('integral_freight_barcode', '!=', False),('pad_freight_barcode', '!=', False)]}">
|
||||||
<div>
|
<div>
|
||||||
<separator string="刀杆:" style="font-size: 13px;"/>
|
<separator string="刀杆:" style="font-size: 13px;"/>
|
||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="bar_code_id" placeholder="请选择" string="序列号"
|
<field name="bar_freight_barcode" string="货位"/>
|
||||||
class="custom_required"
|
|
||||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="2">
|
<group col="2">
|
||||||
<group>
|
<group>
|
||||||
<field name="bar_name" string="名称"/>
|
<field name="bar_product_id" string="名称"/>
|
||||||
<field name="bar_specification_id" string="规格"/>
|
<field name="bar_specification_id" string="规格"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
@@ -269,20 +263,18 @@
|
|||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="1"
|
<group col="1"
|
||||||
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('bar_code_id', '!=', False)]}">
|
attrs="{'invisible': ['|',('bar_freight_barcode', '!=', False),('bar_freight_barcode', '!=', False)]}">
|
||||||
<div>
|
<div>
|
||||||
<separator string="刀盘:" style="font-size: 13px;"/>
|
<separator string="刀盘:" style="font-size: 13px;"/>
|
||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="pad_code_id" placeholder="请选择" string="序列号"
|
<field name="pad_freight_barcode" string="货位"/>
|
||||||
class="custom_required"
|
|
||||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="2">
|
<group col="2">
|
||||||
<group>
|
<group>
|
||||||
<field name="pad_name" string="名称"/>
|
<field name="pad_product_id" string="名称"/>
|
||||||
<field name="pad_specification_id" string="规格"/>
|
<field name="pad_specification_id" string="规格"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
@@ -304,7 +296,7 @@
|
|||||||
</group>
|
</group>
|
||||||
<group col="2">
|
<group col="2">
|
||||||
<group>
|
<group>
|
||||||
<field name="handle_name" string="名称"/>
|
<field name="handle_product_id" string="名称"/>
|
||||||
<field name="handle_specification_id" string="规格"/>
|
<field name="handle_specification_id" string="规格"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
@@ -319,14 +311,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="chuck_code_id" string="序列号" placeholder="请选择"
|
<field name="chuck_freight_barcode" string="货位"/>
|
||||||
class="custom_required"
|
|
||||||
options="{'no_create': True, 'no_quick_create': True}"/>
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group col="2">
|
<group col="2">
|
||||||
<group>
|
<group>
|
||||||
<field name="chuck_name" string="名称"/>
|
<field name="chuck_product_id" string="名称"/>
|
||||||
<field name="chuck_specification_id" string="规格"/>
|
<field name="chuck_specification_id" string="规格"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ class SfLocation(models.Model):
|
|||||||
name = fields.Char('Location Name', required=True, size=20)
|
name = fields.Char('Location Name', required=True, size=20)
|
||||||
barcode = fields.Char('Barcode', copy=False, size=15)
|
barcode = fields.Char('Barcode', copy=False, size=15)
|
||||||
|
|
||||||
|
|
||||||
# 仓库类别(selection:库区、库位、货位)
|
# 仓库类别(selection:库区、库位、货位)
|
||||||
# location_type = fields.Selection([
|
# location_type = fields.Selection([
|
||||||
# ('库区', '库区'),
|
# ('库区', '库区'),
|
||||||
@@ -127,7 +126,7 @@ class SfLocation(models.Model):
|
|||||||
for record in self:
|
for record in self:
|
||||||
if record.product_sn_id:
|
if record.product_sn_id:
|
||||||
record.product_id = record.product_sn_id.product_id
|
record.product_id = record.product_sn_id.product_id
|
||||||
record.location_status = '占用'
|
# record.location_status = '占用'
|
||||||
else:
|
else:
|
||||||
record.product_id = False
|
record.product_id = False
|
||||||
# record.location_status = '空闲'
|
# record.location_status = '空闲'
|
||||||
@@ -305,7 +304,7 @@ class SfShelf(models.Model):
|
|||||||
class ShelfLocation(models.Model):
|
class ShelfLocation(models.Model):
|
||||||
_name = 'sf.shelf.location'
|
_name = 'sf.shelf.location'
|
||||||
_description = '货位'
|
_description = '货位'
|
||||||
_order = 'create_date desc'
|
_order = 'id asc, create_date asc'
|
||||||
|
|
||||||
# current_location_id = fields.Many2one('sf.shelf.location', string='当前位置')
|
# 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.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_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):
|
def action_location_status_disable(self):
|
||||||
@@ -376,12 +385,20 @@ class ShelfLocation(models.Model):
|
|||||||
"""
|
"""
|
||||||
for record in self:
|
for record in self:
|
||||||
if record.product_sn_id:
|
if record.product_sn_id:
|
||||||
record.sudo().product_id = record.product_sn_id.product_id
|
try:
|
||||||
record.sudo().location_status = '占用'
|
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:
|
else:
|
||||||
record.product_id = False
|
try:
|
||||||
# record.location_status = '空闲'
|
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):
|
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)
|
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)
|
||||||
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)
|
rfid = fields.Char('Rfid', readonly=True)
|
||||||
|
|
||||||
@@ -689,6 +708,7 @@ class Sf_stock_move_line(models.Model):
|
|||||||
def _compute_location_dest_id_value(self):
|
def _compute_location_dest_id_value(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.location_dest_id_value = record.location_dest_id.id if record.location_dest_id else False
|
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(
|
destination_location_id = fields.Many2one(
|
||||||
'sf.shelf.location', string='目标货位')
|
'sf.shelf.location', string='目标货位')
|
||||||
@@ -696,23 +716,31 @@ class Sf_stock_move_line(models.Model):
|
|||||||
@api.onchange('destination_location_id')
|
@api.onchange('destination_location_id')
|
||||||
def _compute_destination_location_id(self):
|
def _compute_destination_location_id(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
shelf_location_obj = self.env['sf.shelf.location'].search(
|
if record.lot_id:
|
||||||
[('product_sn_id', '=', record.lot_id.id)])
|
shelf_location_obj = self.env['sf.shelf.location'].search(
|
||||||
if shelf_location_obj:
|
[('product_sn_id', '=', record.lot_id.id)])
|
||||||
shelf_location_obj.product_sn_id = False
|
if shelf_location_obj:
|
||||||
# obj = self.env['sf.shelf.location'].search([('location_id', '=',
|
shelf_location_obj.product_sn_id = False
|
||||||
# self.destination_location_id.id)])
|
# obj = self.env['sf.shelf.location'].search([('location_id', '=',
|
||||||
obj = self.env['sf.shelf.location'].search([('name', '=',
|
# self.destination_location_id.id)])
|
||||||
self.destination_location_id.name)])
|
obj = self.env['sf.shelf.location'].search([('name', '=',
|
||||||
if obj:
|
self.destination_location_id.name)])
|
||||||
obj.product_sn_id = record.lot_id.id
|
if obj:
|
||||||
|
obj.product_sn_id = record.lot_id.id
|
||||||
|
else:
|
||||||
|
pass
|
||||||
else:
|
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:
|
else:
|
||||||
obj = self.env['sf.shelf.location'].search([('name', '=',
|
obj = self.env['sf.shelf.location'].search([('name', '=',
|
||||||
self.destination_location_id.name)])
|
self.destination_location_id.name)])
|
||||||
if obj:
|
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):
|
class SfStockPicking(models.Model):
|
||||||
@@ -737,8 +765,10 @@ class SfStockPicking(models.Model):
|
|||||||
for line in self.move_line_ids:
|
for line in self.move_line_ids:
|
||||||
if line:
|
if line:
|
||||||
if line.current_location_id:
|
if line.current_location_id:
|
||||||
line.current_location_id.product_sn_id = False
|
if line.current_location_id.product_sn_id:
|
||||||
line.current_location_id.location_status = '空闲'
|
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:
|
for move in self.move_ids:
|
||||||
if move and move.product_id.cutting_tool_material_id.name == '刀柄' or '托盘' in (
|
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})
|
self.env['stock.lot'].search([('name', '=', item.lot_name)]).write({'rfid': item.rfid})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
# def print_all_barcode(self):
|
|
||||||
# """
|
# def print_all_barcode(self):
|
||||||
# 打印所有编码
|
# """
|
||||||
# """
|
# 打印所有编码
|
||||||
# print('================')
|
# """
|
||||||
# for record in self.move_ids_without_package:
|
# print('================')
|
||||||
# print('record', record)
|
# for record in self.move_ids_without_package:
|
||||||
# print('record.move_line_ids', record.move_line_ids)
|
# print('record', record)
|
||||||
#
|
# print('record.move_line_ids', record.move_line_ids)
|
||||||
# # record.move_line_ids.print_qr_code()
|
#
|
||||||
#
|
# # 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)
|
# 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):
|
class SfProcurementGroup(models.Model):
|
||||||
|
|||||||
@@ -10,10 +10,18 @@
|
|||||||
<field name="current_location_id" force_save="1"/>
|
<field name="current_location_id" force_save="1"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='location_dest_id'][2]" position="after">
|
<xpath expr="//field[@name='location_dest_id'][2]" position="after">
|
||||||
<field name="destination_location_id" domain="[
|
<field name="current_product_id" invisible="1"/>
|
||||||
('location_id', '=', location_dest_id_value),
|
<field name="there_is_no_sn" invisible="1"/>
|
||||||
('location_status', '=', '空闲')
|
<!-- <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_product_type"/> -->
|
||||||
<!-- <field name="location_dest_id"/> -->
|
<!-- <field name="location_dest_id"/> -->
|
||||||
<field name="location_dest_id_value" invisible="1"/>
|
<field name="location_dest_id_value" invisible="1"/>
|
||||||
|
|||||||
@@ -149,6 +149,7 @@
|
|||||||
<field name="location_id"/>
|
<field name="location_id"/>
|
||||||
<field name="product_sn_id"/>
|
<field name="product_sn_id"/>
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
|
<field name="product_num" readonly="1"/>
|
||||||
<field name="location_status"/>
|
<field name="location_status"/>
|
||||||
<field name="storage_time" widget="datetime"/>
|
<field name="storage_time" widget="datetime"/>
|
||||||
<field name="production_id" readonly="1"/>
|
<field name="production_id" readonly="1"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user