Compare commits

..

7 Commits

15 changed files with 275 additions and 422 deletions

View File

@@ -44,7 +44,7 @@ class StockRuleInherit(models.Model):
po = self.env['purchase.order'].sudo().search([ po = self.env['purchase.order'].sudo().search([
('partner_id', '=', supplier.partner_id.id), ('partner_id', '=', supplier.partner_id.id),
('company_id', '=', procurement.company_id.id), # 保证公司一致 ('company_id', '=', procurement.company_id.id), # 保证公司一致
('origin', 'like', procurement.origin), # 根据来源匹配 ('origin', '=', procurement.origin), # 根据来源匹配
('state', '=', 'draft') # 状态为草稿 ('state', '=', 'draft') # 状态为草稿
], limit=1) ], limit=1)
logging.info("po=: %s", po) logging.info("po=: %s", po)

View File

@@ -15,4 +15,3 @@ from . import sf_technology_design
from . import sf_production_common from . import sf_production_common
from . import sale_order from . import sale_order
from . import quick_easy_order from . import quick_easy_order
from . import purchase_order

View File

@@ -8,7 +8,6 @@ import re
import requests import requests
from itertools import groupby from itertools import groupby
from collections import defaultdict, namedtuple from collections import defaultdict, namedtuple
from odoo import api, fields, models, SUPERUSER_ID, _ from odoo import api, fields, models, SUPERUSER_ID, _
from odoo.exceptions import UserError, ValidationError from odoo.exceptions import UserError, ValidationError
from odoo.addons.sf_base.commons.common import Common from odoo.addons.sf_base.commons.common import Common
@@ -19,7 +18,6 @@ class MrpProduction(models.Model):
_inherit = 'mrp.production' _inherit = 'mrp.production'
_description = "制造订单" _description = "制造订单"
_order = 'create_date desc' _order = 'create_date desc'
sale_order_id = fields.Many2one('sale.order', string='销售订单', compute='_compute_sale_order_id', store=True)
deadline_of_delivery = fields.Date('订单交期', tracking=True, compute='_compute_deadline_of_delivery') deadline_of_delivery = fields.Date('订单交期', tracking=True, compute='_compute_deadline_of_delivery')
# tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘") # tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘")
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests") maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
@@ -36,29 +34,6 @@ class MrpProduction(models.Model):
tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True) tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True)
tool_state_remark2 = fields.Text(string='功能刀具状态备注(无效刀)', readonly=True) tool_state_remark2 = fields.Text(string='功能刀具状态备注(无效刀)', readonly=True)
@api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id')
def _compute_sale_order_id(self):
for production in self:
# 初始化 sale_order_id 为 False
sale_order_id = False
# 使用正则表达式查找产品名称中的 'S' 开头的字母数字字符串
match = re.search(r'S\d+', production.product_id.with_context(lang='zh_CN').name) # 从字符串开始匹配
if match:
result = match.group(0)
try:
# 查找与匹配的字符串相符的销售订单
sale_order = self.env['sale.order'].search(
[('name', '=', result)], limit=1, order='id asc'
)
if sale_order:
production.sale_order_id = sale_order.id
else:
logging.warning("No sale order found for production {} with product {} (name match: {})".format(
production.id, production.product_id.name, result))
except Exception as e:
logging.error("Error while fetching sale order for production {}: {}".format(production.id, str(e)))
@api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id') @api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id')
def _compute_deadline_of_delivery(self): def _compute_deadline_of_delivery(self):
for production in self: for production in self:
@@ -746,16 +721,10 @@ class MrpProduction(models.Model):
for product_id, pd in grouped_product_ids.items(): for product_id, pd in grouped_product_ids.items():
product_id_to_production_names[product_id] = [p.name for p in pd] product_id_to_production_names[product_id] = [p.name for p in pd]
for production in production_all: for production in production_all:
proc_workorders = []
process_parameter_workorder = self.env['mrp.workorder'].search( process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id),
('is_subcontract', '=', True), ('state', '!=', 'cancel')], order='sequence asc') ('is_subcontract', '=', True)], order='sequence asc')
if process_parameter_workorder: if process_parameter_workorder:
# 将这些特殊表面工艺工单的采购单与调拨单置为失效
for workorder in process_parameter_workorder:
workorder._get_surface_technics_purchase_ids().write({'state': 'cancel'})
workorder.move_subcontract_workorder_ids.write({'state': 'cancel'})
workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'cancel'})
consecutive_workorders = [] consecutive_workorders = []
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence) sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence)
for i, workorder in enumerate(sorted_workorders): for i, workorder in enumerate(sorted_workorders):
@@ -768,11 +737,10 @@ class MrpProduction(models.Model):
else: else:
# 处理连续组,如果它不为空 # 处理连续组,如果它不为空
if consecutive_workorders: if consecutive_workorders:
proc_workorders.append(consecutive_workorders)
# 创建外协出入库单和采购订单 # 创建外协出入库单和采购订单
# self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production, sorted_workorders) self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
# self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
# product_id_to_production_names) product_id_to_production_names)
if i < len(sorted_workorders) - 1: if i < len(sorted_workorders) - 1:
# 重置连续组,并添加当前工作订单 # 重置连续组,并添加当前工作订单
consecutive_workorders = [workorder] consecutive_workorders = [workorder]
@@ -783,22 +751,17 @@ class MrpProduction(models.Model):
i - 1].supplier_id.id: i - 1].supplier_id.id:
consecutive_workorders = [workorder] consecutive_workorders = [workorder]
else: else:
proc_workorders.append([workorder])
# 立即创建外协出入库单和采购订单 # 立即创建外协出入库单和采购订单
# self.env['stock.picking'].create_outcontract_picking(workorder, production) self.env['stock.picking'].create_outcontract_picking(workorder, production)
# self.env['purchase.order'].get_purchase_order(workorder, production, self.env['purchase.order'].get_purchase_order(workorder, production,
# product_id_to_production_names) product_id_to_production_names)
consecutive_workorders = [] consecutive_workorders = []
# 处理最后一个组,即使它可能只有一个工作订单 # 处理最后一个组,即使它可能只有一个工作订单
if consecutive_workorders: if consecutive_workorders:
proc_workorders.append(consecutive_workorders) self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
# self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
# self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, product_id_to_production_names)
# product_id_to_production_names)
for workorders in reversed(proc_workorders):
self.env['stock.picking'].create_outcontract_picking(workorders, production, sorted_workorders)
self.env['purchase.order'].get_purchase_order(workorders, production, product_id_to_production_names)
# 工单排序 # 工单排序
def _reset_work_order_sequence1(self, k): def _reset_work_order_sequence1(self, k):
@@ -1461,26 +1424,6 @@ class MrpProduction(models.Model):
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.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id')
def _compute_sale_order_count(self):
for production in self:
if production.sale_order_id:
production.sale_order_count = 1
else:
production.sale_order_count = 0
def action_view_sale_orders(self):
if self.sale_order_id:
action = {
'res_model': 'sale.order',
'type': 'ir.actions.act_window',
}
action.update({
'view_mode': 'form',
'res_id': self.sale_order_id.id,
})
return action
@api.model_create_multi @api.model_create_multi
def create(self, vals_list): def create(self, vals_list):
""" """

View File

@@ -23,15 +23,12 @@ class ResMrpWorkOrder(models.Model):
product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name') product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name')
product_tmpl_id_length = fields.Float(string='坯料长度(mm)', related='material_length', readonly=True, store=False) product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True,
product_tmpl_id_width = fields.Float(string='坯料度(mm)', related='material_width', readonly=True, store=False) string="坯料度(mm)")
product_tmpl_id_height = fields.Float(string='坯料高度(mm)', related='material_height', readonly=True, store=False) product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True,
# product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True, string="坯料宽度(mm)")
# string="坯料长度(mm)") product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True,
# product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True, string="坯料高度(mm)")
# string="坯料宽度(mm)")
# product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True,
# string="坯料高度(mm)")
product_tmpl_id_materials_id = fields.Many2one(related='production_id.product_tmpl_id.materials_id', readonly=True, product_tmpl_id_materials_id = fields.Many2one(related='production_id.product_tmpl_id.materials_id', readonly=True,
store=True, check_company=True, string="材料") store=True, check_company=True, string="材料")
product_tmpl_id_materials_type_id = fields.Many2one(related='production_id.product_tmpl_id.materials_type_id', product_tmpl_id_materials_type_id = fields.Many2one(related='production_id.product_tmpl_id.materials_type_id',
@@ -129,7 +126,7 @@ class ResMrpWorkOrder(models.Model):
Y10_axis = fields.Float(default=0) Y10_axis = fields.Float(default=0)
Z10_axis = fields.Float(default=0) Z10_axis = fields.Float(default=0)
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0) X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格', test_results = fields.Selection([("合格", "合格")], default='合格',
string="检测结果", tracking=True) string="检测结果", tracking=True)
cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序") cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序")
cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序") cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序")
@@ -137,10 +134,8 @@ class ResMrpWorkOrder(models.Model):
glb_file = fields.Binary("glb模型文件", related='production_id.model_file') glb_file = fields.Binary("glb模型文件", related='production_id.model_file')
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='外协出入库单', compute='_compute_surface_technics_picking_ids') # purchase_id = fields.Many2one('purchase.order', string='外协采购单')
purchase_id = fields.Many2many('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') surface_technics_purchase_count = fields.Integer("外协采购", compute='_compute_surface_technics_purchase_ids')
@@ -244,11 +239,13 @@ class ResMrpWorkOrder(models.Model):
previous_workorder = self.env['mrp.workorder'].search( previous_workorder = self.env['mrp.workorder'].search(
[('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'),
('production_id', '=', workorder.production_id.id)]) ('production_id', '=', workorder.production_id.id)])
# if previous_workorder: if previous_workorder:
# if previous_workorder.supplier_id != workorder.supplier_id: if previous_workorder.supplier_id != workorder.supplier_id:
# domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] # process_product = self.env['product.template']._get_process_parameters_product(
# else: # previous_workorder.surface_technics_parameters_id)
domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
else:
domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
picking_ids = self.env['stock.picking'].search(domain, order='id asc') picking_ids = self.env['stock.picking'].search(domain, order='id asc')
workorder.surface_technics_picking_count = len(picking_ids) workorder.surface_technics_picking_count = len(picking_ids)
workorder.picking_ids = picking_ids.ids workorder.picking_ids = picking_ids.ids
@@ -317,27 +314,24 @@ class ResMrpWorkOrder(models.Model):
# if technology_design.is_auto is False: # if technology_design.is_auto is False:
# domain = [('origin', '=', self.production_id.name)] # domain = [('origin', '=', self.production_id.name)]
# else: # else:
purchase_orders_id = self._get_surface_technics_purchase_ids() domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment'),
('state', '!=', 'cancel')]
purchase_orders = self.env['purchase.order'].search(domain)
purchase_orders_id = None
for po in purchase_orders:
for line in po.order_line:
if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id:
if line.product_qty == 1:
purchase_orders_id = line.order_id.id
result = { result = {
"type": "ir.actions.act_window", "type": "ir.actions.act_window",
"res_model": "purchase.order", "res_model": "purchase.order",
"res_id": purchase_orders_id.id, "res_id": purchase_orders_id,
# "domain": [['id', 'in', self.purchase_id]], # "domain": [['id', 'in', self.purchase_id]],
"name": _("Purchase Orders"), "name": _("Purchase Orders"),
'view_mode': 'form', 'view_mode': 'form',
} }
return result return result
def _get_surface_technics_purchase_ids(self):
domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment')]
purchase_orders = self.env['purchase.order'].search(domain)
purchase_orders_id = self.env['purchase.order']
for po in purchase_orders:
for line in po.order_line:
if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id:
if line.product_qty == 1:
purchase_orders_id = line.order_id
return purchase_orders_id
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)
@@ -1035,47 +1029,47 @@ class ResMrpWorkOrder(models.Model):
'production_id.programming_state') 'production_id.programming_state')
def _compute_state(self): def _compute_state(self):
# super()._compute_state() # super()._compute_state()
# for workorder in self: for workorder in self:
# if workorder.sequence != 1: if workorder.sequence != 1:
# previous_workorder = self.env['mrp.workorder'].search( previous_workorder = self.env['mrp.workorder'].search(
# [('production_id', '=', workorder.production_id.id), [('production_id', '=', workorder.production_id.id),
# ('sequence', '=', workorder.sequence - 1)]) ('sequence', '=', workorder.sequence - 1)])
# if workorder.state == 'pending': if workorder.state == 'pending':
# if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
# if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排': if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排':
# if ((workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) if ((workorder.sequence == 1 and not workorder.blocked_by_workorder_ids)
# or (workorder.blocked_by_workorder_ids.state in ('done', 'cancel') or (workorder.blocked_by_workorder_ids.state in ('done', 'cancel')
# and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工']) and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工'])
# or (previous_workorder.state in ('done', 'cancel') or (previous_workorder.state in ('done', 'cancel')
# and not workorder.blocked_by_workorder_ids and not workorder.blocked_by_workorder_ids
# and previous_workorder.test_results not in ['报废', '返工']) and previous_workorder.test_results not in ['报废', '返工'])
# ): ):
# workorder.state = 'ready' workorder.state = 'ready'
# continue continue
# if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'): if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'):
# if workorder.sequence != 1: if workorder.sequence != 1:
# workorder.state = 'pending' workorder.state = 'pending'
# continue continue
# if workorder.state not in ('waiting', 'ready'): if workorder.state not in ('waiting', 'ready'):
# continue continue
# if workorder.state in ( if workorder.state in (
# 'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排': 'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排':
# workorder.state = 'ready' workorder.state = 'ready'
# continue continue
# if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
# workorder.state = 'pending' workorder.state = 'pending'
# if workorder.state in ['waiting']: if workorder.state in ['waiting']:
# if previous_workorder.state == 'waiting': if previous_workorder.state == 'waiting':
# workorder.state = 'pending' workorder.state = 'pending'
# if workorder.sequence == 1 and workorder.state == 'pending': if workorder.sequence == 1 and workorder.state == 'pending':
# workorder.state = 'waiting' workorder.state = 'waiting'
# continue continue
# if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'):
# continue continue
# if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排': if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排':
# workorder.state = 'ready' workorder.state = 'ready'
# elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready': elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready':
# workorder.state = 'waiting' workorder.state = 'waiting'
for workorder in self: for workorder in self:
# 如果工单的工序没有进行排序则跳出循环 # 如果工单的工序没有进行排序则跳出循环
@@ -1100,16 +1094,7 @@ class ResMrpWorkOrder(models.Model):
and workorder.production_id.schedule_state == '已排' and workorder.production_id.schedule_state == '已排'
and len(workorder.production_id.picking_ids.filtered( and len(workorder.production_id.picking_ids.filtered(
lambda w: w.state not in ['done', 'cancel'])) == 0): lambda w: w.state not in ['done', 'cancel'])) == 0):
if workorder.is_subcontract is True: workorder.state = 'ready'
purchase_orders_id = self._get_surface_technics_purchase_ids()
if purchase_orders_id.state == 'purchase':
workorder.state = 'ready'
continue
else:
workorder.state = 'waiting'
continue
else:
workorder.state = 'ready'
continue 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'
@@ -1135,26 +1120,21 @@ class ResMrpWorkOrder(models.Model):
if workorder.is_subcontract is False: if workorder.is_subcontract is False:
workorder.state = 'ready' workorder.state = 'ready'
else: else:
# production_programming = self.env['mrp.production'].search( production_programming = self.env['mrp.production'].search(
# [('origin', '=', self.production_id.origin)], order='name asc') [('origin', '=', self.production_id.origin)], order='name asc')
# production_no_remanufacture = production_programming.filtered( production_no_remanufacture = production_programming.filtered(
# lambda a: a.is_remanufacture is False) lambda a: a.is_remanufacture is False)
# production_list = [production.name for production in production_programming] production_list = [production.name for production in production_programming]
# purchase_orders = self.env['purchase.order'].search( purchase_orders = self.env['purchase.order'].search(
# [('origin', 'ilike', ','.join(production_list))]) [('origin', 'ilike', ','.join(production_list))])
# for line in purchase_orders.order_line: for line in purchase_orders.order_line:
# if ( if (
# line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id
# and line.product_qty == len(production_no_remanufacture)): and line.product_qty == len(production_no_remanufacture)):
# if all(pur_order.state == 'purchase' for pur_order in purchase_orders): if all(pur_order.state == 'purchase' for pur_order in purchase_orders):
# workorder.state = 'ready' workorder.state = 'ready'
# else: else:
# workorder.state = 'waiting' workorder.state = 'waiting'
purchase_orders_id = self._get_surface_technics_purchase_ids()
if purchase_orders_id:
workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting'
else:
workorder.state = 'waiting'
# re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id), # re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id),
# ('processing_panel', '=', workorder.processing_panel), # ('processing_panel', '=', workorder.processing_panel),
@@ -1217,10 +1197,6 @@ class ResMrpWorkOrder(models.Model):
# 重写工单开始按钮方法 # 重写工单开始按钮方法
def button_start(self): def button_start(self):
# 判断工单状态是否为等待组件
if self.state in ['waiting', 'pending']:
raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name)
if self.routing_type == 'CNC加工': if self.routing_type == 'CNC加工':
self.env['sf.production.plan'].sudo().search([('name', '=', self.production_id.name)]).write({ self.env['sf.production.plan'].sudo().search([('name', '=', self.production_id.name)]).write({
'state': 'processing', 'state': 'processing',
@@ -1228,6 +1204,9 @@ class ResMrpWorkOrder(models.Model):
}) })
if self.sequence == 1: if self.sequence == 1:
# 判断工单状态是否为等待组件
if self.state == 'waiting':
raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name)
# 判断是否有坯料的序列号信息 # 判断是否有坯料的序列号信息
boolean = False boolean = False
if self.production_id.move_raw_ids: if self.production_id.move_raw_ids:
@@ -1264,33 +1243,19 @@ class ResMrpWorkOrder(models.Model):
# 表面工艺外协出库单 # 表面工艺外协出库单
if self.routing_type == '表面工艺': if self.routing_type == '表面工艺':
if self.is_subcontract is True: if self.is_subcontract is True:
move_out = self.move_subcontract_workorder_ids[1] move_out = self.env['stock.move'].search(
# move_out = self.env['stock.move'].search( [('location_id', '=', self.env['stock.location'].search(
# [('location_id', '=', self.env['stock.location'].search( [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
# [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), ('location_dest_id', '=', self.env['stock.location'].search(
# ('location_dest_id', '=', self.env['stock.location'].search( [('barcode', 'ilike', 'VL-SPOC')]).id),
# [('barcode', 'ilike', 'VL-SPOC')]).id), ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])])
# ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])])
for mo in move_out: for mo in move_out:
if mo.state != 'done': pick = self.env['stock.picking'].search([('id', '=', mo.picking_id.id), ('name', 'ilike', 'OCOUT'),
mo.write({'state': 'assigned', 'production_id': False}) ('partner_id', '=', self.supplier_id.id)])
if not mo.move_line_ids: if pick:
if mo.state != 'done':
mo.write({'state': 'assigned', 'production_id': False})
self.env['stock.move.line'].create(mo.get_move_line(self.production_id, self)) self.env['stock.move.line'].create(mo.get_move_line(self.production_id, self))
# product_qty = mo.product_uom._compute_quantity(
# mo.product_uom_qty, mo.product_id.uom_id, rounding_method='HALF-UP')
# available_quantity = self.env['stock.quant']._get_available_quantity(
# mo.product_id,
# mo.location_id,
# lot_id=mo.move_line_ids.lot_id,
# strict=False,
# )
# mo._update_reserved_quantity(
# product_qty,
# available_quantity,
# mo.location_id,
# lot_id=mo.move_line_ids.lot_id,
# strict=False,
# )
# move_out._action_assign() # move_out._action_assign()
if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress': if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress':
@@ -1395,13 +1360,6 @@ class ResMrpWorkOrder(models.Model):
picks = record.picking_ids.filtered(lambda p: p.state not in ('done')) picks = record.picking_ids.filtered(lambda p: p.state not in ('done'))
if picks: if picks:
raise UserError('请先完成该工单的工艺外协再进行操作') raise UserError('请先完成该工单的工艺外协再进行操作')
# 表面工艺外协,最后一张工单
workorders = self.production_id.workorder_ids
subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence')
if self == subcontract_workorders[-1]:
# 给下一个库存移动就绪
self.move_subcontract_workorder_ids[0].move_dest_ids._action_done()
# self.production_id.button_mark_done()
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)
@@ -1444,13 +1402,13 @@ class ResMrpWorkOrder(models.Model):
move_raw_id.quantity_done = move_raw_id.product_uom_qty move_raw_id.quantity_done = move_raw_id.product_uom_qty
record.process_state = '已完工' record.process_state = '已完工'
record.production_id.process_state = '已完工' record.production_id.process_state = '已完工'
# if record.routing_type in ['表面工艺']: if record.routing_type in ['表面工艺']:
# raw_move = self.env['stock.move'].sudo().search( raw_move = self.env['stock.move'].sudo().search(
# [('origin', '=', record.production_id.name), [('origin', '=', record.production_id.name),
# ('procure_method', 'in', ['make_to_order', 'make_to_stock']), ('procure_method', 'in', ['make_to_order', 'make_to_stock']),
# ('state', '!=', 'done')]) ('state', '!=', 'done')])
# if raw_move: if raw_move:
# raw_move.write({'state': 'done'}) raw_move.write({'state': 'done'})
record.production_id.button_mark_done1() record.production_id.button_mark_done1()
# record.production_id.state = 'done' # record.production_id.state = 'done'
@@ -1570,8 +1528,6 @@ class ResMrpWorkOrder(models.Model):
'default_confirm_button': '确认解除', 'default_confirm_button': '确认解除',
# 'default_feeder_station_start_id': feeder_station_start_id, # 'default_feeder_station_start_id': feeder_station_start_id,
}} }}
move_subcontract_workorder_ids = fields.One2many('stock.move', 'subcontract_workorder_id', string='组件')
class CNCprocessing(models.Model): class CNCprocessing(models.Model):

View File

@@ -1,31 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import defaultdict
from odoo import api, fields, models, _
from odoo.tools import OrderedSet
# _get_surface_technics_purchase_ids
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
def button_confirm(self):
super().button_confirm()
workorders = self.env['mrp.workorder'].search([('purchase_id', '=', self.id)])
for workorder in workorders:
if workorder.routing_type == '表面工艺' and workorder.is_subcontract is True:
move_out = workorder.move_subcontract_workorder_ids[1]
# move_out = self.env['stock.move'].search(
# [('location_id', '=', self.env['stock.location'].search(
# [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
# ('location_dest_id', '=', self.env['stock.location'].search(
# [('barcode', 'ilike', 'VL-SPOC')]).id),
# ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])])
for mo in move_out:
if mo.state != 'done':
mo.write({'state': 'assigned', 'production_id': False})
if not mo.move_line_ids:
self.env['stock.move.line'].create(mo.get_move_line(workorder.production_id, workorder))
return True

View File

@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import fields, models, api, _ from odoo import fields, models
from odoo.exceptions import ValidationError
class sf_technology_design(models.Model): class sf_technology_design(models.Model):
@@ -30,11 +29,3 @@ class sf_technology_design(models.Model):
def unlink_technology_design(self): def unlink_technology_design(self):
self.active = False self.active = False
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if not vals.get('route_id'):
raise ValidationError(_("工序不能为空"))
return super(sf_technology_design, self).create(vals_list)

View File

@@ -636,89 +636,74 @@ class StockPicking(models.Model):
def button_validate(self): def button_validate(self):
res = super().button_validate() res = super().button_validate()
picking_type_in = self.env.ref('sf_manufacturing.outcontract_picking_in').id if res is True and self.picking_type_id.sequence_code == 'OCOUT':
if res is True and self.picking_type_id.id == picking_type_in: # if self.id == move_out.picking_id.id:
# 如果是最后一张外协入库单,则设置库存位置的预留数量 # if move_out.move_line_ids.workorder_id.state == 'progress':
move_in = self.move_ids move_in = self.env['stock.move'].search(
if move_in: [('location_dest_id', '=', self.env['stock.location'].search(
workorder = move_in.subcontract_workorder_id [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
workorders = workorder.production_id.workorder_ids ('location_id', '=', self.env['stock.location'].search(
subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence') [('barcode', 'ilike', 'VL-SPOC')]).id),
if workorder == subcontract_workorders[-1]: ('origin', '=', self.origin), ('state', 'not in', ['cancel', 'done'])])
self.env['stock.quant']._update_reserved_quantity( production = self.env['mrp.production'].search([('name', '=', self.origin)])
move_in.product_id, move_in.location_dest_id, move_in.product_uom_qty, for mi in move_in:
lot_id=move_in.move_line_ids.lot_id, pick = self.env['stock.picking'].search([('id', '=', mi.picking_id.id), ('name', 'ilike', 'OCIN'),
package_id=False, owner_id=False, strict=False ('partner_id', '=', self.partner_id.id)])
) # if pick:
workorder.button_finish() # if mi.state != 'done':
picking_type_out = self.env.ref('sf_manufacturing.outcontract_picking_out').id # mi.write({'state': 'assigned'})
if res and self.picking_type_id.id == picking_type_out: # self.env['stock.move.line'].create(mi.get_move_line(production, None))
move_out = self.move_ids
if move_out:
workorder = move_out.subcontract_workorder_id
workorder.button_start()
return res return res
# 创建 外协出库入单 # 创建 外协出库入单
def create_outcontract_picking(self, workorders, item, sorted_workorders): def create_outcontract_picking(self, sorted_workorders_arr, item):
for workorder in workorders: domain = [('origin', '=', item.name), ('name', 'ilike', 'OCOUT')]
if workorder.move_subcontract_workorder_ids: if len(sorted_workorders_arr) > 1:
workorder.move_subcontract_workorder_ids.write({'state': 'waiting'}) sorted_workorders_arr = sorted_workorders_arr[0]
workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'waiting'}) else:
else: domain += [
# 创建一个新的补货组 ('surface_technics_parameters_id', '=', sorted_workorders_arr[0].surface_technics_parameters_id.id)]
procurement_group_id = self.env['procurement.group'].create({ stock_picking = self.env['stock.picking'].search(domain)
'name': workorder.name, if not stock_picking:
'partner_id': self.partner_id.id, for sorted_workorders in sorted_workorders_arr:
}) # pick_ids = []
move_dest_id = False if not sorted_workorders.picking_ids:
# 如果当前工单是是制造订单的最后一个工单 # outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)])
if workorder == item.workorder_ids[-1]: # if not outcontract_stock_move:
move_dest_id = item.move_raw_ids[0].id # 创建一个新的补货组
else: procurement_group_id = self.env['procurement.group'].create({
# 从sorted_workorders中找到上一工单的move 'name': sorted_workorders.name,
if sorted_workorders.index(workorder) > 0: 'partner_id': self.partner_id.id,
move_dest_id = \ })
sorted_workorders[sorted_workorders.index(workorder) - 1].move_subcontract_workorder_ids[1].id new_picking = True
new_picking = True location_id = self.env['stock.location'].search(
outcontract_picking_type_in = self.env.ref( [('barcode', 'ilike', 'VL-SPOC')]).id,
'sf_manufacturing.outcontract_picking_in').id, location_dest_id = self.env['stock.location'].search(
outcontract_picking_type_out = self.env.ref( [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
'sf_manufacturing.outcontract_picking_out').id, outcontract_picking_type_in = self.env.ref(
moves_in = self.env['stock.move'].sudo().create( 'sf_manufacturing.outcontract_picking_in').id,
self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_in, outcontract_picking_type_out = self.env.ref(
procurement_group_id.id, move_dest_id)) 'sf_manufacturing.outcontract_picking_out').id,
picking_in = self.create( moves_in = self.env['stock.move'].sudo().create(
moves_in._get_new_picking_values_Res(item, workorder, 'WH/OCIN/')) self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id,
# pick_ids.append(picking_in.id) outcontract_picking_type_in, procurement_group_id.id))
moves_in.write( picking_in = self.create(
{'picking_id': picking_in.id, 'state': 'waiting'}) moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/'))
moves_in._assign_picking_post_process(new=new_picking) # pick_ids.append(picking_in.id)
moves_out = self.env['stock.move'].sudo().create( moves_in.write(
self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_out, {'picking_id': picking_in.id, 'state': 'waiting'})
procurement_group_id.id, moves_in.id)) moves_in._assign_picking_post_process(new=new_picking)
workorder.write({'move_subcontract_workorder_ids': [(6, 0, [moves_in.id, moves_out.id])]}) moves_out = self.env['stock.move'].sudo().create(
picking_out = self.create( self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id,
moves_out._get_new_picking_values_Res(item, workorder, 'WH/OCOUT/')) outcontract_picking_type_out, procurement_group_id.id, moves_in.id))
# pick_ids.append(picking_out.id) picking_out = self.create(
moves_out.write( moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/'))
{'picking_id': picking_out.id, 'state': 'waiting'}) # pick_ids.append(picking_out.id)
moves_out._assign_picking_post_process(new=new_picking) moves_out.write(
{'picking_id': picking_out.id, 'state': 'waiting'})
@api.depends('move_type', 'immediate_transfer', 'move_ids.state', 'move_ids.picking_id') moves_out._assign_picking_post_process(new=new_picking)
def _compute_state(self):
super(StockPicking, self)._compute_state()
for picking in self:
# 外协出库单根据工单状态,采购单状态来确定
picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_out').id
if picking.picking_type_id.id == picking_type_id:
if picking.move_ids:
workorder = picking.move_ids[0].subcontract_workorder_id
if picking.state == 'assigned':
if workorder.state in ['pending',
'waiting'] or workorder._get_surface_technics_purchase_ids().state in [
'draft', 'sent']:
picking.state = 'waiting'
class ReStockMove(models.Model): class ReStockMove(models.Model):
@@ -728,18 +713,16 @@ class ReStockMove(models.Model):
materiel_width = fields.Float(string='物料宽度', digits=(16, 4)) materiel_width = fields.Float(string='物料宽度', digits=(16, 4))
materiel_height = fields.Float(string='物料高度', digits=(16, 4)) materiel_height = fields.Float(string='物料高度', digits=(16, 4))
def _get_stock_move_values_Res(self, item, picking_type_id, group_id, move_dest_ids=False): def _get_stock_move_values_Res(self, item, location_src_id, location_dest_id, picking_type_id, group_id, move_dest_ids=False):
route_id = self.env.ref('sf_manufacturing.route_surface_technology_outsourcing').id route = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')])
stock_rule = self.env['stock.rule'].sudo().search(
[('route_id', '=', route_id), ('picking_type_id', '=', picking_type_id)])
move_values = { move_values = {
'name': '', 'name': '',
'company_id': item.company_id.id, 'company_id': item.company_id.id,
'product_id': item.bom_id.bom_line_ids.product_id.id, 'product_id': item.bom_id.bom_line_ids.product_id.id,
'product_uom': item.bom_id.bom_line_ids.product_uom_id.id, 'product_uom': item.bom_id.bom_line_ids.product_uom_id.id,
'product_uom_qty': 1.0, 'product_uom_qty': 1.0,
'location_id': stock_rule.location_src_id.id, 'location_id': location_src_id,
'location_dest_id': stock_rule.location_dest_id.id, 'location_dest_id': location_dest_id,
'origin': item.name, 'origin': item.name,
'group_id': group_id, 'group_id': group_id,
'move_dest_ids': [(6, 0, [move_dest_ids])] if move_dest_ids else False, 'move_dest_ids': [(6, 0, [move_dest_ids])] if move_dest_ids else False,
@@ -766,7 +749,7 @@ class ReStockMove(models.Model):
'picking_type_id': picking_type_id, 'picking_type_id': picking_type_id,
'location_id': self.mapped('location_id').id, 'location_id': self.mapped('location_id').id,
'location_dest_id': self.mapped('location_dest_id').id, 'location_dest_id': self.mapped('location_dest_id').id,
'state': 'waiting', 'state': 'confirmed',
} }
def get_move_line(self, production_id, sorted_workorders): def get_move_line(self, production_id, sorted_workorders):
@@ -982,7 +965,7 @@ class ReStockMove(models.Model):
合并制造订单的完成move单据 合并制造订单的完成move单据
""" """
res = super(ReStockMove, self)._merge_moves_fields() res = super(ReStockMove, self)._merge_moves_fields()
if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨', '生产入库', '客供料入库']: 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 = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc')
productions = self.env['mrp.production'].search( productions = self.env['mrp.production'].search(
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)]) [('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
@@ -1005,14 +988,10 @@ class ReStockMove(models.Model):
production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc') production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc')
productions = self.env['mrp.production'].search( productions = self.env['mrp.production'].search(
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)]) [('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
if productions.mapped('name'): res['origin'] = ','.join(productions.mapped('name'))
res['origin'] = ','.join(productions.mapped('name'))
res['retrospect_ref'] = production.product_id.name res['retrospect_ref'] = production.product_id.name
return res return res
subcontract_workorder_id = fields.Many2one('mrp.workorder', '外协工单组件', check_company=True,
index='btree_not_null')
class ReStockQuant(models.Model): class ReStockQuant(models.Model):
_inherit = 'stock.quant' _inherit = 'stock.quant'

View File

@@ -43,7 +43,6 @@
<field name="activity_ids" string="下一个活动" widget="list_activity" optional="hide"/> <field name="activity_ids" string="下一个活动" widget="list_activity" optional="hide"/>
</xpath> </xpath>
<xpath expr="//field[@name='origin']" position="replace"> <xpath expr="//field[@name='origin']" position="replace">
<field name="sale_order_id" optional="show"/>
<field name="origin" optional="hide"/> <field name="origin" optional="hide"/>
</xpath> </xpath>
<xpath expr="//field[@name='components_availability']" position="replace"> <xpath expr="//field[@name='components_availability']" position="replace">
@@ -124,7 +123,6 @@
<field name="tool_state" <field name="tool_state"
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/> 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="sale_order_id" readonly="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"/>
</xpath> </xpath>
@@ -586,7 +584,6 @@
<searchpanel> <searchpanel>
<field name="state" icon="fa-filter" enable_counters="1"/> <field name="state" icon="fa-filter" enable_counters="1"/>
<field name="delivery_status" icon="fa-filter" enable_counters="1"/> <field name="delivery_status" icon="fa-filter" enable_counters="1"/>
<field name="production_type" icon="fa-filter" enable_counters="1"/>
</searchpanel> </searchpanel>
</xpath> </xpath>
<filter name='todo' position="replace"/> <filter name='todo' position="replace"/>
@@ -741,7 +738,7 @@
<!-- parent="mrp.menu_mrp_manufacturing"--> <!-- parent="mrp.menu_mrp_manufacturing"-->
<!-- sequence="1"/>--> <!-- sequence="1"/>-->
<menuitem id="mrp.menu_mrp_production_action" <menuitem id="menu_mrp_production_action"
name="制造订单" name="制造订单"
parent="mrp.menu_mrp_manufacturing" parent="mrp.menu_mrp_manufacturing"
action="mrp.mrp_production_action" action="mrp.mrp_production_action"

View File

@@ -200,7 +200,7 @@
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('state','=','done')]}"/> --> <!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('state','=','done')]}"/> -->
<!-- <button name="button_workpiece_delivery" type="object" string="工件配送" class="btn-primary"--> <!-- <button name="button_workpiece_delivery" type="object" string="工件配送" class="btn-primary"-->
<!-- attrs="{'invisible': ['|','|','|','|',('routing_type','!=','装夹预调'),('is_delivery','=',True),('state','!=','done'),('is_rework','=',True),'&amp;',('rfid_code','in',['',False]),('state','=','done')]}"/>--> <!-- attrs="{'invisible': ['|','|','|','|',('routing_type','!=','装夹预调'),('is_delivery','=',True),('state','!=','done'),('is_rework','=',True),'&amp;',('rfid_code','in',['',False]),('state','=','done')]}"/>-->
<button name="button_rework_pre" type="object" string="异常反馈" <button name="button_rework_pre" type="object" string="异常反馈" invisible="1"
class="btn-primary" class="btn-primary"
attrs="{'invisible': ['|','|',('routing_type','!=','装夹预调'),('state','!=','progress'),('is_rework','=',True)]}"/> attrs="{'invisible': ['|','|',('routing_type','!=','装夹预调'),('state','!=','progress'),('is_rework','=',True)]}"/>
<button name="unbind_tray" type="object" string="解绑托盘" <button name="unbind_tray" type="object" string="解绑托盘"

View File

@@ -66,30 +66,30 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
# 工单采购单外协出入库单皆需取消 # 工单采购单外协出入库单皆需取消
domain = [('production_id', '=', special.production_id.id)] domain = [('production_id', '=', special.production_id.id)]
if special.process_parameters_id: if special.process_parameters_id:
domain += [('surface_technics_parameters_id', '=', special.process_parameters_id.id), ('state', '!=', 'cancel')] domain += [('surface_technics_parameters_id', '=', special.process_parameters_id.id)]
else: else:
domain += [('technology_design_id', '=', special.id), ('state', '!=', 'cancel')] domain += [('technology_design_id', '=', special.id)]
workorder = self.env['mrp.workorder'].search(domain) workorder = self.env['mrp.workorder'].search(domain)
# previous_workorder = self.env['mrp.workorder'].search( previous_workorder = self.env['mrp.workorder'].search(
# [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'),
# ('production_id', '=', workorder.production_id.id)]) ('production_id', '=', workorder.production_id.id)])
# if previous_workorder: if previous_workorder:
# if previous_workorder.supplier_id != workorder.supplier_id: if previous_workorder.supplier_id != workorder.supplier_id:
# is_cancel = True is_cancel = True
# else: else:
# is_cancel = True is_cancel = True
# if workorder.state != 'cancel' and is_cancel is True: if workorder.state != 'cancel' and is_cancel is True:
# workorder.write({'state': 'cancel'}) workorder.write({'state': 'cancel'})
# workorder.picking_ids.write({'state': 'cancel'}) workorder.picking_ids.write({'state': 'cancel'})
# workorder.picking_ids.move_ids.write({'state': 'cancel'}) workorder.picking_ids.move_ids.write({'state': 'cancel'})
# purchase_order = self.env['purchase.order'].search( purchase_order = self.env['purchase.order'].search(
# [('origin', '=', workorder.production_id.name)]) [('origin', '=', workorder.production_id.name)])
# for line in purchase_order.order_line: for line in purchase_order.order_line:
# if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id: if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id:
# purchase_order.write({'state': 'cancel'}) purchase_order.write({'state': 'cancel'})
else: else:
workorder = self.env['mrp.workorder'].search( workorder = self.env['mrp.workorder'].search(
[('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')]) [('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id)])
if not workorder: if not workorder:
if special.route_id.routing_type == '表面工艺': if special.route_id.routing_type == '表面工艺':
product_production_process = self.env['product.template'].search( product_production_process = self.env['product.template'].search(
@@ -110,12 +110,11 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
workorder.blocked_by_workorder_ids = None workorder.blocked_by_workorder_ids = None
else: else:
if workorder.blocked_by_workorder_ids: if workorder.blocked_by_workorder_ids:
workorder.blocked_by_workorder_ids = workorder.blocked_by_workorder_ids[0] workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0]
productions._reset_work_order_sequence() productions._reset_work_order_sequence()
# 退回时不对外协出入库单和采购单做处理 if self.production_id.product_id.categ_id.type == '成品':
# if self.production_id.product_id.categ_id.type == '成品': productions._reset_subcontract_pick_purchase()
# productions._reset_subcontract_pick_purchase() productions.get_subcontract_pick_purchase()
# productions.get_subcontract_pick_purchase()
productions.is_adjust = True productions.is_adjust = True
for item in productions: for item in productions:
workorders = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted( workorders = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted(

View File

@@ -59,33 +59,35 @@ class ProductionTechnologyWizard(models.TransientModel):
for special in special_design: for special in special_design:
workorders_values = [] workorders_values = []
if special.active is False: if special.active is False:
# is_cancel = False is_cancel = False
# 工单采购单外协出入库单皆需取消 # 工单采购单外协出入库单皆需取消
domain = [('production_id', '=', special.production_id.id)] domain = [('production_id', '=', special.production_id.id)]
if special.process_parameters_id: if special.process_parameters_id:
domain += [('surface_technics_parameters_id', '=', special.process_parameters_id.id), ('state', '!=', 'cancel')] domain += [('surface_technics_parameters_id', '=', special.process_parameters_id.id)]
else: else:
domain += [('technology_design_id', '=', special.id), ('state', '!=', 'cancel')] domain += [('technology_design_id', '=', special.id)]
workorder = self.env['mrp.workorder'].search(domain) workorder = self.env['mrp.workorder'].search(domain)
# previous_workorder = self.env['mrp.workorder'].search( previous_workorder = self.env['mrp.workorder'].search(
# [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'),
# ('production_id', '=', workorder.production_id.id)]) ('production_id', '=', workorder.production_id.id)])
# if previous_workorder: if previous_workorder:
# if previous_workorder.supplier_id != workorder.supplier_id: if previous_workorder.supplier_id != workorder.supplier_id:
# is_cancel = True is_cancel = True
# if workorder.state != 'cancel' and is_cancel is True: else:
workorder.write({'state': 'cancel'}) is_cancel = True
workorder.picking_ids.write({'state': 'cancel'}) if workorder.state != 'cancel' and is_cancel is True:
workorder.picking_ids.move_ids.write({'state': 'cancel'}) workorder.write({'state': 'cancel'})
purchase_order = self.env['purchase.order'].search( workorder.picking_ids.write({'state': 'cancel'})
[('origin', '=', workorder.production_id.name), ('purchase_type', '=', 'consignment')]) workorder.picking_ids.move_ids.write({'state': 'cancel'})
for line in purchase_order.order_line: purchase_order = self.env['purchase.order'].search(
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id: [('origin', '=', workorder.production_id.name)])
purchase_order.write({'state': 'cancel'}) for line in purchase_order.order_line:
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id:
purchase_order.write({'state': 'cancel'})
else: else:
if special.production_id.workorder_ids: if special.production_id.workorder_ids:
workorder = self.env['mrp.workorder'].search( workorder = self.env['mrp.workorder'].search(
[('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')]) [('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id)])
if not workorder: if not workorder:
if special.route_id.routing_type == '表面工艺': if special.route_id.routing_type == '表面工艺':
product_production_process = self.env['product.template'].search( product_production_process = self.env['product.template'].search(
@@ -98,7 +100,7 @@ class ProductionTechnologyWizard(models.TransientModel):
else: else:
workorders_values.append( workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(special.production_id, special)) self.env['mrp.workorder'].json_workorder_str(special.production_id, special))
special.production_id.write({'workorder_ids': workorders_values}) special.production_id.write({'workorder_ids': workorders_values})
else: else:
if len(workorder.blocked_by_workorder_ids) > 1: if len(workorder.blocked_by_workorder_ids) > 1:
if workorder.sequence == 1: if workorder.sequence == 1:

View File

@@ -257,7 +257,7 @@
<record id="sf_production_plan_action" model="ir.actions.act_window"> <record id="sf_production_plan_action" model="ir.actions.act_window">
<field name="name">CNC产线计划排程</field> <field name="name">制造订单生产计划</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">sf.production.plan</field> <field name="res_model">sf.production.plan</field>
<field name="view_mode">gantt,tree,form</field> <field name="view_mode">gantt,tree,form</field>

View File

@@ -25,7 +25,7 @@ class SfQualityCncTest(models.Model):
('pass', '合格'), ('pass', '合格'),
('fail', '不合格')], string='判定结果') ('fail', '不合格')], string='判定结果')
number = fields.Integer('数量', default=1) number = fields.Integer('数量', default=1)
test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], string="检测结果") test_results = fields.Selection([("合格", "合格")], string="检测结果")
reason = fields.Selection( reason = fields.Selection(
[("programming", "编程"), ("cutter", "刀具"), ("clamping", "装夹"), ("operate computer", "操机"), [("programming", "编程"), ("cutter", "刀具"), ("clamping", "装夹"), ("operate computer", "操机"),
("technology", "工艺"), ("customer redrawing", "客户改图")], string="原因") ("technology", "工艺"), ("customer redrawing", "客户改图")], string="原因")

View File

@@ -247,27 +247,45 @@ class RePurchaseOrder(models.Model):
raise UserError('请对【产品】中的【税】进行选择') raise UserError('请对【产品】中的【税】进行选择')
def get_purchase_order(self, consecutive_process_parameters, production, product_id_to_production_names): def get_purchase_order(self, consecutive_process_parameters, production, product_id_to_production_names):
server_product_process = []
production_process = product_id_to_production_names.get(
production.product_id.id)
purchase_order = self.env['purchase.order'].search(
[('state', '=', 'draft'), ('origin', '=', production.name),
('purchase_type', '=', 'consignment')], order='name asc')
for pp in consecutive_process_parameters: for pp in consecutive_process_parameters:
server_product_process = [] server_template = self.env['product.template'].search(
purchase_order = pp._get_surface_technics_purchase_ids() [('server_product_process_parameters_id', '=', pp.surface_technics_parameters_id.id),
if purchase_order: ('detailed_type', '=', 'service')])
purchase_order.write({'state': 'draft'}) if not purchase_order:
else:
server_template = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', pp.surface_technics_parameters_id.id),
('detailed_type', '=', 'service')])
server_product_process.append((0, 0, { server_product_process.append((0, 0, {
'product_id': server_template.product_variant_id.id, 'product_id': server_template.product_variant_id.id,
'product_qty': 1, 'product_qty': 1,
'product_uom': server_template.uom_id.id 'product_uom': server_template.uom_id.id
})) }))
purchase_order = self.env['purchase.order'].sudo().create({ for purchase in purchase_order:
'partner_id': server_template.seller_ids[0].partner_id.id, for po in purchase.order_line:
'origin': production.name, if po.product_id == server_template.product_variant_id:
'state': 'draft', continue
'purchase_type': 'consignment', if server_template.server_product_process_parameters_id != po.product_id.server_product_process_parameters_id:
'order_line': server_product_process}) purchase_order_line = self.env['purchase.order.line'].search(
pp.purchase_id = [(6, 0, [purchase_order.id])] [('product_id', '=', server_template.product_variant_id.id),
('product_qty', '=', 1.0), ('id', '=', purchase.id)], limit=1,
order='id desc')
if not purchase_order_line:
server_product_process.append((0, 0, {
'product_id': server_template.product_variant_id.id,
'product_qty': 1,
'product_uom': server_template.uom_id.id
}))
if server_product_process:
self.env['purchase.order'].sudo().create({
'partner_id': server_template.seller_ids[0].partner_id.id,
'origin': production.name,
'state': 'draft',
'purchase_type': 'consignment',
'order_line': server_product_process})
# self.env.cr.commit() # self.env.cr.commit()
@api.onchange('order_line') @api.onchange('order_line')

View File

@@ -128,9 +128,9 @@
<!-- action="account.res_partner_action_customer"--> <!-- action="account.res_partner_action_customer"-->
<!-- groups="sales_team.group_sale_salesman"--> <!-- groups="sales_team.group_sale_salesman"-->
<!-- sequence="40"/>--> <!-- sequence="40"/>-->
<!-- <menuitem sequence="21" name="快速订单" id="menu_quick_easy_order"--> <menuitem sequence="21" name="快速订单" id="menu_quick_easy_order"
<!-- action="action_quick_easy_order"--> action="action_quick_easy_order"
<!-- parent="sale.sale_order_menu"--> parent="sale.sale_order_menu"
<!-- groups="sales_team.group_sale_salesman,sf_base.group_sale_salemanager,sf_base.group_sale_director"/>--> groups="sales_team.group_sale_salesman,sf_base.group_sale_salemanager,sf_base.group_sale_director"/>
</data> </data>
</odoo> </odoo>