Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化
# Conflicts: # sf_manufacturing/models/mrp_workorder.py
This commit is contained in:
@@ -721,6 +721,7 @@ 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)], order='sequence asc')
|
('is_subcontract', '=', True)], order='sequence asc')
|
||||||
@@ -737,10 +738,11 @@ 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)
|
# self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production, sorted_workorders)
|
||||||
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]
|
||||||
@@ -751,18 +753,22 @@ 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:
|
||||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
|
proc_workorders.append(consecutive_workorders)
|
||||||
self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
|
# self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
|
||||||
product_id_to_production_names)
|
# self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
|
||||||
|
# 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):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
|
|||||||
@@ -23,12 +23,15 @@ 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(related='production_id.product_tmpl_id.length', readonly=True, store=True,
|
product_tmpl_id_length = fields.Float(string='坯料长度(mm)', related='material_length', readonly=True, store=False)
|
||||||
string="坯料长度(mm)")
|
product_tmpl_id_width = fields.Float(string='坯料宽度(mm)', related='material_width', readonly=True, store=False)
|
||||||
product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True,
|
product_tmpl_id_height = fields.Float(string='坯料高度(mm)', related='material_height', readonly=True, store=False)
|
||||||
string="坯料宽度(mm)")
|
# product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True,
|
||||||
product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True,
|
# string="坯料长度(mm)")
|
||||||
string="坯料高度(mm)")
|
# product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True,
|
||||||
|
# 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',
|
||||||
@@ -134,8 +137,10 @@ 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='外协出入库单', compute='_compute_surface_technics_picking_ids')
|
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')
|
||||||
|
|
||||||
@@ -239,12 +244,10 @@ 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:
|
||||||
# process_product = self.env['product.template']._get_process_parameters_product(
|
# domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
|
||||||
# previous_workorder.surface_technics_parameters_id)
|
# else:
|
||||||
domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
|
|
||||||
else:
|
|
||||||
domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
|
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)
|
||||||
@@ -314,24 +317,27 @@ 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:
|
||||||
domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment'),
|
purchase_orders_id = self._get_surface_technics_purchase_ids()
|
||||||
('state', '!=', 'cancel')]
|
result = {
|
||||||
|
"type": "ir.actions.act_window",
|
||||||
|
"res_model": "purchase.order",
|
||||||
|
"res_id": purchase_orders_id.id,
|
||||||
|
# "domain": [['id', 'in', self.purchase_id]],
|
||||||
|
"name": _("Purchase Orders"),
|
||||||
|
'view_mode': 'form',
|
||||||
|
}
|
||||||
|
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 = self.env['purchase.order'].search(domain)
|
||||||
purchase_orders_id = None
|
purchase_orders_id = None
|
||||||
for po in purchase_orders:
|
for po in purchase_orders:
|
||||||
for line in po.order_line:
|
for line in po.order_line:
|
||||||
if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id:
|
if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id:
|
||||||
if line.product_qty == 1:
|
if line.product_qty == 1:
|
||||||
purchase_orders_id = line.order_id.id
|
purchase_orders_id = line.order_id
|
||||||
result = {
|
return purchase_orders_id
|
||||||
"type": "ir.actions.act_window",
|
|
||||||
"res_model": "purchase.order",
|
|
||||||
"res_id": purchase_orders_id,
|
|
||||||
# "domain": [['id', 'in', self.purchase_id]],
|
|
||||||
"name": _("Purchase Orders"),
|
|
||||||
'view_mode': 'form',
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
|
|
||||||
supplier_id = fields.Many2one('res.partner', string='外协供应商')
|
supplier_id = fields.Many2one('res.partner', string='外协供应商')
|
||||||
equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True)
|
equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True)
|
||||||
@@ -1029,47 +1035,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:
|
||||||
# 如果工单的工序没有进行排序则跳出循环
|
# 如果工单的工序没有进行排序则跳出循环
|
||||||
@@ -1120,19 +1126,24 @@ 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:
|
||||||
|
# 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:
|
else:
|
||||||
workorder.state = 'waiting'
|
workorder.state = 'waiting'
|
||||||
|
|
||||||
@@ -1197,6 +1208,10 @@ 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',
|
||||||
@@ -1204,9 +1219,6 @@ 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:
|
||||||
@@ -1243,19 +1255,33 @@ 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.env['stock.move'].search(
|
move_out = self.move_subcontract_workorder_ids[1]
|
||||||
[('location_id', '=', self.env['stock.location'].search(
|
# move_out = self.env['stock.move'].search(
|
||||||
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
|
# [('location_id', '=', self.env['stock.location'].search(
|
||||||
('location_dest_id', '=', self.env['stock.location'].search(
|
# [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
|
||||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
# ('location_dest_id', '=', self.env['stock.location'].search(
|
||||||
('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])])
|
# [('barcode', 'ilike', 'VL-SPOC')]).id),
|
||||||
|
# ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])])
|
||||||
for mo in move_out:
|
for mo in move_out:
|
||||||
pick = self.env['stock.picking'].search([('id', '=', mo.picking_id.id), ('name', 'ilike', 'OCOUT'),
|
|
||||||
('partner_id', '=', self.supplier_id.id)])
|
|
||||||
if pick:
|
|
||||||
if mo.state != 'done':
|
if mo.state != 'done':
|
||||||
mo.write({'state': 'assigned', 'production_id': False})
|
mo.write({'state': 'assigned', 'production_id': False})
|
||||||
|
if not mo.move_line_ids:
|
||||||
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':
|
||||||
@@ -1360,6 +1386,13 @@ 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)
|
||||||
@@ -1402,13 +1435,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'
|
||||||
|
|
||||||
@@ -1529,6 +1562,8 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
# '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):
|
||||||
_name = 'sf.cnc.processing'
|
_name = 'sf.cnc.processing'
|
||||||
|
|||||||
@@ -636,74 +636,85 @@ class StockPicking(models.Model):
|
|||||||
|
|
||||||
def button_validate(self):
|
def button_validate(self):
|
||||||
res = super().button_validate()
|
res = super().button_validate()
|
||||||
if res is True and self.picking_type_id.sequence_code == 'OCOUT':
|
picking_type_in = self.env.ref('sf_manufacturing.outcontract_picking_in').id
|
||||||
# if self.id == move_out.picking_id.id:
|
if res is True and self.picking_type_id.id == picking_type_in:
|
||||||
# if move_out.move_line_ids.workorder_id.state == 'progress':
|
# 如果是最后一张外协入库单,则设置库存位置的预留数量
|
||||||
move_in = self.env['stock.move'].search(
|
move_in = self.move_ids
|
||||||
[('location_dest_id', '=', self.env['stock.location'].search(
|
if move_in:
|
||||||
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
|
workorder = move_in.subcontract_workorder_id
|
||||||
('location_id', '=', self.env['stock.location'].search(
|
workorders = workorder.production_id.workorder_ids
|
||||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence')
|
||||||
('origin', '=', self.origin), ('state', 'not in', ['cancel', 'done'])])
|
if workorder == subcontract_workorders[-1]:
|
||||||
production = self.env['mrp.production'].search([('name', '=', self.origin)])
|
self.env['stock.quant']._update_reserved_quantity(
|
||||||
for mi in move_in:
|
move_in.product_id, move_in.location_dest_id, move_in.product_uom_qty, 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:
|
|
||||||
# if mi.state != 'done':
|
|
||||||
# mi.write({'state': 'assigned'})
|
|
||||||
# self.env['stock.move.line'].create(mi.get_move_line(production, None))
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
# 创建 外协出库入单
|
# 创建 外协出库入单
|
||||||
def create_outcontract_picking(self, sorted_workorders_arr, item):
|
def create_outcontract_picking(self, workorders, item, sorted_workorders):
|
||||||
domain = [('origin', '=', item.name), ('name', 'ilike', 'OCOUT')]
|
domain = [('origin', '=', item.name), ('name', 'ilike', 'OCOUT')]
|
||||||
if len(sorted_workorders_arr) > 1:
|
if len(workorders) > 1:
|
||||||
sorted_workorders_arr = sorted_workorders_arr[0]
|
workorders = workorders[0]
|
||||||
else:
|
else:
|
||||||
domain += [
|
domain += [
|
||||||
('surface_technics_parameters_id', '=', sorted_workorders_arr[0].surface_technics_parameters_id.id)]
|
('surface_technics_parameters_id', '=', workorders[0].surface_technics_parameters_id.id)]
|
||||||
stock_picking = self.env['stock.picking'].search(domain)
|
stock_picking = self.env['stock.picking'].search(domain)
|
||||||
if not stock_picking:
|
if not stock_picking:
|
||||||
for sorted_workorders in sorted_workorders_arr:
|
for workorder in workorders:
|
||||||
# pick_ids = []
|
# pick_ids = []
|
||||||
if not sorted_workorders.picking_ids:
|
if not workorder.picking_ids:
|
||||||
# outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)])
|
# outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)])
|
||||||
# if not outcontract_stock_move:
|
# if not outcontract_stock_move:
|
||||||
# 创建一个新的补货组
|
# 创建一个新的补货组
|
||||||
procurement_group_id = self.env['procurement.group'].create({
|
procurement_group_id = self.env['procurement.group'].create({
|
||||||
'name': sorted_workorders.name,
|
'name': workorder.name,
|
||||||
'partner_id': self.partner_id.id,
|
'partner_id': self.partner_id.id,
|
||||||
})
|
})
|
||||||
|
move_dest_id = False
|
||||||
|
# 如果当前工单是是制造订单的最后一个工单
|
||||||
|
if workorder == item.workorder_ids[-1]:
|
||||||
|
move_dest_id = item.move_raw_ids[0].id
|
||||||
|
else:
|
||||||
|
# 从sorted_workorders中找到上一工单的move
|
||||||
|
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(
|
|
||||||
[('barcode', 'ilike', 'VL-SPOC')]).id,
|
|
||||||
location_dest_id = self.env['stock.location'].search(
|
|
||||||
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
|
|
||||||
outcontract_picking_type_in = self.env.ref(
|
outcontract_picking_type_in = self.env.ref(
|
||||||
'sf_manufacturing.outcontract_picking_in').id,
|
'sf_manufacturing.outcontract_picking_in').id,
|
||||||
outcontract_picking_type_out = self.env.ref(
|
outcontract_picking_type_out = self.env.ref(
|
||||||
'sf_manufacturing.outcontract_picking_out').id,
|
'sf_manufacturing.outcontract_picking_out').id,
|
||||||
moves_in = self.env['stock.move'].sudo().create(
|
moves_in = self.env['stock.move'].sudo().create(
|
||||||
self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id,
|
self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_in, procurement_group_id.id, move_dest_id))
|
||||||
outcontract_picking_type_in, procurement_group_id.id))
|
|
||||||
picking_in = self.create(
|
picking_in = self.create(
|
||||||
moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/'))
|
moves_in._get_new_picking_values_Res(item, workorder, 'WH/OCIN/'))
|
||||||
# pick_ids.append(picking_in.id)
|
# pick_ids.append(picking_in.id)
|
||||||
moves_in.write(
|
moves_in.write(
|
||||||
{'picking_id': picking_in.id, 'state': 'waiting'})
|
{'picking_id': picking_in.id, 'state': 'waiting'})
|
||||||
moves_in._assign_picking_post_process(new=new_picking)
|
moves_in._assign_picking_post_process(new=new_picking)
|
||||||
moves_out = self.env['stock.move'].sudo().create(
|
moves_out = self.env['stock.move'].sudo().create(
|
||||||
self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id,
|
self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_out, procurement_group_id.id, moves_in.id))
|
||||||
outcontract_picking_type_out, procurement_group_id.id, moves_in.id))
|
workorder.write({'move_subcontract_workorder_ids': [(6, 0, [moves_in.id, moves_out.id])]})
|
||||||
picking_out = self.create(
|
picking_out = self.create(
|
||||||
moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/'))
|
moves_out._get_new_picking_values_Res(item, workorder, 'WH/OCOUT/'))
|
||||||
# pick_ids.append(picking_out.id)
|
# pick_ids.append(picking_out.id)
|
||||||
moves_out.write(
|
moves_out.write(
|
||||||
{'picking_id': picking_out.id, 'state': 'waiting'})
|
{'picking_id': picking_out.id, 'state': 'waiting'})
|
||||||
moves_out._assign_picking_post_process(new=new_picking)
|
moves_out._assign_picking_post_process(new=new_picking)
|
||||||
|
return moves_in, moves_out
|
||||||
|
|
||||||
|
@api.depends('move_type', 'immediate_transfer', 'move_ids.state', 'move_ids.picking_id')
|
||||||
|
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):
|
||||||
@@ -713,16 +724,17 @@ 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, location_src_id, location_dest_id, picking_type_id, group_id, move_dest_ids=False):
|
def _get_stock_move_values_Res(self, item, picking_type_id, group_id, move_dest_ids=False):
|
||||||
route = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')])
|
route_id = self.env.ref('sf_manufacturing.route_surface_technology_outsourcing').id
|
||||||
|
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': location_src_id,
|
'location_id': stock_rule.location_src_id.id,
|
||||||
'location_dest_id': location_dest_id,
|
'location_dest_id': stock_rule.location_dest_id.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,
|
||||||
@@ -749,7 +761,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': 'confirmed',
|
'state': 'waiting',
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_move_line(self, production_id, sorted_workorders):
|
def get_move_line(self, production_id, sorted_workorders):
|
||||||
@@ -965,7 +977,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)])
|
||||||
@@ -992,6 +1004,8 @@ class ReStockMove(models.Model):
|
|||||||
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'
|
||||||
|
|||||||
@@ -738,7 +738,7 @@
|
|||||||
<!-- parent="mrp.menu_mrp_manufacturing"-->
|
<!-- parent="mrp.menu_mrp_manufacturing"-->
|
||||||
<!-- sequence="1"/>-->
|
<!-- sequence="1"/>-->
|
||||||
|
|
||||||
<menuitem id="menu_mrp_production_action"
|
<menuitem id="mrp.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"
|
||||||
|
|||||||
@@ -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">制造订单生产计划</field>
|
<field name="name">CNC产线计划排程</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>
|
||||||
|
|||||||
@@ -280,12 +280,13 @@ class RePurchaseOrder(models.Model):
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
if server_product_process:
|
if server_product_process:
|
||||||
self.env['purchase.order'].sudo().create({
|
purchase_order = self.env['purchase.order'].sudo().create({
|
||||||
'partner_id': server_template.seller_ids[0].partner_id.id,
|
'partner_id': server_template.seller_ids[0].partner_id.id,
|
||||||
'origin': production.name,
|
'origin': production.name,
|
||||||
'state': 'draft',
|
'state': 'draft',
|
||||||
'purchase_type': 'consignment',
|
'purchase_type': 'consignment',
|
||||||
'order_line': server_product_process})
|
'order_line': server_product_process})
|
||||||
|
pp.purchase_id = [(6, 0, [purchase_order.id])]
|
||||||
# self.env.cr.commit()
|
# self.env.cr.commit()
|
||||||
|
|
||||||
@api.onchange('order_line')
|
@api.onchange('order_line')
|
||||||
|
|||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user