diff --git a/jikimo_sale_multiple_supply_methods/views/sale_order_views.xml b/jikimo_sale_multiple_supply_methods/views/sale_order_views.xml
index 1cf6eb3f..8b1a85d0 100644
--- a/jikimo_sale_multiple_supply_methods/views/sale_order_views.xml
+++ b/jikimo_sale_multiple_supply_methods/views/sale_order_views.xml
@@ -22,7 +22,7 @@
confirm_to_supply_method
-
+
draft,sent,supply method,sale
diff --git a/sf_base/models/base.py b/sf_base/models/base.py
index e8db18da..15d4f9cc 100644
--- a/sf_base/models/base.py
+++ b/sf_base/models/base.py
@@ -416,7 +416,8 @@ class EmbryoRedundancy(models.Model):
_name = "sf.embryo.redundancy"
name = fields.Char('名称', required=True)
- long = fields.Float('长度', required=True)
- width = fields.Float('宽度', required=True)
- height = fields.Float('高度', required=True)
+ long = fields.Float('长度(mm)', required=True)
+ width = fields.Float('宽度(mm)', required=True)
+ height = fields.Float('高度(mm)', required=True)
code = fields.Char('编码', required=True)
+ active = fields.Boolean('有效', default=True)
diff --git a/sf_base/views/base_view.xml b/sf_base/views/base_view.xml
index eb2c1571..bd6f103b 100644
--- a/sf_base/views/base_view.xml
+++ b/sf_base/views/base_view.xml
@@ -633,4 +633,26 @@
sf.machining.accuracy
tree
+
+ #------------------坯料冗余量------------------
+
+ tree.sf.embryo.redundancy
+ sf.embryo.redundancy
+
+
+
+
+
+
+
+
+
+
+
+
+ 坯料冗余量
+ ir.actions.act_window
+ sf.embryo.redundancy
+ tree
+
\ No newline at end of file
diff --git a/sf_base/views/menu_view.xml b/sf_base/views/menu_view.xml
index 4c662976..cf7c7aaf 100644
--- a/sf_base/views/menu_view.xml
+++ b/sf_base/views/menu_view.xml
@@ -141,18 +141,25 @@
sequence="1"
action="action_sf_machine_brand"/>
+
+
diff --git a/sf_dlm/models/stock_rule_inherit.py b/sf_dlm/models/stock_rule_inherit.py
index d20fcd58..72e7ed28 100644
--- a/sf_dlm/models/stock_rule_inherit.py
+++ b/sf_dlm/models/stock_rule_inherit.py
@@ -1,3 +1,4 @@
+import logging
from odoo import models, fields, api, _
@@ -29,7 +30,14 @@ class StockRuleInherit(models.Model):
if supplier:
domain = rule._make_po_get_domain(procurement.company_id, procurement.values,
supplier.partner_id)
- po = self.env['purchase.order'].sudo().search([dom for dom in domain], limit=1)
+ logging.info("domain=============: %s", domain)
+ po = self.env['purchase.order'].sudo().search([
+ ('partner_id', '=', supplier.partner_id.id),
+ ('company_id', '=', procurement.company_id.id), # 保证公司一致
+ ('origin', '=', procurement.origin), # 根据来源匹配
+ ('state', '=', 'draft') # 状态为草稿
+ ], limit=1)
+ logging.info("po=: %s", po)
if po:
po.write({'purchase_type': 'consignment'})
break
diff --git a/sf_machine_connect/controllers/controllers.py b/sf_machine_connect/controllers/controllers.py
index ab03dff2..7eaac8aa 100644
--- a/sf_machine_connect/controllers/controllers.py
+++ b/sf_machine_connect/controllers/controllers.py
@@ -1264,6 +1264,7 @@ class Sf_Dashboard_Connect(http.Controller):
"""
获取
"""
+ logging.info("kw=============:%s" % kw)
res = {'status': 1, 'message': '成功', 'data': {}}
# 连接数据库
conn = psycopg2.connect(**db_config)
diff --git a/sf_maintenance/models/sf_maintenance_oee.py b/sf_maintenance/models/sf_maintenance_oee.py
index eef42a60..95dd74a4 100644
--- a/sf_maintenance/models/sf_maintenance_oee.py
+++ b/sf_maintenance/models/sf_maintenance_oee.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import re
import json
+import logging
import datetime
import requests
from odoo import api, fields, models, _
@@ -90,11 +91,18 @@ class SfMaintenanceEquipmentOEE(models.Model):
def get_running_datas(self):
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
- url_time = base_url + '/api/RunningTimeDetail'
+ logging.info("base_url=============:%s" % base_url)
+ # 只有当原始 URL 使用 http 时才替换为 https
+ if base_url.startswith("http://"):
+ secure_base_url = base_url.replace("http://", "https://")
+ else:
+ secure_base_url = base_url
+ url_time = secure_base_url + '/api/RunningTimeDetail'
+ logging.info("url_time=============:%s" % url_time)
cnc_list_obj = self.env['maintenance.equipment'].sudo().search(
[('function_type', '!=', False), ('active', '=', True)])
machine_list = list(map(lambda x: x.code, cnc_list_obj))
- # print('machine_list: %s' % machine_list)
+ logging.info("machine_list=============:%s" % machine_list)
data_time = {
"machine_list": str(machine_list)
diff --git a/sf_manufacturing/models/model_type.py b/sf_manufacturing/models/model_type.py
index d08b024b..0dd272bd 100644
--- a/sf_manufacturing/models/model_type.py
+++ b/sf_manufacturing/models/model_type.py
@@ -6,7 +6,8 @@ class ModelType(models.Model):
_description = '模型类型'
name = fields.Char('名称')
- embryo_tolerance = fields.Integer('坯料容余')
+ # embryo_tolerance = fields.Char('坯料容余')
+ embryo_tolerance_id = fields.Many2one('sf.embryo.redundancy', string='坯料容余')
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',
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index 0bc01470..f1bbfeb5 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -34,6 +34,28 @@ class MrpProduction(models.Model):
tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True)
tool_state_remark2 = fields.Text(string='功能刀具状态备注(无效刀)', readonly=True)
+ @api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id')
+ def _compute_deadline_of_delivery(self):
+ for production in self:
+ # 确保 procurement_group_id 和相关字段存在
+ if production.procurement_group_id:
+ # 获取相关的 sale_id
+ sale_order_id = production.procurement_group_id.mrp_production_ids.mapped(
+ 'move_dest_ids.group_id.sale_id')
+
+ # 确保 sale_order_id 是有效的 ID 列表
+ if sale_order_id:
+ # 获取 sale.order 记录
+ sale_id = self.env['sale.order'].sudo().browse(sale_order_id.ids) # 使用 mapped 返回的 ID 列表
+
+ # 处理 sale_id
+ if sale_id:
+ # 假设我们只需要第一个 sale_id
+ production.deadline_of_delivery = sale_id[0].deadline_of_delivery if sale_id else False
+ else:
+ production.deadline_of_delivery = False
+ else:
+ production.deadline_of_delivery = False
def _compute_default_delivery_status(self):
try:
if self.state == 'cancel':
@@ -123,29 +145,6 @@ class MrpProduction(models.Model):
else:
return 0.0
- @api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id')
- def _compute_deadline_of_delivery(self):
- for production in self:
- # 确保 procurement_group_id 和相关字段存在
- if production.procurement_group_id:
- # 获取相关的 sale_id
- sale_order_id = production.procurement_group_id.mrp_production_ids.mapped(
- 'move_dest_ids.group_id.sale_id')
-
- # 确保 sale_order_id 是有效的 ID 列表
- if sale_order_id:
- # 获取 sale.order 记录
- sale_id = self.env['sale.order'].sudo().browse(sale_order_id.ids) # 使用 mapped 返回的 ID 列表
-
- # 处理 sale_id
- if sale_id:
- # 假设我们只需要第一个 sale_id
- production.deadline_of_delivery = sale_id[0].deadline_of_delivery if sale_id else False
- else:
- production.deadline_of_delivery = False
- else:
- production.deadline_of_delivery = False
-
@api.depends('workorder_ids.tool_state_remark')
def _compute_tool_state_remark(self):
for item in self:
@@ -984,54 +983,30 @@ class MrpProduction(models.Model):
self._reset_work_order_sequence()
return True
+ def production_process(self, pro_plan):
+ type_map = {'装夹预调': False, 'CNC加工': False, '解除装夹': False}
+ # 最后一次加工结束时间
+ last_time = pro_plan.date_planned_start
+ # 预置时间
+ works = self.workorder_ids
+ for index,work in enumerate(works):
+ count = type_map.get(work.routing_type)
+ date_planned_end = None
+ date_planned_start = None
+ if self.production_type=='自动化产线加工':
+ date_planned_start,date_planned_end,last_time = work.auto_production_process(last_time,count,type_map)
+ elif self.production_type=='':
+ date_planned_start,date_planned_end,last_time = work.manual_offline_process(last_time,index)
+ work.update_work_start_end(date_planned_start,date_planned_end)
+ # def
def process_range_time(self):
for production in self:
works = production.workorder_ids
pro_plan = self.env['sf.production.plan'].search([('production_id', '=', production.id)], limit=1)
if not pro_plan:
continue
- type_map = {'装夹预调': False, 'CNC加工': False, '解除装夹': False}
- # 最后一次加工结束时间
- last_time = pro_plan.date_planned_start
- # 预置时间
- for work in works:
- count = type_map.get(work.routing_type)
- date_planned_end = None
- date_planned_start = None
- duration_expected = datetime.timedelta(minutes=work.duration_expected)
- reserve_time = datetime.timedelta(minutes=work.reserved_duration)
- if not count:
- # 第一轮加工
- if work.routing_type == '装夹预调':
- date_planned_end = last_time - reserve_time
- date_planned_start = date_planned_end - duration_expected
- elif work.routing_type == 'CNC加工':
- date_planned_start = last_time
- date_planned_end = last_time + duration_expected
- last_time = date_planned_end
- else:
- date_planned_start = last_time + reserve_time
- date_planned_end = date_planned_start + duration_expected
- last_time = date_planned_end
- type_map.update({work.routing_type: True})
- else:
- date_planned_start = last_time + reserve_time
- date_planned_end = date_planned_start + duration_expected
- last_time = date_planned_end
- work.leave_id.write({
- 'date_from': date_planned_start,
- 'date_to': date_planned_end,
- })
- # work.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end})
- # 设置一个较大的结束时间,防止在设置开始时间时,结束时间小于开始时间
- work.date_planned_finished = datetime.datetime.today() + datetime.timedelta(days=100)
- work.date_planned_start = date_planned_start
- work.date_planned_finished = date_planned_end
- routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
- [('name', '=', work.routing_type)])
-
- work.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end,
- 'duration_expected': routing_workcenter.time_cycle})
+ if production.production_type:
+ production.production_process(pro_plan)
# 修改标记已完成方法
def button_mark_done1(self):
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 6b0f0004..8aa17535 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -2032,3 +2032,55 @@ class CMMprogram(models.Model):
'program_create_date': datetime.strptime(item['program_create_date'], '%Y-%m-%d %H:%M:%S'),
}))
return cmm_program
+
+ def update_work_start_end(self,date_planned_start,date_planned_end):
+ self.leave_id.write({
+ 'date_from': date_planned_start,
+ 'date_to': date_planned_end,
+ })
+ self.date_planned_finished = datetime.datetime.today() + datetime.timedelta(days=100)
+ self.date_planned_start = date_planned_start
+ self.date_planned_finished = date_planned_end
+ routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
+ [('name', '=', self.routing_type)])
+
+ self.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end,
+ 'duration_expected': routing_workcenter.time_cycle})
+
+ def auto_production_process(self, last_time, is_first, type_map):
+ date_planned_end = None
+ date_planned_start = None
+ duration_expected = datetime.timedelta(minutes=self.duration_expected)
+ reserve_time = datetime.timedelta(minutes=self.reserved_duration)
+ if is_first:
+ # 第一轮加工
+ if self.routing_type == '装夹预调':
+ date_planned_end = last_time - reserve_time
+ date_planned_start = date_planned_end - duration_expected
+ elif self.routing_type == 'CNC加工':
+ date_planned_start = last_time
+ date_planned_end = last_time + duration_expected
+ last_time = date_planned_end
+ else:
+ date_planned_start = last_time + reserve_time
+ date_planned_end = date_planned_start + duration_expected
+ last_time = date_planned_end
+ type_map.update({self.routing_type: True})
+ else:
+ date_planned_start = last_time + reserve_time
+ date_planned_end = date_planned_start + duration_expected
+ last_time = date_planned_end
+ return date_planned_start, date_planned_end, last_time
+ def manual_offline_process(self,last_time,is_first):
+ date_planned_end = None
+ date_planned_start = None
+ duration_expected = datetime.timedelta(minutes=self.duration_expected)
+ reserve_time = datetime.timedelta(minutes=self.reserved_duration)
+ if is_first:
+ date_planned_start = last_time
+ date_planned_end = last_time + duration_expected
+
+ else:
+ date_planned_start = last_time + reserve_time
+ date_planned_end = date_planned_start + duration_expected
+ return date_planned_start, date_planned_end,last_time
\ No newline at end of file
diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py
index 9cce1d62..210a27d0 100644
--- a/sf_manufacturing/models/product_template.py
+++ b/sf_manufacturing/models/product_template.py
@@ -852,9 +852,11 @@ class ResProductMo(models.Model):
attachment = self.attachment_create(item['model_name'], item['model_data'])
# 获取坯料冗余配置
if not item.get('embryo_redundancy'):
- embryo_redundancy_id = self.env['sf.embryo.redundancy'].search([('name', '=', '粗坯料')], limit=1)
+ embryo_redundancy_id = model_type.embryo_tolerance_id
else:
embryo_redundancy_id = item.get('embryo_redundancy')
+ if not embryo_redundancy_id:
+ raise UserError('请先配置模型类型内的坯料冗余')
vals = {
'name': '%s-%s-%s' % ('P', order_id.name, i),
'model_long': item['model_long'] + embryo_redundancy_id.long,
@@ -938,11 +940,6 @@ class ResProductMo(models.Model):
# surface_technology = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')])
# if surface_technology:
# no_bom_copy_product_id.route_ids |= surface_technology
- # 获取坯料冗余配置
- if not item.get('embryo_redundancy_id'):
- embryo_redundancy_id = self.env['sf.embryo.redundancy'].search([('name', '=', '粗坯料')], limit=1)
- else:
- embryo_redundancy_id = item.get('embryo_redundancy_id')
no_bom_copy_product_id.product_tmpl_id.active = True
logging.info('no_bom_copy_product_id[is_manual_processing]:%s' % no_bom_copy_product_id.is_manual_processing)
materials_id = self.env['sf.production.materials'].search(
@@ -951,6 +948,13 @@ class ResProductMo(models.Model):
[('materials_no', '=', item['texture_type_code'])])
model_type = self.env['sf.model.type'].search([], limit=1)
supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
+ # 获取坯料冗余配置
+ if not item.get('embryo_redundancy_id'):
+ embryo_redundancy_id = model_type.embryo_tolerance_id
+ else:
+ embryo_redundancy_id = item.get('embryo_redundancy_id')
+ if not embryo_redundancy_id:
+ raise UserError('请先配置模型类型内的坯料冗余')
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
vals = {
'name': '%s-%s-%s [%s %s-%s * %s * %s]' % ('R',
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index d2d3ab84..801806ad 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -309,18 +309,21 @@ class StockRule(models.Model):
production_item.write({'programming_no': production_programming.programming_no,
'programming_state': '编程中'})
if not technology_design_values:
+ i = 0
if production_item.product_id.categ_id.type == '成品':
# 根据加工面板的面数及成品工序模板生成工序设计
- i = 0
+
for k in (production_item.product_id.model_processing_panel.split(',')):
if production_item.production_type == '自动化产线加工':
- model = 'sf.product.model.type.routing.sort'
+ product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search(
+ [('product_model_type_id', '=', production_item.product_id.product_model_type_id.id)],
+ order='sequence asc'
+ )
else:
- model = 'sf.manual.product.model.type.routing.sort'
- product_routing_workcenter = self.env[model].search(
- [('product_model_type_id', '=', production_item.product_id.product_model_type_id.id)],
- order='sequence asc'
- )
+ product_routing_workcenter = self.env['sf.manual.product.model.type.routing.sort'].search(
+ [('manual_product_model_type_id', '=', production_item.product_id.product_model_type_id.id)],
+ order='sequence asc'
+ )
for route in product_routing_workcenter:
i += 1
technology_design_values.append(
@@ -935,6 +938,11 @@ class ReStockMove(models.Model):
move_lines_commands.append((0, 0, move_line_cmd))
qty_by_location[loc.id] += 1
return move_lines_commands
+
+ # def _prepare_procurement_origin(self):
+ # """修改采购来源"""
+ # self.ensure_one()
+ # return self.group_id and self.group_id.name or (self.origin or self.picking_id.name or "/")
class ReStockQuant(models.Model):
diff --git a/sf_manufacturing/views/model_type_view.xml b/sf_manufacturing/views/model_type_view.xml
index 56d5f94c..f0ffd81a 100644
--- a/sf_manufacturing/views/model_type_view.xml
+++ b/sf_manufacturing/views/model_type_view.xml
@@ -31,7 +31,7 @@