物料需求计划管理
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user