物料需求计划管理

This commit is contained in:
guanhuan
2025-06-26 17:18:03 +08:00
parent c14e2c19bf
commit fe4659987f
5 changed files with 83 additions and 7 deletions

View File

@@ -85,6 +85,8 @@ class SfDemandPlan(models.Model):
default=False
)
procurement_group_id = fields.Many2one('procurement.group', '补货组', copy=False)
@api.depends('product_id.part_number', 'product_id.model_name')
def _compute_part_number(self):
for line in self:

View File

@@ -13,6 +13,10 @@ class SfProductionDemandPlan(models.Model):
_name = 'sf.production.demand.plan'
_description = 'sf_production_demand_plan'
def get_location_id(self):
stock_location = self.env['stock.location'].sudo().search([('name', '=', '客户')], limit=1)
return stock_location.id
def _get_machining_precision(self):
machinings = self.env['sf.machining.accuracy'].sudo().search([])
list = [(m.sync_id, m.name) for m in machinings]
@@ -31,7 +35,7 @@ class SfProductionDemandPlan(models.Model):
('50', '待下达生产'),
('60', '已下达'),
('100', '取消'),
], string='状态', default='30')
], string='状态', default='30', readonly=True)
demand_plan_id = fields.Many2one(comodel_name="sf.demand.plan",
string="物料需求", readonly=True)
sale_order_id = fields.Many2one(comodel_name="sale.order",
@@ -59,7 +63,7 @@ class SfProductionDemandPlan(models.Model):
('manual', "人工线下加工"),
('purchase', "外购"),
('outsourcing', "委外加工"),
], string='供货方式')
], string='供货方式', default='manual')
product_uom_qty = fields.Float(
string="需求数量",
related='sale_order_line_id.product_uom_qty', store=True)
@@ -145,7 +149,8 @@ class SfProductionDemandPlan(models.Model):
blank_arrival_date = fields.Date('采购计划到货(坯料)')
finished_product_arrival_date = fields.Date('采购计划到货(成品)')
bom_id = fields.Many2one('mrp.bom', readonly=True, string="BOM")
bom_id = fields.Many2one('mrp.bom', string="BOM", readonly=True)
location_id = fields.Many2one('stock.location', string='需求位置', default=get_location_id, readonly=True)
@api.depends('supply_method')
def _compute_route_ids(self):
@@ -552,6 +557,11 @@ class SfProductionDemandPlan(models.Model):
'default_release_message': f"您正在下达计划量 {self.plan_uom_qty},需求数量为 {self.product_uom_qty},已超过需求数量,是否继续?",
}}
self.mrp_bom_create()
self._action_launch_stock_rule()
if self.supply_method in ('automation', 'manual'):
self.write({'status': '50'})
else:
self.write({'status': '60'})
def mrp_bom_create(self):
self.ensure_one()
@@ -689,3 +699,66 @@ class SfProductionDemandPlan(models.Model):
product_bom_purchase.with_user(self.env.ref("base.user_admin")).bom_create_line_has(
purchase_embryo)
self.bom_id = product_bom_purchase.id
def _action_launch_stock_rule(self):
procurements = []
group_id = self.demand_plan_id.procurement_group_id
if not group_id:
group_id = self.env['procurement.group'].create(self._prepare_procurement_group_vals())
self.demand_plan_id.procurement_group_id = group_id
else:
updated_vals = {}
if group_id.partner_id != self.sale_order_id.partner_shipping_id:
updated_vals.update({'partner_id': self.sale_order_id.partner_shipping_id.id})
if group_id.move_type != self.sale_order_id.picking_policy:
updated_vals.update({'move_type': self.sale_order_id.picking_policy})
if updated_vals:
group_id.write(updated_vals)
values = self._prepare_procurement_values(group_id=group_id)
line_uom = self.sale_order_line_id.product_uom
quant_uom = self.product_id.uom_id
plan_uom_qty, procurement_uom = line_uom._adjust_uom_quantities(self.plan_uom_qty, quant_uom)
procurements.append(self.env['procurement.group'].Procurement(
self.product_id, plan_uom_qty, procurement_uom,
self.sale_order_id.partner_shipping_id.property_stock_customer,
self.product_id.display_name, self.sale_order_id.name, self.sale_order_id.company_id, values))
if procurements:
procurement_group = self.env['procurement.group']
if self.env.context.get('import_file'):
procurement_group = procurement_group.with_context(import_file=False)
procurement_group.run(procurements)
orders = self.mapped('sale_order_id')
for order in orders:
pickings_to_confirm = order.picking_ids.filtered(lambda p: p.state not in ['cancel', 'done'])
if pickings_to_confirm:
pickings_to_confirm.action_confirm()
return True
def _prepare_procurement_group_vals(self):
return {
'name': self.sale_order_id.name,
'move_type': self.sale_order_id.picking_policy,
'sale_id': self.sale_order_id.id,
'partner_id': self.sale_order_id.partner_shipping_id.id,
}
def _prepare_procurement_values(self, group_id=False):
self.ensure_one()
date_deadline = self.sale_order_id.commitment_date or (
self.sale_order_id.date_order + timedelta(days=self.sale_order_line_id.customer_lead or 0.0))
date_planned = date_deadline - timedelta(days=self.sale_order_id.company_id.security_lead)
values = {
'group_id': group_id,
'sale_line_id': self.sale_order_line_id.id,
'date_planned': date_planned,
'date_deadline': date_deadline,
'route_ids': self.route_ids,
'warehouse_id': self.sale_order_id.warehouse_id or False,
'partner_id': self.sale_order_id.partner_shipping_id.id,
'product_description_variants': self.sale_order_line_id.with_context(
lang=self.sale_order_id.partner_id.lang)._get_sale_order_line_multiline_description_variants(),
'company_id': self.sale_order_id.company_id,
'product_packaging_id': self.sale_order_line_id.product_packaging_id,
'sequence': self.sale_order_line_id.sequence,
}
return values

View File

@@ -71,7 +71,7 @@
<button name="release_production_order" type="object" string="下达生产" class="btn-primary"
attrs="{'invisible': ['|',('status', '!=', '50'), ('supply_method', 'not in', ['automation', 'manual'])]}"/>
<button name="edit_button" type="object" string="编辑" class="btn-primary"/>
<button name="edit_button" type="object" string="拆分" class="btn-primary"/>
</tree>
</field>
</record>

View File

@@ -33,17 +33,17 @@
<field name="model_process_parameters_ids" widget="many2many_tags"/>
<field name="model_machining_precision"/>
<field name="inventory_quantity_auto_apply"/>
<field name="priority"/>
<field name="priority" attrs="{'readonly': [('state', '=', '40')]}"/>
</group>
</group>
<notebook>
<page string="计划">
<field name="line_ids">
<field name="line_ids" attrs="{'readonly': [('state', '=', '40')]}">
<tree editable="bottom" delete="false">
<field name="status"/>
<field name="supply_method" attrs="{'readonly': [('status', '!=', '30')]}"/>
<field name="route_ids" widget="many2many_tags" optional="hide"/>
<!--<field name="需求位置"/>-->
<field name="location_id" optional="hide"/>
<field name="bom_id" optional="hide"/>
<field name="plan_uom_qty"/>
<field name="blank_arrival_date"/>

View File

@@ -20,3 +20,4 @@ class SfReleasePlanWizard(models.TransientModel):
def confirm(self):
if self.demand_plan_line_id:
self.demand_plan_line_id.mrp_bom_create()
self.demand_plan_line_id._action_launch_stock_rule()