根据工序模板生成工单,及相关页面新增加工面板及重复字段
This commit is contained in:
@@ -12,7 +12,6 @@ class ModelType(models.Model):
|
|||||||
class ResMrpRoutingWorkcenter(models.Model):
|
class ResMrpRoutingWorkcenter(models.Model):
|
||||||
_inherit = 'mrp.routing.workcenter'
|
_inherit = 'mrp.routing.workcenter'
|
||||||
|
|
||||||
code = fields.Char('唯一编码')
|
|
||||||
is_repeat = fields.Boolean('重复', default=False)
|
is_repeat = fields.Boolean('重复', default=False)
|
||||||
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
|
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
|
||||||
workcenter_ids = fields.Many2many('mrp.workcenter', 'rel_workcenter_route', required=True)
|
workcenter_ids = fields.Many2many('mrp.workcenter', 'rel_workcenter_route', required=True)
|
||||||
@@ -20,10 +19,9 @@ class ResMrpRoutingWorkcenter(models.Model):
|
|||||||
|
|
||||||
# 获得当前登陆者公司
|
# 获得当前登陆者公司
|
||||||
def get_company_id(self):
|
def get_company_id(self):
|
||||||
company = self.env.ref('base.main_company')
|
self.company_id = self.env.user.company_id.id
|
||||||
return company.id
|
|
||||||
|
|
||||||
company_id = fields.Many2one('res.company', default=lambda self: self.env.company)
|
company_id = fields.Many2one('res.company', compute="get_company_id", related=False)
|
||||||
|
|
||||||
|
|
||||||
class ModelTypeRoutingSort(models.Model):
|
class ModelTypeRoutingSort(models.Model):
|
||||||
|
|||||||
@@ -16,12 +16,17 @@ class ResProductTemplate(models.Model):
|
|||||||
model_type_id = fields.Many2one('sf.model.type', string='模型类型')
|
model_type_id = fields.Many2one('sf.model.type', string='模型类型')
|
||||||
processing_panel = fields.Char('模型加工面板')
|
processing_panel = fields.Char('模型加工面板')
|
||||||
# 胚料的长,宽,高
|
# 胚料的长,宽,高
|
||||||
embryo_long = fields.Float('胚料长[mm]', digits=(16, 3))
|
embryo_long = fields.Float('胚料长[mm]', digits=(16, 3), onchange='count_embryo_size')
|
||||||
embryo_width = fields.Float('胚料宽[mm]', digits=(16, 3))
|
embryo_width = fields.Float('胚料宽[mm]', digits=(16, 3), onchange='count_embryo_size')
|
||||||
embryo_height = fields.Float('胚料高[mm]', digits=(16, 3))
|
embryo_height = fields.Float('胚料高[mm]', digits=(16, 3), onchange='count_embryo_size')
|
||||||
embryo_materials_id = fields.Many2one('mrs.production.materials', string='胚料材料')
|
embryo_materials_id = fields.Many2one('mrs.production.materials', string='胚料材料')
|
||||||
embryo_materials_type_id = fields.Many2one('mrs.materials.model', string='胚料材料型号')
|
embryo_materials_type_id = fields.Many2one('mrs.materials.model', string='胚料材料型号')
|
||||||
|
|
||||||
|
volume = fields.Float(compute='_compute_volume', store=True)
|
||||||
|
|
||||||
|
@api.depends('embryo_long', 'embryo_width', 'embryo_height')
|
||||||
|
def _compute_volume(self):
|
||||||
|
self.volume = self.embryo_long * self.embryo_width * self.embryo_height
|
||||||
|
|
||||||
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品
|
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品
|
||||||
def product_create(self, product_id, item, order_id, order_number, i):
|
def product_create(self, product_id, item, order_id, order_number, i):
|
||||||
@@ -49,16 +54,18 @@ class ResProductTemplate(models.Model):
|
|||||||
# 并根据模型类型计算出产品的胚料尺寸;
|
# 并根据模型类型计算出产品的胚料尺寸;
|
||||||
@api.onchange('model_type_id')
|
@api.onchange('model_type_id')
|
||||||
def count_embryo_size(self):
|
def count_embryo_size(self):
|
||||||
|
if not self.model_type_id:
|
||||||
|
return
|
||||||
bom = self.env['product.product'].search(
|
bom = self.env['product.product'].search(
|
||||||
[('categ_id.is_embryo', '=', True), ('product_tmpl_id', '=', self.id)],
|
[('categ_id.is_embryo', '=', True), ('product_tmpl_id', '=', self.id)],
|
||||||
limit=1,
|
limit=1,
|
||||||
order='volume desc'
|
order='volume desc'
|
||||||
)
|
)
|
||||||
for item in self:
|
for item in self:
|
||||||
item.model_long = bom.embryo_long + 1
|
item.embryo_long = bom.embryo_long + 1
|
||||||
item.embryo_width = bom.embryo_width + 1
|
item.embryo_width = bom.embryo_width + 1
|
||||||
item.embryo_height = bom.embryo_height + 1
|
item.embryo_height = bom.embryo_height + 1
|
||||||
item.volume = item.model_long * item.embryo_width * item.embryo_height
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<data>
|
<data>
|
||||||
|
#-----------------作业-------------------
|
||||||
<record model="ir.ui.view" id="view_mrp_routing_workcenter_form_inherit_sf">
|
<record model="ir.ui.view" id="view_mrp_routing_workcenter_form_inherit_sf">
|
||||||
<field name="name">mrp.routing.workcenter.form.inherit.sf</field>
|
<field name="name">mrp.routing.workcenter.form.inherit.sf</field>
|
||||||
<field name="model">mrp.routing.workcenter</field>
|
<field name="model">mrp.routing.workcenter</field>
|
||||||
@@ -9,7 +10,34 @@
|
|||||||
<field name="workcenter_id" position="replace">
|
<field name="workcenter_id" position="replace">
|
||||||
<field name="workcenter_ids" widget="many2many_tags" string="工作中心" required="0"/>
|
<field name="workcenter_ids" widget="many2many_tags" string="工作中心" required="0"/>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="bom_product_template_attribute_value_ids" position="after">
|
||||||
|
<field name="is_repeat"/>
|
||||||
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
#-----------------工单-------------------
|
||||||
|
<record model="ir.ui.view" id="view_mrp_workorder_form_inherit_sf">
|
||||||
|
<field name="name">mrp.workorder.form.inherit.sf</field>
|
||||||
|
<field name="model">mrp.workorder</field>
|
||||||
|
<field name="inherit_id" ref="mrp.mrp_production_workorder_tree_view"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="name" position="after">
|
||||||
|
<field name="processing_panel"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
#-----------------制造订单-------------------
|
||||||
|
<!-- <record model="ir.ui.view" id="view_mrp_production_form_inherit_sf">-->
|
||||||
|
<!-- <field name="name">mrp.production.form.inherit.sf</field>-->
|
||||||
|
<!-- <field name="model">mrp.production</field>-->
|
||||||
|
<!-- <field name="inherit_id" ref="mrp.mrp_production_form_view"/>-->
|
||||||
|
<!-- <field name="arch" type="xml">-->
|
||||||
|
<!-- <field name="workorder_ids" position="after">-->
|
||||||
|
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </record>-->
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -1,65 +1,9 @@
|
|||||||
from collections import defaultdict
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
|
|
||||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
from odoo.osv import expression
|
|
||||||
from odoo.addons.stock.models.stock_rule import ProcurementException
|
|
||||||
from odoo.tools import float_compare, OrderedSet
|
|
||||||
|
|
||||||
|
|
||||||
class ReStockRule(models.Model):
|
class ResWorkcenterProductivity(models.Model):
|
||||||
_inherit = 'stock.rule'
|
_inherit = 'mrp.workcenter.productivity'
|
||||||
|
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
|
||||||
def _run_manufacture(self, procurements):
|
|
||||||
productions_values_by_company = defaultdict(list)
|
|
||||||
errors = []
|
|
||||||
for procurement, rule in procurements:
|
|
||||||
if float_compare(procurement.product_qty, 0, precision_rounding=procurement.product_uom.rounding) <= 0:
|
|
||||||
# If procurement contains negative quantity, don't create a MO that would be for a negative value.
|
|
||||||
continue
|
|
||||||
bom = rule._get_matching_bom(procurement.product_id, procurement.company_id, procurement.values)
|
|
||||||
|
|
||||||
productions_values_by_company[procurement.company_id.id].append(rule._prepare_mo_vals(*procurement, bom))
|
|
||||||
|
|
||||||
if errors:
|
|
||||||
raise ProcurementException(errors)
|
|
||||||
|
|
||||||
for company_id, productions_values in productions_values_by_company.items():
|
|
||||||
# create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
|
|
||||||
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
|
|
||||||
productions_values)
|
|
||||||
self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
|
|
||||||
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
|
|
||||||
print(productions.product_id.processing_panel)
|
|
||||||
# 查出产品的加工面板并对根据面板的数量循环生成工序
|
|
||||||
for k in (productions.product_id.processing_panel.split(',')):
|
|
||||||
print(productions.product_id.model_type_id.routing_tmpl_ids)
|
|
||||||
for j in productions.product_id.model_type_id.routing_tmpl_ids:
|
|
||||||
productions._create_workorder()
|
|
||||||
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
|
|
||||||
(
|
|
||||||
p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm()
|
|
||||||
|
|
||||||
for production in productions:
|
|
||||||
origin_production = production.move_dest_ids and production.move_dest_ids[
|
|
||||||
0].raw_material_production_id or False
|
|
||||||
orderpoint = production.orderpoint_id
|
|
||||||
if orderpoint and orderpoint.create_uid.id == SUPERUSER_ID and orderpoint.trigger == 'manual':
|
|
||||||
production.message_post(
|
|
||||||
body=_('This production order has been created from Replenishment Report.'),
|
|
||||||
message_type='comment',
|
|
||||||
subtype_xmlid='mail.mt_note')
|
|
||||||
elif orderpoint:
|
|
||||||
production.message_post_with_view(
|
|
||||||
'mail.message_origin_link',
|
|
||||||
values={'self': production, 'origin': orderpoint},
|
|
||||||
subtype_id=self.env.ref('mail.mt_note').id)
|
|
||||||
elif origin_production:
|
|
||||||
production.message_post_with_view(
|
|
||||||
'mail.message_origin_link',
|
|
||||||
values={'self': production, 'origin': origin_production},
|
|
||||||
subtype_id=self.env.ref('mail.mt_note').id)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class ResMrpWorkOrder(models.Model):
|
class ResMrpWorkOrder(models.Model):
|
||||||
@@ -67,50 +11,3 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
|
|
||||||
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
|
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
|
||||||
processing_panel = fields.Char('加工面')
|
processing_panel = fields.Char('加工面')
|
||||||
|
|
||||||
def _action_confirm(self):
|
|
||||||
workorders_by_production = defaultdict(lambda: self.env['mrp.workorder'])
|
|
||||||
for workorder in self:
|
|
||||||
workorders_by_production[workorder.production_id] |= workorder
|
|
||||||
|
|
||||||
for production, workorders in workorders_by_production.items():
|
|
||||||
workorders_by_bom = defaultdict(lambda: self.env['mrp.workorder'])
|
|
||||||
bom = self.env['mrp.bom']
|
|
||||||
moves = production.move_raw_ids | production.move_finished_ids
|
|
||||||
|
|
||||||
for workorder in workorders:
|
|
||||||
bom = workorder.operation_id.bom_id or workorder.production_id.bom_id
|
|
||||||
previous_workorder = workorders_by_bom[bom][-1:]
|
|
||||||
previous_workorder.next_work_order_id = workorder.id
|
|
||||||
workorders_by_bom[bom] |= workorder
|
|
||||||
|
|
||||||
moves.filtered(lambda m: m.operation_id == workorder.operation_id).write({
|
|
||||||
'workorder_id': workorder.id
|
|
||||||
})
|
|
||||||
|
|
||||||
exploded_boms, dummy = production.bom_id.explode(production.product_id, 1,
|
|
||||||
picking_type=production.bom_id.picking_type_id)
|
|
||||||
exploded_boms = {b[0]: b[1] for b in exploded_boms}
|
|
||||||
for move in moves:
|
|
||||||
if move.workorder_id:
|
|
||||||
continue
|
|
||||||
bom = move.bom_line_id.bom_id
|
|
||||||
while bom and bom not in workorders_by_bom:
|
|
||||||
bom_data = exploded_boms.get(bom, {})
|
|
||||||
bom = bom_data.get('parent_line') and bom_data['parent_line'].bom_id or False
|
|
||||||
if bom in workorders_by_bom:
|
|
||||||
move.write({
|
|
||||||
'workorder_id': workorders_by_bom[bom][-1:].id
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
move.write({
|
|
||||||
'workorder_id': workorders_by_bom[production.bom_id][-1:].id
|
|
||||||
})
|
|
||||||
|
|
||||||
for workorders in workorders_by_bom.values():
|
|
||||||
if not workorders:
|
|
||||||
continue
|
|
||||||
if workorders[0].state == 'pending':
|
|
||||||
workorders[0].state = 'ready' if workorders[0].production_availability == 'assigned' else 'waiting'
|
|
||||||
for workorder in workorders:
|
|
||||||
workorder._start_nextworkorder()
|
|
||||||
|
|||||||
@@ -68,9 +68,24 @@ class MrpProduction(models.Model):
|
|||||||
'operation_id': operation.id,
|
'operation_id': operation.id,
|
||||||
'state': 'pending',
|
'state': 'pending',
|
||||||
}]
|
}]
|
||||||
print('1111111')
|
# 根据加工面板的面数及对应的工序模板生成工序
|
||||||
production.workorder_ids = [(5, 0)] + [(0, 0, value) for value in workorders_values]
|
for k in (production.product_id.processing_panel.split(',')):
|
||||||
print('22222')
|
for route in production.product_id.model_type_id.routing_tmpl_ids:
|
||||||
|
if route.route_workcenter_id:
|
||||||
|
workorders_values_str = [0, '', {
|
||||||
|
'product_uom_id': production.product_uom_id.id,
|
||||||
|
'qty_producing': 0,
|
||||||
|
'operation_id': False,
|
||||||
|
'name': route.route_workcenter_id.name,
|
||||||
|
'processing_panel': k,
|
||||||
|
'workcenter_id': False,
|
||||||
|
'date_planned_start': False,
|
||||||
|
'date_planned_finished': False,
|
||||||
|
'duration_expected': 60,
|
||||||
|
'duration': 0
|
||||||
|
}]
|
||||||
|
workorders_values.append(workorders_values_str)
|
||||||
|
production.workorder_ids = workorders_values
|
||||||
for workorder in production.workorder_ids:
|
for workorder in production.workorder_ids:
|
||||||
workorder.duration_expected = workorder._get_duration_expected()
|
workorder.duration_expected = workorder._get_duration_expected()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user