251 lines
14 KiB
Python
251 lines
14 KiB
Python
import logging
|
||
import json
|
||
import re
|
||
|
||
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'
|
||
for line in self.order_line:
|
||
if line.product_id.auto_machining:
|
||
line.supply_method = 'automation'
|
||
|
||
def action_confirm(self):
|
||
if self._get_forbidden_state_confirm() & set(self.mapped('state')):
|
||
raise UserError(_('订单状态已发生变化,请刷新当前页面'))
|
||
# 判断是否所有产品都选择了供货方式
|
||
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
|
||
# line.product_id.tracking = product_template_id.tracking
|
||
|
||
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,
|
||
'blank_volume': product.model_volume,
|
||
'blank_area': product.model_area,
|
||
'price': product.list_price,
|
||
'embryo_redundancy_id': line.embryo_redundancy_id,
|
||
'model_id': line.model_id
|
||
}
|
||
product_name = ''
|
||
match = re.search(r'(S\d{5}-\d+)', product.name)
|
||
product_seria = 0
|
||
# 如果匹配成功,提取结果
|
||
if match:
|
||
product_name = match.group(0)
|
||
# 获取成品名结尾-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 and 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)
|
||
return super(SaleOrder, self).action_confirm()
|
||
|
||
def action_show_cancel_wizard(self):
|
||
wizard = self.env['sf.sale.order.cancel.wizard'].create({
|
||
'order_id': self.id,
|
||
})
|
||
|
||
# 创建关联单据行
|
||
self.env['sf.sale.order.cancel.line'].create_from_order(wizard.id, self)
|
||
|
||
return {
|
||
'name': '取消销售订单',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'sf.sale.order.cancel.wizard',
|
||
'view_mode': 'form',
|
||
'target': 'new',
|
||
'res_id': wizard.id,
|
||
}
|
||
def create_sale_documents(self, contract_file_name, contract_file):
|
||
# 创建ir.attachment记录
|
||
attachment = self.env['ir.attachment'].sudo().create({
|
||
'name': contract_file_name,
|
||
'type': 'binary',
|
||
'datas': contract_file,
|
||
'res_model': 'sale.order',
|
||
})
|
||
|
||
# 获取默认的文档文件夹
|
||
workspace = self.env.ref('sf_sale.documents_sales_contracts_folder_1').id
|
||
|
||
# 创建 documents.document 记录
|
||
document = self.env['documents.document'].sudo().create({
|
||
'name': contract_file_name,
|
||
'attachment_id': attachment.id,
|
||
'folder_id': workspace,
|
||
'res_model': 'sale.order',
|
||
'res_id': self.id,
|
||
})
|
||
|
||
self.write({
|
||
'contract_document_id': document.id
|
||
})
|
||
|
||
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')))
|
||
if vals['supply_method'] == 'purchase' and line.is_incoming_material:
|
||
raise UserError('当前(%s)产品为客供料,不能选择外购' % ','.join(line.mapped('product_id.name')))
|
||
return super(SaleOrderLine, self).write(vals)
|
||
|
||
cancel_auto_machining = fields.Boolean('是否取消自动化加工', compute='_compute_cancel_auto_machining', store=True)
|
||
cancel_auto_machining_reason = fields.Char('更改供货原因')
|
||
|
||
@api.depends('product_id', 'supply_method')
|
||
def _compute_cancel_auto_machining(self):
|
||
for line in self:
|
||
line.cancel_auto_machining = True if line.product_id.auto_machining \
|
||
and line.supply_method != 'automation' else False
|
||
|
||
|