248 lines
12 KiB
Python
248 lines
12 KiB
Python
from odoo import models, fields, api
|
||
from odoo.exceptions import ValidationError
|
||
import logging
|
||
|
||
|
||
class ResProductTemplate(models.Model):
|
||
_inherit = 'product.template'
|
||
|
||
# 模型的长,宽,高,体积,精度,材料
|
||
model_long = fields.Float('模型长[mm]', digits=(16, 3))
|
||
model_width = fields.Float('模型宽[mm]', digits=(16, 3))
|
||
model_height = fields.Float('模型高[mm]', digits=(16, 3))
|
||
model_volume = fields.Float('模型体积[m³]')
|
||
model_machining_precision = fields.Selection([
|
||
('±0.10mm', '±0.10mm'),
|
||
('±0.05mm', '±0.05mm'),
|
||
('±0.03mm', '±0.03mm'),
|
||
('±0.02mm', '±0.02mm'),
|
||
('±0.01mm', '±0.01mm')], string='加工精度')
|
||
model_type_id = fields.Many2one('sf.model.type', string='模型类型')
|
||
model_processing_panel = fields.Char('模型加工面板')
|
||
model_surface_process_id = fields.Many2one('sf.production.process', string='表面工艺')
|
||
model_process_parameters_id = fields.Many2one('sf.processing.technology', string='工艺参数')
|
||
# model_price = fields.Float('模型单价', digits=(16, 3))
|
||
model_remark = fields.Char('模型备注说明')
|
||
length = fields.Float('长[mm]', digits=(16, 3))
|
||
width = fields.Float('宽[mm]', digits=(16, 3))
|
||
height = fields.Float('高[mm]', digits=(16, 3))
|
||
materials_id = fields.Many2one('sf.production.materials', string='材料')
|
||
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号')
|
||
single_manufacturing = fields.Boolean(string="单个制造")
|
||
|
||
# 胚料的库存路线设置
|
||
# def _get_routes(self, route_type):
|
||
# route_manufacture = self.env.ref('mrp.route_warehouse0_manufacture', raise_if_not_found=False).sudo()
|
||
# route_mto = self.env.ref('stock.route_warehouse0_mto', raise_if_not_found=False).sudo()
|
||
# route_purchase = self.env.ref('purchase_stock.route_warehouse0_buy', raise_if_not_found=False).sudo()
|
||
# if route_manufacture and route_mto:
|
||
# # 外协
|
||
# if route_type == 'subcontract':
|
||
# route_subcontract = self.env.ref('mrp_subcontracting.route_resupply_subcontractor_mto',
|
||
# raise_if_not_found=False).sudo()
|
||
# return [route_mto.id, route_purchase.id, route_subcontract.id]
|
||
# elif route_type == 'purchase':
|
||
# # 采购
|
||
# return [route_mto.id, route_purchase.id]
|
||
# else:
|
||
# return [route_mto.id, route_manufacture.id]
|
||
# return []
|
||
|
||
# route_ids = fields.Many2many(default=lambda self: self._get_route())
|
||
|
||
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品
|
||
def product_create(self, product_id, item, order_id, order_number, i):
|
||
copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
|
||
# copy_product_id.product_tmpl_id.active = True
|
||
vals = {
|
||
'name': '%s-%s' % (order_id.name, i),
|
||
'model_long': item['model_long'],
|
||
'model_width': item['model_width'],
|
||
'model_height': item['model_height'],
|
||
'model_type_id': 1,
|
||
'model_machining_precision': item['model_machining_precision'],
|
||
'model_processing_panel': 'R,U',
|
||
'length': item['model_long'],
|
||
'width': item['model_width'],
|
||
'height': item['model_height'],
|
||
'volume': (item['model_long'] * item['model_width'] * item['model_height']),
|
||
# 'model_price': item['price'],
|
||
# 'single_manufacturing': True,
|
||
'list_price': item['price'],
|
||
# 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id,
|
||
'materials_id': self.env['sf.production.materials'].search(
|
||
[('materials_no', '=', item['texture_code'])]).id,
|
||
'materials_type_id': self.env['sf.materials.model'].search(
|
||
[('materials_no', '=', item['texture_type_code'])]).id,
|
||
# 'model_surface_process_id': self.env['sf.production.process'].search(
|
||
# [('process_encode', '=', item['surface_process_code'])]).id,
|
||
# 'model_process_parameters_id': self.env['sf.processing.technology'].search(
|
||
# [('process_encode', '=', item['process_parameters_code'])]).id,
|
||
'model_remark': item['remark'],
|
||
'default_code': '%s-%s' % (order_number, i),
|
||
'barcode': item['barcode'],
|
||
'active': True,
|
||
# 'route_ids': self._get_routes('')
|
||
}
|
||
copy_product_id.sudo().write(vals)
|
||
# product_id.active = False
|
||
return copy_product_id
|
||
|
||
# 创建胚料
|
||
def no_bom_product_create(self, product_id, item, order_id, route_type):
|
||
no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
|
||
# no_bom_copy_product_id.product_tmpl_id.active = True
|
||
materials_id = self.env['sf.production.materials'].search(
|
||
[('materials_no', '=', item['texture_code'])])
|
||
materials_type_id = self.env['sf.materials.model'].search(
|
||
[('materials_no', '=', item['texture_type_code'])])
|
||
supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
|
||
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
|
||
vals = {
|
||
'name': '%s %s %s %s * %s * %s' % (
|
||
order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'],
|
||
item['model_height']),
|
||
'length': item['model_long'],
|
||
'width': item['model_width'],
|
||
'height': item['model_height'],
|
||
'volume': item['model_long'] * item['model_width'] * item['model_height'],
|
||
# 'model_price': item['price'],
|
||
'list_price': item['price'],
|
||
'materials_id': materials_id.id,
|
||
'materials_type_id': materials_type_id.id,
|
||
# 'route_ids': self._get_routes(route_type),
|
||
# 'categ_id': self.env.ref('sf_dlm.product_category_embryo_sf').id,
|
||
# 'model_surface_process_id': self.env['sf.production.process'].search(
|
||
# [('process_encode', '=', item['surface_process_code'])]).id,
|
||
# 'model_process_parameters_id': self.env['sf.processing.technology'].search(
|
||
# [('process_encode', '=', item['process_parameters_code'])]).id,
|
||
'active': True
|
||
}
|
||
# 外协和采购生成的胚料需要根据材料型号绑定供应商
|
||
if route_type == 'subcontract':
|
||
no_bom_copy_product_id.purchase_ok = True
|
||
no_bom_copy_product_id.seller_ids = [
|
||
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0, 'is_subcontractor': True})]
|
||
logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
|
||
elif route_type == 'purchase':
|
||
no_bom_copy_product_id.purchase_ok = True
|
||
no_bom_copy_product_id.seller_ids = [
|
||
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
|
||
logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
|
||
no_bom_copy_product_id.write(vals)
|
||
logging.info('no_bom_copy_product_id-vals:%s' % vals)
|
||
# product_id.active = False
|
||
return no_bom_copy_product_id
|
||
|
||
# 根据模型类型默认给模型的长高宽加配置的长度;
|
||
@api.onchange('model_type_id')
|
||
def add_product_size(self):
|
||
if not self.model_type_id:
|
||
return
|
||
model_type = self.env['sf.model.type'].search(
|
||
[('id', '=', self.model_type_id.id), ('embryo_tolerance', '=', True)])
|
||
if model_type:
|
||
self.model_long = self.model_long + 1
|
||
self.model_width = self.model_width + 1
|
||
self.model_height = self.model_width + 1
|
||
else:
|
||
return
|
||
|
||
|
||
class ResMrpBom(models.Model):
|
||
_inherit = 'mrp.bom'
|
||
|
||
subcontractor_id = fields.Many2one('res.partner', string='外包商')
|
||
|
||
def bom_create_line_has(self, embryo):
|
||
vals = {
|
||
'bom_id': self.id,
|
||
'product_id': embryo.id,
|
||
'product_tmpl_id': embryo.product_tmpl_id.id,
|
||
'product_qty': 1,
|
||
'product_uom_id': 1
|
||
}
|
||
logging.info('bom_create_line_has-vals:%s' % vals)
|
||
return self.env['mrp.bom.line'].create(vals)
|
||
|
||
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom
|
||
def bom_create(self, product, bom_type, product_type):
|
||
bom_id = self.env['mrp.bom'].create({
|
||
'product_tmpl_id': product.product_tmpl_id.id,
|
||
'type': bom_type,
|
||
# 'subcontractor_id': '' or subcontract.partner_id.id,
|
||
'product_qty': 1,
|
||
'product_uom_id': 1
|
||
})
|
||
if bom_type == 'subcontract' and product_type != False:
|
||
subcontract = self.get_supplier(product.materials_type_id)
|
||
bom_id.subcontractor_id = subcontract.partner_id.id
|
||
logging.info('bom_create-vals:%s' % bom_id)
|
||
return bom_id
|
||
|
||
# 胚料BOM组件:选取当前胚料原材料,
|
||
# 然后根据当前的胚料的体积得出需要的原材料重量(立方米m³) *材料密度 * 1000 = 所需原材料重量KG(公斤)
|
||
# 胚料所需原材料公式:当前的胚料的体积(立方米m³) *材料密度 * 1000 = 所需原材料重量KG(公斤)
|
||
def bom_create_line(self, embryo):
|
||
# 选取当前胚料原材料
|
||
bom_line = self.get_raw_bom(embryo)
|
||
vals = {
|
||
'bom_id': self.id,
|
||
'product_id': bom_line.id,
|
||
'product_tmpl_id': bom_line.product_tmpl_id.id,
|
||
'product_qty': bom_line.volume * bom_line.materials_type_id.density * 1000,
|
||
'product_uom_id': bom_line.uom_id.id
|
||
}
|
||
logging.info('bom_create_line-vals1:%s' % vals)
|
||
return self.env['mrp.bom.line'].create(vals)
|
||
|
||
# 查询材料型号默认排第一的供应商
|
||
def get_supplier(self, materials_type):
|
||
seller_id = self.env['sf.supplier.sort'].search(
|
||
[('materials_model_id', '=', materials_type.id)],
|
||
limit=1,
|
||
order='sequence asc')
|
||
logging.info('get_supplier-vals:%s' % seller_id)
|
||
return seller_id
|
||
|
||
# 匹配bom
|
||
def get_bom(self, product):
|
||
logging.info('get_bom-product:%s' % product)
|
||
logging.info('get_bom-product:%s' % product.materials_type_id.id)
|
||
embryo_has = self.env['product.product'].search(
|
||
[('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id),
|
||
('length', '>', product.length), ('width', '>', product.width),
|
||
('height', '>', product.height)
|
||
],
|
||
limit=1,
|
||
order='volume desc'
|
||
)
|
||
logging.info('get_bom-vals:%s' % embryo_has)
|
||
if embryo_has:
|
||
rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100
|
||
if rate_of_waste >= 20:
|
||
return embryo_has
|
||
else:
|
||
return
|
||
|
||
# 查bom的原材料
|
||
def get_raw_bom(self, product):
|
||
raw_bom = self.env['product.product'].search(
|
||
[('categ_id.type', '=', '原材料'), ('materials_type_id', '=', product.materials_type_id.id)])
|
||
return raw_bom
|
||
|
||
|
||
class ResProductCategory(models.Model):
|
||
_inherit = "product.category"
|
||
|
||
type = fields.Selection(
|
||
[("成品", "成品"), ("胚料", "胚料"), ("原材料", "原材料")],
|
||
default="", string="类型")
|
||
|
||
# @api.constrains('type')
|
||
# def _check_type(self):
|
||
# category = self.env['product.category'].search(
|
||
# [('type', '=', self.type)])
|
||
# if category:
|
||
# raise ValidationError("该类别已存在,请选择其他类别")
|