Merge branch 'feature/销售订单按钮优化' into feature/制造订单功能刀具状态优化
This commit is contained in:
@@ -296,8 +296,13 @@ class MrpProduction(models.Model):
|
|||||||
# 编程单更新
|
# 编程单更新
|
||||||
def update_programming_state(self):
|
def update_programming_state(self):
|
||||||
try:
|
try:
|
||||||
|
manufacturing_type = 'rework'
|
||||||
|
if self.is_scrap:
|
||||||
|
manufacturing_type = 'scrap'
|
||||||
|
elif self.tool_state == '2':
|
||||||
|
manufacturing_type = 'invalid_tool_rework'
|
||||||
res = {'programming_no': self.programming_no,
|
res = {'programming_no': self.programming_no,
|
||||||
'manufacturing_type': 'rework' if self.is_scrap is False else 'scrap'}
|
'manufacturing_type': manufacturing_type}
|
||||||
logging.info('res=%s:' % res)
|
logging.info('res=%s:' % res)
|
||||||
configsettings = self.env['res.config.settings'].get_values()
|
configsettings = self.env['res.config.settings'].get_values()
|
||||||
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
ret = json.loads(ret['result'])
|
ret = json.loads(ret['result'])
|
||||||
logging.info('下发编程单:%s' % ret)
|
logging.info('下发编程单:%s' % ret)
|
||||||
domain = [('programming_no', '=', ret['programming_no'])]
|
domain = [('programming_no', '=', ret['programming_no'])]
|
||||||
if ret['manufacturing_type'] == 'scrap':
|
if ret['manufacturing_type'] in ('scrap', 'invalid_tool_rework'):
|
||||||
domain += [('state', 'not in', ['done', 'scrap', 'cancel'])]
|
domain += [('state', 'not in', ['done', 'scrap', 'cancel'])]
|
||||||
productions = request.env['mrp.production'].with_user(
|
productions = request.env['mrp.production'].with_user(
|
||||||
request.env.ref("base.user_admin")).search(domain)
|
request.env.ref("base.user_admin")).search(domain)
|
||||||
@@ -96,6 +96,14 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
res.update({
|
res.update({
|
||||||
'production_ids': productions.ids
|
'production_ids': productions.ids
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# 对制造订单所以面的cnc工单的程序用刀进行校验
|
||||||
|
try:
|
||||||
|
productions.production_cnc_tool_checkout()
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(f'对cnc工单的程序用刀进行校验报错:{e}')
|
||||||
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
else:
|
else:
|
||||||
res = {'status': 0, 'message': '该制造订单暂未开始'}
|
res = {'status': 0, 'message': '该制造订单暂未开始'}
|
||||||
|
|||||||
@@ -17,11 +17,6 @@
|
|||||||
<xpath expr="//field[@name='user_id']" position="replace">
|
<xpath expr="//field[@name='user_id']" position="replace">
|
||||||
<field name="user_id" widget="many2one_avatar_user" context="{'is_sale': True }"/>
|
<field name="user_id" widget="many2one_avatar_user" context="{'is_sale': True }"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='action_quotation_send'][1]" position="replace">
|
|
||||||
<button name="action_quotation_send" string="通过EMAIL发送" type="object"
|
|
||||||
class="btn-primary" data-hotkey="g" context="{'validate_analytic': True}"
|
|
||||||
attrs="{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel'])]}"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//form/header/button[@name='action_confirm']" position="after">
|
<xpath expr="//form/header/button[@name='action_confirm']" position="after">
|
||||||
<button name="submit" string="提交" type="object"
|
<button name="submit" string="提交" type="object"
|
||||||
context="{'default_order_id':active_id}"
|
context="{'default_order_id':active_id}"
|
||||||
@@ -52,6 +47,39 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
<attribute name="string">拒绝接单</attribute>
|
<attribute name="string">拒绝接单</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ======================= 销售订单按钮顺序优化 start ======================= -->
|
||||||
|
<xpath expr="//form/header/button[@name='action_quotation_send'][1]" position="attributes">
|
||||||
|
<attribute name="invisible">1</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//form/header/button[@name='action_quotation_send'][4]" position="attributes">
|
||||||
|
<attribute name="invisible">1</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//form/header/button[@id='create_invoice']" position="attributes">
|
||||||
|
<attribute name="invisible">1</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//form/header/button[@id='create_invoice_percentage']" position="attributes">
|
||||||
|
<attribute name="invisible">1</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//form/header/button[@name='action_cancel']" position="after">
|
||||||
|
<button id="create_invoice" name="%(sale.action_view_sale_advance_payment_inv)d"
|
||||||
|
string="创建结算单"
|
||||||
|
type="action" class="btn-primary" data-hotkey="q"
|
||||||
|
attrs="{'invisible': [('invoice_status', '!=', 'to invoice')]}"/>
|
||||||
|
<button id="create_invoice_percentage" name="%(sale.action_view_sale_advance_payment_inv)d"
|
||||||
|
string="创建结算单"
|
||||||
|
type="action" context="{'default_advance_payment_method': 'percentage'}" data-hotkey="q"
|
||||||
|
attrs="{'invisible': ['|',('invoice_status', '!=', 'no'), ('state', '!=', 'sale')]}"/>
|
||||||
|
<button name="action_quotation_send" string="通过EMAIL发送" type="object"
|
||||||
|
class="btn-primary" data-hotkey="g" context="{'validate_analytic': True}"
|
||||||
|
attrs="{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel'])]}"/>
|
||||||
|
<button name="action_quotation_send" string="通过EMAIL发送" type="object" states="sent,sale"
|
||||||
|
data-hotkey="g" context="{'validate_analytic': True}"/>
|
||||||
|
</xpath>
|
||||||
|
<!-- ====================== 销售订单按钮顺序优化 end======================== -->
|
||||||
|
|
||||||
|
|
||||||
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">
|
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">
|
||||||
<attribute name="invisible">1</attribute>
|
<attribute name="invisible">1</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|||||||
@@ -314,37 +314,41 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
|
|||||||
'applicant': None,
|
'applicant': None,
|
||||||
'sf_functional_tool_assembly_id': None})
|
'sf_functional_tool_assembly_id': None})
|
||||||
|
|
||||||
def create_cam_work_plan(self, cnc_processing):
|
def create_cam_work_plan(self, cnc_ids):
|
||||||
"""
|
"""
|
||||||
根据传入的工单信息,查询是否有需要的功能刀具,如果没有则生成CAM工单程序用刀计划
|
根据传入的工单信息,查询是否有需要的功能刀具,如果没有则生成CAM工单程序用刀计划
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# 获取编程单号
|
# 获取编程单号
|
||||||
programming_no = cnc_processing.workorder_id.production_id.programming_no
|
programming_no = cnc_ids[0].workorder_id.production_id.programming_no
|
||||||
logging.info(f'编程单号:{programming_no}')
|
logging.info(f'编程单号:{programming_no}')
|
||||||
cam_id = self.env['sf.cam.work.order.program.knife.plan'].sudo().search(
|
for cnc_processing in cnc_ids:
|
||||||
[('programming_no', '=', programming_no),
|
tool_name = cnc_processing.cutting_tool_name
|
||||||
('functional_tool_name', '=', cnc_processing.cutting_tool_name)])
|
cam_id = self.env['sf.cam.work.order.program.knife.plan'].sudo().search(
|
||||||
logging.info(f'CAM装刀计划:{cam_id}')
|
[('programming_no', '=', programming_no),
|
||||||
if not cam_id:
|
('functional_tool_name', '=', tool_name)])
|
||||||
knife_plan = self.env['sf.cam.work.order.program.knife.plan'].sudo().create({
|
if cam_id:
|
||||||
'name': cnc_processing.workorder_id.production_id.name,
|
logging.info(f'编程单号{programming_no}功能刀具名称{tool_name}已存在CAM装刀计划:{cam_id}')
|
||||||
'programming_no': programming_no,
|
else:
|
||||||
'cam_procedure_code': cnc_processing.program_name,
|
knife_plan = self.env['sf.cam.work.order.program.knife.plan'].sudo().create({
|
||||||
'filename': cnc_processing.cnc_id.name,
|
'name': cnc_processing.workorder_id.production_id.name,
|
||||||
'functional_tool_name': cnc_processing.cutting_tool_name,
|
'programming_no': programming_no,
|
||||||
'cam_cutter_spacing_code': cnc_processing.cutting_tool_no,
|
'cam_procedure_code': cnc_processing.program_name,
|
||||||
'process_type': cnc_processing.processing_type,
|
'filename': cnc_processing.cnc_id.name,
|
||||||
'margin_x_y': float(cnc_processing.margin_x_y),
|
'functional_tool_name': tool_name,
|
||||||
'margin_z': float(cnc_processing.margin_z),
|
'cam_cutter_spacing_code': cnc_processing.cutting_tool_no,
|
||||||
'finish_depth': float(cnc_processing.depth_of_processing_z),
|
'process_type': cnc_processing.processing_type,
|
||||||
'extension_length': float(cnc_processing.cutting_tool_extension_length),
|
'margin_x_y': float(cnc_processing.margin_x_y),
|
||||||
'shank_model': cnc_processing.cutting_tool_handle_type,
|
'margin_z': float(cnc_processing.margin_z),
|
||||||
'estimated_processing_time': cnc_processing.estimated_processing_time,
|
'finish_depth': float(cnc_processing.depth_of_processing_z),
|
||||||
})
|
'extension_length': float(cnc_processing.cutting_tool_extension_length),
|
||||||
logging.info('CAM工单程序用刀计划创建成功!!!')
|
'shank_model': cnc_processing.cutting_tool_handle_type,
|
||||||
# 创建装刀请求
|
'estimated_processing_time': cnc_processing.estimated_processing_time,
|
||||||
knife_plan.apply_for_tooling()
|
})
|
||||||
|
logging.info(f'创建CAM工单程序用刀计划:{knife_plan}')
|
||||||
|
# 创建装刀请求
|
||||||
|
knife_plan.apply_for_tooling()
|
||||||
|
logging.info('CAM工单程序用刀计划创建已完成!!!')
|
||||||
|
|
||||||
def unlink_cam_plan(self, production):
|
def unlink_cam_plan(self, production):
|
||||||
for item in production:
|
for item in production:
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class CNCprocessing(models.Model):
|
|||||||
# else:
|
# else:
|
||||||
# raise ValidationError("MES装刀指令发送失败")
|
# raise ValidationError("MES装刀指令发送失败")
|
||||||
|
|
||||||
def cnc_tool_checkout(self, cnc_processing_ids):
|
def cnc_tool_checkout_1(self, cnc_processing_ids):
|
||||||
"""
|
"""
|
||||||
根据传入的工单信息,查询是否有需要的功能刀具,如果没有则生成CAM工单程序用刀计划
|
根据传入的工单信息,查询是否有需要的功能刀具,如果没有则生成CAM工单程序用刀计划
|
||||||
"""
|
"""
|
||||||
@@ -128,13 +128,6 @@ class CNCprocessing(models.Model):
|
|||||||
})
|
})
|
||||||
logging.info('工单cnc程序用刀校验已完成!')
|
logging.info('工单cnc程序用刀校验已完成!')
|
||||||
|
|
||||||
@api.model_create_multi
|
|
||||||
def create(self, vals):
|
|
||||||
obj = super(CNCprocessing, self).create(vals)
|
|
||||||
# 调用CAM工单程序用刀计划创建方法
|
|
||||||
self.cnc_tool_checkout(obj)
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
class MrpWorkCenter(models.Model):
|
class MrpWorkCenter(models.Model):
|
||||||
_inherit = 'mrp.workcenter'
|
_inherit = 'mrp.workcenter'
|
||||||
@@ -143,3 +136,78 @@ class MrpWorkCenter(models.Model):
|
|||||||
action = self.env.ref('sf_tool_management.sf_functional_tool_assembly_view_act')
|
action = self.env.ref('sf_tool_management.sf_functional_tool_assembly_view_act')
|
||||||
result = action.read()[0]
|
result = action.read()[0]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class MrpProduction(models.Model):
|
||||||
|
_inherit = 'mrp.production'
|
||||||
|
|
||||||
|
def production_cnc_tool_checkout(self):
|
||||||
|
logging.info('开始进行工单cnc程序用刀校验!!!')
|
||||||
|
invalid_tool = [] # 无效刀
|
||||||
|
invalid_tool_processing_panel = [] # 无效刀加工面
|
||||||
|
missing_tool_1 = [] # 缺刀(机内、线边)
|
||||||
|
missing_tool_2 = [] # 缺刀(库存)
|
||||||
|
for item in self:
|
||||||
|
workorder_ids = item.workorder_ids.filtered(lambda a: a.state not in ['rework', 'cancel'])
|
||||||
|
for workorder_id in workorder_ids:
|
||||||
|
if workorder_id.cnc_ids:
|
||||||
|
for cnc_id in workorder_id.cnc_ids:
|
||||||
|
tool_name = cnc_id.cutting_tool_name
|
||||||
|
# 查询功能刀具在清单中是否存在
|
||||||
|
tool_inventory_id = self.env['sf.tool.inventory'].sudo().search([('name', '=', tool_name)])
|
||||||
|
if not tool_inventory_id:
|
||||||
|
invalid_tool.append(tool_name)
|
||||||
|
invalid_tool_processing_panel.append(workorder_id.processing_panel)
|
||||||
|
continue
|
||||||
|
# 查询功能刀具是否存在库存
|
||||||
|
functional_tools = self.env['sf.functional.cutting.tool.entity'].sudo().search(
|
||||||
|
[('tool_name_id', '=', tool_inventory_id.id), ('functional_tool_status', '=', '正常')])
|
||||||
|
if not functional_tools.filtered(lambda p: p.current_location in ('线边刀库', '机内刀库')):
|
||||||
|
missing_tool_1.append(tool_name) # 判断为 ('线边刀库', '机内刀库') 缺刀
|
||||||
|
if not functional_tools:
|
||||||
|
missing_tool_2.append(tool_name) # 判断为 库存缺刀
|
||||||
|
break
|
||||||
|
# 修改cnc程序的‘刀具状态’
|
||||||
|
workorder_ids = self.env['mrp.workorder'].sudo().search([('production_id', 'in', self.ids)])
|
||||||
|
if invalid_tool:
|
||||||
|
# 修改cnc程序的‘刀具状态’为 ‘无效刀’
|
||||||
|
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
|
||||||
|
[('workorder_id', 'in', workorder_ids.ids), ('cutting_tool_name', 'in', invalid_tool)])
|
||||||
|
if cnc_ids:
|
||||||
|
cnc_ids.write({'tool_state': '2'})
|
||||||
|
# 创建制造订单无效刀检测结果记录
|
||||||
|
for production_id in self:
|
||||||
|
for processing_panel in list(set(invalid_tool_processing_panel)):
|
||||||
|
if not production_id.detection_result_ids.filtered(
|
||||||
|
lambda a: (a.processing_panel == processing_panel and a.detailed_reason == '无效功能刀具'
|
||||||
|
and a.handle_result == '待处理' and a.routing_type == 'CNC加工'
|
||||||
|
and a.rework_reason == 'programming' and a.test_results == '返工')):
|
||||||
|
production_id.detection_result_ids.create({
|
||||||
|
'production_id': production_id.id,
|
||||||
|
'processing_panel': processing_panel,
|
||||||
|
'routing_type': 'CNC加工',
|
||||||
|
'rework_reason': 'programming', # 原因:编程(programming)
|
||||||
|
'detailed_reason': '无效功能刀具',
|
||||||
|
'test_results': '返工',
|
||||||
|
'handle_result': '待处理'
|
||||||
|
})
|
||||||
|
# 自动调用重新获取编程的方法
|
||||||
|
logging.info('cnc用刀校验到无效刀自动调用重新编程方法:update_programming_state()')
|
||||||
|
self[0].update_programming_state()
|
||||||
|
# 修改制造订单 编程状态变为“编程中”
|
||||||
|
self.write({'programming_state': '编程中', 'work_state': '编程中'})
|
||||||
|
if missing_tool_1:
|
||||||
|
# 修改 修改cnc程序的‘刀具状态’ 为 ‘缺刀’
|
||||||
|
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
|
||||||
|
[('workorder_id', 'in', workorder_ids.ids), ('cutting_tool_name', 'in', missing_tool_1)])
|
||||||
|
if cnc_ids:
|
||||||
|
cnc_ids.write({'tool_state': '1'})
|
||||||
|
if missing_tool_2 and not invalid_tool:
|
||||||
|
# 调用CAM工单程序用刀计划创建方法
|
||||||
|
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
|
||||||
|
[('workorder_id', 'in', workorder_ids.filtered(lambda a: a.production_id == self[0].id).ids),
|
||||||
|
('cutting_tool_name', 'in', missing_tool_2)])
|
||||||
|
if cnc_ids:
|
||||||
|
logging.info('调用CAM工单程序用刀计划创建方法!!!')
|
||||||
|
self.env['sf.cam.work.order.program.knife.plan'].sudo().create_cam_work_plan(cnc_ids)
|
||||||
|
logging.info('工单cnc程序用刀校验完成!!!')
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
<field name="barcode_id" invisible="1"/>
|
<field name="barcode_id" invisible="1"/>
|
||||||
<field name="rfid"/>
|
<field name="rfid"/>
|
||||||
<field name="tool_name_id"/>
|
<field name="tool_name_id"/>
|
||||||
<field name="image" widget='image'/>
|
|
||||||
<field name="tool_groups_id"/>
|
<field name="tool_groups_id"/>
|
||||||
<field name="functional_tool_diameter"/>
|
<field name="functional_tool_diameter"/>
|
||||||
<field name="knife_tip_r_angle"/>
|
<field name="knife_tip_r_angle"/>
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ class ShelfLocation(models.Model):
|
|||||||
_name = 'sf.shelf.location'
|
_name = 'sf.shelf.location'
|
||||||
_inherit = ['printing.utils']
|
_inherit = ['printing.utils']
|
||||||
_description = '货位'
|
_description = '货位'
|
||||||
_rec_name = 'barcode'
|
# _rec_name = 'barcode'
|
||||||
_order = 'id asc, create_date asc'
|
_order = 'id asc, create_date asc'
|
||||||
|
|
||||||
# current_location_id = fields.Many2one('sf.shelf.location', string='当前位置')
|
# current_location_id = fields.Many2one('sf.shelf.location', string='当前位置')
|
||||||
|
|||||||
Reference in New Issue
Block a user