import logging import json from odoo import models, fields, api from odoo.exceptions import UserError _logger = logging.getLogger(__name__) class SaleOrder(models.Model): _inherit = 'sale.order' state = fields.Selection([ ('draft', "报价"), ('sent', "报价已发送"), ('supply method', "供货方式待确认"), ('sale', "销售订单"), ('processing', "加工中"), ('physical_distribution', "物流中"), ('delivered', "已交付"), ('done', "已锁定"), ('cancel', "已取消"), ]) def confirm_to_supply_method(self): self.state = 'supply method' def action_confirm(self): # 判断是否所有产品都选择了供货方式 filter_line = self.order_line.filtered(lambda line: not line.supply_method) if filter_line: raise UserError('当前订单内(%s)产品未选择路线,请选择后重试' % ','.join(filter_line.mapped('product_id.name'))) for line in self.order_line: bom_type = '' # 根据供货方式修改成品模板 if line.supply_method == 'automation': bom_type = 'normal' product_template_id = self.env.ref('sf_dlm.product_template_sf').sudo().product_tmpl_id elif line.supply_method == 'outsourcing': bom_type = 'subcontract' product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_outsourcing').sudo() elif line.supply_method == 'purchase': product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_purchase').sudo() elif line.supply_method == 'manual': bom_type = 'normal' product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_manual_processing').sudo() # 复制成品模板上的属性 line.product_id.product_tmpl_id.copy_template(product_template_id) # 将模板上的single_manufacturing属性复制到成品上 line.product_id.single_manufacturing = product_template_id.single_manufacturing order_id = self product = line.product_id # 拼接方法需要的item结构 item = { 'texture_code': product.materials_id.materials_no, 'texture_type_code': product.materials_type_id.materials_no, 'model_long': product.length, 'model_width': product.width, 'model_height': product.height, 'price': product.list_price, 'embryo_redundancy_id': line.embryo_redundancy_id, } # 获取成品名结尾-n的n product_seria = int(product.name.split('-')[-1]) # 成品供货方式为采购则不生成bom if line.supply_method != 'purchase': bom_data = self.env['mrp.bom'].with_user(self.env.ref("base.user_admin")).get_bom(product) _logger.info('bom_data:%s' % bom_data) if bom_data: bom = self.env['mrp.bom'].with_user(self.env.ref("base.user_admin")).bom_create(product, 'normal', False) bom.with_user(self.env.ref("base.user_admin")).bom_create_line_has(bom_data) else: # 当成品上带有客供料选项时,生成坯料时选择“客供料”路线 if line.embryo_redundancy_id: # 将成品模板的内容复制到成品上 customer_provided_embryo = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_embryo_customer_provided').sudo() # 创建坯料,客供料的批量不需要创建bom material_customer_provided_embryo = self.env['product.template'].sudo().no_bom_product_create( customer_provided_embryo.with_context(active_test=False).product_variant_id, item, order_id, 'material_customer_provided', product_seria, product) # 成品配置bom product_bom_material_customer_provided = self.env['mrp.bom'].with_user( self.env.ref("base.user_admin")).bom_create( product, bom_type, 'product') product_bom_material_customer_provided.with_user(self.env.ref("base.user_admin")).bom_create_line_has( material_customer_provided_embryo) elif line.product_id.materials_type_id.gain_way == '自加工': self_machining_id = self.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo() # 创建坯料 self_machining_embryo = self.env['product.template'].sudo().no_bom_product_create( self_machining_id, item, order_id, 'self_machining', product_seria, product) # 创建坯料的bom self_machining_bom = self.env['mrp.bom'].with_user( self.env.ref("base.user_admin")).bom_create( self_machining_embryo, 'normal', False) # 创建坯料里bom的组件 self_machining_bom_line = self_machining_bom.with_user( self.env.ref("base.user_admin")).bom_create_line( self_machining_embryo) if not self_machining_bom_line: raise UserError('该订单模型的材料型号暂未有原材料,请先配置再进行分配') # 产品配置bom product_bom_self_machining = self.env['mrp.bom'].with_user( self.env.ref("base.user_admin")).bom_create( product, bom_type, 'product') product_bom_self_machining.with_user(self.env.ref("base.user_admin")).bom_create_line_has( self_machining_embryo) elif line.product_id.materials_type_id.gain_way == '外协': outsource_id = self.env.ref('sf_dlm.product_embryo_sf_outsource').sudo() # 创建坯料 outsource_embryo = self.env['product.template'].sudo().no_bom_product_create(outsource_id, item, order_id, 'subcontract', product_seria, product) if outsource_embryo == -3: raise UserError('该订单模型的材料型号暂未设置获取方式和供应商,请先配置再进行分配') # 创建坯料的bom outsource_bom = self.env['mrp.bom'].with_user(self.env.ref("base.user_admin")).bom_create( outsource_embryo, 'subcontract', True) # 创建坯料的bom的组件 outsource_bom_line = outsource_bom.with_user( self.env.ref("base.user_admin")).bom_create_line(outsource_embryo) if not outsource_bom_line: raise UserError('该订单模型的材料型号暂未有原材料,请先配置再进行分配') # 产品配置bom product_bom_outsource = self.env['mrp.bom'].with_user( self.env.ref("base.user_admin")).bom_create(product, bom_type, 'product') product_bom_outsource.with_user(self.env.ref("base.user_admin")).bom_create_line_has( outsource_embryo) elif line.product_id.materials_type_id.gain_way == '采购': purchase_id = self.env.ref('sf_dlm.product_embryo_sf_purchase').sudo() purchase_embryo = self.env['product.template'].sudo().no_bom_product_create(purchase_id, item, order_id, 'purchase', product_seria, product) if purchase_embryo == -3: raise UserError('该订单模型的材料型号暂未设置获取方式和供应商,请先配置再进行分配') else: # 产品配置bom product_bom_purchase = self.env['mrp.bom'].with_user( self.env.ref("base.user_admin")).bom_create(product, bom_type, 'product') product_bom_purchase.with_user(self.env.ref("base.user_admin")).bom_create_line_has( purchase_embryo) result = super(SaleOrder, self).action_confirm() self.merge_picking() return result def merge_picking(self): """ 合并多个stock.picking为一个新的stock.picking。 :param picking_ids: 需要合并的stock.picking记录ID列表 :return: 合并后的新的stock.picking对象 """ picking_idss = self.env['stock.picking'].search([('retrospect_ref', 'ilike','%'+ self.name +'%')]) for pick in picking_idss: print('qfwowio',pick) picking_ids = self.env['stock.picking'].search([('retrospect_ref', '=', self.default_code)]) if not picking_ids: return # 获取需要合并的 stock.picking 记录 # 创建一个新的 stock.picking 作为合并结果 group = self.env['procurement.group'].create({ 'name': self.name, 'partner_id': self.partner_id.id, }) new_picking = self.env['stock.picking'].create({ 'partner_id': picking_ids[0].partner_id.id, 'location_id': picking_ids[0].location_id.id, 'location_dest_id': picking_ids[0].location_dest_id.id, 'move_ids': False, 'sale_id': self.id, 'picking_type_id': picking_ids[0].picking_type_id.id, 'origin': '合并自: ' + ','.join([p.origin for p in picking_ids]), 'retrospect_ref':self.default_code, 'person_of_delivery':picking_ids[0].person_of_delivery, 'telephone_of_delivery': picking_ids[0].telephone_of_delivery, 'address_of_delivery': picking_ids[0].address_of_delivery, 'group_id':picking_ids[0].group_id.id }) # 合并所有 move_lines for picking in picking_ids: for move in picking.move_ids: # 复制 move_lines 到新的 picking new_move_vals = move.copy_data()[0] new_move_vals['picking_id']=new_picking.id self.env['stock.move'].create(new_move_vals) for pick in picking_idss: print('qfwowio',pick) # 处理合并后的配送单状态 new_picking.action_confirm() # 确认新的配送单 for pick in picking_idss: print('qfwowio',pick) new_picking.action_assign() # 分配新的配送单 # 删除原有的配送单 picking_ids.write({'state': 'cancel'}) # 将原配送单状态更改为取消 return new_picking class SaleOrderLine(models.Model): _inherit = 'sale.order.line' part_number = fields.Char('零件图号', related='product_id.part_number', readonly=True) # 供货方式 supply_method = fields.Selection([ ('automation', "自动化产线加工"), ('manual', "人工线下加工"), ('purchase', "外购"), ('outsourcing', "委外加工"), ], string='供货方式') def write(self, vals): if 'supply_method' in vals: for line in self: if vals['supply_method'] == 'automation' and line.manual_quotation: raise UserError('当前(%s)产品为人工编程产品,不能选择自动化产线加工' % ','.join(line.mapped('product_id.name'))) return super(SaleOrderLine, self).write(vals)