diff --git a/sf_demand_plan/models/sf_production_demand_plan.py b/sf_demand_plan/models/sf_production_demand_plan.py
index 12214bff..49cbe926 100644
--- a/sf_demand_plan/models/sf_production_demand_plan.py
+++ b/sf_demand_plan/models/sf_production_demand_plan.py
@@ -196,11 +196,14 @@ class SfProductionDemandPlan(models.Model):
else:
line.model_long = None
- @api.depends('product_id.model_long', 'product_id.model_width', 'product_id.model_height')
+ @api.depends('product_id.model_long', 'product_id.model_width', 'product_id.model_height', 'product_id.blank_type')
def _compute_embryo_long(self):
for line in self:
if line.product_id:
- line.embryo_long = f"{round(line.product_id.model_long, 3)}*{round(line.product_id.model_width, 3)}*{round(line.product_id.model_height, 3)}"
+ if line.product_id.blank_type == '圆料':
+ line.embryo_long = f"Ø{round(line.product_id.model_width, 3)}*{round(line.product_id.model_long, 3)}"
+ else:
+ line.embryo_long = f"{round(line.product_id.model_long, 3)}*{round(line.product_id.model_width, 3)}*{round(line.product_id.model_height, 3)}"
else:
line.embryo_long = None
@@ -403,29 +406,30 @@ class SfProductionDemandPlan(models.Model):
outsourcing_purchase_request.extend(pr_ids.ids)
if record.supply_method == 'outsourcing' and not record.sale_order_line_id.is_incoming_material:
bom_line_ids = record.product_id.bom_ids.bom_line_ids
- # BOM_数量
- total_product_qty = sum(line.product_qty for line in bom_line_ids)
- bom_product_ids = bom_line_ids.mapped('product_id')
- product_purchase_orders = self.env['purchase.order'].sudo().search([
- ('state', 'in', ('purchase', 'done')),
- ('order_line.product_id', 'in', bom_product_ids.ids)
- ])
- # 购订单_数量
- total_outsourcing_purchase_quantity = sum(
- sum(
- order.order_line.filtered(
- lambda line: line.product_id in bom_product_ids
- ).mapped('product_qty')
+ if bom_line_ids:
+ # BOM_数量
+ total_product_qty = sum(line.product_qty for line in bom_line_ids)
+ bom_product_ids = bom_line_ids.mapped('product_id')
+ product_purchase_orders = self.env['purchase.order'].sudo().search([
+ ('state', 'in', ('purchase', 'done')),
+ ('order_line.product_id', 'in', bom_product_ids.ids)
+ ])
+ # 购订单_数量
+ total_outsourcing_purchase_quantity = sum(
+ sum(
+ order.order_line.filtered(
+ lambda line: line.product_id in bom_product_ids
+ ).mapped('product_qty')
+ )
+ for order in product_purchase_orders
)
- for order in product_purchase_orders
- )
- quantity = total_outsourcing_purchase_quantity / total_product_qty
- if float_compare(quantity, record.product_uom_qty,
- precision_rounding=record.product_id.uom_id.rounding) == -1:
- purchase_request = self.env['purchase.request'].sudo().search(
- [('line_ids.product_id', 'in', bom_product_ids.ids),
- ('line_ids.purchase_state', 'not in', ('purchase', 'done')), ('state', '!=', 'done')])
- outsourcing_purchase_request.extend(purchase_request.ids)
+ quantity = total_outsourcing_purchase_quantity / total_product_qty
+ if float_compare(quantity, record.product_uom_qty,
+ precision_rounding=record.product_id.uom_id.rounding) == -1:
+ purchase_request = self.env['purchase.request'].sudo().search(
+ [('line_ids.product_id', 'in', bom_product_ids.ids),
+ ('line_ids.purchase_state', 'not in', ('purchase', 'done')), ('state', '!=', 'done')])
+ outsourcing_purchase_request.extend(purchase_request.ids)
record.outsourcing_purchase_request = json.dumps(outsourcing_purchase_request)
if outsourcing_purchase_request:
record.hide_action_purchase_orders = True
diff --git a/sf_demand_plan/views/demand_plan.xml b/sf_demand_plan/views/demand_plan.xml
index 24a2707e..5b9c425a 100644
--- a/sf_demand_plan/views/demand_plan.xml
+++ b/sf_demand_plan/views/demand_plan.xml
@@ -28,7 +28,7 @@
-
+
diff --git a/sf_machine_connect/controllers/controllers.py b/sf_machine_connect/controllers/controllers.py
index 4974127e..de4a8a33 100644
--- a/sf_machine_connect/controllers/controllers.py
+++ b/sf_machine_connect/controllers/controllers.py
@@ -601,8 +601,11 @@ class Sf_Dashboard_Connect(http.Controller):
line_list = ast.literal_eval(kw['line_list'])
begin_time_str = kw['begin_time'].strip('"')
end_time_str = kw['end_time'].strip('"')
- begin_time = datetime.strptime(begin_time_str, '%Y-%m-%d %H:%M:%S')
- end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
+ # 将时间减去8小时(UTC+8转UTC)
+ begin_time = (datetime.strptime(begin_time_str, '%Y-%m-%d %H:%M:%S') - timedelta(hours=8))
+ end_time = (datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S') - timedelta(hours=8))
+ # begin_time = datetime.strptime(begin_time_str, '%Y-%m-%d %H:%M:%S')
+ # end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
# print('line_list: %s' % line_list)
print('kw', kw)
time_unit = kw.get('time_unit', 'day').strip('"') # 默认单位为天
@@ -636,6 +639,15 @@ class Sf_Dashboard_Connect(http.Controller):
if time_unit == 'hour':
+
+ # 计划量,目前只能从mail.message中筛选出
+ plan_order_messages = request.env['mail.message'].sudo().search([
+ ('model', '=', 'mrp.workorder'),
+ ('create_date', '>=', begin_time.strftime('%Y-%m-%d %H:%M:%S')),
+ ('create_date', '<=', end_time.strftime('%Y-%m-%d %H:%M:%S')),
+ ('tracking_value_ids.field_desc', '=', '状态'),
+ ('tracking_value_ids.new_value_char', '=', '就绪')
+ ])
for line in line_list:
date_field_name = 'date_finished' # 替换为你模型中的实际字段名
@@ -678,19 +690,10 @@ class Sf_Dashboard_Connect(http.Controller):
)
# 使用小时和分钟作为键,确保每个小时的数据有独立的键
- key = start_time.strftime('%H:%M:%S') # 只取小时:分钟:秒作为键
+ key = (start_time + timedelta(hours=8)).strftime('%H:%M:%S') # 只取小时:分钟:秒作为键
# time_count_dict[key] = len(orders)
time_count_dict[key] = sum(interval_orders.mapped('qty_produced'))
- # 计划量,目前只能从mail.message中筛选出
- plan_order_messages = request.env['mail.message'].sudo().search([
- ('model', '=', 'mrp.workorder'),
- ('create_date', '>=', begin_time.strftime('%Y-%m-%d %H:%M:%S')),
- ('create_date', '<=', end_time.strftime('%Y-%m-%d %H:%M:%S')),
- ('tracking_value_ids.field_desc', '=', '状态'),
- ('tracking_value_ids.new_value_char', '=', '就绪')
- ])
-
for time_interval in time_intervals:
start_time, end_time = time_interval
@@ -715,7 +718,7 @@ class Sf_Dashboard_Connect(http.Controller):
interval_orders = interval_orders.filtered(lambda o: o.routing_type == 'CNC加工' and o.production_line_id.name == line)
# 使用小时和分钟作为键,确保每个小时的数据有独立的键
- key = start_time.strftime('%H:%M:%S') # 只取小时:分钟:秒作为键
+ key = (start_time + timedelta(hours=8)).strftime('%H:%M:%S') # 只取小时:分钟:秒作为键
# time_count_dict[key] = len(orders)
plan_count_dict[key] = sum(interval_orders.mapped('qty_production'))
@@ -859,6 +862,8 @@ class Sf_Dashboard_Connect(http.Controller):
"""
# res = {'status': 1, 'message': '成功', 'not_done_data': [], 'done_data': []}
res = {'status': 1, 'message': '成功', 'data': {}}
+ # 解决产品名称取到英文的问题
+ request.update_context(lang='zh_CN')
plan_obj = request.env['sf.production.plan'].sudo()
work_order_obj = request.env['mrp.workorder'].sudo()
line_list = ast.literal_eval(kw['line_list'])
@@ -867,13 +872,25 @@ class Sf_Dashboard_Connect(http.Controller):
begin_time = datetime.strptime(begin_time_str, '%Y-%m-%d %H:%M:%S')
end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
# print('line_list: %s' % line_list)
- not_done_data = []
- done_data = []
final_data = {}
- not_done_index = 1
- done_index = 1
+
+ # 获取当前时间,并计算24小时前的时间
+ current_time = datetime.now()
+ time_48_hours_ago = current_time - timedelta(hours=48)
+
+ # 计划量,目前只能从mail.message中筛选出
+ plan_order_messages = request.env['mail.message'].sudo().search([
+ ('model', '=', 'mrp.workorder'),
+ ('create_date', '>=', time_48_hours_ago.strftime('%Y-%m-%d %H:%M:%S')),
+ ('tracking_value_ids.field_desc', '=', '状态'),
+ ('tracking_value_ids.new_value_char', 'in', ['就绪', '生产中'])
+ ])
for line in line_list:
+ not_done_data = []
+ done_data = []
+ not_done_index = 1
+ done_index = 1
if line == '业绩总览':
work_order_domain = [('routing_type', 'in', ['人工线下加工', 'CNC加工'])]
@@ -889,21 +906,29 @@ class Sf_Dashboard_Connect(http.Controller):
# [('production_line_id.name', '=', line), ('state', 'not in', ['finished']),
# ('production_id.state', 'not in', ['cancel', 'done']), ('active', '=', True)
# ])
- not_done_orders = work_order_obj.search(work_order_domain +
- [('state', 'in', ['ready', 'progress'])], order='id asc'
- )
+ # not_done_orders = work_order_obj.search(work_order_domain +
+ # [('state', 'in', ['ready', 'progress'])], order='id asc'
+ # )
+ not_done_orders = request.env['mrp.workorder'].sudo().browse(plan_order_messages.mapped('res_id'))
+ if line == '业绩总览':
+ not_done_orders = not_done_orders.filtered(lambda o: o.routing_type in ['人工线下加工', 'CNC加工'])
+ elif line == '人工线下加工中心':
+ not_done_orders = not_done_orders.filtered(lambda o: o.routing_type == '人工线下加工')
+ else:
+ not_done_orders = not_done_orders.filtered(lambda o: o.routing_type == 'CNC加工' and o.production_line_id.name == line)
+
# 完成订单
# 获取当前时间,并计算24小时前的时间
- current_time = datetime.now()
- time_24_hours_ago = current_time - timedelta(hours=24)
+ # current_time = datetime.now()
+ # time_24_hours_ago = current_time - timedelta(hours=24)
finish_orders = work_order_obj.search(work_order_domain + [
- ('state', 'in', ['finished']),
+ ('state', 'in', ['done']),
('production_id.state', 'not in', ['cancel']),
- ('date_finished', '>=', time_24_hours_ago)
+ ('date_finished', '>=', time_48_hours_ago)
], order='id asc')
- # print(finish_orders)
+ # logging.info('完成订单: %s' % finish_orders)
# 获取所有未完成订单的ID列表
order_ids = [order.id for order in not_done_orders]
@@ -962,8 +987,6 @@ class Sf_Dashboard_Connect(http.Controller):
not_done_index += 1
for finish_order in finish_orders:
- if not finish_order.actual_end_time:
- continue
blank_name = ''
try:
blank_name = finish_order.production_id.move_raw_ids[0].product_id.name
@@ -984,8 +1007,8 @@ class Sf_Dashboard_Connect(http.Controller):
'material': material,
'dimensions': dimensions,
'order_qty': order.qty_produced,
- 'finish_time': finish_order.actual_end_time.strftime(
- '%Y-%m-%d %H:%M:%S') if finish_order.actual_end_time else ' '
+ 'finish_time': finish_order.date_finished.strftime(
+ '%Y-%m-%d %H:%M:%S') if finish_order.date_finished else ' '
}
done_data.append(line_dict)
diff --git a/sf_manufacturing/models/__init__.py b/sf_manufacturing/models/__init__.py
index 8af783e7..c8af2d82 100644
--- a/sf_manufacturing/models/__init__.py
+++ b/sf_manufacturing/models/__init__.py
@@ -18,4 +18,5 @@ from . import quick_easy_order
from . import purchase_order
from . import quality_check
from . import purchase_request_line
+from . import bom
# from . import stock_warehouse_orderpoint
\ No newline at end of file
diff --git a/sf_manufacturing/models/bom.py b/sf_manufacturing/models/bom.py
new file mode 100644
index 00000000..d0a35300
--- /dev/null
+++ b/sf_manufacturing/models/bom.py
@@ -0,0 +1,16 @@
+from odoo import models
+from odoo.osv.expression import AND
+
+
+class MrpBom(models.Model):
+ _inherit = 'mrp.bom'
+
+ def _bom_subcontract_find(self, product, picking_type=None, company_id=False, bom_type='subcontract', subcontractor=False):
+ domain = self._bom_find_domain(product, picking_type=picking_type, company_id=company_id, bom_type=bom_type)
+ if self.env.context.get('stock_picking') == 'outsourcing':
+ return self.search(domain, order='sequence, product_id, id', limit=1)
+ if subcontractor:
+ domain = AND([domain, [('subcontractor_ids', 'parent_of', subcontractor.ids)]])
+ return self.search(domain, order='sequence, product_id, id', limit=1)
+ else:
+ return self.env['mrp.bom']
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index 7dbe1706..4e8dc438 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -1205,6 +1205,20 @@ class ReStockMove(models.Model):
res['lot_id'] = self.subcontract_workorder_id.production_id.move_raw_ids.move_line_ids[0].lot_id.id
return res
+ def _get_subcontract_bom(self):
+ self.ensure_one()
+ purchase_type = getattr(self.picking_id.purchase_id, 'purchase_type', False)
+ if purchase_type:
+ self = self.with_context(stock_picking=purchase_type)
+ bom = self.env['mrp.bom'].sudo()._bom_subcontract_find(
+ self.product_id,
+ picking_type=self.picking_type_id,
+ company_id=self.company_id.id,
+ bom_type='subcontract',
+ subcontractor=self.picking_id.partner_id
+ )
+ return bom
+
class ReStockQuant(models.Model):
_inherit = 'stock.quant'