物料需求计划管理
This commit is contained in:
@@ -5,3 +5,5 @@ from . import sf_production_demand_plan
|
|||||||
from . import sale_order
|
from . import sale_order
|
||||||
from . import stock_route
|
from . import stock_route
|
||||||
from . import mrp_bom
|
from . import mrp_bom
|
||||||
|
from . import mrp_production
|
||||||
|
from . import stock_rule
|
||||||
|
|||||||
21
sf_demand_plan/models/mrp_production.py
Normal file
21
sf_demand_plan/models/mrp_production.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import fields, models, api
|
||||||
|
|
||||||
|
|
||||||
|
class MrpProduction(models.Model):
|
||||||
|
_inherit = 'mrp.production'
|
||||||
|
|
||||||
|
demand_plan_line_id = fields.Many2one(comodel_name="sf.production.demand.plan",
|
||||||
|
string="需求计划明细", readonly=True)
|
||||||
|
|
||||||
|
@api.depends('demand_plan_line_id')
|
||||||
|
def _compute_production_type(self):
|
||||||
|
for production in self:
|
||||||
|
if production.demand_plan_line_id.supply_method == 'automation':
|
||||||
|
production.production_type = '自动化产线加工'
|
||||||
|
elif production.demand_plan_line_id.supply_method == 'manual':
|
||||||
|
production.production_type = '人工线下加工'
|
||||||
|
else:
|
||||||
|
production.production_type = None
|
||||||
@@ -85,8 +85,6 @@ class SfDemandPlan(models.Model):
|
|||||||
default=False
|
default=False
|
||||||
)
|
)
|
||||||
|
|
||||||
procurement_group_id = fields.Many2one('procurement.group', '补货组', copy=False)
|
|
||||||
|
|
||||||
@api.depends('product_id.part_number', 'product_id.model_name')
|
@api.depends('product_id.part_number', 'product_id.model_name')
|
||||||
def _compute_part_number(self):
|
def _compute_part_number(self):
|
||||||
for line in self:
|
for line in self:
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
('销售订单', "销售订单"),
|
('销售订单', "销售订单"),
|
||||||
('需求预测', "需求预测"),
|
('需求预测', "需求预测"),
|
||||||
('生产报废', "生产报废"),
|
('生产报废', "生产报废"),
|
||||||
], string='补货原因', default='销售订单')
|
], string='补货原因', default='销售订单', readonly=True)
|
||||||
|
|
||||||
blank_arrival_date = fields.Date('采购计划到货(坯料)')
|
blank_arrival_date = fields.Date('采购计划到货(坯料)')
|
||||||
finished_product_arrival_date = fields.Date('采购计划到货(成品)')
|
finished_product_arrival_date = fields.Date('采购计划到货(成品)')
|
||||||
@@ -164,39 +164,6 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
continue
|
continue
|
||||||
pdp.route_ids = None
|
pdp.route_ids = None
|
||||||
|
|
||||||
# @api.depends('sale_order_id.state', 'sale_order_id.mrp_production_ids.schedule_state', 'sale_order_id.order_line',
|
|
||||||
# 'sale_order_id.mrp_production_ids.state')
|
|
||||||
# def _compute_status(self):
|
|
||||||
# for record in self:
|
|
||||||
# if record.sale_order_id:
|
|
||||||
# sale_order_state = record.sale_order_id.state
|
|
||||||
# if sale_order_state in ('draft', 'sent', 'supply method'):
|
|
||||||
# record.status = '20' # 待确认
|
|
||||||
# if record.supply_method in ('purchase', 'outsourcing') and sale_order_state in (
|
|
||||||
# 'sale', 'processing', 'physical_distribution', 'delivered',
|
|
||||||
# 'done') and sale_order_state != 'cancel':
|
|
||||||
# record.status = '60' # 已下达
|
|
||||||
# if record.supply_method in ('automation', 'manual'):
|
|
||||||
# if sale_order_state in (
|
|
||||||
# 'sale', 'processing', 'physical_distribution', 'delivered',
|
|
||||||
# 'done') and sale_order_state != 'cancel':
|
|
||||||
# record.status = '30' # 需求确认
|
|
||||||
# # 检查所有制造订单的排程单状态,有一个为待排程状态,就为待下达生产
|
|
||||||
# pending_productions = record.sale_order_id.mrp_production_ids.filtered(
|
|
||||||
# lambda p: p.state == 'confirmed' and p.product_id.id == record.product_id.id
|
|
||||||
# )
|
|
||||||
# if pending_productions:
|
|
||||||
# record.status = '50' # 待下达生产
|
|
||||||
# # 检查所有制造订单的排程单状态
|
|
||||||
# if record.sale_order_id.mrp_production_ids:
|
|
||||||
# product_productions = record.sale_order_id.mrp_production_ids.filtered(
|
|
||||||
# lambda p: p.product_id.id == record.product_id.id
|
|
||||||
# )
|
|
||||||
# if product_productions and all(order.schedule_state != '未排' for order in product_productions):
|
|
||||||
# record.status = '60' # 已下达
|
|
||||||
# if sale_order_state == 'cancel' or not record.sale_order_line_id:
|
|
||||||
# record.status = '100' # 取消
|
|
||||||
|
|
||||||
@api.depends('sale_order_line_id.product_id.name')
|
@api.depends('sale_order_line_id.product_id.name')
|
||||||
def _compute_sale_order_line_number(self):
|
def _compute_sale_order_line_number(self):
|
||||||
for line in self:
|
for line in self:
|
||||||
@@ -541,6 +508,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
self.unlink()
|
self.unlink()
|
||||||
|
|
||||||
def button_release_plan(self):
|
def button_release_plan(self):
|
||||||
|
self.ensure_one()
|
||||||
if not self.supply_method:
|
if not self.supply_method:
|
||||||
raise ValidationError(f"供货方式不能为空!")
|
raise ValidationError(f"供货方式不能为空!")
|
||||||
if self.plan_uom_qty > self.product_uom_qty:
|
if self.plan_uom_qty > self.product_uom_qty:
|
||||||
@@ -556,6 +524,12 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
'default_demand_plan_line_id': self.id,
|
'default_demand_plan_line_id': self.id,
|
||||||
'default_release_message': f"您正在下达计划量 {self.plan_uom_qty},需求数量为 {self.product_uom_qty},已超过需求数量,是否继续?",
|
'default_release_message': f"您正在下达计划量 {self.plan_uom_qty},需求数量为 {self.product_uom_qty},已超过需求数量,是否继续?",
|
||||||
}}
|
}}
|
||||||
|
self.action_confirm()
|
||||||
|
|
||||||
|
def action_confirm(self):
|
||||||
|
self = self.with_context(
|
||||||
|
demand_plan_line_id=self.id
|
||||||
|
)
|
||||||
self.mrp_bom_create()
|
self.mrp_bom_create()
|
||||||
self._action_launch_stock_rule()
|
self._action_launch_stock_rule()
|
||||||
if self.supply_method in ('automation', 'manual'):
|
if self.supply_method in ('automation', 'manual'):
|
||||||
@@ -564,7 +538,18 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
self.write({'status': '60'})
|
self.write({'status': '60'})
|
||||||
|
|
||||||
def mrp_bom_create(self):
|
def mrp_bom_create(self):
|
||||||
self.ensure_one()
|
if self.supply_method in ('automation', 'manual'):
|
||||||
|
line_ids = self.demand_plan_id.line_ids.filtered(
|
||||||
|
lambda p: p.supply_method in ('automation', 'manual') and p.status in ('50', '60'))
|
||||||
|
if line_ids:
|
||||||
|
self.bom_id = line_ids[0].bom_id.id
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
line_ids = self.demand_plan_id.line_ids.filtered(
|
||||||
|
lambda p: p.supply_method in ('purchase', 'outsourcing') and p.status == '60')
|
||||||
|
if line_ids:
|
||||||
|
self.bom_id = line_ids[0].bom_id.id
|
||||||
|
return
|
||||||
bom_type = ''
|
bom_type = ''
|
||||||
# 根据供货方式修改成品模板
|
# 根据供货方式修改成品模板
|
||||||
if self.supply_method == 'automation':
|
if self.supply_method == 'automation':
|
||||||
@@ -702,10 +687,9 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
|
|
||||||
def _action_launch_stock_rule(self):
|
def _action_launch_stock_rule(self):
|
||||||
procurements = []
|
procurements = []
|
||||||
group_id = self.demand_plan_id.procurement_group_id
|
group_id = self.sale_order_id.procurement_group_id
|
||||||
if not group_id:
|
if not group_id:
|
||||||
group_id = self.env['procurement.group'].create(self._prepare_procurement_group_vals())
|
group_id = self.env['procurement.group'].create(self._prepare_procurement_group_vals())
|
||||||
self.demand_plan_id.procurement_group_id = group_id
|
|
||||||
self.sale_order_id.procurement_group_id = group_id
|
self.sale_order_id.procurement_group_id = group_id
|
||||||
else:
|
else:
|
||||||
updated_vals = {}
|
updated_vals = {}
|
||||||
@@ -761,5 +745,6 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
'company_id': self.sale_order_id.company_id,
|
'company_id': self.sale_order_id.company_id,
|
||||||
'product_packaging_id': self.sale_order_line_id.product_packaging_id,
|
'product_packaging_id': self.sale_order_line_id.product_packaging_id,
|
||||||
'sequence': self.sale_order_line_id.sequence,
|
'sequence': self.sale_order_line_id.sequence,
|
||||||
|
'demand_plan_line_id': self.id
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
|
|||||||
16
sf_demand_plan/models/stock_rule.py
Normal file
16
sf_demand_plan/models/stock_rule.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import models
|
||||||
|
|
||||||
|
|
||||||
|
class StockRule(models.Model):
|
||||||
|
_inherit = 'stock.rule'
|
||||||
|
|
||||||
|
def _prepare_mo_vals(self, product_id, product_qty, product_uom, location_id, name, origin, company_id, values,
|
||||||
|
bom):
|
||||||
|
res = super()._prepare_mo_vals(product_id, product_qty, product_uom, location_id, name, origin, company_id,
|
||||||
|
values, bom)
|
||||||
|
if self.env.context.get('demand_plan_line_id'):
|
||||||
|
res['demand_plan_line_id'] = self.env.context.get('demand_plan_line_id')
|
||||||
|
return res
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
<field name="write_date" string="更新时间"/>
|
<field name="write_date" string="更新时间"/>
|
||||||
<button string="下达计划" name="button_release_plan" type="object"
|
<button string="下达计划" name="button_release_plan" type="object"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
attrs="{'invisible': [('status', 'in', ('60','100'))]}"
|
attrs="{'invisible': [('status', 'in', ('50','60','100'))]}"
|
||||||
/>
|
/>
|
||||||
<button name="button_delete" type="object" string="删除"
|
<button name="button_delete" type="object" string="删除"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
|
|||||||
@@ -19,5 +19,4 @@ class SfReleasePlanWizard(models.TransientModel):
|
|||||||
|
|
||||||
def confirm(self):
|
def confirm(self):
|
||||||
if self.demand_plan_line_id:
|
if self.demand_plan_line_id:
|
||||||
self.demand_plan_line_id.mrp_bom_create()
|
self.demand_plan_line_id.action_confirm()
|
||||||
self.demand_plan_line_id._action_launch_stock_rule()
|
|
||||||
|
|||||||
Reference in New Issue
Block a user