Merge branch 'refs/heads/develop' into feature/tax_sync
This commit is contained in:
@@ -84,6 +84,7 @@ class MrsProductionProcessCategory(models.Model):
|
|||||||
class MrsProductionProcess(models.Model):
|
class MrsProductionProcess(models.Model):
|
||||||
_name = 'sf.production.process'
|
_name = 'sf.production.process'
|
||||||
_description = '表面工艺'
|
_description = '表面工艺'
|
||||||
|
order = 'sequence asc'
|
||||||
|
|
||||||
code = fields.Char("编码")
|
code = fields.Char("编码")
|
||||||
name = fields.Char('名称')
|
name = fields.Char('名称')
|
||||||
|
|||||||
@@ -19,7 +19,12 @@ class IrSequence(models.Model):
|
|||||||
# date mode
|
# date mode
|
||||||
dt = sequence_date or self._context.get('ir_sequence_date', fields.Date.today())
|
dt = sequence_date or self._context.get('ir_sequence_date', fields.Date.today())
|
||||||
seq_date = self.env['ir.sequence.date_range'].search(
|
seq_date = self.env['ir.sequence.date_range'].search(
|
||||||
[('sequence_id', '=', self.id), ('date_from', '<=', dt), ('date_to', '>=', dt)], limit=1)
|
[
|
||||||
|
('sequence_id', '=', self.id),
|
||||||
|
('date_from', '<=', dt),
|
||||||
|
('date_to', '>=', dt),
|
||||||
|
('date_range_period', '=', self.date_range_period)
|
||||||
|
], limit=1)
|
||||||
if not seq_date:
|
if not seq_date:
|
||||||
if self.date_range_period:
|
if self.date_range_period:
|
||||||
seq_date = self._create_date_range_seq_by_period(dt, self.date_range_period)
|
seq_date = self._create_date_range_seq_by_period(dt, self.date_range_period)
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
<field name="model">sf.production.process</field>
|
<field name="model">sf.production.process</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="表面工艺" create="0" edit="0" delete="0">
|
<tree string="表面工艺" create="0" edit="0" delete="0">
|
||||||
<field name="sequence" widget="handle" string="序号" readonly="1"/>
|
<field name="sequence" string="加工顺序" readonly="1"/>
|
||||||
<field name="code"/>
|
<field name="code"/>
|
||||||
<field name="name" string="名称"/>
|
<field name="name" string="名称"/>
|
||||||
<field name="remark"/>
|
<field name="remark"/>
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ class StatusChange(models.Model):
|
|||||||
logging.info('函数已经执行=============')
|
logging.info('函数已经执行=============')
|
||||||
server_product_none = []
|
server_product_none = []
|
||||||
for order in self.order_line:
|
for order in self.order_line:
|
||||||
|
gain_way_no = order.product_template_id.model_process_parameters_ids.filtered(lambda a: not a.gain_way)
|
||||||
|
if gain_way_no:
|
||||||
|
process_parameters = [item.name for item in gain_way_no]
|
||||||
|
raise UserError(
|
||||||
|
_("请先至【制造】-【配置】中【表面工艺可选参数】为【%s】填写获取方式", ", ".join(process_parameters)))
|
||||||
for item in order.product_template_id.model_process_parameters_ids:
|
for item in order.product_template_id.model_process_parameters_ids:
|
||||||
if item.gain_way == '外协':
|
if item.gain_way == '外协':
|
||||||
server_product = self.env['product.template'].search(
|
server_product = self.env['product.template'].search(
|
||||||
@@ -25,7 +30,7 @@ class StatusChange(models.Model):
|
|||||||
if not server_product:
|
if not server_product:
|
||||||
server_product_none.append(item.name)
|
server_product_none.append(item.name)
|
||||||
if server_product_none:
|
if server_product_none:
|
||||||
raise UserError(_("请先至【产品】中创建【表面工艺参数】为%s的服务产品", ", ".join(server_product_none)))
|
raise UserError(_("请先至【产品】中创建【表面工艺参数】为【%s】的服务产品", ", ".join(server_product_none)))
|
||||||
|
|
||||||
# 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法)
|
# 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ class Sf_Dashboard_Connect(http.Controller):
|
|||||||
SELECT time, device_state, program_name
|
SELECT time, device_state, program_name
|
||||||
FROM device_data
|
FROM device_data
|
||||||
WHERE device_name = %s AND time >= %s AND time <= %s
|
WHERE device_name = %s AND time >= %s AND time <= %s
|
||||||
ORDER BY time ASC;
|
ORDER BY time DESC;
|
||||||
'''
|
'''
|
||||||
# 执行SQL命令,使用参数绑定
|
# 执行SQL命令,使用参数绑定
|
||||||
cur.execute(sql, (item, begin_time, end_time))
|
cur.execute(sql, (item, begin_time, end_time))
|
||||||
@@ -308,7 +308,7 @@ class Sf_Dashboard_Connect(http.Controller):
|
|||||||
plan_data_total_counts = plan_obj.search_count([('production_line_id.name', '=', line)])
|
plan_data_total_counts = plan_obj.search_count([('production_line_id.name', '=', line)])
|
||||||
# 工单完成量
|
# 工单完成量
|
||||||
plan_data_finish_counts = plan_obj.search_count(
|
plan_data_finish_counts = plan_obj.search_count(
|
||||||
[('production_line_id.name', '=', line), ('state', 'not in', ['draft'])])
|
[('production_line_id.name', '=', line), ('state', 'in', ['finished'])])
|
||||||
# 工单计划量
|
# 工单计划量
|
||||||
plan_data_plan_counts = plan_obj.search_count(
|
plan_data_plan_counts = plan_obj.search_count(
|
||||||
[('production_line_id.name', '=', line), ('state', 'not in', ['finished'])])
|
[('production_line_id.name', '=', line), ('state', 'not in', ['finished'])])
|
||||||
@@ -349,67 +349,66 @@ class Sf_Dashboard_Connect(http.Controller):
|
|||||||
return json.dumps(res)
|
return json.dumps(res)
|
||||||
|
|
||||||
# 日完成量统计
|
# 日完成量统计
|
||||||
class DailyFinishCount(http.Controller):
|
@http.route('/api/DailyFinishCount', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
||||||
@http.route('/api/DailyFinishCount', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
def DailyFinishCount(self, **kw):
|
||||||
def DailyFinishCount(self, **kw):
|
"""
|
||||||
"""
|
获取日完成量统计
|
||||||
获取日完成量统计
|
:param kw:
|
||||||
:param kw:
|
:return:
|
||||||
:return:
|
"""
|
||||||
"""
|
res = {'status': 1, 'message': '成功', 'data': {}}
|
||||||
res = {'status': 1, 'message': '成功', 'data': {}}
|
plan_obj = request.env['sf.production.plan'].sudo()
|
||||||
plan_obj = request.env['sf.production.plan'].sudo()
|
line_list = ast.literal_eval(kw['line_list'])
|
||||||
line_list = ast.literal_eval(kw['line_list'])
|
begin_time_str = kw['begin_time'].strip('"')
|
||||||
begin_time_str = kw['begin_time'].strip('"')
|
end_time_str = kw['end_time'].strip('"')
|
||||||
end_time_str = kw['end_time'].strip('"')
|
begin_time = datetime.strptime(begin_time_str, '%Y-%m-%d %H:%M:%S')
|
||||||
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')
|
||||||
end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
|
print('line_list: %s' % line_list)
|
||||||
print('line_list: %s' % line_list)
|
|
||||||
|
|
||||||
def get_date_list(start_date, end_date):
|
def get_date_list(start_date, end_date):
|
||||||
date_list = []
|
date_list = []
|
||||||
current_date = start_date
|
current_date = start_date
|
||||||
while current_date <= end_date:
|
while current_date <= end_date:
|
||||||
date_list.append(current_date)
|
date_list.append(current_date)
|
||||||
current_date += timedelta(days=1)
|
current_date += timedelta(days=1)
|
||||||
return date_list
|
return date_list
|
||||||
|
|
||||||
for line in line_list:
|
for line in line_list:
|
||||||
date_list = get_date_list(begin_time, end_time)
|
date_list = get_date_list(begin_time, end_time)
|
||||||
order_counts = []
|
order_counts = []
|
||||||
|
|
||||||
date_field_name = 'actual_end_time' # 替换为你模型中的实际字段名
|
date_field_name = 'actual_end_time' # 替换为你模型中的实际字段名
|
||||||
|
|
||||||
for date in date_list:
|
for date in date_list:
|
||||||
next_day = date + timedelta(days=1)
|
next_day = date + timedelta(days=1)
|
||||||
orders = plan_obj.search([('production_line_id.name', '=', line), ('state', 'not in', ['draft']),
|
orders = plan_obj.search([('production_line_id.name', '=', line), ('state', 'in', ['finished']),
|
||||||
(date_field_name, '>=', date.strftime('%Y-%m-%d 00:00:00')),
|
(date_field_name, '>=', date.strftime('%Y-%m-%d 00:00:00')),
|
||||||
(date_field_name, '<', next_day.strftime('%Y-%m-%d 00:00:00'))
|
(date_field_name, '<', next_day.strftime('%Y-%m-%d 00:00:00'))
|
||||||
])
|
])
|
||||||
|
|
||||||
rework_orders = plan_obj.search(
|
rework_orders = plan_obj.search(
|
||||||
[('production_line_id.name', '=', line), ('state', 'in', ['rework']),
|
[('production_line_id.name', '=', line), ('production_id.state', 'in', ['rework']),
|
||||||
(date_field_name, '>=', date.strftime('%Y-%m-%d 00:00:00')),
|
(date_field_name, '>=', date.strftime('%Y-%m-%d 00:00:00')),
|
||||||
(date_field_name, '<', next_day.strftime('%Y-%m-%d 00:00:00'))
|
(date_field_name, '<', next_day.strftime('%Y-%m-%d 00:00:00'))
|
||||||
])
|
])
|
||||||
not_passed_orders = plan_obj.search(
|
not_passed_orders = plan_obj.search(
|
||||||
[('production_line_id.name', '=', line), ('state', 'in', ['scrap', 'cancel']),
|
[('production_line_id.name', '=', line), ('production_id.state', 'in', ['scrap', 'cancel']),
|
||||||
(date_field_name, '>=', date.strftime('%Y-%m-%d 00:00:00')),
|
(date_field_name, '>=', date.strftime('%Y-%m-%d 00:00:00')),
|
||||||
(date_field_name, '<', next_day.strftime('%Y-%m-%d 00:00:00'))
|
(date_field_name, '<', next_day.strftime('%Y-%m-%d 00:00:00'))
|
||||||
])
|
])
|
||||||
order_counts.append({
|
order_counts.append({
|
||||||
'date': date.strftime('%Y-%m-%d'),
|
'date': date.strftime('%Y-%m-%d'),
|
||||||
'order_count': len(orders),
|
'order_count': len(orders),
|
||||||
'rework_orders': len(rework_orders),
|
'rework_orders': len(rework_orders),
|
||||||
'not_passed_orders': len(not_passed_orders)
|
'not_passed_orders': len(not_passed_orders)
|
||||||
})
|
})
|
||||||
# 外面包一层,没什么是包一层不能解决的,包一层就能区分了,类似于包一层div
|
# 外面包一层,没什么是包一层不能解决的,包一层就能区分了,类似于包一层div
|
||||||
# 外面包一层的好处是,可以把多个数据结构打包在一起,方便前端处理
|
# 外面包一层的好处是,可以把多个数据结构打包在一起,方便前端处理
|
||||||
|
|
||||||
# date_list_dict = {line: order_counts}
|
# date_list_dict = {line: order_counts}
|
||||||
|
|
||||||
res['data'][line] = order_counts
|
res['data'][line] = order_counts
|
||||||
return json.dumps(res)
|
return json.dumps(res)
|
||||||
|
|
||||||
# 实时产量
|
# 实时产量
|
||||||
@http.route('/api/RealTimeProduct', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
@http.route('/api/RealTimeProduct', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
||||||
@@ -770,10 +769,11 @@ class Sf_Dashboard_Connect(http.Controller):
|
|||||||
@http.route('/api/OEEByTime', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
@http.route('/api/OEEByTime', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
||||||
def OEEByTime(self, **kw):
|
def OEEByTime(self, **kw):
|
||||||
"""
|
"""
|
||||||
获取某段时间的oee,根据用户指定的时间单位(day或hour)返回对应的平均值
|
获取某段时间的OEE,根据用户指定的时间单位(day或hour)返回对应的平均值。
|
||||||
|
如果不传time_unit,则默认按天返回,并补全没有数据的时间段,填充0值。
|
||||||
"""
|
"""
|
||||||
res = {'status': 1, 'message': '成功', 'data': {}}
|
res = {'status': 1, 'message': '成功', 'data': {}}
|
||||||
logging.info('前端请求获取某段时间的oee的参数为:%s' % kw)
|
logging.info('前端请求获取某段时间的OEE的参数为:%s' % kw)
|
||||||
|
|
||||||
# 获取并解析参数
|
# 获取并解析参数
|
||||||
workcenter_list = ast.literal_eval(kw['workcenter_list'])
|
workcenter_list = ast.literal_eval(kw['workcenter_list'])
|
||||||
@@ -790,8 +790,10 @@ class Sf_Dashboard_Connect(http.Controller):
|
|||||||
# 根据时间单位选择不同的时间格式
|
# 根据时间单位选择不同的时间格式
|
||||||
if time_unit == 'hour':
|
if time_unit == 'hour':
|
||||||
time_format = 'YYYY-MM-DD HH24:00:00'
|
time_format = 'YYYY-MM-DD HH24:00:00'
|
||||||
|
time_delta = timedelta(hours=1)
|
||||||
else: # 默认为'day'
|
else: # 默认为'day'
|
||||||
time_format = 'YYYY-MM-DD'
|
time_format = 'YYYY-MM-DD'
|
||||||
|
time_delta = timedelta(days=1)
|
||||||
|
|
||||||
# 查询并计算OEE平均值
|
# 查询并计算OEE平均值
|
||||||
oee_data = {}
|
oee_data = {}
|
||||||
@@ -806,7 +808,20 @@ class Sf_Dashboard_Connect(http.Controller):
|
|||||||
""", (workcenter, begin_time, end_time))
|
""", (workcenter, begin_time, end_time))
|
||||||
|
|
||||||
results = cur.fetchall()
|
results = cur.fetchall()
|
||||||
oee_data[workcenter] = {row[0]: row[1] for row in results}
|
# 初始化当前产线的OEE数据字典
|
||||||
|
workcenter_oee = {row[0]: row[1] for row in results}
|
||||||
|
|
||||||
|
# 补全缺失的时间段
|
||||||
|
current_time = begin_time
|
||||||
|
if time_unit != 'hour':
|
||||||
|
while current_time <= end_time:
|
||||||
|
time_key = current_time.strftime('%Y-%m-%d')
|
||||||
|
if time_key not in workcenter_oee:
|
||||||
|
workcenter_oee[time_key] = 0
|
||||||
|
current_time += time_delta
|
||||||
|
|
||||||
|
# 按时间排序
|
||||||
|
oee_data[workcenter] = dict(sorted(workcenter_oee.items()))
|
||||||
|
|
||||||
# 关闭数据库连接
|
# 关闭数据库连接
|
||||||
cur.close()
|
cur.close()
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('LocationChange error:%s' % e)
|
logging.info('LocationChange error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def AGVToProduct(self, **kw):
|
def AGVToProduct(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -549,7 +549,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('AGVToProduct error:%s' % e)
|
logging.info('AGVToProduct error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def AGVDownProduct(self, **kw):
|
def AGVDownProduct(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -668,7 +668,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('AGVDownProduct error:%s' % e)
|
logging.info('AGVDownProduct error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/AgvStationState', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/AgvStationState', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def AGVStationState(self, **kw):
|
def AGVStationState(self, **kw):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -664,7 +664,7 @@ class MrpProduction(models.Model):
|
|||||||
# 表面工艺工序
|
# 表面工艺工序
|
||||||
# 模型类型的表面工艺工序模版
|
# 模型类型的表面工艺工序模版
|
||||||
surface_tmpl_ids = model_type_id.surface_technics_routing_tmpl_ids
|
surface_tmpl_ids = model_type_id.surface_technics_routing_tmpl_ids
|
||||||
# 产品选择的表面工艺
|
# 产品选择的表面工艺参数
|
||||||
model_process_parameters_ids = rec.product_id.model_process_parameters_ids
|
model_process_parameters_ids = rec.product_id.model_process_parameters_ids
|
||||||
process_dict = {}
|
process_dict = {}
|
||||||
if model_process_parameters_ids:
|
if model_process_parameters_ids:
|
||||||
@@ -673,7 +673,7 @@ class MrpProduction(models.Model):
|
|||||||
for surface_tmpl_id in surface_tmpl_ids:
|
for surface_tmpl_id in surface_tmpl_ids:
|
||||||
if process_id == surface_tmpl_id.route_workcenter_id.surface_technics_id:
|
if process_id == surface_tmpl_id.route_workcenter_id.surface_technics_id:
|
||||||
surface_tmpl_name = surface_tmpl_id.route_workcenter_id.name
|
surface_tmpl_name = surface_tmpl_id.route_workcenter_id.name
|
||||||
process_dict.update({int(process_id.category_id.code): '%s-%s' % (
|
process_dict.update({int(process_id.sequence): '%s-%s' % (
|
||||||
surface_tmpl_name, process_parameters_id.name)})
|
surface_tmpl_name, process_parameters_id.name)})
|
||||||
process_list = sorted(process_dict.keys())
|
process_list = sorted(process_dict.keys())
|
||||||
for process_num in process_list:
|
for process_num in process_list:
|
||||||
@@ -690,14 +690,16 @@ class MrpProduction(models.Model):
|
|||||||
raise ValidationError('该产品【加工面板】为空!')
|
raise ValidationError('该产品【加工面板】为空!')
|
||||||
else:
|
else:
|
||||||
raise ValidationError('该产品没有选择【模版类型】!')
|
raise ValidationError('该产品没有选择【模版类型】!')
|
||||||
|
logging.info('sequence_list: %s' % sequence_list)
|
||||||
for work in rec.workorder_ids:
|
for work in rec.workorder_ids:
|
||||||
if sequence_list.get(work.name):
|
work_name = work.name
|
||||||
work.sequence = sequence_list[work.name]
|
logging.info(work_name)
|
||||||
|
if sequence_list.get(work_name):
|
||||||
|
work.sequence = sequence_list[work_name]
|
||||||
elif sequence_list.get(work.processing_panel):
|
elif sequence_list.get(work.processing_panel):
|
||||||
processing_panel = sequence_list.get(work.processing_panel)
|
processing_panel = sequence_list.get(work.processing_panel)
|
||||||
if processing_panel.get(work.name):
|
if processing_panel.get(work_name):
|
||||||
work.sequence = processing_panel[work.name]
|
work.sequence = processing_panel[work_name]
|
||||||
else:
|
else:
|
||||||
raise ValidationError('工序【%s】在产品选择的模版类型中不存在!' % work.name)
|
raise ValidationError('工序【%s】在产品选择的模版类型中不存在!' % work.name)
|
||||||
else:
|
else:
|
||||||
@@ -723,8 +725,9 @@ class MrpProduction(models.Model):
|
|||||||
sequence_max += 1
|
sequence_max += 1
|
||||||
panel_sequence_list.update({tmpl_id.route_workcenter_id.name: sequence_max})
|
panel_sequence_list.update({tmpl_id.route_workcenter_id.name: sequence_max})
|
||||||
for work_id in work_ids:
|
for work_id in work_ids:
|
||||||
if panel_sequence_list.get(work_id.name):
|
work_name = work_id.name
|
||||||
work_id.sequence = panel_sequence_list[work_id.name]
|
if panel_sequence_list.get(work_name):
|
||||||
|
work_id.sequence = panel_sequence_list[work_name]
|
||||||
|
|
||||||
# 创建工单并进行排序
|
# 创建工单并进行排序
|
||||||
def _create_workorder(self, item):
|
def _create_workorder(self, item):
|
||||||
@@ -1031,8 +1034,8 @@ class MrpProduction(models.Model):
|
|||||||
[('origin', '=', sale_order.name), ('name', 'ilike', 'WH/OUT/')])
|
[('origin', '=', sale_order.name), ('name', 'ilike', 'WH/OUT/')])
|
||||||
move = out_picking.move_ids.filtered(lambda pd: pd.product_id == self.product_id)
|
move = out_picking.move_ids.filtered(lambda pd: pd.product_id == self.product_id)
|
||||||
move_values = {'product_description_variants': '',
|
move_values = {'product_description_variants': '',
|
||||||
'date_planned': datetime.now(),
|
'date_planned': fields.Datetime.now(),
|
||||||
'date_deadline': datetime.now(),
|
'date_deadline': fields.Datetime.now(),
|
||||||
'move_dest_ids': move,
|
'move_dest_ids': move,
|
||||||
'group_id': move.group_id,
|
'group_id': move.group_id,
|
||||||
'route_ids': [],
|
'route_ids': [],
|
||||||
@@ -1101,67 +1104,19 @@ class MrpProduction(models.Model):
|
|||||||
('is_subcontract', '=', True)])
|
('is_subcontract', '=', True)])
|
||||||
if scarp_process_parameter_workorder:
|
if scarp_process_parameter_workorder:
|
||||||
production_programming = self.env['mrp.production'].search(
|
production_programming = self.env['mrp.production'].search(
|
||||||
[('programming_no', '=', self.programming_no)], order='name asc')
|
[('programming_no', '=', self.programming_no), ('id', '!=', productions.id)], order='name asc')
|
||||||
production_list = [production.name for production in production_programming]
|
production_list = [production.name for production in production_programming]
|
||||||
purchase_orders = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
|
purchase_orders = self.env['purchase.order'].search([('origin', 'ilike', ','.join(production_list))])
|
||||||
for purchase_item in purchase_orders.order_line:
|
for purchase_item in purchase_orders.order_line:
|
||||||
for process_item in scarp_process_parameter_workorder:
|
for process_item in scarp_process_parameter_workorder:
|
||||||
if purchase_item.product_id.categ_type == '表面工艺':
|
if purchase_item.product_id.categ_type == '表面工艺':
|
||||||
if purchase_item.product_id.server_product_process_parameters_id == process_item.surface_technics_parameters_id:
|
if purchase_item.product_id.server_product_process_parameters_id == process_item.surface_technics_parameters_id:
|
||||||
print(purchase_orders.find(productions.name))
|
print(purchase_orders.origin.find(productions.name))
|
||||||
if purchase_orders.find(productions.name) == -1:
|
if purchase_orders.origin.find(productions.name) == -1:
|
||||||
purchase_orders.origin += productions.name
|
purchase_orders.origin += ',' + productions.name
|
||||||
if item['is_reprogramming'] is False:
|
if item['is_reprogramming'] is False:
|
||||||
productions._create_workorder(item)
|
productions._create_workorder(item)
|
||||||
productions.programming_state = '已编程'
|
productions.programming_state = '已编程'
|
||||||
for production_item in productions:
|
|
||||||
process_parameter_workorder = self.env['mrp.workorder'].search(
|
|
||||||
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id),
|
|
||||||
('is_subcontract', '=', True)])
|
|
||||||
if process_parameter_workorder:
|
|
||||||
is_pick = False
|
|
||||||
consecutive_workorders = []
|
|
||||||
m = 0
|
|
||||||
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id)
|
|
||||||
for i in range(len(sorted_workorders) - 1):
|
|
||||||
if m == 0:
|
|
||||||
is_pick = False
|
|
||||||
if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \
|
|
||||||
sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \
|
|
||||||
sorted_workorders[i].id == sorted_workorders[i + 1].id - 1:
|
|
||||||
if sorted_workorders[i] not in consecutive_workorders:
|
|
||||||
consecutive_workorders.append(sorted_workorders[i])
|
|
||||||
consecutive_workorders.append(sorted_workorders[i + 1])
|
|
||||||
m += 1
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
|
||||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
|
|
||||||
production_item)
|
|
||||||
if sorted_workorders[i] in consecutive_workorders:
|
|
||||||
is_pick = True
|
|
||||||
consecutive_workorders = []
|
|
||||||
m = 0
|
|
||||||
# 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单
|
|
||||||
if is_pick is False:
|
|
||||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
|
|
||||||
production_item)
|
|
||||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
|
||||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
|
|
||||||
production_item)
|
|
||||||
if sorted_workorders[i] in consecutive_workorders:
|
|
||||||
is_pick = True
|
|
||||||
consecutive_workorders = []
|
|
||||||
m = 0
|
|
||||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
|
||||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
|
|
||||||
production_item)
|
|
||||||
if is_pick is False and m == 0:
|
|
||||||
if len(sorted_workorders) == 1:
|
|
||||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item)
|
|
||||||
else:
|
|
||||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
|
|
||||||
production_item)
|
|
||||||
else:
|
else:
|
||||||
productions.programming_state = '编程中'
|
productions.programming_state = '编程中'
|
||||||
return productions
|
return productions
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
('cancel', '取消')], string='Status',
|
('cancel', '取消')], string='Status',
|
||||||
compute='_compute_state', store=True,
|
compute='_compute_state', store=True,
|
||||||
default='pending', copy=False, readonly=True, recursive=True, index=True, tracking=True)
|
default='pending', copy=False, readonly=True, recursive=True, index=True, tracking=True)
|
||||||
|
|
||||||
# state = fields.Selection(selection_add=[('to be detected', "待检测"), ('rework', '返工')], tracking=True)
|
# state = fields.Selection(selection_add=[('to be detected', "待检测"), ('rework', '返工')], tracking=True)
|
||||||
|
|
||||||
@api.depends('production_id.manual_quotation')
|
@api.depends('production_id.manual_quotation')
|
||||||
@@ -183,17 +184,12 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
if order.routing_type == '表面工艺':
|
if order.routing_type == '表面工艺':
|
||||||
production_programming = self.env['mrp.production'].search(
|
production_programming = self.env['mrp.production'].search(
|
||||||
[('programming_no', '=', order.production_id.programming_no)], order='name asc')
|
[('programming_no', '=', order.production_id.programming_no)], order='name asc')
|
||||||
|
production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False)
|
||||||
production_list = [production.name for production in production_programming]
|
production_list = [production.name for production in production_programming]
|
||||||
purchase = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
|
purchase = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
|
||||||
for line in purchase.order_line:
|
for line in purchase.order_line:
|
||||||
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id and line.product_qty == len(
|
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id and line.product_qty == len(
|
||||||
production_programming):
|
production_no_remanufacture):
|
||||||
# server_product = self.env['product.template'].search(
|
|
||||||
# [('server_product_process_parameters_id', '=', pp.id),
|
|
||||||
# ('detailed_type', '=', 'service')])
|
|
||||||
# purchase_order_line = self.env['purchase.order.line'].search(
|
|
||||||
# [('product_id', '=', server_product.id), ('product_qty', '=', len(production_programming))])
|
|
||||||
# if purchase_order_line:
|
|
||||||
order.surface_technics_purchase_count = len(purchase)
|
order.surface_technics_purchase_count = len(purchase)
|
||||||
else:
|
else:
|
||||||
order.surface_technics_purchase_count = 0
|
order.surface_technics_purchase_count = 0
|
||||||
@@ -243,6 +239,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
store=True, compute='_compute_tool_state')
|
store=True, compute='_compute_tool_state')
|
||||||
tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True)
|
tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True)
|
||||||
reserved_duration = fields.Float('预留时长', default=30, tracking=True)
|
reserved_duration = fields.Float('预留时长', default=30, tracking=True)
|
||||||
|
|
||||||
@api.depends('cnc_ids.tool_state')
|
@api.depends('cnc_ids.tool_state')
|
||||||
def _compute_tool_state_remark(self):
|
def _compute_tool_state_remark(self):
|
||||||
for item in self:
|
for item in self:
|
||||||
@@ -651,7 +648,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
# 拼接工单对象属性值
|
# 拼接工单对象属性值
|
||||||
def json_workorder_str(self, k, production, route, item):
|
def json_workorder_str(self, k, production, route, item):
|
||||||
# 计算预计时长duration_expected
|
# 计算预计时长duration_expected
|
||||||
routing_types = ['切割', '装夹预调', 'CNC加工','解除装夹']
|
routing_types = ['切割', '装夹预调', 'CNC加工', '解除装夹']
|
||||||
if route.routing_type in routing_types:
|
if route.routing_type in routing_types:
|
||||||
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
|
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
|
||||||
[('name', '=', route.routing_type)])
|
[('name', '=', route.routing_type)])
|
||||||
@@ -704,7 +701,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
item),
|
item),
|
||||||
# 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list(
|
# 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list(
|
||||||
# production)
|
# production)
|
||||||
'reserved_duration': reserved_duration,
|
'reserved_duration': reserved_duration,
|
||||||
}]
|
}]
|
||||||
return workorders_values_str
|
return workorders_values_str
|
||||||
|
|
||||||
@@ -969,12 +966,14 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
else:
|
else:
|
||||||
production_programming = self.env['mrp.production'].search(
|
production_programming = self.env['mrp.production'].search(
|
||||||
[('programming_no', '=', self.production_id.programming_no)], order='name asc')
|
[('programming_no', '=', self.production_id.programming_no)], order='name asc')
|
||||||
|
production_no_remanufacture = production_programming.filtered(
|
||||||
|
lambda a: a.is_remanufacture is False)
|
||||||
production_list = [production.name for production in production_programming]
|
production_list = [production.name for production in production_programming]
|
||||||
purchase_orders = self.env['purchase.order'].search(
|
purchase_orders = self.env['purchase.order'].search(
|
||||||
[('origin', '=', ','.join(production_list))])
|
[('origin', 'ilike', ','.join(production_list))])
|
||||||
for line in purchase_orders.order_line:
|
for line in purchase_orders.order_line:
|
||||||
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len(
|
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len(
|
||||||
production_programming):
|
production_no_remanufacture):
|
||||||
if purchase_orders.state == 'purchase':
|
if purchase_orders.state == 'purchase':
|
||||||
workorder.state = 'ready'
|
workorder.state = 'ready'
|
||||||
else:
|
else:
|
||||||
@@ -1169,8 +1168,9 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
if record.routing_type == '装夹预调':
|
if record.routing_type == '装夹预调':
|
||||||
if not record.rfid_code and record.is_rework is False:
|
if not record.rfid_code and record.is_rework is False:
|
||||||
raise UserError("请扫RFID码进行绑定")
|
raise UserError("请扫RFID码进行绑定")
|
||||||
if not record.material_center_point or record.X_deviation_angle <= 0:
|
if record.is_rework is False:
|
||||||
raise UserError("请对前置三元检测定位参数进行计算定位")
|
if not record.material_center_point and record.X_deviation_angle > 0:
|
||||||
|
raise UserError("坯料中心点为空或X偏差角度小于等于0")
|
||||||
record.process_state = '待加工'
|
record.process_state = '待加工'
|
||||||
# record.write({'process_state': '待加工'})
|
# record.write({'process_state': '待加工'})
|
||||||
record.production_id.process_state = '待加工'
|
record.production_id.process_state = '待加工'
|
||||||
|
|||||||
@@ -288,28 +288,46 @@ class StockRule(models.Model):
|
|||||||
# 为同一个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(
|
||||||
|
[('product_id.id', '=', production_item.product_id.id),
|
||||||
|
('origin', '=', production_item.origin)],
|
||||||
|
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 not production_programming.programming_no:
|
||||||
is_purchase = False
|
if production_item.product_id.model_process_parameters_ids:
|
||||||
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids,
|
is_purchase = False
|
||||||
key=lambda w: w.id)
|
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids,
|
||||||
|
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:
|
||||||
|
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
|
if sorted_process_parameters[i] in consecutive_process_parameters:
|
||||||
|
is_purchase = True
|
||||||
|
consecutive_process_parameters = []
|
||||||
|
m = 0
|
||||||
|
# 当前面的连续外协采购单生成再生成当前外协采购单
|
||||||
|
if is_purchase is False:
|
||||||
|
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
||||||
|
production_item,
|
||||||
|
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,
|
||||||
@@ -318,39 +336,22 @@ class StockRule(models.Model):
|
|||||||
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 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,
|
|
||||||
product_id_to_production_names)
|
|
||||||
if m == len(consecutive_process_parameters) - 1 and m != 0:
|
|
||||||
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
|
||||||
production_item,
|
|
||||||
product_id_to_production_names)
|
|
||||||
if sorted_process_parameters[i] in consecutive_process_parameters:
|
|
||||||
is_purchase = True
|
|
||||||
consecutive_process_parameters = []
|
|
||||||
m = 0
|
|
||||||
if m == len(consecutive_process_parameters) - 1 and m != 0:
|
|
||||||
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
|
|
||||||
production_item,
|
|
||||||
product_id_to_production_names)
|
|
||||||
if is_purchase is False and m == 0:
|
|
||||||
if len(sorted_process_parameters) == 1:
|
|
||||||
self.env['purchase.order'].get_purchase_order(sorted_process_parameters,
|
|
||||||
production_item,
|
|
||||||
product_id_to_production_names)
|
|
||||||
else:
|
|
||||||
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 is_purchase is False and m == 0:
|
||||||
|
if len(sorted_process_parameters) == 1:
|
||||||
|
self.env['purchase.order'].get_purchase_order(sorted_process_parameters,
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
|
else:
|
||||||
|
self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i],
|
||||||
|
production_item,
|
||||||
|
product_id_to_production_names)
|
||||||
# # 同一个产品多个制造订单对应一个编程单和模型库
|
# # 同一个产品多个制造订单对应一个编程单和模型库
|
||||||
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
||||||
if not production_item.programming_no:
|
if not production_item.programming_no:
|
||||||
production_programming = self.env['mrp.production'].search(
|
|
||||||
[('product_id.id', '=', production_item.product_id.id),
|
|
||||||
('origin', '=', production_item.origin)],
|
|
||||||
limit=1, order='id asc')
|
|
||||||
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]))
|
||||||
@@ -440,7 +441,7 @@ class ProductionLot(models.Model):
|
|||||||
if product.tracking == "serial":
|
if product.tracking == "serial":
|
||||||
last_serial = self.env['stock.lot'].search(
|
last_serial = self.env['stock.lot'].search(
|
||||||
[('company_id', '=', company.id), ('product_id', '=', product.id)],
|
[('company_id', '=', company.id), ('product_id', '=', product.id)],
|
||||||
limit=1, order='id DESC')
|
limit=1, order='name desc')
|
||||||
if last_serial:
|
if last_serial:
|
||||||
if product.categ_id.name == '刀具':
|
if product.categ_id.name == '刀具':
|
||||||
return self.env['stock.lot'].get_tool_generate_lot_names1(company, product)
|
return self.env['stock.lot'].get_tool_generate_lot_names1(company, product)
|
||||||
@@ -544,7 +545,7 @@ class StockPicking(models.Model):
|
|||||||
|
|
||||||
# 设置外协出入单的名称
|
# 设置外协出入单的名称
|
||||||
def _get_name_Res(self, rescode):
|
def _get_name_Res(self, rescode):
|
||||||
last_picking = self.sudo().search([('name', 'like', rescode)], order='create_date desc,id desc', limit=1)
|
last_picking = self.sudo().search([('name', 'ilike', rescode)], order='create_date desc,id desc', limit=1)
|
||||||
if not last_picking:
|
if not last_picking:
|
||||||
num = "%04d" % 1
|
num = "%04d" % 1
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -437,6 +437,12 @@
|
|||||||
<xpath expr="//header//button[@name='action_cancel']" position="replace">
|
<xpath expr="//header//button[@name='action_cancel']" position="replace">
|
||||||
<button name="action_cancel" type="object" string="取消" groups="sf_base.group_sf_mrp_user"/>
|
<button name="action_cancel" type="object" string="取消" groups="sf_base.group_sf_mrp_user"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='state']" position="replace">
|
||||||
|
<field name="state" decoration-success="state in ('done', 'to_close')"
|
||||||
|
decoration-warning="state == 'progress'" decoration-info="state == 'confirmed'"
|
||||||
|
decoration-danger="state in ('cancel','rework','scrap')" decoration-muted="state == 'draft'"
|
||||||
|
optional="show" widget="badge" class="text-dark"/>
|
||||||
|
</xpath>
|
||||||
<xpath expr="//field[@name='state']" position="after">
|
<xpath expr="//field[@name='state']" position="after">
|
||||||
<field name="tool_state" invisible="1"/>
|
<field name="tool_state" invisible="1"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<field name="name" decoration-success="is_subcontract" decoration-bf="is_subcontract"/>
|
<field name="name" decoration-success="is_subcontract" decoration-bf="is_subcontract"/>
|
||||||
</field>
|
</field>
|
||||||
<field name="name" position="before">
|
<field name="name" position="before">
|
||||||
<field name="sequence"/>
|
<field name="sequence" string="序号"/>
|
||||||
<field name='user_permissions' invisible="1"/>
|
<field name='user_permissions' invisible="1"/>
|
||||||
</field>
|
</field>
|
||||||
<field name="name" position="after">
|
<field name="name" position="after">
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
logging.info('下发编程单:%s' % ret)
|
logging.info('下发编程单:%s' % ret)
|
||||||
domain = [('programming_no', '=', ret['programming_no'])]
|
domain = [('programming_no', '=', ret['programming_no'])]
|
||||||
if ret['manufacturing_type'] == 'scrap':
|
if ret['manufacturing_type'] == 'scrap':
|
||||||
domain += [('state', 'not in', ['done', 'scrap'])]
|
domain += [('state', 'not in', ['done', 'scrap', 'cancel'])]
|
||||||
productions = request.env['mrp.production'].with_user(
|
productions = request.env['mrp.production'].with_user(
|
||||||
request.env.ref("base.user_admin")).search(domain)
|
request.env.ref("base.user_admin")).search(domain)
|
||||||
if productions:
|
if productions:
|
||||||
@@ -51,45 +51,27 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
production.product_id.model_processing_panel = ret['processing_panel']
|
production.product_id.model_processing_panel = ret['processing_panel']
|
||||||
production._create_workorder(ret)
|
production._create_workorder(ret)
|
||||||
productions.process_range_time()
|
productions.process_range_time()
|
||||||
# else:
|
else:
|
||||||
# for panel in ret['processing_panel'].split(','):
|
for panel in ret['processing_panel'].split(','):
|
||||||
# # 查询状态为进行中且工序类型为CNC加工的工单
|
# 查询状态为进行中且工序类型为CNC加工的工单
|
||||||
# cnc_workorder = production.workorder_ids.filtered(
|
cnc_workorder_has = production.workorder_ids.filtered(
|
||||||
# lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
lambda ach: ach.routing_type == 'CNC加工' and ach.state not in ['progress', 'done',
|
||||||
# 'cancel'] and ac.processing_panel == panel)
|
'rework',
|
||||||
# if cnc_workorder:
|
'cancel'] and ach.processing_panel == panel)
|
||||||
# if cnc_workorder.cnc_ids:
|
if cnc_workorder_has:
|
||||||
# cnc_workorder.cmm_ids.sudo().unlink()
|
if cnc_workorder_has.cnc_ids:
|
||||||
# cnc_workorder.cnc_ids.sudo().unlink()
|
cnc_workorder_has.cmm_ids.sudo().unlink()
|
||||||
# request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
|
cnc_workorder_has.cnc_ids.sudo().unlink()
|
||||||
# production)
|
request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
|
||||||
# # program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
production)
|
||||||
# # panel)
|
cnc_workorder_has.write(
|
||||||
# program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
|
{'cnc_ids': cnc_workorder_has.cnc_ids.sudo()._json_cnc_processing(panel, ret),
|
||||||
# logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
|
'cmm_ids': cnc_workorder_has.cmm_ids.sudo()._json_cmm_program(panel, ret)})
|
||||||
# files_panel = os.listdir(program_path_tmp_panel)
|
|
||||||
# if files_panel:
|
|
||||||
# for file in files_panel:
|
|
||||||
# file_extension = os.path.splitext(file)[1]
|
|
||||||
# logging.info('file_extension:%s' % file_extension)
|
|
||||||
# if file_extension.lower() == '.pdf':
|
|
||||||
# panel_file_path = os.path.join(program_path_tmp_panel, file)
|
|
||||||
# logging.info('panel_file_path:%s' % panel_file_path)
|
|
||||||
# cnc_workorder.write(
|
|
||||||
# {'cnc_ids': cnc_workorder.cnc_ids.sudo()._json_cnc_processing(panel, ret),
|
|
||||||
# 'cmm_ids': cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel, ret),
|
|
||||||
# 'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
|
|
||||||
# pre_workorder = production.workorder_ids.filtered(
|
|
||||||
# lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done',
|
|
||||||
# 'cancel'] and ap.processing_panel == panel)
|
|
||||||
# if pre_workorder:
|
|
||||||
# pre_workorder.write(
|
|
||||||
# {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
|
|
||||||
for panel in ret['processing_panel'].split(','):
|
for panel in ret['processing_panel'].split(','):
|
||||||
# 查询状态为进行中且工序类型为CNC加工的工单
|
# 查询状态为进行中且工序类型为CNC加工的工单
|
||||||
cnc_workorder = productions.workorder_ids.filtered(
|
cnc_workorder = productions.workorder_ids.filtered(
|
||||||
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done', 'rework'
|
||||||
'cancel'] and ac.processing_panel == panel)
|
'cancel'] and ac.processing_panel == panel)
|
||||||
if cnc_workorder:
|
if cnc_workorder:
|
||||||
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
||||||
# panel)
|
# panel)
|
||||||
@@ -105,8 +87,8 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
logging.info('panel_file_path:%s' % panel_file_path)
|
logging.info('panel_file_path:%s' % panel_file_path)
|
||||||
cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
|
cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||||
pre_workorder = productions.workorder_ids.filtered(
|
pre_workorder = productions.workorder_ids.filtered(
|
||||||
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done',
|
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', 'rework'
|
||||||
'cancel'] and ap.processing_panel == panel)
|
'cancel'] and ap.processing_panel == panel)
|
||||||
if pre_workorder:
|
if pre_workorder:
|
||||||
pre_workorder.write(
|
pre_workorder.write(
|
||||||
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
|
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||||
|
|||||||
@@ -48565,3 +48565,16 @@ msgstr ""
|
|||||||
#: model:ir.model.fields.selection,name:sf_maintenance.selection__maintenance_equipment__heightened_way__chilunjia
|
#: model:ir.model.fields.selection,name:sf_maintenance.selection__maintenance_equipment__heightened_way__chilunjia
|
||||||
msgid "齿轮架驱动"
|
msgid "齿轮架驱动"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: sf_manufacturing
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/sf_manufacturing/models/mrp_production.py:0
|
||||||
|
#: model:ir.actions.act_window,name:sf_manufacturing.action_sf_production_wizard
|
||||||
|
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_production__state__scrap
|
||||||
|
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_workorder__test_results__报废
|
||||||
|
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__sf_detection_result__test_results__报废
|
||||||
|
#: model_terms:ir.ui.view,arch_db:sf_manufacturing.custom_mrp_production_form_view
|
||||||
|
#: model_terms:ir.ui.view,arch_db:sf_manufacturing.custom_view_mrp_production_filter
|
||||||
|
#, python-format
|
||||||
|
msgid "报废"
|
||||||
|
msgstr "报废"
|
||||||
@@ -225,45 +225,42 @@ class RePurchaseOrder(models.Model):
|
|||||||
raise UserError('请对【产品】中的【税】进行选择')
|
raise UserError('请对【产品】中的【税】进行选择')
|
||||||
|
|
||||||
def get_purchase_order(self, consecutive_process_parameters, production, product_id_to_production_names):
|
def get_purchase_order(self, consecutive_process_parameters, production, product_id_to_production_names):
|
||||||
is_exist = True
|
|
||||||
server_product_process = []
|
server_product_process = []
|
||||||
production_process = product_id_to_production_names.get(
|
production_process = product_id_to_production_names.get(
|
||||||
production.product_id.id)
|
production.product_id.id)
|
||||||
for pp in consecutive_process_parameters:
|
for pp in consecutive_process_parameters:
|
||||||
if pp.gain_way == '外协':
|
if pp.gain_way == '外协':
|
||||||
server_product = self.env['product.template'].search(
|
server_template = self.env['product.template'].search(
|
||||||
[('server_product_process_parameters_id', '=', pp.id),
|
[('server_product_process_parameters_id', '=', pp.id),
|
||||||
('detailed_type', '=', 'service')])
|
('detailed_type', '=', 'service')])
|
||||||
purchase_order_line = self.env['purchase.order.line'].search(
|
purchase_order_line = self.env['purchase.order.line'].search(
|
||||||
[('product_id', '=', server_product.id), ('product_qty', '=', len(production_process))])
|
[('product_id', '=', server_template.product_variant_id.id),
|
||||||
|
('product_qty', '=', len(production_process))], limit=1, order='id desc')
|
||||||
if not purchase_order_line:
|
if not purchase_order_line:
|
||||||
is_exist = False
|
|
||||||
server_product_process.append((0, 0, {
|
server_product_process.append((0, 0, {
|
||||||
'product_id': server_product.product_variant_id.id,
|
'product_id': server_template.product_variant_id.id,
|
||||||
'product_qty': len(production_process),
|
'product_qty': len(production_process),
|
||||||
'product_uom': server_product.uom_id.id
|
'product_uom': server_template.uom_id.id
|
||||||
}))
|
}))
|
||||||
else:
|
else:
|
||||||
for item in purchase_order_line:
|
for item in purchase_order_line:
|
||||||
purchase_order = self.env['purchase.order'].search(
|
if production.name in production_process:
|
||||||
[('state', '=', 'draft'), ('origin', 'ilike', production.name),
|
purchase_order = self.env['purchase.order'].search(
|
||||||
('id', '=', item.order_id.id)])
|
[('state', '=', 'draft'), ('origin', '=', ','.join(production_process)),
|
||||||
if not purchase_order:
|
('id', '=', item.order_id.id)])
|
||||||
is_exist = False
|
if not purchase_order:
|
||||||
server_product_process.append((0, 0, {
|
server_product_process.append((0, 0, {
|
||||||
'product_id': server_product.product_variant_id.id,
|
'product_id': server_template.product_variant_id.id,
|
||||||
'product_qty': len(production_process),
|
'product_qty': len(production_process),
|
||||||
'product_uom': server_product.uom_id.id
|
'product_uom': server_template.uom_id.id
|
||||||
}))
|
}))
|
||||||
if is_exist is False:
|
if server_product_process:
|
||||||
purchase_order = self.env['purchase.order'].search(
|
self.env['purchase.order'].sudo().create({
|
||||||
[('state', '=', 'draft'), ('origin', '=', ','.join(production_process))])
|
'partner_id': server_template.seller_ids.partner_id.id,
|
||||||
if not purchase_order or len(purchase_order) >= 1:
|
'origin': ','.join(production_process),
|
||||||
self.env['purchase.order'].sudo().create({
|
'state': 'draft',
|
||||||
'partner_id': server_product.seller_ids.partner_id.id,
|
'order_line': server_product_process})
|
||||||
'origin': ','.join(production_process),
|
# self.env.cr.commit()
|
||||||
'state': 'draft',
|
|
||||||
'order_line': server_product_process})
|
|
||||||
|
|
||||||
@api.onchange('order_line')
|
@api.onchange('order_line')
|
||||||
def _onchange_order_line(self):
|
def _onchange_order_line(self):
|
||||||
|
|||||||
@@ -387,9 +387,9 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
|
|||||||
lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
|
lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
|
||||||
if lot_ids:
|
if lot_ids:
|
||||||
for lot_id in lot_ids:
|
for lot_id in lot_ids:
|
||||||
if lot_id.quant_ids[-1].location_id.name in '刀具房':
|
if lot_id.tool_material_status == '可用':
|
||||||
record.handle_code_id = lot_id.id
|
record.handle_code_id = lot_id.id
|
||||||
elif lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
|
elif lot_id.quant_ids[-1].location_id.name in ['刀具组装位置']:
|
||||||
raise ValidationError('该刀柄已使用,请重新扫描!!!')
|
raise ValidationError('该刀柄已使用,请重新扫描!!!')
|
||||||
else:
|
else:
|
||||||
raise ValidationError('该刀柄未入库,请重新扫描!!!')
|
raise ValidationError('该刀柄未入库,请重新扫描!!!')
|
||||||
|
|||||||
Reference in New Issue
Block a user