物料需求计划
This commit is contained in:
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
from . import sf_production_demand_plan
|
from . import sf_production_demand_plan
|
||||||
from . import sale_order
|
from . import sale_order
|
||||||
|
from . import sf_demand_plan
|
||||||
|
|||||||
123
sf_demand_plan/models/sf_demand_plan.py
Normal file
123
sf_demand_plan/models/sf_demand_plan.py
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import models, fields, api, _
|
||||||
|
|
||||||
|
|
||||||
|
class SfDemandPlan(models.Model):
|
||||||
|
_name = 'sf.demand.plan'
|
||||||
|
_description = 'sf_demand_plan'
|
||||||
|
|
||||||
|
def _get_machining_precision(self):
|
||||||
|
machinings = self.env['sf.machining.accuracy'].sudo().search([])
|
||||||
|
list = [(m.sync_id, m.name) for m in machinings]
|
||||||
|
return list
|
||||||
|
|
||||||
|
line_ids = fields.One2many('sf.production.demand.plan', 'demand_plan_id', string="需求计划", copy=True)
|
||||||
|
|
||||||
|
sale_order_id = fields.Many2one(comodel_name="sale.order",
|
||||||
|
string="销售订单", readonly=True)
|
||||||
|
sale_order_line_id = fields.Many2one(comodel_name="sale.order.line",
|
||||||
|
string="销售订单明细", readonly=True)
|
||||||
|
|
||||||
|
product_id = fields.Many2one(
|
||||||
|
comodel_name='product.product',
|
||||||
|
related='sale_order_line_id.product_id',
|
||||||
|
string='产品', store=True, index=True)
|
||||||
|
|
||||||
|
part_name = fields.Char('零件名称', related='product_id.part_name')
|
||||||
|
part_number = fields.Char('零件图号', compute='_compute_part_number', store=True)
|
||||||
|
materials_id = fields.Char('材料', compute='_compute_materials_id', store=True)
|
||||||
|
|
||||||
|
blank_type = fields.Selection([('圆料', '圆料'), ('方料', '方料')], string='坯料分类',
|
||||||
|
related='product_id.blank_type')
|
||||||
|
embryo_long = fields.Char('坯料尺寸(mm)', compute='_compute_embryo_long', store=True)
|
||||||
|
is_incoming_material = fields.Boolean('客供料', related='sale_order_line_id.is_incoming_material', store=True)
|
||||||
|
# product_uom_qty = fields.Float(
|
||||||
|
# string="待计划",
|
||||||
|
# related='sale_order_line_id.product_uom_qty', store=True)
|
||||||
|
model_id = fields.Char('模型ID', related='product_id.model_id')
|
||||||
|
customer_name = fields.Char('客户', related='sale_order_id.customer_name')
|
||||||
|
product_uom_qty = fields.Float(
|
||||||
|
string="需求数量",
|
||||||
|
related='sale_order_line_id.product_uom_qty', store=True)
|
||||||
|
deadline_of_delivery = fields.Date('客户交期', related='sale_order_line_id.delivery_end_date', store=True)
|
||||||
|
contract_date = fields.Date('合同日期', related='sale_order_id.contract_date')
|
||||||
|
contract_code = fields.Char('合同号', related='sale_order_id.contract_code', store=True)
|
||||||
|
|
||||||
|
model_process_parameters_ids = fields.Many2many('sf.production.process.parameter',
|
||||||
|
'plan_process_parameter_rel',
|
||||||
|
string='表面工艺',
|
||||||
|
compute='_compute_model_process_parameters_ids'
|
||||||
|
, store=True
|
||||||
|
)
|
||||||
|
model_machining_precision = fields.Selection(selection=_get_machining_precision, string='精度',
|
||||||
|
related='product_id.model_machining_precision')
|
||||||
|
|
||||||
|
inventory_quantity_auto_apply = fields.Float(
|
||||||
|
string="成品库存",
|
||||||
|
compute='_compute_inventory_quantity_auto_apply', store=True
|
||||||
|
)
|
||||||
|
|
||||||
|
priority = fields.Selection([
|
||||||
|
('1', '紧急'),
|
||||||
|
('2', '高'),
|
||||||
|
('3', '中'),
|
||||||
|
('4', '低'),
|
||||||
|
], string='优先级', default='3')
|
||||||
|
|
||||||
|
@api.depends('product_id.part_number', 'product_id.model_name')
|
||||||
|
def _compute_part_number(self):
|
||||||
|
for line in self:
|
||||||
|
if line.product_id:
|
||||||
|
if line.product_id.part_number:
|
||||||
|
line.part_number = line.product_id.part_number
|
||||||
|
else:
|
||||||
|
if line.product_id.model_name:
|
||||||
|
line.part_number = line.product_id.model_name.rsplit('.', 1)[0]
|
||||||
|
else:
|
||||||
|
line.part_number = None
|
||||||
|
|
||||||
|
@api.depends('product_id.materials_id')
|
||||||
|
def _compute_materials_id(self):
|
||||||
|
for line in self:
|
||||||
|
if line.product_id:
|
||||||
|
line.materials_id = f"{line.product_id.materials_id.name}/{line.product_id.materials_type_id.name}"
|
||||||
|
else:
|
||||||
|
line.materials_id = None
|
||||||
|
|
||||||
|
@api.depends('product_id.model_long', 'product_id.model_width', 'product_id.model_height')
|
||||||
|
def _compute_embryo_long(self):
|
||||||
|
for line in self:
|
||||||
|
if line.product_id:
|
||||||
|
line.embryo_long = f"{round(line.product_id.model_long, 3)}*{round(line.product_id.model_width, 3)}*{round(line.product_id.model_height, 3)}"
|
||||||
|
else:
|
||||||
|
line.embryo_long = None
|
||||||
|
|
||||||
|
@api.depends('product_id.model_process_parameters_ids')
|
||||||
|
def _compute_model_process_parameters_ids(self):
|
||||||
|
for line in self:
|
||||||
|
if line.product_id and line.product_id.model_process_parameters_ids:
|
||||||
|
line.model_process_parameters_ids = [(6, 0, line.product_id.model_process_parameters_ids.ids)]
|
||||||
|
else:
|
||||||
|
line.model_process_parameters_ids = [(5, 0, 0)]
|
||||||
|
|
||||||
|
def _compute_inventory_quantity_auto_apply(self):
|
||||||
|
location_id = self.env['stock.location'].search([('name', '=', '成品存货区')], limit=1).id
|
||||||
|
product_ids = self.mapped('product_id').ids
|
||||||
|
if product_ids:
|
||||||
|
quant_data = self.env['stock.quant'].read_group(
|
||||||
|
domain=[
|
||||||
|
('product_id', 'in', product_ids),
|
||||||
|
('location_id', '=', location_id)
|
||||||
|
],
|
||||||
|
fields=['product_id', 'inventory_quantity_auto_apply'],
|
||||||
|
groupby=['product_id']
|
||||||
|
)
|
||||||
|
quantity_map = {item['product_id'][0]: item['inventory_quantity_auto_apply'] for item in quant_data}
|
||||||
|
else:
|
||||||
|
quantity_map = {}
|
||||||
|
for line in self:
|
||||||
|
if line.product_id:
|
||||||
|
line.inventory_quantity_auto_apply = quantity_map.get(line.product_id.id, 0.0)
|
||||||
|
else:
|
||||||
|
line.inventory_quantity_auto_apply = 0.0
|
||||||
@@ -31,6 +31,8 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
('60', '已下达'),
|
('60', '已下达'),
|
||||||
('100', '取消'),
|
('100', '取消'),
|
||||||
], string='状态', compute='_compute_status', store=True)
|
], string='状态', compute='_compute_status', store=True)
|
||||||
|
demand_plan_id = fields.Many2one(comodel_name="sf.demand.plan",
|
||||||
|
string="物料需求", readonly=True)
|
||||||
sale_order_id = fields.Many2one(comodel_name="sale.order",
|
sale_order_id = fields.Many2one(comodel_name="sale.order",
|
||||||
string="销售订单", readonly=True)
|
string="销售订单", readonly=True)
|
||||||
sale_order_line_id = fields.Many2one(comodel_name="sale.order.line",
|
sale_order_line_id = fields.Many2one(comodel_name="sale.order.line",
|
||||||
@@ -49,7 +51,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
string='产品', store=True, index=True)
|
string='产品', store=True, index=True)
|
||||||
model_id = fields.Char('模型ID', related='product_id.model_id')
|
model_id = fields.Char('模型ID', related='product_id.model_id')
|
||||||
part_name = fields.Char('零件名称', related='product_id.part_name')
|
part_name = fields.Char('零件名称', related='product_id.part_name')
|
||||||
part_number = fields.Char('零件图号', compute='_compute_part_number', store=True)
|
part_number = fields.Char('零件图号', related='demand_plan_id.part_number')
|
||||||
is_incoming_material = fields.Boolean('客供料', related='sale_order_line_id.is_incoming_material', store=True)
|
is_incoming_material = fields.Boolean('客供料', related='sale_order_line_id.is_incoming_material', store=True)
|
||||||
supply_method = fields.Selection([
|
supply_method = fields.Selection([
|
||||||
('automation', "自动化产线加工"),
|
('automation', "自动化产线加工"),
|
||||||
@@ -63,7 +65,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
deadline_of_delivery = fields.Date('客户交期', related='sale_order_line_id.delivery_end_date', store=True)
|
deadline_of_delivery = fields.Date('客户交期', related='sale_order_line_id.delivery_end_date', store=True)
|
||||||
inventory_quantity_auto_apply = fields.Float(
|
inventory_quantity_auto_apply = fields.Float(
|
||||||
string="成品库存",
|
string="成品库存",
|
||||||
compute='_compute_inventory_quantity_auto_apply'
|
related='demand_plan_id.inventory_quantity_auto_apply'
|
||||||
)
|
)
|
||||||
qty_delivered = fields.Float(
|
qty_delivered = fields.Float(
|
||||||
"交货数量", related='sale_order_line_id.qty_delivered')
|
"交货数量", related='sale_order_line_id.qty_delivered')
|
||||||
@@ -72,14 +74,14 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
model_long = fields.Char('尺寸(mm)', compute='_compute_model_long')
|
model_long = fields.Char('尺寸(mm)', compute='_compute_model_long')
|
||||||
blank_type = fields.Selection([('圆料', '圆料'), ('方料', '方料')], string='坯料分类',
|
blank_type = fields.Selection([('圆料', '圆料'), ('方料', '方料')], string='坯料分类',
|
||||||
related='product_id.blank_type')
|
related='product_id.blank_type')
|
||||||
embryo_long = fields.Char('坯料尺寸(mm)', compute='_compute_embryo_long')
|
embryo_long = fields.Char('坯料尺寸(mm)', related='demand_plan_id.embryo_long')
|
||||||
materials_id = fields.Char('材料', compute='_compute_materials_id', store=True)
|
materials_id = fields.Char('材料', related='demand_plan_id.materials_id')
|
||||||
model_machining_precision = fields.Selection(selection=_get_machining_precision, string='精度',
|
model_machining_precision = fields.Selection(selection=_get_machining_precision, string='精度',
|
||||||
related='product_id.model_machining_precision')
|
related='product_id.model_machining_precision')
|
||||||
model_process_parameters_ids = fields.Many2many('sf.production.process.parameter',
|
model_process_parameters_ids = fields.Many2many('sf.production.process.parameter',
|
||||||
'plan_process_parameter_rel',
|
'plan_process_parameter_rel',
|
||||||
string='表面工艺',
|
string='表面工艺',
|
||||||
compute='_compute_model_process_parameters_ids'
|
related='demand_plan_id.model_process_parameters_ids'
|
||||||
, store=True
|
, store=True
|
||||||
)
|
)
|
||||||
product_remark = fields.Char("产品备注", related='product_id.model_remark')
|
product_remark = fields.Char("产品备注", related='product_id.model_remark')
|
||||||
@@ -176,18 +178,6 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
else:
|
else:
|
||||||
line.sale_order_line_number = None
|
line.sale_order_line_number = None
|
||||||
|
|
||||||
@api.depends('product_id.part_number', 'product_id.model_name')
|
|
||||||
def _compute_part_number(self):
|
|
||||||
for line in self:
|
|
||||||
if line.product_id:
|
|
||||||
if line.product_id.part_number:
|
|
||||||
line.part_number = line.product_id.part_number
|
|
||||||
else:
|
|
||||||
if line.product_id.model_name:
|
|
||||||
line.part_number = line.product_id.model_name.rsplit('.', 1)[0]
|
|
||||||
else:
|
|
||||||
line.part_number = None
|
|
||||||
|
|
||||||
@api.depends('product_id.length', 'product_id.width', 'product_id.height')
|
@api.depends('product_id.length', 'product_id.width', 'product_id.height')
|
||||||
def _compute_model_long(self):
|
def _compute_model_long(self):
|
||||||
for line in self:
|
for line in self:
|
||||||
@@ -196,51 +186,6 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
else:
|
else:
|
||||||
line.model_long = None
|
line.model_long = None
|
||||||
|
|
||||||
@api.depends('product_id.model_long', 'product_id.model_width', 'product_id.model_height')
|
|
||||||
def _compute_embryo_long(self):
|
|
||||||
for line in self:
|
|
||||||
if line.product_id:
|
|
||||||
line.embryo_long = f"{round(line.product_id.model_long, 3)}*{round(line.product_id.model_width, 3)}*{round(line.product_id.model_height, 3)}"
|
|
||||||
else:
|
|
||||||
line.embryo_long = None
|
|
||||||
|
|
||||||
@api.depends('product_id.materials_id')
|
|
||||||
def _compute_materials_id(self):
|
|
||||||
for line in self:
|
|
||||||
if line.product_id:
|
|
||||||
line.materials_id = f"{line.product_id.materials_id.name}/{line.product_id.materials_type_id.name}"
|
|
||||||
else:
|
|
||||||
line.materials_id = None
|
|
||||||
|
|
||||||
@api.depends('product_id.model_process_parameters_ids')
|
|
||||||
def _compute_model_process_parameters_ids(self):
|
|
||||||
for line in self:
|
|
||||||
if line.product_id and line.product_id.model_process_parameters_ids:
|
|
||||||
line.model_process_parameters_ids = [(6, 0, line.product_id.model_process_parameters_ids.ids)]
|
|
||||||
else:
|
|
||||||
line.model_process_parameters_ids = [(5, 0, 0)]
|
|
||||||
|
|
||||||
def _compute_inventory_quantity_auto_apply(self):
|
|
||||||
location_id = self.env['stock.location'].search([('name', '=', '成品存货区')], limit=1).id
|
|
||||||
product_ids = self.mapped('product_id').ids
|
|
||||||
if product_ids:
|
|
||||||
quant_data = self.env['stock.quant'].read_group(
|
|
||||||
domain=[
|
|
||||||
('product_id', 'in', product_ids),
|
|
||||||
('location_id', '=', location_id)
|
|
||||||
],
|
|
||||||
fields=['product_id', 'inventory_quantity_auto_apply'],
|
|
||||||
groupby=['product_id']
|
|
||||||
)
|
|
||||||
quantity_map = {item['product_id'][0]: item['inventory_quantity_auto_apply'] for item in quant_data}
|
|
||||||
else:
|
|
||||||
quantity_map = {}
|
|
||||||
for line in self:
|
|
||||||
if line.product_id:
|
|
||||||
line.inventory_quantity_auto_apply = quantity_map.get(line.product_id.id, 0.0)
|
|
||||||
else:
|
|
||||||
line.inventory_quantity_auto_apply = 0.0
|
|
||||||
|
|
||||||
@api.depends('sale_order_id.mrp_production_ids.workorder_ids.date_start')
|
@api.depends('sale_order_id.mrp_production_ids.workorder_ids.date_start')
|
||||||
def _compute_actual_start_date(self):
|
def _compute_actual_start_date(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
@@ -329,7 +274,6 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
for pro_plan in pro_plan_list:
|
for pro_plan in pro_plan_list:
|
||||||
pro_plan.do_production_schedule()
|
pro_plan.do_production_schedule()
|
||||||
|
|
||||||
|
|
||||||
def button_action_print(self):
|
def button_action_print(self):
|
||||||
return {
|
return {
|
||||||
'res_model': 'sf.demand.plan.print.wizard',
|
'res_model': 'sf.demand.plan.print.wizard',
|
||||||
|
|||||||
Reference in New Issue
Block a user