Merge branch 'develop' into feature/sale_order_route_pick
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
import traceback
|
||||||
|
|
||||||
from odoo import http
|
from odoo import http
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
from odoo.addons.sf_bf_connect.controllers.controllers import Sf_Bf_Connect
|
from odoo.addons.sf_bf_connect.controllers.controllers import Sf_Bf_Connect
|
||||||
@@ -44,7 +46,8 @@ class JikimoSaleRoutePicking(Sf_Bf_Connect):
|
|||||||
i += 1
|
i += 1
|
||||||
res['factory_order_no'] = order_id.name
|
res['factory_order_no'] = order_id.name
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.info('get_bfm_process_order_list error:%s' % e)
|
traceback_error = traceback.format_exc()
|
||||||
|
logging.error('get_bfm_process_order_list error: %s' % traceback_error)
|
||||||
res['status'] = -1
|
res['status'] = -1
|
||||||
res['message'] = '工厂创建销售订单和产品失败,请联系管理员'
|
res['message'] = '工厂创建销售订单和产品失败,请联系管理员'
|
||||||
request.cr.rollback()
|
request.cr.rollback()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import traceback
|
||||||
|
|
||||||
from odoo import http
|
from odoo import http
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
|
|
||||||
@@ -123,7 +125,8 @@ class Sf_Bf_Connect(http.Controller):
|
|||||||
res['factory_order_no'] = order_id.name
|
res['factory_order_no'] = order_id.name
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info('get_bfm_process_order_list error:%s' % e)
|
traceback_error = traceback.format_exc()
|
||||||
|
logging.error('get_bfm_process_order_list error: %s' % traceback_error)
|
||||||
res['status'] = -1
|
res['status'] = -1
|
||||||
res['message'] = '工厂创建销售订单和产品失败,请联系管理员'
|
res['message'] = '工厂创建销售订单和产品失败,请联系管理员'
|
||||||
request.cr.rollback()
|
request.cr.rollback()
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ class MrpProduction(models.Model):
|
|||||||
|
|
||||||
@api.depends(
|
@api.depends(
|
||||||
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state',
|
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state',
|
||||||
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state', 'programming_state')
|
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state', 'programming_state', 'is_adjust')
|
||||||
def _compute_state(self):
|
def _compute_state(self):
|
||||||
for production in self:
|
for production in self:
|
||||||
if not production.state or not production.product_uom_id:
|
if not production.state or not production.product_uom_id:
|
||||||
@@ -314,11 +314,16 @@ class MrpProduction(models.Model):
|
|||||||
if not production.workorder_ids or production.is_adjust is True:
|
if not production.workorder_ids or production.is_adjust is True:
|
||||||
production.state = 'technology_to_confirmed'
|
production.state = 'technology_to_confirmed'
|
||||||
else:
|
else:
|
||||||
production.state = 'confirmed'
|
if production.is_adjust is True:
|
||||||
|
production.state = 'technology_to_confirmed'
|
||||||
|
else:
|
||||||
|
production.state = 'confirmed'
|
||||||
elif production.state == 'pending_cam' and production.schedule_state == '未排':
|
elif production.state == 'pending_cam' and production.schedule_state == '未排':
|
||||||
production.state = 'confirmed'
|
production.state = 'confirmed'
|
||||||
elif production.state == 'to_close' and production.schedule_state == '已排':
|
elif production.state == 'to_close' and production.schedule_state == '已排':
|
||||||
production.state = 'pending_cam'
|
production.state = 'pending_cam'
|
||||||
|
elif production.state == 'confirmed' and production.is_adjust is True:
|
||||||
|
production.state = 'technology_to_confirmed'
|
||||||
if production.state == 'progress':
|
if production.state == 'progress':
|
||||||
if all(wo_state not in ('progress', 'done', 'rework', 'scrap') for wo_state in
|
if all(wo_state not in ('progress', 'done', 'rework', 'scrap') for wo_state in
|
||||||
production.workorder_ids.mapped('state')):
|
production.workorder_ids.mapped('state')):
|
||||||
@@ -383,9 +388,12 @@ class MrpProduction(models.Model):
|
|||||||
def technology_confirm(self):
|
def technology_confirm(self):
|
||||||
process_parameters = []
|
process_parameters = []
|
||||||
account_moves = []
|
account_moves = []
|
||||||
|
parameters_not = []
|
||||||
special_design = self.technology_design_ids.filtered(
|
special_design = self.technology_design_ids.filtered(
|
||||||
lambda a: a.routing_tag == 'special' and a.is_auto is False)
|
lambda a: a.routing_tag == 'special' and a.is_auto is False)
|
||||||
for special in special_design:
|
for special in special_design:
|
||||||
|
if special.route_id.routing_type == '表面工艺' and not special.process_parameters_id:
|
||||||
|
parameters_not.append(special.route_id.name)
|
||||||
if special.process_parameters_id:
|
if special.process_parameters_id:
|
||||||
product_production_process = self.env['product.template'].search(
|
product_production_process = self.env['product.template'].search(
|
||||||
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
|
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
|
||||||
@@ -399,6 +407,8 @@ class MrpProduction(models.Model):
|
|||||||
account_moves.append(purchase.name)
|
account_moves.append(purchase.name)
|
||||||
if account_moves:
|
if account_moves:
|
||||||
raise UserError(_("请联系工厂生产经理对采购订单为%s生成的账单进行取消", ", ".join(account_moves)))
|
raise UserError(_("请联系工厂生产经理对采购订单为%s生成的账单进行取消", ", ".join(account_moves)))
|
||||||
|
if parameters_not:
|
||||||
|
raise UserError(_("【工艺设计】-【工序】为%s未选择参数,请选择", ", ".join(parameters_not)))
|
||||||
if process_parameters:
|
if process_parameters:
|
||||||
raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters)))
|
raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters)))
|
||||||
# 判断同一个加工面的标准工序的顺序是否依次排序
|
# 判断同一个加工面的标准工序的顺序是否依次排序
|
||||||
@@ -1126,6 +1136,14 @@ class MrpProduction(models.Model):
|
|||||||
cloud_programming = None
|
cloud_programming = None
|
||||||
if self.programming_state in ['已编程']:
|
if self.programming_state in ['已编程']:
|
||||||
cloud_programming = self._cron_get_programming_state()
|
cloud_programming = self._cron_get_programming_state()
|
||||||
|
result_ids = self.detection_result_ids.filtered(lambda dr: dr.handle_result == '待处理')
|
||||||
|
work_ids = []
|
||||||
|
if result_ids:
|
||||||
|
for result_id in result_ids:
|
||||||
|
work_ids.append(self.workorder_ids.filtered(
|
||||||
|
lambda wk: (wk.name == result_id.routing_type
|
||||||
|
and wk.processing_panel == result_id.processing_panel
|
||||||
|
and wk.state == 'done')).id)
|
||||||
return {
|
return {
|
||||||
'name': _('返工'),
|
'name': _('返工'),
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
@@ -1134,7 +1152,7 @@ class MrpProduction(models.Model):
|
|||||||
'target': 'new',
|
'target': 'new',
|
||||||
'context': {
|
'context': {
|
||||||
'default_production_id': self.id,
|
'default_production_id': self.id,
|
||||||
'default_workorder_ids': self.workorder_ids.filtered(lambda wk: wk.state == 'done').ids,
|
'default_workorder_ids': work_ids,
|
||||||
'default_reprogramming_num': cloud_programming['reprogramming_num'],
|
'default_reprogramming_num': cloud_programming['reprogramming_num'],
|
||||||
'default_programming_state': cloud_programming['programming_state'],
|
'default_programming_state': cloud_programming['programming_state'],
|
||||||
'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False
|
'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False
|
||||||
@@ -1288,6 +1306,7 @@ class MrpProduction(models.Model):
|
|||||||
raise_user_error=not self.env.context.get('from_orderpoint'))
|
raise_user_error=not self.env.context.get('from_orderpoint'))
|
||||||
productions = self.env['mrp.production'].sudo().search(
|
productions = self.env['mrp.production'].sudo().search(
|
||||||
[('origin', '=', self.origin)], order='id desc', limit=1)
|
[('origin', '=', self.origin)], order='id desc', limit=1)
|
||||||
|
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
|
||||||
move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc')
|
move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc')
|
||||||
for mo in move:
|
for mo in move:
|
||||||
domain = []
|
domain = []
|
||||||
@@ -1314,7 +1333,6 @@ class MrpProduction(models.Model):
|
|||||||
mo_move.write({'reference': sfp_move.reference, 'partner_id': sfp_move.partner_id.id,
|
mo_move.write({'reference': sfp_move.reference, 'partner_id': sfp_move.partner_id.id,
|
||||||
'picking_id': sfp_move.picking_id.id, 'picking_type_id': sfp_move.picking_type_id.id,
|
'picking_id': sfp_move.picking_id.id, 'picking_type_id': sfp_move.picking_type_id.id,
|
||||||
'production_id': False})
|
'production_id': False})
|
||||||
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
|
|
||||||
# productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
|
# productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
|
||||||
# {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
|
# {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
|
||||||
stock_picking_remanufacture = self.env['stock.picking'].search([('origin', '=', productions.name)])
|
stock_picking_remanufacture = self.env['stock.picking'].search([('origin', '=', productions.name)])
|
||||||
@@ -1389,7 +1407,7 @@ class MrpProduction(models.Model):
|
|||||||
def _compute_production_type(self):
|
def _compute_production_type(self):
|
||||||
for production in self:
|
for production in self:
|
||||||
production.production_type = '自动化产线加工' if not production.product_id.is_manual_processing else '人工线下加工'
|
production.production_type = '自动化产线加工' if not production.product_id.is_manual_processing else '人工线下加工'
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
"""
|
"""
|
||||||
@@ -1405,7 +1423,7 @@ class MrpProduction(models.Model):
|
|||||||
vals['name'] = self.env['stock.picking.type'].browse(picking_type_id).sequence_id.next_by_id()
|
vals['name'] = self.env['stock.picking.type'].browse(picking_type_id).sequence_id.next_by_id()
|
||||||
if not vals.get('procurement_group_id'):
|
if not vals.get('procurement_group_id'):
|
||||||
product_id = self.env['product.product'].browse(vals['product_id'])
|
product_id = self.env['product.product'].browse(vals['product_id'])
|
||||||
if product_id.product_tmpl_id.single_manufacturing:
|
if product_id.product_tmpl_id.single_manufacturing:
|
||||||
if product_id.id not in product_group_id.keys():
|
if product_id.id not in product_group_id.keys():
|
||||||
procurement_group_vals = self._prepare_procurement_group_vals(vals)
|
procurement_group_vals = self._prepare_procurement_group_vals(vals)
|
||||||
group_id = self.env["procurement.group"].create(procurement_group_vals).id
|
group_id = self.env["procurement.group"].create(procurement_group_vals).id
|
||||||
@@ -1415,23 +1433,29 @@ class MrpProduction(models.Model):
|
|||||||
vals['procurement_group_id'] = product_group_id[product_id.id]
|
vals['procurement_group_id'] = product_group_id[product_id.id]
|
||||||
return super(MrpProduction, self).create(vals_list)
|
return super(MrpProduction, self).create(vals_list)
|
||||||
|
|
||||||
@api.depends('procurement_group_id.stock_move_ids.created_purchase_line_id.order_id', 'procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id')
|
@api.depends('procurement_group_id.stock_move_ids.created_purchase_line_id.order_id',
|
||||||
|
'procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id')
|
||||||
def _compute_purchase_order_count(self):
|
def _compute_purchase_order_count(self):
|
||||||
for production in self:
|
for production in self:
|
||||||
# 找到来源的第一张制造订单的采购组
|
# 找到来源的第一张制造订单的采购组
|
||||||
if production.product_id.product_tmpl_id.single_manufacturing == True:
|
if production.product_id.product_tmpl_id.single_manufacturing == True:
|
||||||
first_production = self.env['mrp.production'].search([('origin', '=', production.origin), ('product_id', '=', production.product_id.id)], limit=1, order='id asc')
|
first_production = self.env['mrp.production'].search(
|
||||||
production.purchase_order_count = len(first_production.procurement_group_id.stock_move_ids.created_purchase_line_id.order_id |
|
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)], limit=1,
|
||||||
first_production.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id)
|
order='id asc')
|
||||||
|
production.purchase_order_count = len(
|
||||||
|
first_production.procurement_group_id.stock_move_ids.created_purchase_line_id.order_id |
|
||||||
|
first_production.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id)
|
||||||
else:
|
else:
|
||||||
production.purchase_order_count = len(production.procurement_group_id.stock_move_ids.created_purchase_line_id.order_id |
|
production.purchase_order_count = len(
|
||||||
production.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id)
|
production.procurement_group_id.stock_move_ids.created_purchase_line_id.order_id |
|
||||||
|
production.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id)
|
||||||
|
|
||||||
@api.depends('procurement_group_id', 'procurement_group_id.stock_move_ids.group_id')
|
@api.depends('procurement_group_id', 'procurement_group_id.stock_move_ids.group_id')
|
||||||
def _compute_picking_ids(self):
|
def _compute_picking_ids(self):
|
||||||
for order in self:
|
for order in self:
|
||||||
if order.product_id.product_tmpl_id.single_manufacturing == True:
|
if order.product_id.product_tmpl_id.single_manufacturing == True:
|
||||||
first_order = self.env['mrp.production'].search([('origin', '=', order.origin), ('product_id', '=', order.product_id.id)], limit=1, order='id asc')
|
first_order = self.env['mrp.production'].search(
|
||||||
|
[('origin', '=', order.origin), ('product_id', '=', order.product_id.id)], limit=1, order='id asc')
|
||||||
order.picking_ids = self.env['stock.picking'].search([
|
order.picking_ids = self.env['stock.picking'].search([
|
||||||
('group_id', '=', first_order.procurement_group_id.id), ('group_id', '!=', False),
|
('group_id', '=', first_order.procurement_group_id.id), ('group_id', '!=', False),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
# if technology_design.is_auto is False:
|
# if technology_design.is_auto is False:
|
||||||
# domain = [('origin', '=', order.production_id.name)]
|
# domain = [('origin', '=', order.production_id.name)]
|
||||||
# else:
|
# else:
|
||||||
domain = [('purchase_type', '=', 'consignment'),('origin', '=', ','.join(production_list))]
|
domain = [('purchase_type', '=', 'consignment'), ('origin', '=', ','.join(production_list))]
|
||||||
purchase = self.env['purchase.order'].search(domain)
|
purchase = self.env['purchase.order'].search(domain)
|
||||||
if not purchase:
|
if not purchase:
|
||||||
order.surface_technics_purchase_count = 0
|
order.surface_technics_purchase_count = 0
|
||||||
@@ -1062,7 +1062,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0):
|
if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0):
|
||||||
continue
|
continue
|
||||||
# ===== 对所有按序号排序的非[进行中、完成、返工、取消]状态的工单,除了第一条之外的工单状态都设置为[等待其他工单] =====
|
# ===== 对所有按序号排序的非[进行中、完成、返工、取消]状态的工单,除了第一条之外的工单状态都设置为[等待其他工单] =====
|
||||||
logging.info(workorder.state)
|
# logging.info(workorder.state)
|
||||||
work_ids = workorder.production_id.workorder_ids.filtered(
|
work_ids = workorder.production_id.workorder_ids.filtered(
|
||||||
lambda wk: wk.state not in ['done', 'rework', 'cancel'])
|
lambda wk: wk.state not in ['done', 'rework', 'cancel'])
|
||||||
if not work_ids:
|
if not work_ids:
|
||||||
@@ -1075,6 +1075,13 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
if workorder.state != 'pending':
|
if workorder.state != 'pending':
|
||||||
workorder.state = 'pending'
|
workorder.state = 'pending'
|
||||||
continue
|
continue
|
||||||
|
# ================= 如果制造订单制造类型为【人工线下加工】==========================
|
||||||
|
if (workorder.production_id.production_type == '人工线下加工'
|
||||||
|
and workorder.production_id.schedule_state == '已排'
|
||||||
|
and len(workorder.production_id.picking_ids.filtered(
|
||||||
|
lambda w: w.state not in ['done', 'cancel'])) == 0):
|
||||||
|
workorder.state = 'ready'
|
||||||
|
continue
|
||||||
# ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]==========================
|
# ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]==========================
|
||||||
if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework'
|
if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework'
|
||||||
or workorder.production_id.schedule_state != '已排'
|
or workorder.production_id.schedule_state != '已排'
|
||||||
@@ -1096,7 +1103,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
# if purchase_order.picking_ids.filtered(lambda p: p.state in ['waiting', 'confirmed', 'assigned']):
|
# if purchase_order.picking_ids.filtered(lambda p: p.state in ['waiting', 'confirmed', 'assigned']):
|
||||||
# workorder.state = 'waiting'
|
# workorder.state = 'waiting'
|
||||||
# continue
|
# continue
|
||||||
if workorder.routing_type == '表面工艺':
|
if workorder.technology_design_id.routing_tag == 'special':
|
||||||
if workorder.is_subcontract is False:
|
if workorder.is_subcontract is False:
|
||||||
workorder.state = 'ready'
|
workorder.state = 'ready'
|
||||||
else:
|
else:
|
||||||
@@ -1195,11 +1202,12 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
raise UserError('制造订单【%s】缺少组件的序列号信息!' % self.production_id.name)
|
raise UserError('制造订单【%s】缺少组件的序列号信息!' % self.production_id.name)
|
||||||
self.pro_code = self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name
|
self.pro_code = self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name
|
||||||
# cnc校验
|
# cnc校验
|
||||||
cnc_workorder = self.search(
|
if self.production_id.production_type == '自动化产线加工':
|
||||||
[('production_id', '=', self.production_id.id), ('routing_type', '=', 'CNC加工')],
|
cnc_workorder = self.search(
|
||||||
limit=1, order='id asc')
|
[('production_id', '=', self.production_id.id), ('routing_type', '=', 'CNC加工')],
|
||||||
if not cnc_workorder.cnc_ids:
|
limit=1, order='id asc')
|
||||||
raise UserError(_('该制造订单还未下发CNC程序,请稍后再试'))
|
if not cnc_workorder.cnc_ids:
|
||||||
|
raise UserError(_('该制造订单还未下发CNC程序,请稍后再试'))
|
||||||
else:
|
else:
|
||||||
if self.production_id.tool_state in ['1', '2']:
|
if self.production_id.tool_state in ['1', '2']:
|
||||||
if self.production_id.tool_state == '1':
|
if self.production_id.tool_state == '1':
|
||||||
|
|||||||
@@ -874,8 +874,8 @@ class ResProductMo(models.Model):
|
|||||||
'height': item['model_height'],
|
'height': item['model_height'],
|
||||||
'volume': item['model_long'] * item['model_width'] * item['model_height'],
|
'volume': item['model_long'] * item['model_width'] * item['model_height'],
|
||||||
'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']),
|
'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']),
|
||||||
'model_name': attachment.name,
|
'model_name': attachment.name if attachment else None,
|
||||||
'upload_model_file': [(6, 0, [attachment.id])],
|
'upload_model_file': [(6, 0, [attachment.id])] if attachment else None,
|
||||||
'list_price': item['price'],
|
'list_price': item['price'],
|
||||||
'materials_id': self.env['sf.production.materials'].search(
|
'materials_id': self.env['sf.production.materials'].search(
|
||||||
[('materials_no', '=', item['texture_code'])]).id,
|
[('materials_no', '=', item['texture_code'])]).id,
|
||||||
@@ -924,6 +924,8 @@ class ResProductMo(models.Model):
|
|||||||
return [(6, 0, process_parameters_ids)]
|
return [(6, 0, process_parameters_ids)]
|
||||||
|
|
||||||
def attachment_create(self, name, data):
|
def attachment_create(self, name, data):
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
attachment = self.env['ir.attachment'].create({
|
attachment = self.env['ir.attachment'].create({
|
||||||
'datas': base64.b64decode(data),
|
'datas': base64.b64decode(data),
|
||||||
'type': 'binary',
|
'type': 'binary',
|
||||||
|
|||||||
@@ -337,8 +337,8 @@ class StockRule(models.Model):
|
|||||||
product_routing_workcenter = self.env[model].search(domain, order='sequence asc')
|
product_routing_workcenter = self.env[model].search(domain, order='sequence asc')
|
||||||
if production_item.production_type == '自动化产线加工':
|
if production_item.production_type == '自动化产线加工':
|
||||||
for k in (production_item.product_id.model_processing_panel.split(',')):
|
for k in (production_item.product_id.model_processing_panel.split(',')):
|
||||||
i += 1
|
|
||||||
for route in product_routing_workcenter:
|
for route in product_routing_workcenter:
|
||||||
|
i += 1
|
||||||
technology_design_values.append(
|
technology_design_values.append(
|
||||||
self.env['sf.technology.design'].json_technology_design_str(k, route, i, False))
|
self.env['sf.technology.design'].json_technology_design_str(k, route, i, False))
|
||||||
else:
|
else:
|
||||||
@@ -480,6 +480,8 @@ class ProductionLot(models.Model):
|
|||||||
[('company_id', '=', company.id), ('product_id', '=', product.id),
|
[('company_id', '=', company.id), ('product_id', '=', product.id),
|
||||||
('name', 'ilike', product.name.split('[')[0])],
|
('name', 'ilike', product.name.split('[')[0])],
|
||||||
limit=1, order='name desc')
|
limit=1, order='name desc')
|
||||||
|
if not last_serial:
|
||||||
|
return "%s-%03d" % (product.name, 1)
|
||||||
return self.env['stock.lot'].generate_lot_names1(product.name, last_serial.name, 2)[1]
|
return self.env['stock.lot'].generate_lot_names1(product.name, last_serial.name, 2)[1]
|
||||||
now = datetime.now().strftime("%Y%m%d")
|
now = datetime.now().strftime("%Y%m%d")
|
||||||
if product.cutting_tool_model_id:
|
if product.cutting_tool_model_id:
|
||||||
@@ -973,12 +975,19 @@ class ReStockMove(models.Model):
|
|||||||
创建调拨单时,在此新增或修改调拨单的数据
|
创建调拨单时,在此新增或修改调拨单的数据
|
||||||
"""
|
"""
|
||||||
res = super(ReStockMove, self)._get_new_picking_values()
|
res = super(ReStockMove, self)._get_new_picking_values()
|
||||||
if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨']:
|
## 制造订单报废生成的新制造订单不走合并
|
||||||
production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc')
|
production_remanufacture = None
|
||||||
productions = self.env['mrp.production'].search(
|
if 'origin' in res:
|
||||||
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
|
if self.picking_type_id.name in ['生产发料', '内部调拨']:
|
||||||
res['origin'] = ','.join(productions.mapped('name'))
|
production_remanufacture = self.env['mrp.production'].search(
|
||||||
res['retrospect_ref'] = production.product_id.name
|
[('name', '=', res['origin']), ('is_remanufacture', '=', True)])
|
||||||
|
if not production_remanufacture:
|
||||||
|
if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨']:
|
||||||
|
production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc')
|
||||||
|
productions = self.env['mrp.production'].search(
|
||||||
|
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
|
||||||
|
res['origin'] = ','.join(productions.mapped('name'))
|
||||||
|
res['retrospect_ref'] = production.product_id.name
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ access_sf_model_type_group_sale_director,sf_model_type_group_sale_director,model
|
|||||||
access_sf_model_type_group_purchase_director,sf_model_type_group_purchase_director,model_sf_model_type,sf_base.group_purchase_director,1,0,0,0
|
access_sf_model_type_group_purchase_director,sf_model_type_group_purchase_director,model_sf_model_type,sf_base.group_purchase_director,1,0,0,0
|
||||||
access_sf_model_type_group_plan_director,sf_model_type_group_plan_director,model_sf_model_type,sf_base.group_plan_director,1,0,0,0
|
access_sf_model_type_group_plan_director,sf_model_type_group_plan_director,model_sf_model_type,sf_base.group_plan_director,1,0,0,0
|
||||||
access_sf_product_model_type_routing_sort_group_sf_mrp_user,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
access_sf_product_model_type_routing_sort_group_sf_mrp_user,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
||||||
access_sf_product_model_type_routing_sort_manager,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
|
access_sf_product_model_type_routing_sort_manager,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
|
||||||
access_sf_embryo_model_type_routing_sort_group_sf_mrp_user,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
access_sf_embryo_model_type_routing_sort_group_sf_mrp_user,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
||||||
access_sf_embryo_model_type_routing_sort_manager,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
|
access_sf_embryo_model_type_routing_sort_manager,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
|
||||||
access_sf_surface_technics_model_type_routing_sort,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
access_sf_surface_technics_model_type_routing_sort,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
||||||
access_sf_surface_technics_model_type_routing_sort_manager,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
|
access_sf_surface_technics_model_type_routing_sort_manager,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
|
||||||
access_sf_production_line_group_sf_mrp_user,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_user,1,1,1,0
|
access_sf_production_line_group_sf_mrp_user,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_user,1,1,1,0
|
||||||
access_sf_production_line_manager,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_manager,1,1,1,0
|
access_sf_production_line_manager,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_manager,1,1,1,0
|
||||||
access_maintenance_equipment_tool_group_sf_mrp_user,maintenance_equipment_tool,model_maintenance_equipment_tool,sf_base.group_sf_mrp_user,1,0,0,0
|
access_maintenance_equipment_tool_group_sf_mrp_user,maintenance_equipment_tool,model_maintenance_equipment_tool,sf_base.group_sf_mrp_user,1,0,0,0
|
||||||
@@ -176,6 +176,6 @@ access_sf_production_technology_re_adjust_wizard_group_sf_mrp_manager,sf_product
|
|||||||
access_sf_production_technology_re_adjust_wizard_group_production_engineer,sf_production_technology_re_adjust_wizard_group_production_engineer,model_sf_production_technology_re_adjust_wizard,sf_base.group_production_engineer,1,1,1,0
|
access_sf_production_technology_re_adjust_wizard_group_production_engineer,sf_production_technology_re_adjust_wizard_group_production_engineer,model_sf_production_technology_re_adjust_wizard,sf_base.group_production_engineer,1,1,1,0
|
||||||
|
|
||||||
access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
||||||
access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
|
access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
|
||||||
access_sf_manual_product_model_type_routing_sort_group_plan_dispatch,sf_manual_product_model_type_routing_sort_group_plan_dispatch,model_sf_manual_product_model_type_routing_sort,sf_base.group_plan_dispatch,1,0,0,0
|
access_sf_manual_product_model_type_routing_sort_group_plan_dispatch,sf_manual_product_model_type_routing_sort_group_plan_dispatch,model_sf_manual_product_model_type_routing_sort,sf_base.group_plan_dispatch,1,0,0,0
|
||||||
access_sf_detection_result_manager,sf_detection_result_manager,model_sf_detection_result,,1,1,1,1
|
access_sf_detection_result_manager,sf_detection_result_manager,model_sf_detection_result,,1,1,1,1
|
||||||
|
|||||||
|
@@ -120,7 +120,8 @@
|
|||||||
<!-- <field name="production_line_state" readonly="1"/>-->
|
<!-- <field name="production_line_state" readonly="1"/>-->
|
||||||
<field name="part_name"/>
|
<field name="part_name"/>
|
||||||
<field name="part_number" string="零件图号"/>
|
<field name="part_number" string="零件图号"/>
|
||||||
<field name="tool_state" attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
|
<field name="tool_state"
|
||||||
|
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
|
||||||
<field name="tool_state_remark" string="备注" attrs="{'invisible': [('tool_state', '!=', '1')]}"/>
|
<field name="tool_state_remark" string="备注" attrs="{'invisible': [('tool_state', '!=', '1')]}"/>
|
||||||
<field name="deadline_of_delivery" readonly="1"/>
|
<field name="deadline_of_delivery" readonly="1"/>
|
||||||
<field name="tool_state_remark2" invisible="1"/>
|
<field name="tool_state_remark2" invisible="1"/>
|
||||||
@@ -365,7 +366,8 @@
|
|||||||
<field name="sequence" widget="handle"/>
|
<field name="sequence" widget="handle"/>
|
||||||
<field name="route_id" context="{'production_id': production_id}"
|
<field name="route_id" context="{'production_id': production_id}"
|
||||||
attrs="{'readonly': [('id', '!=', False)]}" options="{'no_create': True}"/>
|
attrs="{'readonly': [('id', '!=', False)]}" options="{'no_create': True}"/>
|
||||||
<field name="process_parameters_id" attrs="{'readonly': [('id', '!=', False)]}"
|
<field name="process_parameters_id"
|
||||||
|
attrs="{'readonly': [('id', '!=', False),('routing_tag', '=', 'standard')]}"
|
||||||
string="参数" context="{'route_id':route_id}" options="{'no_create': True}"/>
|
string="参数" context="{'route_id':route_id}" options="{'no_create': True}"/>
|
||||||
<field name="panel" readonly="1"/>
|
<field name="panel" readonly="1"/>
|
||||||
<field name="routing_tag" readonly="1" widget="badge"
|
<field name="routing_tag" readonly="1" widget="badge"
|
||||||
@@ -387,13 +389,16 @@
|
|||||||
</page>
|
</page>
|
||||||
|
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//sheet/group/group/div[@class='d-flex flex-row align-items-start']/span[last()]" position="attributes">
|
<xpath expr="//sheet/group/group/div[@class='d-flex flex-row align-items-start']/span[last()]"
|
||||||
|
position="attributes">
|
||||||
<attribute name="invisible">True</attribute>
|
<attribute name="invisible">True</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//sheet/group/group/div[@class='d-flex flex-row align-items-start']/button[@name='action_product_forecast_report']" position="attributes">
|
<xpath expr="//sheet/group/group/div[@class='d-flex flex-row align-items-start']/button[@name='action_product_forecast_report']"
|
||||||
|
position="attributes">
|
||||||
<attribute name="invisible">True</attribute>
|
<attribute name="invisible">True</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//sheet/div[@class='oe_button_box']/button[@name='action_view_mrp_production_childs']/div/span[last()]" position="replace">
|
<xpath expr="//sheet/div[@class='oe_button_box']/button[@name='action_view_mrp_production_childs']/div/span[last()]"
|
||||||
|
position="replace">
|
||||||
<span class="o_stat_text">子MO</span>
|
<span class="o_stat_text">子MO</span>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
|
|||||||
@@ -251,7 +251,7 @@
|
|||||||
decoration-danger="tag_type == '重新加工'"/>
|
decoration-danger="tag_type == '重新加工'"/>
|
||||||
<field name="is_test_env" invisible="1"/>
|
<field name="is_test_env" invisible="1"/>
|
||||||
<field name="rfid_code" force_save="1" readonly="1" cache="True"
|
<field name="rfid_code" force_save="1" readonly="1" cache="True"
|
||||||
attrs="{'invisible': [('rfid_code_old', '!=', False)]}" />
|
attrs="{'invisible': [('rfid_code_old', '!=', False)]}" widget="qrcode_widget"/>
|
||||||
<field name="rfid_code" string="RFID码(手动输入框)" force_save="1" readonly="0" cache="True"
|
<field name="rfid_code" string="RFID码(手动输入框)" force_save="1" readonly="0" cache="True"
|
||||||
attrs="{'invisible': ['|',('rfid_code_old', '!=', False), ('is_test_env', '=', False)]}"/>
|
attrs="{'invisible': ['|',('rfid_code_old', '!=', False), ('is_test_env', '=', False)]}"/>
|
||||||
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
|
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
|
|||||||
|
|
||||||
def confirm(self):
|
def confirm(self):
|
||||||
if self.is_technology_re_adjust is True:
|
if self.is_technology_re_adjust is True:
|
||||||
domain = [('origin', '=', self.origin), ('state', '=', 'technology_to_confirmed'),
|
domain = [('origin', '=', self.origin), ('state', '=', 'confirmed'),
|
||||||
('product_id', '=', self.production_id.product_id.id)]
|
('product_id', '=', self.production_id.product_id.id)]
|
||||||
else:
|
else:
|
||||||
domain = [('id', '=', self.production_id.id)]
|
domain = [('id', '=', self.production_id.id)]
|
||||||
|
|||||||
@@ -51,18 +51,6 @@ class ReworkWizard(models.TransientModel):
|
|||||||
self.workorder_id.button_finish()
|
self.workorder_id.button_finish()
|
||||||
else:
|
else:
|
||||||
if self.workorder_ids:
|
if self.workorder_ids:
|
||||||
# handle_result = self.production_id.detection_result_ids.filtered(
|
|
||||||
# lambda dr: dr.handle_result == '待处理')
|
|
||||||
# if handle_result:
|
|
||||||
# processing_panels_to_handle = set(handle_item.processing_panel for handle_item in handle_result)
|
|
||||||
# processing_panels_choice = set(dr_panel.name for dr_panel in self.processing_panel_id)
|
|
||||||
# # 使用集合的差集操作找出那些待处理结果中有但实际可用加工面中没有的加工面
|
|
||||||
# processing_panels_missing = processing_panels_to_handle - processing_panels_choice
|
|
||||||
# # 存在不一致的加工面
|
|
||||||
# if processing_panels_missing:
|
|
||||||
# processing_panels_str = ','.join(processing_panels_missing)
|
|
||||||
# raise UserError('您还有待处理的检测结果中为%s的加工面未选择' % processing_panels_str)
|
|
||||||
|
|
||||||
rework_workorder_ids = self.production_id.workorder_ids.filtered(
|
rework_workorder_ids = self.production_id.workorder_ids.filtered(
|
||||||
lambda ap: ap.id in self.workorder_ids.ids)
|
lambda ap: ap.id in self.workorder_ids.ids)
|
||||||
clamp_workorder_ids = None
|
clamp_workorder_ids = None
|
||||||
@@ -87,8 +75,9 @@ class ReworkWizard(models.TransientModel):
|
|||||||
(item.route_id.name == work.name and item.panel
|
(item.route_id.name == work.name and item.panel
|
||||||
and item.panel == work.processing_panel))
|
and item.panel == work.processing_panel))
|
||||||
if route:
|
if route:
|
||||||
workorders_values.append(
|
work_list = self.env['mrp.workorder'].json_workorder_str(self.production_id, route[0])
|
||||||
self.env['mrp.workorder'].json_workorder_str(self.production_id, route[0]))
|
work_list[2].update({'tag_type': '重新加工'})
|
||||||
|
workorders_values.append(work_list)
|
||||||
# 创建新工单,并进行返工配置的相关操作
|
# 创建新工单,并进行返工配置的相关操作
|
||||||
if workorders_values:
|
if workorders_values:
|
||||||
# 创建新工单、工序排序、完成检测结果单据
|
# 创建新工单、工序排序、完成检测结果单据
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class ReSaleOrder(models.Model):
|
|||||||
product.materials_id.name),
|
product.materials_id.name),
|
||||||
'price_unit': product.list_price,
|
'price_unit': product.list_price,
|
||||||
'product_uom_qty': item['number'],
|
'product_uom_qty': item['number'],
|
||||||
'model_glb_file': base64.b64decode(item['model_file']),
|
'model_glb_file': base64.b64decode(item['model_file']) if item['model_file'] else None,
|
||||||
'remark': item.get('remark'),
|
'remark': item.get('remark'),
|
||||||
'embryo_redundancy_id': item.get('embryo_redundancy_id'),
|
'embryo_redundancy_id': item.get('embryo_redundancy_id'),
|
||||||
'is_incoming_material': True if item.get('embryo_redundancy_id') else False,
|
'is_incoming_material': True if item.get('embryo_redundancy_id') else False,
|
||||||
|
|||||||
Reference in New Issue
Block a user