Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化表面工艺外协
This commit is contained in:
@@ -13,7 +13,7 @@ class BasicParametersFixture(models.Model):
|
|||||||
diameter = fields.Float('直径(mm)', digits=(16, 2))
|
diameter = fields.Float('直径(mm)', digits=(16, 2))
|
||||||
|
|
||||||
# '零点卡盘' 字段
|
# '零点卡盘' 字段
|
||||||
weight = fields.Float('重量(mm)', digits=(16, 2))
|
weight = fields.Float('重量(kg)', digits=(16, 2))
|
||||||
orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2))
|
orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2))
|
||||||
clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2))
|
clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2))
|
||||||
clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数')
|
clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数')
|
||||||
|
|||||||
@@ -171,7 +171,7 @@
|
|||||||
<field name="width"/>
|
<field name="width"/>
|
||||||
<field name="height"/>
|
<field name="height"/>
|
||||||
<field name="diameter"/>
|
<field name="diameter"/>
|
||||||
<field name="weight"/>
|
<field name="weight" string="重量(kg)"/>
|
||||||
<field name="orientation_dish_diameter"/>
|
<field name="orientation_dish_diameter"/>
|
||||||
<field name="clamping_diameter"/>
|
<field name="clamping_diameter"/>
|
||||||
<field name="clamping_num"/>
|
<field name="clamping_num"/>
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
<field name="width"/>
|
<field name="width"/>
|
||||||
<field name="height"/>
|
<field name="height"/>
|
||||||
<field name="diameter"/>
|
<field name="diameter"/>
|
||||||
<field name="weight"/>
|
<field name="weight" string="重量(kg)"/>
|
||||||
<field name="clamping_diameter"/>
|
<field name="clamping_diameter"/>
|
||||||
<field name="connector_diameter"/>
|
<field name="connector_diameter"/>
|
||||||
<field name="chucking_power_max"/>
|
<field name="chucking_power_max"/>
|
||||||
@@ -220,7 +220,7 @@
|
|||||||
<field name="length"/>
|
<field name="length"/>
|
||||||
<field name="width"/>
|
<field name="width"/>
|
||||||
<field name="height"/>
|
<field name="height"/>
|
||||||
<field name="weight"/>
|
<field name="weight" string="重量(kg)"/>
|
||||||
<field name="gripper_length_min"/>
|
<field name="gripper_length_min"/>
|
||||||
<field name="gripper_width_min"/>
|
<field name="gripper_width_min"/>
|
||||||
<field name="gripper_height_min"/>
|
<field name="gripper_height_min"/>
|
||||||
@@ -248,7 +248,7 @@
|
|||||||
<field name="length"/>
|
<field name="length"/>
|
||||||
<field name="width"/>
|
<field name="width"/>
|
||||||
<field name="height"/>
|
<field name="height"/>
|
||||||
<field name="weight"/>
|
<field name="weight" string="重量(kg)"/>
|
||||||
<field name="gripper_length_min"/>
|
<field name="gripper_length_min"/>
|
||||||
<field name="gripper_width_min"/>
|
<field name="gripper_width_min"/>
|
||||||
<field name="gripper_height_min"/>
|
<field name="gripper_height_min"/>
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
<field name="width"/>
|
<field name="width"/>
|
||||||
<field name="height"/>
|
<field name="height"/>
|
||||||
<field name="height_tolerance_value"/>
|
<field name="height_tolerance_value"/>
|
||||||
<field name="weight"/>
|
<field name="weight" string="重量(kg)"/>
|
||||||
<field name="gripper_length_min"/>
|
<field name="gripper_length_min"/>
|
||||||
<field name="gripper_width_min"/>
|
<field name="gripper_width_min"/>
|
||||||
<field name="gripper_height_min"/>
|
<field name="gripper_height_min"/>
|
||||||
@@ -307,7 +307,7 @@
|
|||||||
<field name="length"/>
|
<field name="length"/>
|
||||||
<field name="width"/>
|
<field name="width"/>
|
||||||
<field name="height"/>
|
<field name="height"/>
|
||||||
<field name="weight"/>
|
<field name="weight" string="重量(kg)"/>
|
||||||
<field name="gripper_length_min"/>
|
<field name="gripper_length_min"/>
|
||||||
<field name="gripper_width_min"/>
|
<field name="gripper_width_min"/>
|
||||||
<field name="gripper_height_min"/>
|
<field name="gripper_height_min"/>
|
||||||
@@ -335,7 +335,7 @@
|
|||||||
<field name="width"/>
|
<field name="width"/>
|
||||||
<field name="height"/>
|
<field name="height"/>
|
||||||
<field name="diameter"/>
|
<field name="diameter"/>
|
||||||
<field name="weight"/>
|
<field name="weight" string="重量(kg)"/>
|
||||||
<field name="gripper_length_min"/>
|
<field name="gripper_length_min"/>
|
||||||
<field name="gripper_width_min"/>
|
<field name="gripper_width_min"/>
|
||||||
<field name="gripper_height_min"/>
|
<field name="gripper_height_min"/>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
from odoo import fields, models
|
from odoo.exceptions import UserError
|
||||||
|
from odoo import fields, models, _
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -14,6 +15,17 @@ class StatusChange(models.Model):
|
|||||||
def action_confirm(self):
|
def action_confirm(self):
|
||||||
# 在原有方法执行前记录日志和执行其他操作
|
# 在原有方法执行前记录日志和执行其他操作
|
||||||
logging.info('函数已经执行=============')
|
logging.info('函数已经执行=============')
|
||||||
|
server_product_none = []
|
||||||
|
for order in self.order_line:
|
||||||
|
for item in order.product_template_id.model_process_parameters_ids:
|
||||||
|
if item.gain_way == '外协':
|
||||||
|
server_product = self.env['product.template'].search(
|
||||||
|
[('server_product_process_parameters_id', '=', item.id),
|
||||||
|
('detailed_type', '=', 'service')])
|
||||||
|
if not server_product:
|
||||||
|
server_product_none.append(item.name)
|
||||||
|
if server_product_none:
|
||||||
|
raise UserError(_("请先至【产品】中创建【表面工艺参数】为%s的服务产品", ", ".join(server_product_none)))
|
||||||
|
|
||||||
# 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法)
|
# 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法)
|
||||||
res = super(StatusChange, self).action_confirm()
|
res = super(StatusChange, self).action_confirm()
|
||||||
@@ -202,12 +214,12 @@ class FinishStatusChange(models.Model):
|
|||||||
[('id', 'child_of', self.picking_type_id.warehouse_id.view_location_id.id),
|
[('id', 'child_of', self.picking_type_id.warehouse_id.view_location_id.id),
|
||||||
('usage', '!=', 'supplier')])
|
('usage', '!=', 'supplier')])
|
||||||
if self.env['stock.move'].search([
|
if self.env['stock.move'].search([
|
||||||
('state', 'in', ['confirmed', 'partially_available', 'waiting', 'assigned']),
|
('state', 'in', ['confirmed', 'partially_available', 'waiting', 'assigned']),
|
||||||
('product_qty', '>', 0),
|
('product_qty', '>', 0),
|
||||||
('location_id', 'in', wh_location_ids),
|
('location_id', 'in', wh_location_ids),
|
||||||
('move_orig_ids', '=', False),
|
('move_orig_ids', '=', False),
|
||||||
('picking_id', 'not in', self.ids),
|
('picking_id', 'not in', self.ids),
|
||||||
('product_id', 'in', lines.product_id.ids)], limit=1):
|
('product_id', 'in', lines.product_id.ids)], limit=1):
|
||||||
action = self.action_view_reception_report()
|
action = self.action_view_reception_report()
|
||||||
action['context'] = {'default_picking_ids': self.ids}
|
action['context'] = {'default_picking_ids': self.ids}
|
||||||
return action
|
return action
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class ResMrpBomMo(models.Model):
|
|||||||
# 查bom的原材料
|
# 查bom的原材料
|
||||||
def get_raw_bom(self, product):
|
def get_raw_bom(self, product):
|
||||||
raw_bom = self.env['product.product'].search(
|
raw_bom = self.env['product.product'].search(
|
||||||
[('categ_id.type', '=', '原材料'), ('materials_type_id', '=', product.materials_type_id.id)])
|
[('categ_id.type', '=', '原材料'), ('materials_type_id', '=', product.materials_type_id.id)],limit=1)
|
||||||
return raw_bom
|
return raw_bom
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('get_qcCheck error:%s' % e)
|
logging.info('get_qcCheck error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def button_Work_START(self, **kw):
|
def button_Work_START(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -193,7 +193,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('button_Work_START error:%s' % e)
|
logging.info('button_Work_START error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def button_Work_End(self, **kw):
|
def button_Work_End(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -244,7 +244,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('button_Work_End error:%s' % e)
|
logging.info('button_Work_End error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/PartQualityInspect', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/PartQualityInspect', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def PartQualityInspect(self, **kw):
|
def PartQualityInspect(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -290,7 +290,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('PartQualityInspect error:%s' % e)
|
logging.info('PartQualityInspect error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/CMMProgDolod', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/CMMProgDolod', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def CMMProgDolod(self, **kw):
|
def CMMProgDolod(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -330,7 +330,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('CMMProgDolod error:%s' % e)
|
logging.info('CMMProgDolod error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/NCProgDolod', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/NCProgDolod', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def NCProgDolod(self, **kw):
|
def NCProgDolod(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -429,7 +429,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('LocationChange error:%s' % e)
|
logging.info('LocationChange error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def AGVToProduct(self, **kw):
|
def AGVToProduct(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -490,7 +490,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('AGVToProduct error:%s' % e)
|
logging.info('AGVToProduct error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def AGVDownProduct(self, **kw):
|
def AGVDownProduct(self, **kw):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -185,8 +185,8 @@ class MrpProduction(models.Model):
|
|||||||
production.workorder_ids):
|
production.workorder_ids):
|
||||||
production.state = 'rework'
|
production.state = 'rework'
|
||||||
# 如果制造订单的功能刀具为【无效刀】则制造订单状态改为返工
|
# 如果制造订单的功能刀具为【无效刀】则制造订单状态改为返工
|
||||||
if production.tool_state == '2':
|
# if production.tool_state == '2':
|
||||||
production.state = 'rework'
|
# production.state = 'rework'
|
||||||
|
|
||||||
def action_check(self):
|
def action_check(self):
|
||||||
"""
|
"""
|
||||||
@@ -905,7 +905,6 @@ class MrpProduction(models.Model):
|
|||||||
# production.write(
|
# production.write(
|
||||||
# {'state': 'progress', 'programming_state': '已编程', 'is_rework': False})
|
# {'state': 'progress', 'programming_state': '已编程', 'is_rework': False})
|
||||||
# logging.info('返工含有已编程未下发的程序更新完成:%s' % production.name)
|
# logging.info('返工含有已编程未下发的程序更新完成:%s' % production.name)
|
||||||
logging.info('更新程序完成:%s' % production.name)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise UserError(result['message'])
|
raise UserError(result['message'])
|
||||||
|
|||||||
@@ -131,7 +131,9 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
is_subcontract = fields.Boolean(string='是否外协')
|
is_subcontract = fields.Boolean(string='是否外协')
|
||||||
surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数")
|
surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数")
|
||||||
picking_ids = fields.Many2many('stock.picking', string='外协出入库单')
|
picking_ids = fields.Many2many('stock.picking', string='外协出入库单')
|
||||||
|
# purchase_id = fields.Many2one('purchase.order', string='外协采购单')
|
||||||
surface_technics_picking_count = fields.Integer("外协出入库", compute='_compute_surface_technics_picking_ids')
|
surface_technics_picking_count = fields.Integer("外协出入库", compute='_compute_surface_technics_picking_ids')
|
||||||
|
surface_technics_purchase_count = fields.Integer("外协采购", compute='_compute_surface_technics_purchase_ids')
|
||||||
|
|
||||||
@api.depends('name', 'production_id.name')
|
@api.depends('name', 'production_id.name')
|
||||||
def _compute_surface_technics_picking_ids(self):
|
def _compute_surface_technics_picking_ids(self):
|
||||||
@@ -153,6 +155,43 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
action['context'] = dict(self._context, default_origin=self.name)
|
action['context'] = dict(self._context, default_origin=self.name)
|
||||||
return action
|
return action
|
||||||
|
|
||||||
|
@api.depends('state', 'production_id.name')
|
||||||
|
def _compute_surface_technics_purchase_ids(self):
|
||||||
|
for order in self:
|
||||||
|
if order.routing_type == '表面工艺':
|
||||||
|
production_programming = self.env['mrp.production'].search(
|
||||||
|
[('programming_no', '=', order.production_id.programming_no)], order='name asc')
|
||||||
|
production_list = [production.name for production in production_programming]
|
||||||
|
purchase = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
|
||||||
|
for line in purchase.order_line:
|
||||||
|
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id and line.product_qty == len(
|
||||||
|
production_programming):
|
||||||
|
# server_product = self.env['product.template'].search(
|
||||||
|
# [('server_product_process_parameters_id', '=', pp.id),
|
||||||
|
# ('detailed_type', '=', 'service')])
|
||||||
|
# purchase_order_line = self.env['purchase.order.line'].search(
|
||||||
|
# [('product_id', '=', server_product.id), ('product_qty', '=', len(production_programming))])
|
||||||
|
# if purchase_order_line:
|
||||||
|
order.surface_technics_purchase_count = len(purchase)
|
||||||
|
else:
|
||||||
|
order.surface_technics_purchase_count = 0
|
||||||
|
|
||||||
|
def action_view_surface_technics_purchase(self):
|
||||||
|
self.ensure_one()
|
||||||
|
production_programming = self.env['mrp.production'].search(
|
||||||
|
[('programming_no', '=', self.production_id.programming_no)], order='name asc')
|
||||||
|
production_list = [production.name for production in production_programming]
|
||||||
|
purchase_orders = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
|
||||||
|
result = {
|
||||||
|
"type": "ir.actions.act_window",
|
||||||
|
"res_model": "purchase.order",
|
||||||
|
"res_id": purchase_orders.id,
|
||||||
|
# "domain": [['id', 'in', self.purchase_id]],
|
||||||
|
"name": _("Purchase Orders"),
|
||||||
|
'view_mode': 'form',
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
supplier_id = fields.Many2one('res.partner', string='外协供应商')
|
supplier_id = fields.Many2one('res.partner', string='外协供应商')
|
||||||
equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True)
|
equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True)
|
||||||
# 保存名称
|
# 保存名称
|
||||||
@@ -885,7 +924,22 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
# workorder.state = 'ready'
|
# workorder.state = 'ready'
|
||||||
if workorder.routing_type == '表面工艺' and workorder.state not in ['done', 'progress']:
|
if workorder.routing_type == '表面工艺' and workorder.state not in ['done', 'progress']:
|
||||||
if unclamp_workorder:
|
if unclamp_workorder:
|
||||||
workorder.state = 'ready'
|
if workorder.is_subcontract is False:
|
||||||
|
workorder.state = 'ready'
|
||||||
|
else:
|
||||||
|
production_programming = self.env['mrp.production'].search(
|
||||||
|
[('programming_no', '=', self.production_id.programming_no)], order='name asc')
|
||||||
|
production_list = [production.name for production in production_programming]
|
||||||
|
purchase_orders = self.env['purchase.order'].search(
|
||||||
|
[('origin', '=', ','.join(production_list))])
|
||||||
|
for line in purchase_orders.order_line:
|
||||||
|
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len(
|
||||||
|
production_programming):
|
||||||
|
if purchase_orders.state == 'purchase':
|
||||||
|
workorder.state = 'ready'
|
||||||
|
else:
|
||||||
|
workorder.state = 'waiting'
|
||||||
|
|
||||||
# else:
|
# else:
|
||||||
# if workorder.state not in ['cancel', 'rework']:
|
# if workorder.state not in ['cancel', 'rework']:
|
||||||
# workorder.state = 'rework'
|
# workorder.state = 'rework'
|
||||||
@@ -1110,28 +1164,13 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
picking_out = record.env['stock.move.line'].search(
|
picking_out = record.env['stock.move.line'].search(
|
||||||
[('picking_id', '=', record.picking_ids[0].id)])
|
[('picking_id', '=', record.picking_ids[0].id)])
|
||||||
logging.info('picking_out:%s' % picking_out.picking_id.name)
|
logging.info('picking_out:%s' % picking_out.picking_id.name)
|
||||||
if picking_out:
|
# if picking_out:
|
||||||
order_line_ids = []
|
# order_line_ids = []
|
||||||
logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name)
|
# logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name)
|
||||||
server_product = self.env['product.template'].search(
|
#
|
||||||
[('server_product_process_parameters_id', '=', record.surface_technics_parameters_id.id),
|
# else:
|
||||||
('detailed_type', '=', 'service')])
|
# raise UserError(
|
||||||
logging.info('server_product:%s' % server_product.name)
|
# '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name)
|
||||||
if server_product:
|
|
||||||
order_line_ids.append((0, 0, {
|
|
||||||
'product_id': server_product.product_variant_id.id,
|
|
||||||
'product_qty': 1,
|
|
||||||
'product_uom': server_product.uom_id.id
|
|
||||||
}))
|
|
||||||
self.env['purchase.order'].sudo().create({
|
|
||||||
'partner_id': server_product.seller_ids.partner_id.id,
|
|
||||||
'origin': record.production_id.name,
|
|
||||||
'state': 'draft',
|
|
||||||
'order_line': order_line_ids,
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
raise UserError(
|
|
||||||
'请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name)
|
|
||||||
tem_date_planned_finished = record.date_planned_finished
|
tem_date_planned_finished = record.date_planned_finished
|
||||||
tem_date_finished = record.date_finished
|
tem_date_finished = record.date_finished
|
||||||
logging.info('routing_type:%s' % record.routing_type)
|
logging.info('routing_type:%s' % record.routing_type)
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import base64
|
|||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import ValidationError, UserError
|
||||||
from odoo.modules import get_resource_path
|
from odoo.modules import get_resource_path
|
||||||
|
|
||||||
|
|
||||||
from OCC.Extend.DataExchange import read_step_file
|
from OCC.Extend.DataExchange import read_step_file
|
||||||
from OCC.Extend.DataExchange import write_stl_file
|
from OCC.Extend.DataExchange import write_stl_file
|
||||||
|
|
||||||
@@ -106,6 +108,15 @@ class ResProductMo(models.Model):
|
|||||||
|
|
||||||
name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False)
|
name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False)
|
||||||
|
|
||||||
|
@api.constrains('seller_ids')
|
||||||
|
def _check_seller_ids(self):
|
||||||
|
if self.categ_type == '表面工艺':
|
||||||
|
if self.seller_ids:
|
||||||
|
if self.seller_ids[0].price == 0.0:
|
||||||
|
raise UserError("请在该产品【采购】中的【价格】进行输入")
|
||||||
|
else:
|
||||||
|
raise UserError("请在【采购】中输入供应商信息")
|
||||||
|
|
||||||
@api.depends('cutting_tool_model_id', 'specification_id')
|
@api.depends('cutting_tool_model_id', 'specification_id')
|
||||||
def _compute_tool_name(self):
|
def _compute_tool_name(self):
|
||||||
for item in self:
|
for item in self:
|
||||||
@@ -113,6 +124,10 @@ class ResProductMo(models.Model):
|
|||||||
name = '%s%s' % (item.cutting_tool_model_id.name, item.specification_id.name)
|
name = '%s%s' % (item.cutting_tool_model_id.name, item.specification_id.name)
|
||||||
item.name = name
|
item.name = name
|
||||||
|
|
||||||
|
def _get_process_parameters_product(self, production_process):
|
||||||
|
return self.env['product.template'].search(
|
||||||
|
[('server_product_process_parameters_id', '=', production_process.id)]).seller_ids[0]
|
||||||
|
|
||||||
@api.onchange('cutting_tool_model_id')
|
@api.onchange('cutting_tool_model_id')
|
||||||
def _onchange_cutting_tool_model_id(self):
|
def _onchange_cutting_tool_model_id(self):
|
||||||
for item in self:
|
for item in self:
|
||||||
@@ -640,6 +655,10 @@ class ResProductMo(models.Model):
|
|||||||
'part_number': item.get('part_number') or '',
|
'part_number': item.get('part_number') or '',
|
||||||
'active': True,
|
'active': True,
|
||||||
}
|
}
|
||||||
|
tax_id = self.env['account.tax'].sudo().search(
|
||||||
|
[('type_tax_use', '=', 'sale'), ('amount', '=', item.get('tax')), ('price_include', '=', 'True')])
|
||||||
|
if tax_id:
|
||||||
|
vals.update({'taxes_id':[(6,0,[int(tax_id)])]})
|
||||||
copy_product_id.sudo().write(vals)
|
copy_product_id.sudo().write(vals)
|
||||||
product_id.product_tmpl_id.active = False
|
product_id.product_tmpl_id.active = False
|
||||||
return copy_product_id
|
return copy_product_id
|
||||||
@@ -800,7 +819,7 @@ class ResProductFixture(models.Model):
|
|||||||
diameter = fields.Float('直径(mm)', digits=(16, 2))
|
diameter = fields.Float('直径(mm)', digits=(16, 2))
|
||||||
|
|
||||||
# '零点卡盘' 字段
|
# '零点卡盘' 字段
|
||||||
weight = fields.Float('重量(mm)', digits=(16, 2))
|
weight = fields.Float('重量(kg)', digits=(16, 2))
|
||||||
orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2))
|
orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2))
|
||||||
clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2))
|
clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2))
|
||||||
clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数')
|
clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数')
|
||||||
@@ -947,6 +966,7 @@ class SfMaintenanceEquipmentAndProductTemplate(models.Model):
|
|||||||
raise ValidationError("机床基坐标获取失败")
|
raise ValidationError("机床基坐标获取失败")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SfMaintenanceEquipmentTool(models.Model):
|
class SfMaintenanceEquipmentTool(models.Model):
|
||||||
_name = 'maintenance.equipment.tool'
|
_name = 'maintenance.equipment.tool'
|
||||||
_description = '机床刀位'
|
_description = '机床刀位'
|
||||||
|
|||||||
@@ -217,6 +217,23 @@ class StockRule(models.Model):
|
|||||||
(
|
(
|
||||||
p.move_dest_ids.procure_method != 'make_to_order' and not
|
p.move_dest_ids.procure_method != 'make_to_order' and not
|
||||||
p.move_raw_ids and not p.workorder_ids)).action_confirm()
|
p.move_raw_ids and not p.workorder_ids)).action_confirm()
|
||||||
|
# 处理 根据制造订单生成的采购单坯料入库时到原材料库,手动将原材料位置该为坯料存货区
|
||||||
|
for production in productions:
|
||||||
|
if production.picking_ids:
|
||||||
|
product_type_id = production.picking_ids[0].move_ids[0].product_id.categ_id
|
||||||
|
if product_type_id.name == '坯料':
|
||||||
|
location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')])
|
||||||
|
if not location_id:
|
||||||
|
logging.info(f'没有搜索到【坯料存货区】: {location_id}')
|
||||||
|
break
|
||||||
|
for picking_id in production.picking_ids:
|
||||||
|
if picking_id.picking_type_id.name == '内部调拨':
|
||||||
|
if picking_id.location_dest_id.product_type != product_type_id:
|
||||||
|
picking_id.location_dest_id = location_id.id
|
||||||
|
elif picking_id.picking_type_id.name == '生产发料':
|
||||||
|
if picking_id.location_id.product_type != product_type_id:
|
||||||
|
picking_id.location_id = location_id.id
|
||||||
|
|
||||||
for production in productions:
|
for production in productions:
|
||||||
'''
|
'''
|
||||||
创建制造订单时生成序列号
|
创建制造订单时生成序列号
|
||||||
@@ -272,6 +289,61 @@ class StockRule(models.Model):
|
|||||||
product_id_to_production_names[product_id] = [production.name for production in all_production]
|
product_id_to_production_names[product_id] = [production.name for production in all_production]
|
||||||
for production_item in productions:
|
for production_item in productions:
|
||||||
if production_item.product_id.id in product_id_to_production_names:
|
if production_item.product_id.id in product_id_to_production_names:
|
||||||
|
if production_item.product_id.model_process_parameters_ids:
|
||||||
|
is_purchase = False
|
||||||
|
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids,
|
||||||
|
key=lambda w: w.id)
|
||||||
|
|
||||||
|
consecutive_process_parameters = []
|
||||||
|
m = 0
|
||||||
|
for i in range(len(sorted_process_parameters) - 1):
|
||||||
|
if m == 0:
|
||||||
|
is_purchase = False
|
||||||
|
if self.env['product.template']._get_process_parameters_product(
|
||||||
|
sorted_process_parameters[i]).partner_id == self.env[
|
||||||
|
'product.template']._get_process_parameters_product(sorted_process_parameters[
|
||||||
|
i + 1]).partner_id and \
|
||||||
|
sorted_process_parameters[i].gain_way == '外协':
|
||||||
|
if sorted_process_parameters[i] not in consecutive_process_parameters:
|
||||||
|
consecutive_process_parameters.append(sorted_process_parameters[i])
|
||||||
|
consecutive_process_parameters.append(sorted_process_parameters[i + 1])
|
||||||
|
m += 1
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if m == len(consecutive_process_parameters) - 1 and m != 0:
|
||||||
|
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
|
if sorted_process_parameters[i] in consecutive_process_parameters:
|
||||||
|
is_purchase = True
|
||||||
|
consecutive_process_parameters = []
|
||||||
|
m = 0
|
||||||
|
# 当前面的连续外协采购单生成再生成当前外协采购单
|
||||||
|
if is_purchase is False:
|
||||||
|
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
|
if m == len(consecutive_process_parameters) - 1 and m != 0:
|
||||||
|
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
|
if sorted_process_parameters[i] in consecutive_process_parameters:
|
||||||
|
is_purchase = True
|
||||||
|
consecutive_process_parameters = []
|
||||||
|
m = 0
|
||||||
|
if m == len(consecutive_process_parameters) - 1 and m != 0:
|
||||||
|
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
|
if is_purchase is False and m == 0:
|
||||||
|
if len(sorted_process_parameters) == 1:
|
||||||
|
self.env['purchase.order'].get_purchase_order(sorted_process_parameters,
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
|
else:
|
||||||
|
self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i],
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
# # 同一个产品多个制造订单对应一个编程单和模型库
|
# # 同一个产品多个制造订单对应一个编程单和模型库
|
||||||
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
||||||
if not production_item.programming_no:
|
if not production_item.programming_no:
|
||||||
@@ -498,7 +570,7 @@ class StockPicking(models.Model):
|
|||||||
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
|
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
|
||||||
('location_id', '=', self.env['stock.location'].search(
|
('location_id', '=', self.env['stock.location'].search(
|
||||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
||||||
('origin', '=', self.origin)])
|
('origin', '=', self.origin), ('picking_id', '=', self.id)])
|
||||||
if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id:
|
if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id:
|
||||||
if move_out.origin == move_in.origin:
|
if move_out.origin == move_in.origin:
|
||||||
if move_out.picking_id.state != 'done':
|
if move_out.picking_id.state != 'done':
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
groups="sf_base.group_sf_mrp_user"/>
|
groups="sf_base.group_sf_mrp_user"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="(//header//button[@name='button_scrap'])" position="replace">
|
<xpath expr="(//header//button[@name='button_scrap'])" position="replace">
|
||||||
<button name="button_scrap" invisible="1"/>
|
<button name="button_scrap" invisible="0"/>
|
||||||
<button name="do_update_program" string="更新程序" type="object" groups="sf_base.group_sf_mrp_user"
|
<button name="do_update_program" string="更新程序" type="object" groups="sf_base.group_sf_mrp_user"
|
||||||
confirm="是否确认更新程序"
|
confirm="是否确认更新程序"
|
||||||
attrs="{'invisible': ['|',('state', '!=', 'rework'),('programming_state', '!=', '已编程未下发')]}"/>
|
attrs="{'invisible': ['|',('state', '!=', 'rework'),('programming_state', '!=', '已编程未下发')]}"/>
|
||||||
@@ -285,7 +285,7 @@
|
|||||||
|
|
||||||
<xpath expr="//sheet//notebook//page[@name='operations']" position="after">
|
<xpath expr="//sheet//notebook//page[@name='operations']" position="after">
|
||||||
<page string="检测结果" attrs="{'invisible': [('detection_result_ids', '=', [])]}">
|
<page string="检测结果" attrs="{'invisible': [('detection_result_ids', '=', [])]}">
|
||||||
<field name="detection_result_ids" string="" readonly="1">
|
<field name="detection_result_ids" string="" readonly="0">
|
||||||
<tree sample="1">
|
<tree sample="1">
|
||||||
<field name="production_id" invisible="1"/>
|
<field name="production_id" invisible="1"/>
|
||||||
<field name="processing_panel"/>
|
<field name="processing_panel"/>
|
||||||
@@ -568,7 +568,7 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form>
|
<form>
|
||||||
<group>
|
<group>
|
||||||
<!-- <field name="handle_result"/>-->
|
<field name="handle_result"/>
|
||||||
<field name="test_report" readonly="1" widget="pdf_viewer"/>
|
<field name="test_report" readonly="1" widget="pdf_viewer"/>
|
||||||
</group>
|
</group>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -118,6 +118,17 @@
|
|||||||
statusbar_visible="pending,waiting,ready,progress,to be detected,done,rework"/>
|
statusbar_visible="pending,waiting,ready,progress,to be detected,done,rework"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//div[@name='button_box']" position="inside">
|
<xpath expr="//div[@name='button_box']" position="inside">
|
||||||
|
<button type="object" name="action_view_surface_technics_purchase" class="oe_stat_button"
|
||||||
|
icon="fa-credit-card"
|
||||||
|
groups="base.group_user,sf_base.group_sf_order_user"
|
||||||
|
attrs="{'invisible': [('surface_technics_purchase_count', '=', 0),('routing_type', '!=', '表面工艺')]}">
|
||||||
|
<div class="o_field_widget o_stat_info">
|
||||||
|
<span class="o_stat_value">
|
||||||
|
<field name="surface_technics_purchase_count"/>
|
||||||
|
</span>
|
||||||
|
<span class="o_stat_text">采购</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
<button type="object" name="action_view_surface_technics_picking" class="oe_stat_button" icon="fa-truck"
|
<button type="object" name="action_view_surface_technics_picking" class="oe_stat_button" icon="fa-truck"
|
||||||
groups="base.group_user,sf_base.group_sf_order_user"
|
groups="base.group_user,sf_base.group_sf_order_user"
|
||||||
attrs="{'invisible': [('surface_technics_picking_count', '=', 0)]}">
|
attrs="{'invisible': [('surface_technics_picking_count', '=', 0)]}">
|
||||||
|
|||||||
@@ -88,8 +88,8 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
||||||
'cancel'] and ac.processing_panel == panel)
|
'cancel'] and ac.processing_panel == panel)
|
||||||
if cnc_workorder:
|
if cnc_workorder:
|
||||||
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
||||||
# panel)
|
panel)
|
||||||
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
|
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
|
||||||
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
|
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
|
||||||
files_panel = os.listdir(program_path_tmp_panel)
|
files_panel = os.listdir(program_path_tmp_panel)
|
||||||
|
|||||||
@@ -371,6 +371,7 @@ class QuickEasyOrder(models.Model):
|
|||||||
product_bom_purchase.bom_create_line_has(purchase_embryo)
|
product_bom_purchase.bom_create_line_has(purchase_embryo)
|
||||||
order_id.with_user(self.env.ref("base.user_admin")).sale_order_create_line(product, item)
|
order_id.with_user(self.env.ref("base.user_admin")).sale_order_create_line(product, item)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logging.error('工厂创建销售订单和产品失败,请联系管理员'.format(e))
|
||||||
# self.cr.rollback()
|
# self.cr.rollback()
|
||||||
return UserError('工厂创建销售订单和产品失败,请联系管理员')
|
return UserError('工厂创建销售订单和产品失败,请联系管理员')
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class ReSaleOrder(models.Model):
|
|||||||
deadline_of_delivery, payments_way, pay_way):
|
deadline_of_delivery, payments_way, pay_way):
|
||||||
now_time = datetime.datetime.now()
|
now_time = datetime.datetime.now()
|
||||||
partner = self.get_customer()
|
partner = self.get_customer()
|
||||||
order_id = self.env['sale.order'].sudo().create({
|
data ={
|
||||||
'company_id': company_id.id,
|
'company_id': company_id.id,
|
||||||
'date_order': now_time,
|
'date_order': now_time,
|
||||||
'name': self.env['ir.sequence'].next_by_code('sale.order', sequence_date=now_time),
|
'name': self.env['ir.sequence'].next_by_code('sale.order', sequence_date=now_time),
|
||||||
@@ -66,10 +66,18 @@ class ReSaleOrder(models.Model):
|
|||||||
'person_of_delivery': delivery_name,
|
'person_of_delivery': delivery_name,
|
||||||
'telephone_of_delivery': delivery_telephone,
|
'telephone_of_delivery': delivery_telephone,
|
||||||
'address_of_delivery': delivery_address,
|
'address_of_delivery': delivery_address,
|
||||||
'deadline_of_delivery': deadline_of_delivery,
|
|
||||||
'payments_way': payments_way,
|
'payments_way': payments_way,
|
||||||
'pay_way': pay_way,
|
'pay_way': pay_way,
|
||||||
})
|
}
|
||||||
|
if deadline_of_delivery:
|
||||||
|
# deadline_of_delivery字段存在为false字符串情况
|
||||||
|
if not isinstance(deadline_of_delivery, str):
|
||||||
|
data.update({'deadline_of_delivery': deadline_of_delivery})
|
||||||
|
else:
|
||||||
|
if deadline_of_delivery!="False":
|
||||||
|
data.update({'deadline_of_delivery': deadline_of_delivery})
|
||||||
|
|
||||||
|
order_id = self.env['sale.order'].sudo().create(data)
|
||||||
return order_id
|
return order_id
|
||||||
|
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
@@ -211,6 +219,47 @@ class RePurchaseOrder(models.Model):
|
|||||||
if not line.taxes_id:
|
if not line.taxes_id:
|
||||||
raise UserError('请对【产品】中的【税】进行选择')
|
raise UserError('请对【产品】中的【税】进行选择')
|
||||||
|
|
||||||
|
def get_purchase_order(self, consecutive_process_parameters, production, product_id_to_production_names):
|
||||||
|
is_exist = True
|
||||||
|
server_product_process = []
|
||||||
|
production_process = product_id_to_production_names.get(
|
||||||
|
production.product_id.id)
|
||||||
|
for pp in consecutive_process_parameters:
|
||||||
|
if pp.gain_way == '外协':
|
||||||
|
server_product = self.env['product.template'].search(
|
||||||
|
[('server_product_process_parameters_id', '=', pp.id),
|
||||||
|
('detailed_type', '=', 'service')])
|
||||||
|
purchase_order_line = self.env['purchase.order.line'].search(
|
||||||
|
[('product_id', '=', server_product.id), ('product_qty', '=', len(production_process))])
|
||||||
|
if not purchase_order_line:
|
||||||
|
is_exist = False
|
||||||
|
server_product_process.append((0, 0, {
|
||||||
|
'product_id': server_product.product_variant_id.id,
|
||||||
|
'product_qty': len(production_process),
|
||||||
|
'product_uom': server_product.uom_id.id
|
||||||
|
}))
|
||||||
|
else:
|
||||||
|
for item in purchase_order_line:
|
||||||
|
purchase_order = self.env['purchase.order'].search(
|
||||||
|
[('state', '=', 'draft'), ('origin', 'ilike', production.name),
|
||||||
|
('id', '=', item.order_id.id)])
|
||||||
|
if not purchase_order:
|
||||||
|
is_exist = False
|
||||||
|
server_product_process.append((0, 0, {
|
||||||
|
'product_id': server_product.product_variant_id.id,
|
||||||
|
'product_qty': len(production_process),
|
||||||
|
'product_uom': server_product.uom_id.id
|
||||||
|
}))
|
||||||
|
if is_exist is False:
|
||||||
|
purchase_order = self.env['purchase.order'].search(
|
||||||
|
[('state', '=', 'draft'), ('origin', '=', ','.join(production_process))])
|
||||||
|
if not purchase_order:
|
||||||
|
self.env['purchase.order'].sudo().create({
|
||||||
|
'partner_id': server_product.seller_ids.partner_id.id,
|
||||||
|
'origin': ','.join(production_process),
|
||||||
|
'state': 'draft',
|
||||||
|
'order_line': server_product_process})
|
||||||
|
|
||||||
@api.onchange('order_line')
|
@api.onchange('order_line')
|
||||||
def _onchange_order_line(self):
|
def _onchange_order_line(self):
|
||||||
for order in self:
|
for order in self:
|
||||||
@@ -230,6 +279,14 @@ class RePurchaseOrder(models.Model):
|
|||||||
if picking_id.move_ids:
|
if picking_id.move_ids:
|
||||||
for move_id in picking_id.move_ids:
|
for move_id in picking_id.move_ids:
|
||||||
move_id.put_move_line()
|
move_id.put_move_line()
|
||||||
|
for line in item.order_line:
|
||||||
|
if line.product_id.categ_type == '表面工艺':
|
||||||
|
for production_name in item.origin.split(','):
|
||||||
|
production = self.env['mrp.production'].search([('name', '=', production_name)])
|
||||||
|
for workorder in production.workorder_ids.filtered(
|
||||||
|
lambda wd: wd.routing_type == '表面工艺' and wd.state == 'waiting' and line.product_id.server_product_process_parameters_id == wd.surface_technics_parameters_id):
|
||||||
|
workorder.state = 'ready'
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,15 +34,13 @@
|
|||||||
<!-- </xpath>-->
|
<!-- </xpath>-->
|
||||||
<xpath expr="//form/header/button[@name='action_confirm'][2]" position="replace">
|
<xpath expr="//form/header/button[@name='action_confirm'][2]" position="replace">
|
||||||
<button name="action_confirm" data-hotkey="v"
|
<button name="action_confirm" data-hotkey="v"
|
||||||
string="确认" type="object" context="{'validate_analytic': True}"
|
string="确认接单" type="object" context="{'validate_analytic': True}"
|
||||||
attrs="{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&','&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel']),('delivery_status', '!=', False)]}"/>
|
attrs="{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&','&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel']),('delivery_status', '!=', False)]}"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='action_cancel']" position="attributes">
|
<xpath expr="//form/header/button[@name='action_cancel']" position="attributes">
|
||||||
<attribute name="attrs">{'invisible': ['|','&',('state', 'in',
|
<attribute name="attrs">{'invisible': ['|','&',('check_status', '!=', 'approved'),('state',
|
||||||
['cancel','draft']),('check_status',
|
'in', ['draft','cancel']),'&','&',('check_status', '=', 'approved'),('state', 'in',
|
||||||
'in',
|
['sale','cancel']),('delivery_status', '!=', False)]}
|
||||||
[False,'approved']),'&',('check_status', '=', 'approved'),('state', 'in',
|
|
||||||
['sale','cancel','draft'])]}
|
|
||||||
</attribute>
|
</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">
|
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">
|
||||||
|
|||||||
@@ -1103,7 +1103,7 @@ class StockMove(models.Model):
|
|||||||
move_line_ids = picking_id.move_line_ids
|
move_line_ids = picking_id.move_line_ids
|
||||||
for move_line_id in move_line_ids:
|
for move_line_id in move_line_ids:
|
||||||
for res in data:
|
for res in data:
|
||||||
if move_line_id.lot_id.product_id == res['lot_id'].product_id:
|
if move_line_id.product_id == res['lot_id'].product_id:
|
||||||
move_line_id.write({
|
move_line_id.write({
|
||||||
'destination_location_id': res.get('destination').id,
|
'destination_location_id': res.get('destination').id,
|
||||||
'lot_id': res.get('lot_id').id
|
'lot_id': res.get('lot_id').id
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
<!-- ]"/> -->
|
<!-- ]"/> -->
|
||||||
<field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), '|',
|
<field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), '|',
|
||||||
('location_status', '=', '空闲'), ('product_id', '=', current_product_id), ('product_sn_id',
|
('location_status', '=', '空闲'), ('product_id', '=', current_product_id), ('product_sn_id',
|
||||||
'=', there_is_no_sn)]" options="{'no_create': True,'no_create_edit':True}"/>
|
'=', there_is_no_sn), ('rotative_Boolean', '=', False)]"
|
||||||
|
options="{'no_create': True,'no_create_edit':True}"/>
|
||||||
<field name="rfid_barcode" string="Rfid"/>
|
<field name="rfid_barcode" string="Rfid"/>
|
||||||
|
|
||||||
<!-- <field name="location_dest_id_product_type"/> -->
|
<!-- <field name="location_dest_id_product_type"/> -->
|
||||||
|
|||||||
Reference in New Issue
Block a user