需求计划

This commit is contained in:
guanhuan
2025-05-22 11:37:41 +08:00
parent 1856a1a4ef
commit 50f8bf5ab1
8 changed files with 311 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import sf_production_demand_plan
from . import sale_order

View File

@@ -0,0 +1,14 @@
from odoo import models, fields, api, _
class ReSaleOrder(models.Model):
_inherit = 'sale.order'
def sale_order_create_line(self, product, item):
ret = super(ReSaleOrder, self).sale_order_create_line(product, item)
vals = {
'sale_order_id': ret.order_id.id,
'sale_order_line_id': ret.id,
}
self.env['sf.production.demand.plan'].sudo().create(vals)
return ret

View File

@@ -0,0 +1,158 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
class sf_production_plan(models.Model):
_name = 'sf.production.demand.plan'
_description = 'sf_production_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
priority = fields.Selection([
('1', '紧急'),
('2', ''),
('3', ''),
('4', ''),
], string='优先级', default='3')
status = fields.Selection([
('20', '待确认'),
('30', '需求确认'),
('50', '已下达'),
('100', '取消'),
], string='状态')
sale_order_id = fields.Many2one(comodel_name="sale.order",
string="销售订单")
sale_order_line_id = fields.Many2one(comodel_name="sale.order.line",
string="销售订单行")
company_id = fields.Many2one(
related='sale_order_id.company_id',
store=True, index=True, precompute=True)
partner_id = fields.Many2one(
comodel_name='res.partner',
related='sale_order_line_id.order_partner_id',
string="客户",
store=True, index=True)
order_remark = fields.Text(related='sale_order_id.remark',
string="订单备注", store=True)
glb_url = fields.Char(related='sale_order_line_id.glb_url', string='glb文件地址')
product_id = fields.Many2one(
comodel_name='product.product',
related='sale_order_line_id.product_id',
string='产品', store=True, index=True)
model_id = fields.Char('模型ID', related='product_id.model_id')
part_name = fields.Char('零件名称', related='product_id.part_name')
part_number = fields.Char('零件图号', compute='_compute_part_number', store=True)
is_incoming_material = fields.Boolean('客供料', related='sale_order_line_id.is_incoming_material', store=True)
supply_method = fields.Selection([
('automation', "自动化产线加工"),
('manual', "人工线下加工"),
('purchase', "外购"),
('outsourcing', "委外加工"),
], string='供货方式', related='sale_order_line_id.supply_method', store=True)
product_uom_qty = fields.Float(
string="需求数量",
related='sale_order_line_id.product_uom_qty', store=True)
deadline_of_delivery = fields.Date('客户交期', related='sale_order_id.deadline_of_delivery', store=True)
inventory_quantity_auto_apply = fields.Float(
string="成品库存",
compute='_compute_inventory_quantity_auto_apply'
)
qty_delivered = fields.Float(
"交货数量", related='sale_order_line_id.qty_delivered')
qty_to_deliver = fields.Float(
"待交货数量", related='sale_order_line_id.qty_to_deliver')
model_long = fields.Char('尺寸', compute='_compute_model_long')
materials_id = fields.Char('材料', compute='_compute_materials_id', store=True)
model_machining_precision = fields.Selection(selection=_get_machining_precision, string='精度',
related='product_id.model_machining_precision')
model_process_parameters_ids = fields.Many2many('sf.production.process.parameter',
'plan_process_parameter_rel',
string='表面工艺',
compute='_compute_model_process_parameters_ids'
)
product_remark = fields.Char("产品备注", related='product_id.model_remark')
order_code = fields.Char('E-SHOP订单号', related='sale_order_id.order_code')
order_state = fields.Selection(
string='订单状态',
related='sale_order_line_id.state')
route_id = fields.Many2one('stock.route', string='路线', related='sale_order_line_id.route_id', store=True)
date_order = fields.Datetime('下单日期', related='sale_order_id.date_order')
plan_remark = fields.Text("计划备注")
processing_time = fields.Char('程序工时')
planned_start_date = fields.Date('计划开工日期')
actual_start_date = fields.Date('实际开工日期')
actual_end_date = fields.Date('实际完工日期')
print_count = fields.Char('打印次数', default='T0C0')
sequence = fields.Integer('序号')
@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')
def _compute_model_long(self):
for line in self:
if line.product_id:
line.model_long = f"{line.product_id.length}*{line.product_id.width}*{line.product_id.height}"
else:
line.model_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.constrains('planned_start_date')
def _check_planned_start_date(self):
for record in self:
if record.planned_start_date and record.planned_start_date < fields.Date.today():
raise ValidationError("计划开工日期必须大于或等于今天。")