物料需求计划管理
This commit is contained in:
@@ -85,6 +85,8 @@ 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:
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
_name = 'sf.production.demand.plan'
|
_name = 'sf.production.demand.plan'
|
||||||
_description = '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):
|
def _get_machining_precision(self):
|
||||||
machinings = self.env['sf.machining.accuracy'].sudo().search([])
|
machinings = self.env['sf.machining.accuracy'].sudo().search([])
|
||||||
list = [(m.sync_id, m.name) for m in machinings]
|
list = [(m.sync_id, m.name) for m in machinings]
|
||||||
@@ -31,7 +35,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
('50', '待下达生产'),
|
('50', '待下达生产'),
|
||||||
('60', '已下达'),
|
('60', '已下达'),
|
||||||
('100', '取消'),
|
('100', '取消'),
|
||||||
], string='状态', default='30')
|
], string='状态', default='30', readonly=True)
|
||||||
demand_plan_id = fields.Many2one(comodel_name="sf.demand.plan",
|
demand_plan_id = fields.Many2one(comodel_name="sf.demand.plan",
|
||||||
string="物料需求", readonly=True)
|
string="物料需求", readonly=True)
|
||||||
sale_order_id = fields.Many2one(comodel_name="sale.order",
|
sale_order_id = fields.Many2one(comodel_name="sale.order",
|
||||||
@@ -59,7 +63,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
('manual', "人工线下加工"),
|
('manual', "人工线下加工"),
|
||||||
('purchase', "外购"),
|
('purchase', "外购"),
|
||||||
('outsourcing', "委外加工"),
|
('outsourcing', "委外加工"),
|
||||||
], string='供货方式')
|
], string='供货方式', default='manual')
|
||||||
product_uom_qty = fields.Float(
|
product_uom_qty = fields.Float(
|
||||||
string="需求数量",
|
string="需求数量",
|
||||||
related='sale_order_line_id.product_uom_qty', store=True)
|
related='sale_order_line_id.product_uom_qty', store=True)
|
||||||
@@ -145,7 +149,8 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
|
|
||||||
blank_arrival_date = fields.Date('采购计划到货(坯料)')
|
blank_arrival_date = fields.Date('采购计划到货(坯料)')
|
||||||
finished_product_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')
|
@api.depends('supply_method')
|
||||||
def _compute_route_ids(self):
|
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},已超过需求数量,是否继续?",
|
'default_release_message': f"您正在下达计划量 {self.plan_uom_qty},需求数量为 {self.product_uom_qty},已超过需求数量,是否继续?",
|
||||||
}}
|
}}
|
||||||
self.mrp_bom_create()
|
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):
|
def mrp_bom_create(self):
|
||||||
self.ensure_one()
|
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(
|
product_bom_purchase.with_user(self.env.ref("base.user_admin")).bom_create_line_has(
|
||||||
purchase_embryo)
|
purchase_embryo)
|
||||||
self.bom_id = product_bom_purchase.id
|
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"
|
<button name="release_production_order" type="object" string="下达生产" class="btn-primary"
|
||||||
attrs="{'invisible': ['|',('status', '!=', '50'), ('supply_method', 'not in', ['automation', 'manual'])]}"/>
|
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>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -33,17 +33,17 @@
|
|||||||
<field name="model_process_parameters_ids" widget="many2many_tags"/>
|
<field name="model_process_parameters_ids" widget="many2many_tags"/>
|
||||||
<field name="model_machining_precision"/>
|
<field name="model_machining_precision"/>
|
||||||
<field name="inventory_quantity_auto_apply"/>
|
<field name="inventory_quantity_auto_apply"/>
|
||||||
<field name="priority"/>
|
<field name="priority" attrs="{'readonly': [('state', '=', '40')]}"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="计划">
|
<page string="计划">
|
||||||
<field name="line_ids">
|
<field name="line_ids" attrs="{'readonly': [('state', '=', '40')]}">
|
||||||
<tree editable="bottom" delete="false">
|
<tree editable="bottom" delete="false">
|
||||||
<field name="status"/>
|
<field name="status"/>
|
||||||
<field name="supply_method" attrs="{'readonly': [('status', '!=', '30')]}"/>
|
<field name="supply_method" attrs="{'readonly': [('status', '!=', '30')]}"/>
|
||||||
<field name="route_ids" widget="many2many_tags" optional="hide"/>
|
<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="bom_id" optional="hide"/>
|
||||||
<field name="plan_uom_qty"/>
|
<field name="plan_uom_qty"/>
|
||||||
<field name="blank_arrival_date"/>
|
<field name="blank_arrival_date"/>
|
||||||
|
|||||||
@@ -20,3 +20,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.mrp_bom_create()
|
||||||
|
self.demand_plan_line_id._action_launch_stock_rule()
|
||||||
|
|||||||
Reference in New Issue
Block a user