将数据初始化由产品辩题改为为模板

This commit is contained in:
胡尧
2024-11-14 15:02:11 +08:00
parent 63b9f495e9
commit daba7d5155
13 changed files with 379 additions and 379 deletions

View File

@@ -7,13 +7,16 @@ from odoo import api, SUPERUSER_ID
def _data_install(cr, registry): def _data_install(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {}) env = api.Environment(cr, SUPERUSER_ID, {})
# 获取所有需要设置的产品模板 # 获取所有需要设置的产品模板
env.ref('jikimo_sale_multiple_supply_methods.product_product_purchase').product_tmpl_id.write({'active': False}) env.ref('jikimo_sale_multiple_supply_methods.product_template_purchase').product_variant_id.write({'active': False})
env.ref('jikimo_sale_multiple_supply_methods.product_product_manual_processing').product_tmpl_id.write({'active': False, 'single_manufacturing': True}) env.ref('jikimo_sale_multiple_supply_methods.product_template_manual_processing').product_variant_id.write({'active': False, 'single_manufacturing': True})
env.ref('jikimo_sale_multiple_supply_methods.product_product_default').product_tmpl_id.write({'active': False}) env.ref('jikimo_sale_multiple_supply_methods.product_template_default').product_variant_id.write({'active': False})
env.ref('jikimo_sale_multiple_supply_methods.product_product_raw_material_customer_provided').product_tmpl_id.write({'active': False}) env.ref('jikimo_sale_multiple_supply_methods.product_template_raw_material_customer_provided').product_variant_id.write({'active': False})
env.ref('jikimo_sale_multiple_supply_methods.product_product_outsourcing').product_tmpl_id.write({'active': False}) env.ref('jikimo_sale_multiple_supply_methods.product_template_outsourcing').product_variant_id.write({'active': False})
# 更新产品模板相关字段 env.ref('sf_dlm.product_embryo_sf_self_machining').product_tmpl_id.write({'categ_type': '坯料'})
env['product.template'].update_related_fields() env.ref('sf_dlm.product_template_sf').product_tmpl_id.write({'categ_type': '成品'})
env.ref('sf_dlm.product_embryo_sf_outsource').product_tmpl_id.write({'categ_type': '坯料'})
env.ref('sf_dlm.product_embryo_sf_purchase').product_tmpl_id.write({'categ_type': '坯料'})
# 为三步制造增加规则 # 为三步制造增加规则
warehouse = env['stock.warehouse'].search([('company_id', '=', env.company.id)], limit=1) warehouse = env['stock.warehouse'].search([('company_id', '=', env.company.id)], limit=1)
product_route_id = warehouse.pbm_route_id product_route_id = warehouse.pbm_route_id

View File

@@ -19,7 +19,8 @@ class JikimoSaleRoutePicking(Sf_Bf_Connect):
res = {'status': 1, 'factory_order_no': ''} res = {'status': 1, 'factory_order_no': ''}
# _logger.info('get_bfm_process_order_list:%s' % kw['order_number']) # _logger.info('get_bfm_process_order_list:%s' % kw['order_number'])
try: try:
product_id = request.env.ref('jikimo_sale_multiple_supply_methods.product_product_default').sudo() product_id = request.env.ref('jikimo_sale_multiple_supply_methods.product_template_default').with_context(active_test=False).sudo().product_variant_id
_logger.info('product_id:%s' % product_id)
company_id = request.env.ref('base.main_company').sudo() company_id = request.env.ref('base.main_company').sudo()
bfm_process_order_list = json.loads(kw['bfm_process_order_list']) bfm_process_order_list = json.loads(kw['bfm_process_order_list'])
order_id = request.env['sale.order'].with_user(request.env.ref("base.user_admin")).sale_order_create( order_id = request.env['sale.order'].with_user(request.env.ref("base.user_admin")).sale_order_create(

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<data noupdate="0"> <data noupdate="0">
<record id="product_product_manual_processing" model="product.product"> <record id="product_template_manual_processing" model="product.template">
<field name="name">人工线下加工模板</field> <field name="name">人工线下加工模板</field>
<field name="active" eval="False"/> <field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/> <field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
@@ -16,10 +16,11 @@
<field name="single_manufacturing">true</field> <field name="single_manufacturing">true</field>
<field name="tracking">serial</field> <field name="tracking">serial</field>
<field name="is_bfm">true</field> <field name="is_bfm">true</field>
<field name="categ_type">成品</field>
<field name="is_manual_processing">true</field> <field name="is_manual_processing">true</field>
</record> </record>
<record id="product_product_purchase" model="product.product"> <record id="product_template_purchase" model="product.template">
<field name="name">成品外购模板</field> <field name="name">成品外购模板</field>
<field name="active" eval="False"/> <field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/> <field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
@@ -30,10 +31,11 @@
<field name="uom_id" ref="uom.product_uom_unit"/> <field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/> <field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/> <field name="company_id" ref="base.main_company"/>
<field name="categ_type">成品</field>
<field name="is_bfm">true</field> <field name="is_bfm">true</field>
</record> </record>
<record id="product_product_outsourcing" model="product.product"> <record id="product_template_outsourcing" model="product.template">
<field name="name">成品委外加工模板</field> <field name="name">成品委外加工模板</field>
<field name="active" eval="False"/> <field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/> <field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
@@ -44,10 +46,11 @@
<field name="uom_id" ref="uom.product_uom_unit"/> <field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/> <field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/> <field name="company_id" ref="base.main_company"/>
<field name="categ_type">成品</field>
<field name="is_bfm">true</field> <field name="is_bfm">true</field>
</record> </record>
<record id="product_product_default" model="product.product"> <record id="product_template_default" model="product.template">
<field name="name">成品初始化模板</field> <field name="name">成品初始化模板</field>
<field name="active" eval="False"/> <field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/> <field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
@@ -57,6 +60,7 @@
<field name="uom_id" ref="uom.product_uom_unit"/> <field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/> <field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/> <field name="company_id" ref="base.main_company"/>
<field name="categ_type">成品</field>
<field name="is_bfm">true</field> <field name="is_bfm">true</field>
</record> </record>
@@ -65,7 +69,7 @@
<field name="partner_id" eval="91"/> <field name="partner_id" eval="91"/>
</record> </record>
<record id="product_product_raw_material_customer_provided" model="product.product"> <record id="product_template_raw_material_customer_provided" model="product.template">
<field name="name">坯料客供料模板</field> <field name="name">坯料客供料模板</field>
<field name="active" eval="False"/> <field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_embryo_sf"/> <field name="categ_id" ref="sf_dlm.product_category_embryo_sf"/>
@@ -79,6 +83,7 @@
<field name="uom_id" ref="uom.product_uom_unit"/> <field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/> <field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/> <field name="company_id" ref="base.main_company"/>
<field name="categ_type">坯料</field>
<field name="seller_ids" eval="[ref('jikimo_sale_multiple_supply_methods.product_supplierinfo_bfm')]"/> <field name="seller_ids" eval="[ref('jikimo_sale_multiple_supply_methods.product_supplierinfo_bfm')]"/>
</record> </record>

View File

@@ -30,11 +30,3 @@ class ProductTemplate(models.Model):
self.is_manual_processing = product_template_id.is_manual_processing self.is_manual_processing = product_template_id.is_manual_processing
# 复制 seller_ids # 复制 seller_ids
self.seller_ids = [(0, 0, {'partner_id': seller.partner_id.id, 'delay': 1.0}) for seller in product_template_id.seller_ids] self.seller_ids = [(0, 0, {'partner_id': seller.partner_id.id, 'delay': 1.0}) for seller in product_template_id.seller_ids]
@api.model
def update_related_fields(self):
# 获取所有记录
products = self.search([('categ_type', '=', False), ('active', '=', False)])
for product in products:
# 通过调用 write 方法来触发 related 字段的更新
product.write({'categ_type': product.categ_id.type})

View File

@@ -56,7 +56,7 @@ class QuickEasyOrder(models.Model):
'part_name': '', 'part_name': '',
}) })
company_id = self.env.ref('base.main_company').sudo() company_id = self.env.ref('base.main_company').sudo()
product_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_product_default').sudo() product_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_default').sudo().with_context(active_test=False).product_variant_id
# user_id = request.env.ref('base.user_admin').sudo() # user_id = request.env.ref('base.user_admin').sudo()
order_id = self.env['sale.order'].sale_order_create(company_id, 'XXXXX', 'XXXXX', 'XXXXX', order_id = self.env['sale.order'].sale_order_create(company_id, 'XXXXX', 'XXXXX', 'XXXXX',
str(datetime.now()), '现结', '支付宝', state='draft') str(datetime.now()), '现结', '支付宝', state='draft')

View File

@@ -31,18 +31,18 @@ class SaleOrder(models.Model):
# 根据供货方式修改成品模板 # 根据供货方式修改成品模板
if line.supply_method == 'automation': if line.supply_method == 'automation':
bom_type = 'normal' bom_type = 'normal'
product_template_id = self.env.ref('sf_dlm.product_template_sf').sudo() product_template_id = self.env.ref('sf_dlm.product_template_sf').sudo().product_tmpl_id
elif line.supply_method == 'outsourcing': elif line.supply_method == 'outsourcing':
bom_type = 'subcontract' bom_type = 'subcontract'
product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_product_outsourcing').sudo() product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_outsourcing').sudo()
elif line.supply_method == 'purchase': elif line.supply_method == 'purchase':
product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_product_purchase').sudo() product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_purchase').sudo()
elif line.supply_method == 'manual': elif line.supply_method == 'manual':
bom_type = 'normal' bom_type = 'normal'
product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_product_manual_processing').sudo() 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.product_tmpl_id) line.product_id.product_tmpl_id.copy_template(product_template_id)
order_id = self order_id = self
product = line.product_id product = line.product_id
@@ -66,10 +66,10 @@ class SaleOrder(models.Model):
# 当成品上带有客供料选项时,生成坯料时选择“客供料”路线 # 当成品上带有客供料选项时,生成坯料时选择“客供料”路线
if line.is_incoming_material: if line.is_incoming_material:
# 将成品模板的内容复制到成品上 # 将成品模板的内容复制到成品上
customer_provided_embryo = self.env.ref('jikimo_sale_multiple_supply_methods.product_product_raw_material_customer_provided').sudo() customer_provided_embryo = self.env.ref('jikimo_sale_multiple_supply_methods.product_tempalte_raw_material_customer_provided').sudo()
# 创建坯料客供料的批量不需要创建bom # 创建坯料客供料的批量不需要创建bom
material_customer_provided_embryo = self.env['product.template'].sudo().no_bom_product_create( material_customer_provided_embryo = self.env['product.template'].sudo().no_bom_product_create(
customer_provided_embryo, customer_provided_embryo.with_context(active_test=False).product_variant_id,
item, item,
order_id, 'material_customer_provided', 0, product) order_id, 'material_customer_provided', 0, product)
# 成品配置bom # 成品配置bom

View File

@@ -10,7 +10,7 @@
""", """,
'category': 'sf', 'category': 'sf',
'website': 'https://www.sf.jikimo.com', 'website': 'https://www.sf.jikimo.com',
'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse','jikimo_attachment_viewer', 'jikimo_sale_multiple_supply_methods'], 'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse','jikimo_attachment_viewer'],
'data': [ 'data': [
'data/stock_data.xml', 'data/stock_data.xml',
'data/empty_racks_data.xml', 'data/empty_racks_data.xml',

View File

@@ -10,7 +10,7 @@ class ModelType(models.Model):
product_routing_tmpl_ids = fields.One2many('sf.product.model.type.routing.sort', 'product_model_type_id', product_routing_tmpl_ids = fields.One2many('sf.product.model.type.routing.sort', 'product_model_type_id',
'成品工序模板(自动化产线加工') '成品工序模板(自动化产线加工')
embryo_routing_tmpl_ids = fields.One2many('sf.embryo.model.type.routing.sort', 'embryo_model_type_id', embryo_routing_tmpl_ids = fields.One2many('sf.embryo.model.type.routing.sort', 'embryo_model_type_id',
'坯料工序模板') '坯料工序模板(人工线下加工)')
surface_technics_routing_tmpl_ids = fields.One2many('sf.surface_technics.model.type.routing.sort', surface_technics_routing_tmpl_ids = fields.One2many('sf.surface_technics.model.type.routing.sort',
'surface_technics_model_type_id', 'surface_technics_model_type_id',
'表面工艺工序模板') '表面工艺工序模板')

View File

@@ -277,8 +277,7 @@ class MrpProduction(models.Model):
precision_rounding=move.product_uom.rounding or move.product_id.uom_id.rounding) precision_rounding=move.product_uom.rounding or move.product_id.uom_id.rounding)
for move in production.move_raw_ids if move.product_id): for move in production.move_raw_ids if move.product_id):
production.state = 'progress' production.state = 'progress'
elif not production.technology_design_ids:
production.state = 'technology_to_confirmed'
# 新添加的状态逻辑 # 新添加的状态逻辑
if ( if (
production.state == 'to_close' or production.state == 'progress') and production.schedule_state == '未排': production.state == 'to_close' or production.state == 'progress') and production.schedule_state == '未排':
@@ -1301,17 +1300,17 @@ class MrpProduction(models.Model):
return production_values_str return production_values_str
# 增加制造订单类型 # 增加制造订单类型
production_type = fields.Selection( # production_type = fields.Selection(
[('自动化产线加工', '自动化产线加工'), ('人工线下加工', '人工线下加工')], # [('自动化产线加工', '自动化产线加工'), ('人工线下加工', '人工线下加工')],
string='制造类型', # string='制造类型',
compute='_compute_production_type', # compute='_compute_production_type',
store=True # store=True
) # )
@api.depends('product_id.is_manual_processing') # @api.depends('product_id.is_manual_processing')
def _compute_production_type(self): # def _compute_production_type(self):
for production in self: # for production in self:
production.production_type = '自动化产线加工' if not production.product_id.is_manual_processing else '人工线下加工' # production.production_type = '自动化产线加工' if not production.product_id.is_manual_processing else '人工线下加工'
class sf_detection_result(models.Model): class sf_detection_result(models.Model):

View File

@@ -66,358 +66,358 @@ class stockWarehouse(models.Model):
class StockRule(models.Model): class StockRule(models.Model):
_inherit = 'stock.rule' _inherit = 'stock.rule'
@api.model # @api.model
def _run_pull(self, procurements): # def _run_pull(self, procurements):
logging.info(procurements) # logging.info(procurements)
moves_values_by_company = defaultdict(list) # moves_values_by_company = defaultdict(list)
mtso_products_by_locations = defaultdict(list) # mtso_products_by_locations = defaultdict(list)
# To handle the `mts_else_mto` procure method, we do a preliminary loop to # # To handle the `mts_else_mto` procure method, we do a preliminary loop to
# isolate the products we would need to read the forecasted quantity, # # isolate the products we would need to read the forecasted quantity,
# in order to to batch the read. We also make a sanitary check on the # # in order to to batch the read. We also make a sanitary check on the
# `location_src_id` field. # # `location_src_id` field.
# list1 = [] # # list1 = []
# for item in procurements: # # for item in procurements:
# num = int(item[0].product_qty) # # num = int(item[0].product_qty)
# if num > 1: # # if num > 1:
# for no in range(1, num+1): # # for no in range(1, num+1):
# # #
# Procurement = namedtuple('Procurement', ['product_id', 'product_qty', # # Procurement = namedtuple('Procurement', ['product_id', 'product_qty',
# 'product_uom', 'location_id', 'name', 'origin', # # 'product_uom', 'location_id', 'name', 'origin',
# 'company_id', # # 'company_id',
# 'values']) # # 'values'])
# s = Procurement(product_id=item[0].product_id,product_qty=1.0,product_uom=item[0].product_uom, # # s = Procurement(product_id=item[0].product_id,product_qty=1.0,product_uom=item[0].product_uom,
# location_id=item[0].location_id, # # location_id=item[0].location_id,
# name=item[0].name, # # name=item[0].name,
# origin=item[0].origin, # # origin=item[0].origin,
# company_id=item[0].company_id, # # company_id=item[0].company_id,
# values=item[0].values, # # values=item[0].values,
# ) # # )
# item1 = list(item) # # item1 = list(item)
# item1[0]=s # # item1[0]=s
# # #
# list1.append(tuple(item1)) # # list1.append(tuple(item1))
# else: # # else:
# list1.append(item) # # list1.append(item)
for procurement, rule in procurements: # for procurement, rule in procurements:
if not rule.location_src_id: # if not rule.location_src_id:
msg = _('No source location defined on stock rule: %s!') % (rule.name,) # msg = _('No source location defined on stock rule: %s!') % (rule.name,)
raise ProcurementException([(procurement, msg)]) # raise ProcurementException([(procurement, msg)])
if rule.procure_method == 'mts_else_mto': # if rule.procure_method == 'mts_else_mto':
mtso_products_by_locations[rule.location_src_id].append(procurement.product_id.id) # mtso_products_by_locations[rule.location_src_id].append(procurement.product_id.id)
# Get the forecasted quantity for the `mts_else_mto` procurement. # # Get the forecasted quantity for the `mts_else_mto` procurement.
forecasted_qties_by_loc = {} # forecasted_qties_by_loc = {}
for location, product_ids in mtso_products_by_locations.items(): # for location, product_ids in mtso_products_by_locations.items():
products = self.env['product.product'].browse(product_ids).with_context(location=location.id) # products = self.env['product.product'].browse(product_ids).with_context(location=location.id)
forecasted_qties_by_loc[location] = {product.id: product.free_qty for product in products} # forecasted_qties_by_loc[location] = {product.id: product.free_qty for product in products}
# Prepare the move values, adapt the `procure_method` if needed. # # Prepare the move values, adapt the `procure_method` if needed.
procurements = sorted(procurements, key=lambda proc: float_compare(proc[0].product_qty, 0.0, # procurements = sorted(procurements, key=lambda proc: float_compare(proc[0].product_qty, 0.0,
precision_rounding=proc[ # precision_rounding=proc[
0].product_uom.rounding) > 0) # 0].product_uom.rounding) > 0)
list2 = [] # list2 = []
for item in procurements: # for item in procurements:
num = int(item[0].product_qty) # num = int(item[0].product_qty)
product = self.env['product.product'].search( # product = self.env['product.product'].search(
[("id", '=', item[0].product_id.id)]) # [("id", '=', item[0].product_id.id)])
product_tmpl = self.env['product.template'].search( # product_tmpl = self.env['product.template'].search(
["&", ("id", '=', product.product_tmpl_id.id), ('single_manufacturing', "!=", False)]) # ["&", ("id", '=', product.product_tmpl_id.id), ('single_manufacturing', "!=", False)])
if product_tmpl: # if product_tmpl:
if num > 1: # if num > 1:
for no in range(1, num + 1): # for no in range(1, num + 1):
Procurement = namedtuple('Procurement', ['product_id', 'product_qty', # Procurement = namedtuple('Procurement', ['product_id', 'product_qty',
'product_uom', 'location_id', 'name', 'origin', # 'product_uom', 'location_id', 'name', 'origin',
'company_id', # 'company_id',
'values']) # 'values'])
s = Procurement(product_id=item[0].product_id, product_qty=1.0, product_uom=item[0].product_uom, # s = Procurement(product_id=item[0].product_id, product_qty=1.0, product_uom=item[0].product_uom,
location_id=item[0].location_id, # location_id=item[0].location_id,
name=item[0].name, # name=item[0].name,
origin=item[0].origin, # origin=item[0].origin,
company_id=item[0].company_id, # company_id=item[0].company_id,
values=item[0].values, # values=item[0].values,
) # )
item1 = list(item) # item1 = list(item)
item1[0] = s # item1[0] = s
list2.append(tuple(item1)) # list2.append(tuple(item1))
else: # else:
list2.append(item) # list2.append(item)
else: # else:
list2.append(item) # list2.append(item)
for procurement, rule in list2: # for procurement, rule in list2:
procure_method = rule.procure_method # procure_method = rule.procure_method
if rule.procure_method == 'mts_else_mto': # if rule.procure_method == 'mts_else_mto':
qty_needed = procurement.product_uom._compute_quantity(procurement.product_qty, # qty_needed = procurement.product_uom._compute_quantity(procurement.product_qty,
procurement.product_id.uom_id) # procurement.product_id.uom_id)
if float_compare(qty_needed, 0, precision_rounding=procurement.product_id.uom_id.rounding) <= 0: # if float_compare(qty_needed, 0, precision_rounding=procurement.product_id.uom_id.rounding) <= 0:
procure_method = 'make_to_order' # procure_method = 'make_to_order'
for move in procurement.values.get('group_id', self.env['procurement.group']).stock_move_ids: # for move in procurement.values.get('group_id', self.env['procurement.group']).stock_move_ids:
if move.rule_id == rule and float_compare(move.product_uom_qty, 0, # if move.rule_id == rule and float_compare(move.product_uom_qty, 0,
precision_rounding=move.product_uom.rounding) > 0: # precision_rounding=move.product_uom.rounding) > 0:
procure_method = move.procure_method # procure_method = move.procure_method
break # break
forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed # forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed
elif float_compare(qty_needed, forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id], # elif float_compare(qty_needed, forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id],
precision_rounding=procurement.product_id.uom_id.rounding) > 0: # precision_rounding=procurement.product_id.uom_id.rounding) > 0:
procure_method = 'make_to_order' # procure_method = 'make_to_order'
else: # else:
forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed # forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed
procure_method = 'make_to_stock' # procure_method = 'make_to_stock'
move_values = rule._get_stock_move_values(*procurement) # move_values = rule._get_stock_move_values(*procurement)
move_values['procure_method'] = procure_method # move_values['procure_method'] = procure_method
moves_values_by_company[procurement.company_id.id].append(move_values) # moves_values_by_company[procurement.company_id.id].append(move_values)
for company_id, moves_values in moves_values_by_company.items(): # for company_id, moves_values in moves_values_by_company.items():
# create the move as SUPERUSER because the current user may not have the rights to do it (mto product # # create the move as SUPERUSER because the current user may not have the rights to do it (mto product
# launched by a sale for example) # # launched by a sale for example)
moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( # moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
moves_values) # moves_values)
# Since action_confirm launch following procurement_group we should activate it. # # Since action_confirm launch following procurement_group we should activate it.
moves._action_confirm() # moves._action_confirm()
return True # return True
def attachment_update(self, name, res_id, res_field): def attachment_update(self, name, res_id, res_field):
attachment_info = self.env['ir.attachment'].sudo().search( attachment_info = self.env['ir.attachment'].sudo().search(
[('res_id', '=', res_id), ('res_field', '=', res_field)], limit=1) [('res_id', '=', res_id), ('res_field', '=', res_field)], limit=1)
attachment_info.write({'name': name}) attachment_info.write({'name': name})
@api.model # @api.model
def _run_manufacture(self, procurements): # def _run_manufacture(self, procurements):
productions_values_by_company = defaultdict(list) # productions_values_by_company = defaultdict(list)
errors = [] # errors = []
for procurement, rule in procurements: # for procurement, rule in procurements:
if float_compare(procurement.product_qty, 0, precision_rounding=procurement.product_uom.rounding) <= 0: # 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. # # If procurement contains negative quantity, don't create a MO that would be for a negative value.
continue # continue
bom = rule._get_matching_bom(procurement.product_id, procurement.company_id, procurement.values) # 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)) # productions_values_by_company[procurement.company_id.id].append(rule._prepare_mo_vals(*procurement, bom))
if errors: # if errors:
raise ProcurementException(errors) # raise ProcurementException(errors)
for company_id, productions_values in productions_values_by_company.items(): # 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 # # 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) # # (mto product launched by a sale for example)
'''创建制造订单''' # '''创建制造订单'''
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( # productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
productions_values) # productions_values)
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) # # self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
# self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) # # self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
''' # '''
创建工单 # 创建工单
''' # '''
# productions._create_workorder() # # productions._create_workorder()
# # #
self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) # self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ # 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_dest_ids.procure_method != 'make_to_order' and not
p.move_raw_ids and not p.workorder_ids)).action_confirm() # p.move_raw_ids and not p.workorder_ids)).action_confirm()
# 处理 根据制造订单生成的采购单坯料入库时到原材料库,手动将原材料位置该为坯料存货区 # # 处理 根据制造订单生成的采购单坯料入库时到原材料库,手动将原材料位置该为坯料存货区
for production in productions: # for production in productions:
if production.picking_ids: # if production.picking_ids:
product_type_id = production.picking_ids[0].move_ids[0].product_id.categ_id # product_type_id = production.picking_ids[0].move_ids[0].product_id.categ_id
if product_type_id.name == '坯料': # if product_type_id.name == '坯料':
location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')]) # location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')])
if not location_id: # if not location_id:
logging.info(f'没有搜索到【坯料存货区】: {location_id}') # logging.info(f'没有搜索到【坯料存货区】: {location_id}')
break # break
for picking_id in production.picking_ids: # for picking_id in production.picking_ids:
if picking_id.picking_type_id.name == '内部调拨': # if picking_id.picking_type_id.name == '内部调拨':
if picking_id.location_dest_id.product_type != product_type_id: # if picking_id.location_dest_id.product_type != product_type_id:
picking_id.location_dest_id = location_id.id # picking_id.location_dest_id = location_id.id
elif picking_id.picking_type_id.name == '生产发料': # elif picking_id.picking_type_id.name == '生产发料':
if picking_id.location_id.product_type != product_type_id: # if picking_id.location_id.product_type != product_type_id:
picking_id.location_id = location_id.id # picking_id.location_id = location_id.id
for production in productions: # for production in productions:
''' # '''
创建制造订单时生成序列号 # 创建制造订单时生成序列号
''' # '''
production.action_generate_serial() # production.action_generate_serial()
origin_production = production.move_dest_ids and production.move_dest_ids[ # origin_production = production.move_dest_ids and production.move_dest_ids[
0].raw_material_production_id or False # 0].raw_material_production_id or False
orderpoint = production.orderpoint_id # orderpoint = production.orderpoint_id
if orderpoint and orderpoint.create_uid.id == SUPERUSER_ID and orderpoint.trigger == 'manual': # if orderpoint and orderpoint.create_uid.id == SUPERUSER_ID and orderpoint.trigger == 'manual':
production.message_post( # production.message_post(
body=_('This production order has been created from Replenishment Report.'), # body=_('This production order has been created from Replenishment Report.'),
message_type='comment', # message_type='comment',
subtype_xmlid='mail.mt_note') # subtype_xmlid='mail.mt_note')
elif orderpoint: # elif orderpoint:
production.message_post_with_view( # production.message_post_with_view(
'mail.message_origin_link', # 'mail.message_origin_link',
values={'self': production, 'origin': orderpoint}, # values={'self': production, 'origin': orderpoint},
subtype_id=self.env.ref('mail.mt_note').id) # subtype_id=self.env.ref('mail.mt_note').id)
elif origin_production: # elif origin_production:
production.message_post_with_view( # production.message_post_with_view(
'mail.message_origin_link', # 'mail.message_origin_link',
values={'self': production, 'origin': origin_production}, # values={'self': production, 'origin': origin_production},
subtype_id=self.env.ref('mail.mt_note').id) # subtype_id=self.env.ref('mail.mt_note').id)
''' # '''
创建生产计划 # 创建生产计划
''' # '''
# 工单耗时 # # 工单耗时
workorder_duration = 0 # workorder_duration = 0
for workorder in production.workorder_ids: # for workorder in production.workorder_ids:
workorder_duration += workorder.duration_expected # workorder_duration += workorder.duration_expected
sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)]) # sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)])
if sale_order: # if sale_order:
# sale_order.write({'schedule_status': 'to schedule'}) # # sale_order.write({'schedule_status': 'to schedule'})
self.env['sf.production.plan'].sudo().with_company(company_id).create({ # self.env['sf.production.plan'].sudo().with_company(company_id).create({
'name': production.name, # 'name': production.name,
'order_deadline': sale_order.deadline_of_delivery, # 'order_deadline': sale_order.deadline_of_delivery,
'production_id': production.id, # 'production_id': production.id,
'date_planned_start': production.date_planned_start, # 'date_planned_start': production.date_planned_start,
'origin': production.origin, # 'origin': production.origin,
'product_qty': production.product_qty, # 'product_qty': production.product_qty,
'product_id': production.product_id.id, # 'product_id': production.product_id.id,
'state': 'draft', # 'state': 'draft',
}) # })
technology_design_values = [] # technology_design_values = []
all_production = productions # all_production = productions
grouped_product_ids = {k: list(g) for k, g in groupby(all_production, key=lambda x: x.product_id.id)} # grouped_product_ids = {k: list(g) for k, g in groupby(all_production, key=lambda x: x.product_id.id)}
# 初始化一个字典来存储每个product_id对应的生产订单名称列表 # # 初始化一个字典来存储每个product_id对应的生产订单名称列表
product_id_to_production_names = {} # product_id_to_production_names = {}
# 对于每个product_id获取其所有生产订单的名称 # # 对于每个product_id获取其所有生产订单的名称
for product_id, all_production in grouped_product_ids.items(): # for product_id, all_production in grouped_product_ids.items():
# 为同一个product_id创建一个生产订单名称列表 # # 为同一个product_id创建一个生产订单名称列表
product_id_to_production_names[product_id] = [production.name for production in all_production] # product_id_to_production_names[product_id] = [production.name for production in all_production]
for production_item in productions: # for production_item in productions:
production_programming = self.env['mrp.production'].search( # # production_programming = self.env['mrp.production'].search(
[('product_id.id', '=', production_item.product_id.id), # # [('product_id.id', '=', production_item.product_id.id),
('origin', '=', production_item.origin)], # # ('origin', '=', production_item.origin)],
limit=1, order='id asc') # # limit=1, order='id asc')
if production_item.product_id.id in product_id_to_production_names: # if production_item.product_id.id in product_id_to_production_names:
if production_item.product_id.model_process_parameters_ids: # if production_item.product_id.model_process_parameters_ids:
is_purchase = False # is_purchase = False
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, # sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids,
key=lambda w: w.id) # key=lambda w: w.id)
consecutive_process_parameters = [] # consecutive_process_parameters = []
m = 0 # m = 0
for i in range(len(sorted_process_parameters) - 1): # for i in range(len(sorted_process_parameters) - 1):
if m == 0: # if m == 0:
is_purchase = False # is_purchase = False
if self.env['product.template']._get_process_parameters_product( # if self.env['product.template']._get_process_parameters_product(
sorted_process_parameters[i]).partner_id == self.env[ # sorted_process_parameters[i]).partner_id == self.env[
'product.template']._get_process_parameters_product(sorted_process_parameters[ # 'product.template']._get_process_parameters_product(sorted_process_parameters[
i + 1]).partner_id and \ # i + 1]).partner_id and \
sorted_process_parameters[i].gain_way == '外协': # sorted_process_parameters[i].gain_way == '外协':
if sorted_process_parameters[i] not in consecutive_process_parameters: # if sorted_process_parameters[i] not in consecutive_process_parameters:
consecutive_process_parameters.append(sorted_process_parameters[i]) # consecutive_process_parameters.append(sorted_process_parameters[i])
consecutive_process_parameters.append(sorted_process_parameters[i + 1]) # consecutive_process_parameters.append(sorted_process_parameters[i + 1])
m += 1 # m += 1
continue # continue
else: # else:
if m == len(consecutive_process_parameters) - 1 and m != 0: # if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, # self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item, # production_item,
product_id_to_production_names) # product_id_to_production_names)
if sorted_process_parameters[i] in consecutive_process_parameters: # if sorted_process_parameters[i] in consecutive_process_parameters:
is_purchase = True # is_purchase = True
consecutive_process_parameters = [] # consecutive_process_parameters = []
m = 0 # m = 0
# 当前面的连续外协采购单生成再生成当前外协采购单 # # 当前面的连续外协采购单生成再生成当前外协采购单
if is_purchase is False: # if is_purchase is False:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, # self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item, # production_item,
product_id_to_production_names) # product_id_to_production_names)
if m == len(consecutive_process_parameters) - 1 and m != 0: # if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, # self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item, # production_item,
product_id_to_production_names) # product_id_to_production_names)
if sorted_process_parameters[i] in consecutive_process_parameters: # if sorted_process_parameters[i] in consecutive_process_parameters:
is_purchase = True # is_purchase = True
consecutive_process_parameters = [] # consecutive_process_parameters = []
m = 0 # m = 0
if m == len(consecutive_process_parameters) - 1 and m != 0: # if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, # self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item, # production_item,
product_id_to_production_names) # product_id_to_production_names)
if is_purchase is False and m == 0: # if is_purchase is False and m == 0:
if len(sorted_process_parameters) == 1: # if len(sorted_process_parameters) == 1:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters, # self.env['purchase.order'].get_purchase_order(sorted_process_parameters,
production_item, # production_item,
product_id_to_production_names) # product_id_to_production_names)
else: # else:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i], # self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i],
production_item, # production_item,
product_id_to_production_names) # product_id_to_production_names)
if not technology_design_values: # if not technology_design_values:
if production.product_id.categ_id.type == '成品': # if production.product_id.categ_id.type == '成品':
production.product_id.model_processing_panel = 'ZM,FM' # production.product_id.model_processing_panel = 'ZM,FM'
# 根据加工面板的面数及成品工序模板生成工序设计 # # 根据加工面板的面数及成品工序模板生成工序设计
i = 0 # i = 0
for k in (production.product_id.model_processing_panel.split(',')): # for k in (production.product_id.model_processing_panel.split(',')):
product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search( # product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search(
[('product_model_type_id', '=', production.product_id.product_model_type_id.id)], # [('product_model_type_id', '=', production.product_id.product_model_type_id.id)],
order='sequence asc' # order='sequence asc'
) # )
for route in product_routing_workcenter: # for route in product_routing_workcenter:
i += 1 # i += 1
technology_design_values.append( # technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(k, route, i)) # self.env['sf.technology.design'].json_technology_design_str(k, route, i))
surface_technics_arr = [] # surface_technics_arr = []
route_workcenter_arr = [] # route_workcenter_arr = []
for process_param in production.product_id.product_model_type_id.surface_technics_routing_tmpl_ids.filtered( # for process_param in production.product_id.product_model_type_id.surface_technics_routing_tmpl_ids.filtered(
lambda st: st.id in production.product_id.model_process_parameters_ids.ids): # lambda st: st.id in production.product_id.model_process_parameters_ids.ids):
# if item.route_workcenter_id.surface_technics_id.id: # # if item.route_workcenter_id.surface_technics_id.id:
# for process_param in production.product_id.model_process_parameters_ids: # # for process_param in production.product_id.model_process_parameters_ids:
logging.info('process_param:%s%s' % (process_param.id, process_param.name)) # logging.info('process_param:%s%s' % (process_param.id, process_param.name))
if item.route_workcenter_id.surface_technics_id == process_param.process_id: # if item.route_workcenter_id.surface_technics_id == process_param.process_id:
logging.info( # logging.info(
'surface_technics_id:%s%s' % ( # 'surface_technics_id:%s%s' % (
item.route_workcenter_id.surface_technics_id.id, # item.route_workcenter_id.surface_technics_id.id,
item.route_workcenter_id.surface_technics_id.name)) # item.route_workcenter_id.surface_technics_id.name))
surface_technics_arr.append( # surface_technics_arr.append(
item.route_workcenter_id.surface_technics_id.id) # item.route_workcenter_id.surface_technics_id.id)
route_workcenter_arr.append(item.route_workcenter_id.id) # route_workcenter_arr.append(item.route_workcenter_id.id)
if surface_technics_arr: # if surface_technics_arr:
production_process = self.env['sf.production.process'].search( # production_process = self.env['sf.production.process'].search(
[('id', 'in', surface_technics_arr)], # [('id', 'in', surface_technics_arr)],
order='sequence asc' # order='sequence asc'
) # )
for p in production_process: # for p in production_process:
logging.info('production_process:%s' % p.name) # logging.info('production_process:%s' % p.name)
process_parameter = production.product_id.model_process_parameters_ids.filtered( # process_parameter = production.product_id.model_process_parameters_ids.filtered(
lambda pm: pm.process_id.id == p.id) # lambda pm: pm.process_id.id == p.id)
product_production_process = self.env['product.template'].search( # product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', # [('server_product_process_parameters_id', '=',
process_parameter.id)]) # process_parameter.id)])
if process_parameter: # if process_parameter:
i += 1 # i += 1
route_production_process = self.env[ # route_production_process = self.env[
'mrp.routing.workcenter'].search( # 'mrp.routing.workcenter'].search(
[('surface_technics_id', '=', p.id), # [('surface_technics_id', '=', p.id),
('id', 'in', route_workcenter_arr)]) # ('id', 'in', route_workcenter_arr)])
technology_design_values.append( # technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(k, # self.env['sf.technology.design'].json_technology_design_str(k,
route_production_process, # route_production_process,
product_production_process, # product_production_process,
i)) # i))
productions.technology_design_ids = technology_design_values # productions.technology_design_ids = technology_design_values
# # 同一个产品多个制造订单对应一个编程单和模型库 # # # 同一个产品多个制造订单对应一个编程单和模型库
# # 只调用一次fetchCNC并将所有生产订单的名称作为字符串传递 # # # 只调用一次fetchCNC并将所有生产订单的名称作为字符串传递
# if not production_item.programming_no: # # if not production_item.programming_no:
# if not production_programming.programming_no: # # if not production_programming.programming_no:
# production_item.fetchCNC( # # production_item.fetchCNC(
# ', '.join(product_id_to_production_names[production_item.product_id.id])) # # ', '.join(product_id_to_production_names[production_item.product_id.id]))
# else: # # else:
# production_item.write({'programming_no': production_programming.programming_no, # # production_item.write({'programming_no': production_programming.programming_no,
# 'programming_state': '编程中'}) # # 'programming_state': '编程中'})
return True # return True
class ProductionLot(models.Model): class ProductionLot(models.Model):

View File

@@ -36,8 +36,8 @@
decoration-success="reservation_state == 'assigned'"/> decoration-success="reservation_state == 'assigned'"/>
</xpath> </xpath>
<xpath expr="//field[@name='state']" position="before"> <xpath expr="//field[@name='state']" position="before">
<field name="production_type" widget="badge" decoration-warning="production_type == '人工线下加工'" <!-- <field name="production_type" widget="badge" decoration-warning="production_type == '人工线下加工'"
decoration-success="production_type == '自动化产线加工'" optional="show"/> decoration-success="production_type == '自动化产线加工'" optional="show"/> -->
</xpath> </xpath>
<xpath expr="//field[@name='activity_ids']" position="replace"> <xpath expr="//field[@name='activity_ids']" position="replace">
<field name="activity_ids" string="下一个活动" widget="list_activity" optional="hide"/> <field name="activity_ids" string="下一个活动" widget="list_activity" optional="hide"/>
@@ -91,7 +91,7 @@
</xpath> </xpath>
<xpath expr="//sheet//group//group//div[3]" position="after"> <xpath expr="//sheet//group//group//div[3]" position="after">
<field name="production_type" readonly="1"/> <!-- <field name="production_type" readonly="1"/> -->
<field name="manual_quotation" readonly="1"/> <field name="manual_quotation" readonly="1"/>
<field name="programming_no" readonly="1"/> <field name="programming_no" readonly="1"/>
<field name="programming_state" readonly="1" <field name="programming_state" readonly="1"

View File

@@ -417,12 +417,12 @@ class sf_production_plan(models.Model):
raise UserError(e) raise UserError(e)
# 增加制造订单类型 # 增加制造订单类型
production_type = fields.Selection( # production_type = fields.Selection(
[('自动化产线加工', '自动化产线加工'), ('人工线下加工', '人工线下加工')], # [('自动化产线加工', '自动化产线加工'), ('人工线下加工', '人工线下加工')],
string='制造类型', # string='制造类型',
related='production_id.production_type', # related='production_id.production_type',
store=True # store=True
) # )
# 机台作业计划 # 机台作业计划

View File

@@ -22,7 +22,7 @@
<field name="production_line_id"/> <field name="production_line_id"/>
<field name="date_planned_start"/> <field name="date_planned_start"/>
<field name="date_planned_finished"/> <field name="date_planned_finished"/>
<field name="production_type" widget="badge" decoration-warning="production_type == '人工线下加工'" decoration-success="production_type == '自动化产线加工'"/> <!-- <field name="production_type" widget="badge" decoration-warning="production_type == '人工线下加工'" decoration-success="production_type == '自动化产线加工'"/> -->
<field name="actual_start_time" optional='hide'/> <field name="actual_start_time" optional='hide'/>
<field name="actual_end_time" optional='hide'/> <field name="actual_end_time" optional='hide'/>
<field name="actual_process_time" optional='hide'/> <field name="actual_process_time" optional='hide'/>