Accept Merge Request #1518: (feature/新增工艺退回调整 -> develop)

Merge Request: 新增工艺退回调整

Created By: @杨金灵
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @杨金灵
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1518
This commit is contained in:
杨金灵
2024-11-18 11:45:12 +08:00
committed by Coding
15 changed files with 636 additions and 423 deletions

View File

@@ -158,6 +158,8 @@ class MrsProductionProcessParameter(models.Model):
for parameter in self: for parameter in self:
if parameter.process_id: if parameter.process_id:
name = parameter.process_id.name + '-' + parameter.name name = parameter.process_id.name + '-' + parameter.name
else:
name = parameter.name
result.append((parameter.id, name)) result.append((parameter.id, name))
return result return result

View File

@@ -23,6 +23,7 @@
'wizard/rework_wizard_views.xml', 'wizard/rework_wizard_views.xml',
'wizard/production_wizard_views.xml', 'wizard/production_wizard_views.xml',
'wizard/production_technology_wizard_views.xml', 'wizard/production_technology_wizard_views.xml',
'wizard/production_technology_re_adjust_wizard_views.xml',
'views/mrp_views_menus.xml', 'views/mrp_views_menus.xml',
'views/agv_scheduling_views.xml', 'views/agv_scheduling_views.xml',
'views/stock_lot_views.xml', 'views/stock_lot_views.xml',

View File

@@ -307,16 +307,17 @@ 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'
# 新添加的状态逻辑 # 新添加的状态逻辑
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 == '未排':
production.state = 'confirmed' if not production.workorder_ids:
production.state = 'technology_to_confirmed'
else:
production.state = 'confirmed'
elif production.state == 'pending_cam' and production.schedule_state == '未排': elif production.state == 'pending_cam' and production.schedule_state == '未排':
production.state = 'confirmed' production.state = 'confirmed'
elif production.state == 'to_close' and production.schedule_state == '已排': elif production.state == 'to_close' and production.schedule_state == '已排':
production.state = 'pending_cam' production.state = 'pending_cam'
if production.state == 'progress': if production.state == 'progress':
if all(wo_state not in ('progress', 'done', 'rework', 'scrap') for wo_state in if all(wo_state not in ('progress', 'done', 'rework', 'scrap') for wo_state in
production.workorder_ids.mapped('state')): production.workorder_ids.mapped('state')):
@@ -345,11 +346,44 @@ class MrpProduction(models.Model):
if production.tool_state == '2': if production.tool_state == '2':
production.state = 'rework' production.state = 'rework'
# 退回调整
def technology_back_adjust(self):
process_parameters = []
domain = [('state', '=', 'confirmed'), ('origin', '=', self.origin)]
if self.production_type == '自动化产线加工':
cloud_programming = self._cron_get_programming_state()
if cloud_programming['send_state'] == 'sending':
raise UserError(_("编程文件正在下发中,请稍后重试"))
domain += [('programming_no', '=', self.programming_no)]
# 带排程的制造订单
production_confirmed = self.env['mrp.production'].search(domain)
for special in production_confirmed.technology_design_ids:
if special.process_parameters_id:
product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
if not product_production_process:
if special.process_parameters_id not in process_parameters:
process_parameters.append(special.process_parameters_id.display_name)
if process_parameters:
raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters)))
if production_confirmed:
return {
'name': _('退回调整'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'sf.production.technology.re_adjust.wizard',
'target': 'new',
'context': {
'default_production_id': self.id,
'default_origin': self.origin,
}}
# 工艺确认 # 工艺确认
def technology_confirm(self): def technology_confirm(self):
process_parameters = [] process_parameters = []
account_moves = []
special_design = self.technology_design_ids.filtered( special_design = self.technology_design_ids.filtered(
lambda a: a.routing_tag == 'special' and a.process_parameters_id is not False) lambda a: a.routing_tag == 'special' and a.is_auto is False)
for special in special_design: for special in special_design:
if special.process_parameters_id: if special.process_parameters_id:
product_production_process = self.env['product.template'].search( product_production_process = self.env['product.template'].search(
@@ -357,6 +391,13 @@ class MrpProduction(models.Model):
if not product_production_process: if not product_production_process:
if special.process_parameters_id not in process_parameters: if special.process_parameters_id not in process_parameters:
process_parameters.append(special.process_parameters_id.display_name) process_parameters.append(special.process_parameters_id.display_name)
purchase = self.env['purchase.order'].search([('origin', '=', special.production_id.name)])
account = self.env['account.move'].search([('id', 'in', purchase.invoice_ids)])
if account.state not in ['cancel', False]:
if purchase.name not in account_moves:
account_moves.append(purchase.name)
if account_moves:
raise UserError(_("请联系工厂生产经理对采购订单为%s生成的账单进行取消", ", ".join(account_moves)))
if process_parameters: if process_parameters:
raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters))) raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters)))
# 判断同一个加工面的标准工序的顺序是否依次排序 # 判断同一个加工面的标准工序的顺序是否依次排序
@@ -369,8 +410,8 @@ class MrpProduction(models.Model):
next_index = index + 1 next_index = index + 1
next_design = technology_design[next_index] next_design = technology_design[next_index]
next_design_routing_type = next_design.route_id.routing_type next_design_routing_type = next_design.route_id.routing_type
logging.info('当前工序和加工面: %s-%s' % (design.route_id.name, design.panel)) # logging.info('当前工序和加工面: %s-%s' % (design.route_id.name, design.panel))
logging.info('下一个工序和加工面: %s-%s' % (next_design.route_id.name, next_design.panel)) # logging.info('下一个工序和加工面: %s-%s' % (next_design.route_id.name, next_design.panel))
if design.panel is not False: if design.panel is not False:
if design.panel != next_design.panel: if design.panel != next_design.panel:
if index == 0: if index == 0:
@@ -637,19 +678,13 @@ class MrpProduction(models.Model):
}] }]
if production.product_id.categ_id.type == '成品': if production.product_id.categ_id.type == '成品':
# # 根据工序设计生成工单 # # 根据工序设计生成工单
for route in item.technology_design_ids: for route in production.technology_design_ids:
if route.route_id.routing_type not in ['表面工艺']: if route.route_id.routing_type not in ['表面工艺']:
workorders_values.append( workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(production, route)) self.env['mrp.workorder'].json_workorder_str(production, route))
else: else:
product_production_process = self.env['product.template'].search( product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', route.process_parameters_id.id)]) [('server_product_process_parameters_id', '=', route.process_parameters_id.id)])
# if product_production_process:
# route_production_process = self.env[
# 'mrp.routing.workcenter'].search(
# [('surface_technics_id', '=', p.id),
# ('id', 'in', route_workcenter_arr)])
# if route_production_process:
workorders_values.append( workorders_values.append(
self.env[ self.env[
'mrp.workorder']._json_workorder_surface_process_str( 'mrp.workorder']._json_workorder_surface_process_str(
@@ -663,54 +698,60 @@ class MrpProduction(models.Model):
workorders_values.append( workorders_values.append(
self.env['mrp.workorder'].json_workorder_str('', production, route_embryo)) self.env['mrp.workorder'].json_workorder_str('', production, route_embryo))
production.workorder_ids = workorders_values production.workorder_ids = workorders_values
process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.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)
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)
if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production)
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)
if is_pick is False and m == 0:
if len(sorted_workorders) == 1:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production)
else:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production)
for workorder in production.workorder_ids: for workorder in production.workorder_ids:
workorder.duration_expected = workorder._get_duration_expected() workorder.duration_expected = workorder._get_duration_expected()
# 外协出入库单处理
def get_subcontract_pick_purchase(self):
production_all = self.sorted(lambda x: x.id)
product_id_to_production_names = {}
grouped_product_ids = {k: list(g) for k, g in
groupby(production_all, key=lambda x: x.product_id.id)}
for product_id, pd in grouped_product_ids.items():
product_id_to_production_names[product_id] = [p.name for p in pd]
for production in production_all:
process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id),
('is_subcontract', '=', True)], order='sequence asc')
if process_parameter_workorder:
consecutive_workorders = []
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence)
for i, workorder in enumerate(sorted_workorders):
# 检查当前工作订单和下一个工作订单是否连续,并且供应商相同
if workorder.sequence == 1:
consecutive_workorders.append(workorder)
elif workorder.sequence == sorted_workorders[
i - 1].sequence + 1 and workorder.supplier_id.id == sorted_workorders[i - 1].supplier_id.id:
consecutive_workorders.append(workorder)
else:
# 处理连续组,如果它不为空
if consecutive_workorders:
# 创建出库拣货单和采购订单
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
product_id_to_production_names)
if i < len(sorted_workorders) - 1:
# 重置连续组,并添加当前工作订单
consecutive_workorders = [workorder]
else:
# 判断最后一笔:
if workorder.sequence == sorted_workorders[
i - 1].sequence and workorder.supplier_id.id == sorted_workorders[
i - 1].supplier_id.id:
consecutive_workorders = [workorder]
else:
# 立即创建出库拣货单和采购订单
self.env['stock.picking'].create_outcontract_picking(workorder, production)
self.env['purchase.order'].get_purchase_order(workorder, production,
product_id_to_production_names)
consecutive_workorders = []
# 处理最后一个组,即使它可能只有一个工作订单
if consecutive_workorders:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
product_id_to_production_names)
# 工单排序 # 工单排序
def _reset_work_order_sequence1(self, k): def _reset_work_order_sequence1(self, k):
for rec in self: for rec in self:
@@ -809,7 +850,6 @@ class MrpProduction(models.Model):
if td_ids: if td_ids:
work.sequence = td_ids[0].sequence work.sequence = td_ids[0].sequence
def _reset_work_order_sequence_1(self): def _reset_work_order_sequence_1(self):
""" """
工单工序排序方法(旧) 工单工序排序方法(旧)

View File

@@ -38,13 +38,10 @@ class ResMrpWorkOrder(models.Model):
processing_panel = fields.Char('加工面') processing_panel = fields.Char('加工面')
sequence = fields.Integer(string='工序') sequence = fields.Integer(string='工序')
routing_type = fields.Selection([ routing_type = fields.Selection([
# ('获取CNC加工程序', '获取CNC加工程序'),
('装夹预调', '装夹预调'), ('装夹预调', '装夹预调'),
# ('前置三元定位检测', '前置三元定位检测'),
('CNC加工', 'CNC加工'), ('CNC加工', 'CNC加工'),
# ('后置三元质量检测', '后置三元质量检测'),
('解除装夹', '解除装夹'), ('解除装夹', '解除装夹'),
('切割', '切割'), ('表面工艺', '表面工艺') ('切割', '切割'), ('表面工艺', '表面工艺'), ('线切割', '线切割')
], string="工序类型") ], string="工序类型")
results = fields.Char('结果') results = fields.Char('结果')
state = fields.Selection([ state = fields.Selection([
@@ -233,7 +230,7 @@ class ResMrpWorkOrder(models.Model):
def _compute_surface_technics_picking_ids(self): def _compute_surface_technics_picking_ids(self):
for workorder in self: for workorder in self:
if workorder.routing_type == '表面工艺': if workorder.routing_type == '表面工艺':
domain = [('origin', '=', workorder.production_id.name)] domain = [('origin', '=', workorder.production_id.name), ('state', 'not in', ['cancel'])]
previous_workorder = self.env['mrp.workorder'].search( previous_workorder = self.env['mrp.workorder'].search(
[('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'),
('production_id', '=', workorder.production_id.id)]) ('production_id', '=', workorder.production_id.id)])
@@ -267,24 +264,47 @@ class ResMrpWorkOrder(models.Model):
def _compute_surface_technics_purchase_ids(self): def _compute_surface_technics_purchase_ids(self):
for order in self: for order in self:
if order.routing_type == '表面工艺': if order.routing_type == '表面工艺':
production_programming = self.env['mrp.production'].search( if order.production_id.production_type == '自动化产线加工':
[('programming_no', '=', order.production_id.programming_no)], order='name asc') domain = [('programming_no', '=', order.production_id.programming_no)]
production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False) else:
domain = [('origin', '=', order.production_id.origin)]
production_programming = self.env['mrp.production'].search(domain, order='name asc')
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))]) production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False)
technology_design = self.env['sf.technology.design'].search(
[('process_parameters_id', '=', order.surface_technics_parameters_id.id),
('production_id', '=', order.production_id.id)])
if technology_design.is_auto is False:
domain = [('origin', '=', order.production_id.name)]
else:
domain = [('origin', '=', ','.join(production_list))]
purchase = self.env['purchase.order'].search(domain)
if not purchase:
order.surface_technics_purchase_count = 0
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:
production_no_remanufacture): if (line.product_qty == len(production_no_remanufacture)) or technology_design.is_auto is False:
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
def action_view_surface_technics_purchase(self): def action_view_surface_technics_purchase(self):
self.ensure_one() self.ensure_one()
production_programming = self.env['mrp.production'].search( if self.routing_type == '表面工艺':
[('programming_no', '=', self.production_id.programming_no)], order='name asc') if self.production_id.production_type == '自动化产线加工':
domain = [('programming_no', '=', self.production_id.programming_no)]
else:
domain = [('origin', '=', self.production_id.origin)]
production_programming = self.env['mrp.production'].search(domain, 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))]) technology_design = self.env['sf.technology.design'].search(
[('process_parameters_id', '=', self.surface_technics_parameters_id.id),
('production_id', '=', self.production_id.id)])
if technology_design.is_auto is False:
domain = [('origin', '=', self.production_id.name)]
else:
domain = [('origin', '=', ','.join(production_list))]
purchase_orders = self.env['purchase.order'].search(domain)
result = { result = {
"type": "ir.actions.act_window", "type": "ir.actions.act_window",
"res_model": "purchase.order", "res_model": "purchase.order",
@@ -410,7 +430,8 @@ class ResMrpWorkOrder(models.Model):
@api.constrains('blocked_by_workorder_ids') @api.constrains('blocked_by_workorder_ids')
def _check_no_cyclic_dependencies(self): def _check_no_cyclic_dependencies(self):
if self.production_id.state not in ['rework'] and self.state not in ['rework']: if self.production_id.state not in ['rework', 'technology_to_confirmed', 'confirmed'] and self.state not in [
'rework']:
if not self._check_m2m_recursion('blocked_by_workorder_ids'): if not self._check_m2m_recursion('blocked_by_workorder_ids'):
raise ValidationError(_("您不能创建周期性的依赖关系.")) raise ValidationError(_("您不能创建周期性的依赖关系."))
@@ -421,8 +442,9 @@ class ResMrpWorkOrder(models.Model):
for workorder in self.blocked_by_workorder_ids: for workorder in self.blocked_by_workorder_ids:
if workorder.state in ['done', 'cancel', 'rework']: if workorder.state in ['done', 'cancel', 'rework']:
continue continue
workorder._plan_workorder(replan) if workorder.production_id.state not in ['technology_to_confirmed', 'confirmed']:
start_date = max(start_date, workorder.date_planned_finished) workorder._plan_workorder(replan)
start_date = max(start_date, workorder.date_planned_finished)
# Plan only suitable workorders # Plan only suitable workorders
if self.state not in ['pending', 'waiting', 'ready']: if self.state not in ['pending', 'waiting', 'ready']:
return return
@@ -769,6 +791,7 @@ class ResMrpWorkOrder(models.Model):
'operation_id': False, 'operation_id': False,
'name': route.route_id.name, 'name': route.route_id.name,
'processing_panel': route.panel, 'processing_panel': route.panel,
'sequence': route.sequence,
'quality_point_ids': route.route_id.quality_point_ids, 'quality_point_ids': route.route_id.quality_point_ids,
'routing_type': route.route_id.routing_type, 'routing_type': route.route_id.routing_type,
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids, 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids,
@@ -817,6 +840,7 @@ class ResMrpWorkOrder(models.Model):
'operation_id': False, 'operation_id': False,
'name': route.process_parameters_id.display_name, 'name': route.process_parameters_id.display_name,
'processing_panel': '', 'processing_panel': '',
'sequence': route.sequence,
'routing_type': '表面工艺', 'routing_type': '表面工艺',
'surface_technics_parameters_id': route.process_parameters_id.id, 'surface_technics_parameters_id': route.process_parameters_id.id,
'work_state': '', 'work_state': '',
@@ -977,10 +1001,47 @@ class ResMrpWorkOrder(models.Model):
return workorders_values_str return workorders_values_str
@api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state', @api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state',
'production_id.tool_state') 'production_id.tool_state', 'production_id.schedule_state')
def _compute_state(self): def _compute_state(self):
super()._compute_state() # super()._compute_state()
for workorder in self: for workorder in self:
if workorder.sequence != 1:
previous_workorder = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id),
('sequence', '=', workorder.sequence - 1)])
if workorder.state == 'pending':
if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排':
if (workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) or (
workorder.blocked_by_workorder_ids.state in ('done', 'cancel')) or (
previous_workorder.state in (
'done', 'cancel') and not workorder.blocked_by_workorder_ids):
workorder.state = 'ready'
continue
if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'):
if workorder.sequence != 1:
workorder.state = 'pending'
continue
if workorder.state not in ('waiting', 'ready'):
continue
if workorder.state in (
'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排':
workorder.state = 'ready'
continue
if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
workorder.state = 'pending'
if workorder.state in ['waiting']:
if previous_workorder.state == 'waiting':
workorder.state = 'pending'
if workorder.sequence == 1 and workorder.state == 'pending':
workorder.state = 'waiting'
continue
if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'):
continue
if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排':
workorder.state = 'ready'
elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready':
workorder.state = 'waiting'
re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id), re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id),
('processing_panel', '=', workorder.processing_panel), ('processing_panel', '=', workorder.processing_panel),
('is_rework', '=', True), ('state', 'in', ['done', 'rework'])]) ('is_rework', '=', True), ('state', 'in', ['done', 'rework'])])
@@ -1044,7 +1105,7 @@ class ResMrpWorkOrder(models.Model):
workorder.state = 'ready' workorder.state = 'ready'
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') [('origin', '=', self.production_id.origin)], order='name asc')
production_no_remanufacture = production_programming.filtered( production_no_remanufacture = production_programming.filtered(
lambda a: a.is_remanufacture is False) 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]
@@ -1060,68 +1121,68 @@ class ResMrpWorkOrder(models.Model):
elif workorder.production_id.state == 'scrap': elif workorder.production_id.state == 'scrap':
if workorder.routing_type == '解除装夹' and unclamp_workorder.test_results == '报废': if workorder.routing_type == '解除装夹' and unclamp_workorder.test_results == '报废':
workorder.state = 'waiting' workorder.state = 'waiting'
if workorder.routing_type == '装夹预调' and workorder.state in ['waiting', 'ready', 'pending']: # if workorder.routing_type == '装夹预调' and workorder.state in ['waiting', 'ready', 'pending']:
workorder_ids = workorder.production_id.workorder_ids # workorder_ids = workorder.production_id.workorder_ids
work_bo = True # work_bo = True
for wo in workorder_ids.filtered(lambda a: a.routing_type == '装夹预调' and a.state == 'rework'): # for wo in workorder_ids.filtered(lambda a: a.routing_type == '装夹预调' and a.state == 'rework'):
if not workorder_ids.filtered( # if not workorder_ids.filtered(
lambda a: (a.routing_type == '装夹预调' and a.state not in ['rework', 'cancel'] # lambda a: (a.routing_type == '装夹预调' and a.state not in ['rework', 'cancel']
and a.processing_panel == wo.processing_panel)): # and a.processing_panel == wo.processing_panel)):
work_bo = False # work_bo = False
break # break
if (workorder.production_id.programming_state == '已编程' and work_bo # if (workorder.production_id.programming_state == '已编程' and work_bo
and not workorder_ids.filtered(lambda a: a.sequence == 0)): # and not workorder_ids.filtered(lambda a: a.sequence == 0)):
# 当工单对应制造订单的功能刀具状态为 【无效刀】时,先对的第一个装夹预调工单状态设置为 【等待组件】 # # 当工单对应制造订单的功能刀具状态为 【无效刀】时,先对的第一个装夹预调工单状态设置为 【等待组件】
if workorder.production_id.tool_state in ['1', '2']: # if workorder.production_id.tool_state in ['1', '2']:
if workorder.state in ['ready']: # if workorder.state in ['ready']:
workorder.state = 'waiting' # workorder.state = 'waiting'
continue # continue
elif workorder.state in ['waiting']: # elif workorder.state in ['waiting']:
continue # continue
elif workorder.state == 'pending' and workorder == self.search( # elif workorder.state == 'pending' and workorder == self.search(
[('production_id', '=', workorder.production_id.id), # [('production_id', '=', workorder.production_id.id),
('routing_type', '=', '装夹预调'), # ('routing_type', '=', '装夹预调'),
('state', 'not in', ['rework', 'done', 'cancel'])], # ('state', 'not in', ['rework', 'done', 'cancel'])],
limit=1, # limit=1,
order="sequence"): # order="sequence"):
workorder.state = 'waiting' # workorder.state = 'waiting'
continue # continue
elif workorder.production_id.tool_state in ['0']: # elif workorder.production_id.tool_state in ['0']:
if workorder_ids.filtered(lambda a: a.state == 'rework'): # if workorder_ids.filtered(lambda a: a.state == 'rework'):
if not workorder_ids.filtered( # if not workorder_ids.filtered(
lambda a: (a.routing_type not in ['装夹预调'] and # lambda a: (a.routing_type not in ['装夹预调'] and
a.state not in ['pending', 'done', 'rework', 'cancel'])): # a.state not in ['pending', 'done', 'rework', 'cancel'])):
# 查询工序最小的非完工、非返工的装夹预调工单 # # 查询工序最小的非完工、非返工的装夹预调工单
work_id = self.search( # work_id = self.search(
[('production_id', '=', workorder.production_id.id), # [('production_id', '=', workorder.production_id.id),
('state', 'not in', ['rework', 'done', 'cancel'])], # ('state', 'not in', ['rework', 'done', 'cancel'])],
limit=1, # limit=1,
order="sequence") # order="sequence")
if work_id.routing_type == '装夹预调': # if work_id.routing_type == '装夹预调':
if workorder == work_id: # if workorder == work_id:
if workorder.production_id.reservation_state == 'assigned': # if workorder.production_id.reservation_state == 'assigned':
workorder.state = 'ready' # workorder.state = 'ready'
elif workorder.production_id.reservation_state != 'assigned': # elif workorder.production_id.reservation_state != 'assigned':
workorder.state = 'waiting' # workorder.state = 'waiting'
continue # continue
elif (workorder.name == '装夹预调' and # elif (workorder.name == '装夹预调' and
workorder.state not in ['rework', 'done', 'cancel']): # workorder.state not in ['rework', 'done', 'cancel']):
if workorder.state != 'pending': # if workorder.state != 'pending':
workorder.state = 'pending' # workorder.state = 'pending'
if workorder.production_id.tool_state in ['1', '2'] and workorder.state == 'ready': # if workorder.production_id.tool_state in ['1', '2'] and workorder.state == 'ready':
workorder.state = 'waiting' # workorder.state = 'waiting'
continue # continue
if (workorder.production_id.tool_state in ['1', '2'] # if (workorder.production_id.tool_state in ['1', '2']
and not workorder.production_id.workorder_ids.filtered(lambda a: a.sequence == 0) # and not workorder.production_id.workorder_ids.filtered(lambda a: a.sequence == 0)
and workorder.production_id.programming_state == '编程中' and workorder.name == '装夹预调'): # and workorder.production_id.programming_state == '编程中' and workorder.name == '装夹预调'):
if workorder.state == 'pending' and workorder == self.search( # if workorder.state == 'pending' and workorder == self.search(
[('production_id', '=', workorder.production_id.id), # [('production_id', '=', workorder.production_id.id),
('routing_type', '=', '装夹预调'), # ('routing_type', '=', '装夹预调'),
('state', 'not in', ['rework', 'done', 'cancel'])], # ('state', 'not in', ['rework', 'done', 'cancel'])],
limit=1, # limit=1,
order="sequence"): # order="sequence"):
workorder.state = 'waiting' # workorder.state = 'waiting'
continue # continue
# 重写工单开始按钮方法 # 重写工单开始按钮方法
def button_start(self): def button_start(self):
@@ -1131,7 +1192,7 @@ class ResMrpWorkOrder(models.Model):
'actual_start_time': datetime.now() 'actual_start_time': datetime.now()
}) })
if self.routing_type == '装夹预调': if self.sequence == 1:
# 判断是否有坯料的序列号信息 # 判断是否有坯料的序列号信息
boolean = False boolean = False
if self.production_id.move_raw_ids: if self.production_id.move_raw_ids:
@@ -1242,8 +1303,8 @@ class ResMrpWorkOrder(models.Model):
if record.is_rework is False: if record.is_rework is False:
if not record.material_center_point: if not record.material_center_point:
raise UserError("坯料中心点为空,请检查") raise UserError("坯料中心点为空,请检查")
# if record.X_deviation_angle <= 0: # if record.X_deviation_angle <= 0:
# raise UserError("X偏差角度小于等于0请检查本次计算的X偏差角度为%s" % record.X_deviation_angle) # raise UserError("X偏差角度小于等于0请检查本次计算的X偏差角度为%s" % record.X_deviation_angle)
record.process_state = '待加工' record.process_state = '待加工'
# record.write({'process_state': '待加工'}) # record.write({'process_state': '待加工'})
record.production_id.process_state = '待加工' record.production_id.process_state = '待加工'
@@ -1273,23 +1334,10 @@ class ResMrpWorkOrder(models.Model):
''' '''
record.date_finished = datetime.now() record.date_finished = datetime.now()
if record.routing_type == '表面工艺': if record.routing_type == '表面工艺':
logging.info('record.picking_ids:%s' % record.picking_ids)
logging.info('record.picking_out:%s' % record.picking_ids[0])
if record.picking_ids: if record.picking_ids:
for pick_item in record.picking_ids: picks = record.picking_ids.filtered(lambda p: p.state not in ('done'))
if pick_item.state not in ['done']: if picks:
raise UserError( raise UserError('请先完成该工单的工艺外协再进行操作')
'请先完成该工单的工艺外协再进行操作')
picking_out = record.env['stock.move.line'].search(
[('picking_id', '=', record.picking_ids[0].id)])
logging.info('picking_out:%s' % picking_out.picking_id.name)
# if picking_out:
# order_line_ids = []
# logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name)
#
# else:
# raise UserError(
# '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name)
tem_date_planned_finished = record.date_planned_finished tem_date_planned_finished = record.date_planned_finished
tem_date_finished = record.date_finished tem_date_finished = record.date_finished
logging.info('routing_type:%s' % record.routing_type) logging.info('routing_type:%s' % record.routing_type)

View File

@@ -16,13 +16,13 @@ class sf_technology_design(models.Model):
is_auto = fields.Boolean('是否自动生成', default=False) is_auto = fields.Boolean('是否自动生成', default=False)
active = fields.Boolean('有效', default=True) active = fields.Boolean('有效', default=True)
def json_technology_design_str(self, k, route, i): def json_technology_design_str(self, k, route, i, process_parameter):
workorders_values_str = [0, '', { workorders_values_str = [0, '', {
'route_id': route.id, 'route_id': route.id,
'panel': k, 'panel': k,
'process_parameters_id': False if route.routing_type != '表面工艺' else self.env[ 'process_parameters_id': False if route.routing_type != '表面工艺' else self.env[
'sf.production.process.parameter'].search( 'sf.production.process.parameter'].search(
[('process_id', '=', route.surface_technics_id.id)]).id, [('id', '=', process_parameter.id)]).id,
'sequence': i, 'sequence': i,
'is_auto': True}] 'is_auto': True}]
return workorders_values_str return workorders_values_str

View File

@@ -294,135 +294,79 @@ 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( 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: # 同一个产品多个制造订单对应一个编程单和模型库
is_purchase = False # 只调用一次fetchCNC并将所有生产订单的名称作为字符串传递
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, if not production_item.programming_no and production.production_type == '自动化产线加工':
key=lambda w: w.id) if not production_programming.programming_no:
production_item.fetchCNC(
consecutive_process_parameters = [] ', '.join(product_id_to_production_names[production_item.product_id.id]))
m = 0 else:
for i in range(len(sorted_process_parameters) - 1): production_item.write({'programming_no': production_programming.programming_no,
if m == 0: 'programming_state': '编程中'})
is_purchase = False if not technology_design_values:
if self.env['product.template']._get_process_parameters_product( if production_item.product_id.categ_id.type == '成品':
sorted_process_parameters[i]).partner_id == self.env[ # 根据加工面板的面数及成品工序模板生成工序设计
'product.template']._get_process_parameters_product(sorted_process_parameters[ i = 0
i + 1]).partner_id and \ for k in (production_item.product_id.model_processing_panel.split(',')):
sorted_process_parameters[i].gain_way == '外协': if production_item.production_type == '自动化产线加工':
if sorted_process_parameters[i] not in consecutive_process_parameters: model = 'sf.product.model.type.routing.sort'
consecutive_process_parameters.append(sorted_process_parameters[i])
consecutive_process_parameters.append(sorted_process_parameters[i + 1])
m += 1
continue
else: else:
if m == len(consecutive_process_parameters) - 1 and m != 0: model = 'sf.manual.product.model.type.routing.sort'
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, product_routing_workcenter = self.env[model].search(
production_item, [('product_model_type_id', '=', production_item.product_id.product_model_type_id.id)],
product_id_to_production_names) order='sequence asc'
if sorted_process_parameters[i] in consecutive_process_parameters: )
is_purchase = True for route in product_routing_workcenter:
consecutive_process_parameters = [] i += 1
m = 0 technology_design_values.append(
# 当前面的连续外协采购单生成再生成当前外协采购单 self.env['sf.technology.design'].json_technology_design_str(k, route, i, False))
if is_purchase is False: elif production.product_id.categ_id.type == '坯料':
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search(
production_item, [('embryo_model_type_id', '=', production_item.product_id.embryo_model_type_id.id)],
product_id_to_production_names) order='sequence asc'
if m == len(consecutive_process_parameters) - 1 and m != 0: )
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, for route_embryo in embryo_routing_workcenter:
production_item, i += 1
product_id_to_production_names) technology_design_values.append(
if sorted_process_parameters[i] in consecutive_process_parameters: self.env['sf.technology.design'].json_technology_design_str(False, route_embryo, i,
is_purchase = True False))
consecutive_process_parameters = [] surface_technics_arr = []
m = 0 route_workcenter_arr = []
if m == len(consecutive_process_parameters) - 1 and m != 0: for item in production_item.product_id.product_model_type_id.surface_technics_routing_tmpl_ids:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, if item.route_workcenter_id.surface_technics_id.id:
production_item, for process_param in production_item.product_id.model_process_parameters_ids:
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)
if not technology_design_values:
if production.product_id.categ_id.type == '成品':
# production.product_id.model_processing_panel = 'ZM,FM'
# 根据加工面板的面数及成品工序模板生成工序设计
i = 0
for k in (production.product_id.model_processing_panel.split(',')):
# 根据制造类型来选择成品工序模板
if production.production_type == '自动化产线加工':
product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search(
[('product_model_type_id', '=', production.product_id.product_model_type_id.id)],
order='sequence asc'
)
elif production.production_type == '人工线下加工':
product_routing_workcenter = self.env['sf.manual.product.model.type.routing.sort'].search(
[('manual_product_model_type_id', '=', production.product_id.product_model_type_id.id)],
order='sequence asc'
)
for route in product_routing_workcenter:
i += 1
technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(k, route, i))
surface_technics_arr = []
route_workcenter_arr = []
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):
# if item.route_workcenter_id.surface_technics_id.id:
# for process_param in production.product_id.model_process_parameters_ids:
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(
'surface_technics_id:%s%s' % (
item.route_workcenter_id.surface_technics_id.id,
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_item.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( if process_parameter:
[('server_product_process_parameters_id', '=', i += 1
process_parameter.id)]) route_production_process = self.env[
if process_parameter: 'mrp.routing.workcenter'].search(
i += 1 [('surface_technics_id', '=', p.id),
route_production_process = self.env[ ('id', 'in', route_workcenter_arr)])
'mrp.routing.workcenter'].search( technology_design_values.append(
[('surface_technics_id', '=', p.id), self.env['sf.technology.design'].json_technology_design_str(False,
('id', 'in', route_workcenter_arr)]) route_production_process,
technology_design_values.append( i,
self.env['sf.technology.design'].json_technology_design_str(k, process_parameter))
route_production_process,
product_production_process,
i))
productions.technology_design_ids = technology_design_values productions.technology_design_ids = technology_design_values
# # 同一个产品多个制造订单对应一个编程单和模型库
# # 只调用一次fetchCNC并将所有生产订单的名称作为字符串传递
# if not production_item.programming_no:
# if not production_programming.programming_no:
# production_item.fetchCNC(
# ', '.join(product_id_to_production_names[production_item.product_id.id]))
# else:
# production_item.write({'programming_no': production_programming.programming_no,
# 'programming_state': '编程中'})
return True return True
@@ -665,31 +609,27 @@ class StockPicking(models.Model):
return '%s%s' % (rescode, num) return '%s%s' % (rescode, num)
def button_validate(self): def button_validate(self):
move_out = self.env['stock.move'].search( if self.picking_type_id.barcode == 'OCOUT':
[('location_id', '=', self.env['stock.location'].search( move_out = self.env['stock.move'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), [('location_id', '=', self.env['stock.location'].search(
('location_dest_id', '=', self.env['stock.location'].search( [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
[('barcode', 'ilike', 'VL-SPOC')]).id), ('location_dest_id', '=', self.env['stock.location'].search(
('origin', '=', self.origin)]) [('barcode', 'ilike', 'VL-SPOC')]).id),
# if self.id == move_out.picking_id.id: ('origin', '=', self.origin)])
# if move_out.move_line_ids.workorder_id.state not in ['progress']: move_in = self.env['stock.move'].search(
# raise UserError( [('location_dest_id', '=', self.env['stock.location'].search(
# _('该出库单里源单据内的单号为%s的工单还未开始不能进行验证操作' % move_out.move_line_ids.workorder_id.name)) [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
# 入库单验证 ('location_id', '=', self.env['stock.location'].search(
move_in = self.env['stock.move'].search( [('barcode', 'ilike', 'VL-SPOC')]).id),
[('location_dest_id', '=', self.env['stock.location'].search( ('origin', '=', self.origin), ('picking_id', '=', self.id)])
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id:
('location_id', '=', self.env['stock.location'].search( if move_out.origin == move_in.origin:
[('barcode', 'ilike', 'VL-SPOC')]).id), move_in.write({'production_id': False})
('origin', '=', self.origin), ('picking_id', '=', self.id)]) if move_out.picking_id.state != 'done':
if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id: raise UserError(
if move_out.origin == move_in.origin: _('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name))
move_in.write({'production_id': False})
if move_out.picking_id.state != 'done':
raise UserError(
_('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name))
res = super().button_validate() res = super().button_validate()
if res is True: if res is True and self.picking_type_id.barcode == 'OCIN':
if self.id == move_out.picking_id.id: if self.id == move_out.picking_id.id:
# if move_out.move_line_ids.workorder_id.state == 'progress': # if move_out.move_line_ids.workorder_id.state == 'progress':
move_in = self.env['stock.move'].search( move_in = self.env['stock.move'].search(
@@ -707,42 +647,43 @@ class StockPicking(models.Model):
# 创建 外协出库入单 # 创建 外协出库入单
def create_outcontract_picking(self, sorted_workorders_arr, item): def create_outcontract_picking(self, sorted_workorders_arr, item):
m = 0 if len(sorted_workorders_arr) > 1:
for sorted_workorders in sorted_workorders_arr: sorted_workorders_arr = sorted_workorders_arr[0]
# pick_ids = [] stock_picking = self.env['stock.picking'].search(
if m == 0: [('origin', '=', sorted_workorders_arr.production_id.name), ('name', 'ilike', 'OCOUT')])
outcontract_stock_move = self.env['stock.move'].search( if not stock_picking:
[('workorder_id', '=', sorted_workorders.id), ('production_id', '=', item.id)]) for sorted_workorders in sorted_workorders_arr:
if not outcontract_stock_move: # pick_ids = []
new_picking = True if not sorted_workorders.picking_ids:
location_id = self.env['stock.location'].search( outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)])
[('barcode', 'ilike', 'VL-SPOC')]).id, if not outcontract_stock_move:
location_dest_id = self.env['stock.location'].search( new_picking = True
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, location_id = self.env['stock.location'].search(
outcontract_picking_type_in = self.env.ref( [('barcode', 'ilike', 'VL-SPOC')]).id,
'sf_manufacturing.outcontract_picking_in').id, location_dest_id = self.env['stock.location'].search(
outcontract_picking_type_out = self.env.ref( [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
'sf_manufacturing.outcontract_picking_out').id, outcontract_picking_type_in = self.env.ref(
moves_out = self.env['stock.move'].sudo().create( 'sf_manufacturing.outcontract_picking_in').id,
self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id, outcontract_picking_type_out = self.env.ref(
outcontract_picking_type_out)) 'sf_manufacturing.outcontract_picking_out').id,
picking_out = self.create( moves_out = self.env['stock.move'].sudo().create(
moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id,
# pick_ids.append(picking_out.id) outcontract_picking_type_out))
moves_out.write( picking_out = self.create(
{'picking_id': picking_out.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/'))
moves_out._assign_picking_post_process(new=new_picking) # pick_ids.append(picking_out.id)
moves_in = self.env['stock.move'].sudo().create( moves_out.write(
self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id, {'picking_id': picking_out.id, 'state': 'waiting'})
outcontract_picking_type_in)) moves_out._assign_picking_post_process(new=new_picking)
picking_in = self.create( moves_in = self.env['stock.move'].sudo().create(
moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id,
# pick_ids.append(picking_in.id) outcontract_picking_type_in))
moves_in.write( picking_in = self.create(
{'picking_id': picking_in.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/'))
moves_in._assign_picking_post_process(new=new_picking) # pick_ids.append(picking_in.id)
m += 1 moves_in.write(
# sorted_workorders.write({'picking_ids': [(6, 0, pick_ids)]}) {'picking_id': picking_in.id, 'state': 'waiting'})
moves_in._assign_picking_post_process(new=new_picking)
class ReStockMove(models.Model): class ReStockMove(models.Model):
@@ -778,7 +719,7 @@ class ReStockMove(models.Model):
return { return {
'name': self.env['stock.picking']._get_name_Res(rescode), 'name': self.env['stock.picking']._get_name_Res(rescode),
'origin': item.name, 'origin': item.name,
'surface_technics_parameters_id': sorted_workorders.surface_technics_parameters_id.id, # 'surface_technics_parameters_id': sorted_workorders.surface_technics_parameters_id.id,
'company_id': self.mapped('company_id').id, 'company_id': self.mapped('company_id').id,
'user_id': False, 'user_id': False,
'move_type': self.mapped('group_id').move_type or 'direct', 'move_type': self.mapped('group_id').move_type or 'direct',
@@ -799,7 +740,7 @@ class ReStockMove(models.Model):
'picking_id': self.picking_id.id, 'picking_id': self.picking_id.id,
'reserved_uom_qty': 1.0, 'reserved_uom_qty': 1.0,
'lot_id': production_id.move_line_raw_ids.lot_id.id, 'lot_id': production_id.move_line_raw_ids.lot_id.id,
'company_id': self.company_id.id, 'company_id': self.env.company.id,
# 'workorder_id': '' if not sorted_workorders else sorted_workorders.id, # 'workorder_id': '' if not sorted_workorders else sorted_workorders.id,
# 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id, # 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id,
'state': 'assigned', 'state': 'assigned',
@@ -848,7 +789,6 @@ class ReStockMove(models.Model):
elif self.product_id.tracking == "lot": elif self.product_id.tracking == "lot":
self._put_tool_lot(self.company_id, self.product_id, self.origin) self._put_tool_lot(self.company_id, self.product_id, self.origin)
return { return {
'name': _('Detailed Operations'), 'name': _('Detailed Operations'),
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',

View File

@@ -171,6 +171,9 @@ access_sf_technology_design_group_production_engineer,sf_technology_design_group
access_sf_production_technology_wizard_group_plan_dispatch,sf_production_technology_wizard_group_plan_dispatch,model_sf_production_technology_wizard,sf_base.group_plan_dispatch,1,1,1,0 access_sf_production_technology_wizard_group_plan_dispatch,sf_production_technology_wizard_group_plan_dispatch,model_sf_production_technology_wizard,sf_base.group_plan_dispatch,1,1,1,0
access_sf_production_technology_wizard_group_sf_mrp_manager,sf_production_technology_wizard_group_sf_mrp_manager,model_sf_production_technology_wizard,sf_base.group_sf_mrp_manager,1,1,1,0 access_sf_production_technology_wizard_group_sf_mrp_manager,sf_production_technology_wizard_group_sf_mrp_manager,model_sf_production_technology_wizard,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_production_technology_wizard_group_production_engineer,sf_production_technology_wizard_group_production_engineer,model_sf_production_technology_wizard,sf_base.group_production_engineer,1,1,1,0 access_sf_production_technology_wizard_group_production_engineer,sf_production_technology_wizard_group_production_engineer,model_sf_production_technology_wizard,sf_base.group_production_engineer,1,1,1,0
access_sf_production_technology_re_adjust_wizard_group_plan_dispatch,sf_production_technology_re_adjust_wizard_group_plan_dispatch,model_sf_production_technology_re_adjust_wizard,sf_base.group_plan_dispatch,1,1,1,0
access_sf_production_technology_re_adjust_wizard_group_sf_mrp_manager,sf_production_technology_re_adjust_wizard_group_sf_mrp_manager,model_sf_production_technology_re_adjust_wizard,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_production_technology_re_adjust_wizard_group_production_engineer,sf_production_technology_re_adjust_wizard_group_production_engineer,model_sf_production_technology_re_adjust_wizard,sf_base.group_production_engineer,1,1,1,0
access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0 access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0 access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
171
172
173
174
175
176
177
178
179

View File

@@ -92,9 +92,12 @@
</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"/> attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
<field name="programming_no" readonly="1"
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
<field name="programming_state" readonly="1" <field name="programming_state" readonly="1"
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"
decoration-success="programming_state == '已编程'" decoration-success="programming_state == '已编程'"
decoration-warning="programming_state =='编程中'" decoration-warning="programming_state =='编程中'"
decoration-danger="programming_state =='已编程未下发'"/> decoration-danger="programming_state =='已编程未下发'"/>
@@ -127,20 +130,18 @@
string="验证" type="object" class="oe_highlight" string="验证" type="object" class="oe_highlight"
confirm="There are no components to consume. Are you still sure you want to continue?" confirm="There are no components to consume. Are you still sure you want to continue?"
data-hotkey="g" groups="sf_base.group_sf_mrp_user"/> data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
<button name="technology_confirm" string="工艺确认" type="object" class="oe_highlight"
attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '!=', [])]}"></button>
</xpath> </xpath>
<xpath expr="(//header//button[@name='button_mark_done'])[2]" position="replace"> <xpath expr="(//header//button[@name='button_mark_done'])[2]" position="replace">
<button name="button_mark_done" <button name="button_mark_done"
attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}" attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}"
string="验证" type="object" data-hotkey="g" string="验证" type="object" data-hotkey="g"
groups="sf_base.group_sf_mrp_user"/> groups="sf_base.group_sf_mrp_user"/>
<button name="technology_confirm" string="工艺确认" type="object" class="oe_highlight"
attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}"
></button>
</xpath> </xpath>
<xpath expr="(//header//button[@name='button_scrap'])" position="replace"> <xpath expr="(//header//button[@name='button_scrap'])" position="replace">
<button name="technology_confirm" string="工艺确认" type="object" class="oe_highlight"
attrs="{'invisible': [('workorder_ids', '!=', [])]}"></button>
<button name="technology_back_adjust" string="退回调整" type="object" class="oe_highlight"
attrs="{'invisible': [('state', '!=', 'confirmed')]}"></button>
<button name="button_scrap" invisible="1"/> <button name="button_scrap" invisible="1"/>
<button name="do_update_program" string="更新程序" type="object" groups="sf_base.group_sf_mrp_user" <button name="do_update_program" string="更新程序" type="object" groups="sf_base.group_sf_mrp_user"
confirm="是否确认更新程序" confirm="是否确认更新程序"
@@ -310,8 +311,7 @@
</xpath> </xpath>
<xpath expr="//sheet//notebook//page[@name='operations']" position="attributes"> <xpath expr="//sheet//notebook//page[@name='operations']" position="attributes">
<attribute name="attrs">{'invisible': ['|',('schedule_state', '=', '未排'),('workorder_ids', '=', <attribute name="attrs">{'invisible': [('workorder_ids', '=', [])]}
[])]}
</attribute> </attribute>
</xpath> </xpath>
@@ -352,23 +352,20 @@
<field name="part_drawing" widget="adaptive_viewer"/> <field name="part_drawing" widget="adaptive_viewer"/>
</page> </page>
</xpath> </xpath>
<xpath expr="//sheet//notebook" position="inside"> <xpath expr="//sheet//notebook//page[@name='components']" position="before">
<page string="质检标准">
<field name="quality_standard" widget="adaptive_viewer"/>
</page>
<page string="工艺设计"> <page string="工艺设计">
<field name="technology_design_ids" widget="one2many"> <field name="technology_design_ids" widget="one2many">
<tree editable="bottom"> <tree editable="bottom">
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle"/>
<field name="route_id" context="{'production_id': production_id}" <field name="route_id" context="{'production_id': production_id}"
attrs="{'readonly': [('is_auto', '=', True)]}" options="{'no_create': True}"/> attrs="{'readonly': [('id', '!=', False)]}" options="{'no_create': True}"/>
<field name="process_parameters_id" attrs="{'readonly': [('is_auto', '=', True)]}" <field name="process_parameters_id" attrs="{'readonly': [('id', '!=', False)]}"
string="参数" context="{'route_id':route_id}" options="{'no_create': True}"/> string="参数" context="{'route_id':route_id}" options="{'no_create': True}"/>
<field name="panel" readonly="1"/> <field name="panel" readonly="1"/>
<field name="routing_tag" readonly="1" widget="badge" <field name="routing_tag" readonly="1" widget="badge"
decoration-success="routing_tag == 'standard'" decoration-success="routing_tag == 'standard'"
decoration-warning="routing_tag == 'special'"/> decoration-warning="routing_tag == 'special'"/>
<field name="time_cycle_manual" attrs="{'readonly': [('is_auto', '=', True)]}"/> <field name="time_cycle_manual" attrs="{'readonly': [('id', '!=', False)]}"/>
<field name="is_auto" invisible="1"/> <field name="is_auto" invisible="1"/>
<field name="production_id" invisible="1"/> <field name="production_id" invisible="1"/>
<button name="unlink_technology_design" confirm="是否确认删除?" class="oe_highlight" <button name="unlink_technology_design" confirm="是否确认删除?" class="oe_highlight"
@@ -378,6 +375,12 @@
</field> </field>
</page> </page>
</xpath> </xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="质检标准">
<field name="quality_standard" widget="adaptive_viewer"/>
</page>
</xpath>
</field> </field>
</record> </record>

View File

@@ -250,7 +250,7 @@
<field name='tag_type' readonly="1" attrs='{"invisible": [("tag_type","=",False)]}' <field name='tag_type' readonly="1" attrs='{"invisible": [("tag_type","=",False)]}'
decoration-danger="tag_type == '重新加工'"/> decoration-danger="tag_type == '重新加工'"/>
<field name="is_test_env" invisible="1"/> <field name="is_test_env" invisible="1"/>
<field name="rfid_code" force_save="1" readonly="1" cache="True" <field name="rfid_code" force_save="1" readonly="1" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}" widget='qrcode_widget'/> attrs="{'invisible': [('rfid_code_old', '!=', False)]}" widget='qrcode_widget'/>
<field name="rfid_code" string="RFID码(手动输入框)" force_save="1" readonly="0" cache="True" <field name="rfid_code" string="RFID码(手动输入框)" force_save="1" readonly="0" cache="True"
attrs="{'invisible': ['|',('rfid_code_old', '!=', False), ('is_test_env', '=', False)]}"/> attrs="{'invisible': ['|',('rfid_code_old', '!=', False), ('is_test_env', '=', False)]}"/>

View File

@@ -2,3 +2,4 @@ from . import workpiece_delivery_wizard
from . import rework_wizard from . import rework_wizard
from . import production_wizard from . import production_wizard
from . import production_technology_wizard from . import production_technology_wizard
from . import production_technology_re_adjust_wizard

View File

@@ -0,0 +1,110 @@
# -*- coding: utf-8 -*-
import logging
from itertools import groupby
from odoo import models, api, fields, _
class ProductionTechnologyReAdjustWizard(models.TransientModel):
_name = 'sf.production.technology.re_adjust.wizard'
_description = '制造订单工艺调整'
production_id = fields.Many2one('mrp.production', string='制造订单号')
origin = fields.Char(string='源单据')
is_technology_re_adjust = fields.Boolean(default=False)
def confirm(self):
if self.is_technology_re_adjust is True:
domain = [('origin', '=', self.origin), ('state', '=', 'confirmed')]
else:
domain = [('id', '=', self.production_id.id)]
technology_designs = self.env['sf.technology.design'].sudo().search(
[('production_id', '=', self.production_id.id), ('active', 'in', [True, False])])
productions = self.env['mrp.production'].search(domain)
for production_item in productions:
# 该制造订单的其他同一销售订单的制造订单的工艺设计处理
if production_item != self.production_id:
for td_other in production_item.technology_design_ids:
if td_other.is_auto is False:
td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id)
if not td_del or td_del.active is False:
td_other.write({'active': False})
for td_main in technology_designs:
route_other = production_item.technology_design_ids.filtered(
lambda td: td.route_id.id == td_main.route_id.id)
if not route_other and td_main.active is True:
production_item.write({'technology_design_ids': [(0, 0, {
'route_id': td_main.route_id.id,
'process_parameters_id': False if td_main.process_parameters_id is False else
self.env[
'sf.production.process.parameter'].search(
[('id', '=', td_main.process_parameters_id.id)]).id,
'sequence': td_main.sequence,
'is_auto': td_main.is_auto})]})
else:
for ro in route_other:
domain = [('production_id', '=', self.production_id.id), ('active', 'in', [True, False]),
('route_id', '=', ro.route_id.id)]
if ro.route_id.routing_type == '表面工艺':
domain += [('process_parameters_id', '=', ro.process_parameters_id.id)]
elif ro.route_id.routing_tag == 'special' and ro.is_auto is False:
display_name = ro.route_id.display_name
domain += [('name', 'ilike', display_name)]
elif ro.panel is not False:
domain += [('panel', '=', ro.panel)]
td_upd = self.env['sf.technology.design'].sudo().search(domain)
if td_upd:
ro.write({'sequence': td_upd.sequence, 'active': td_upd.active})
special_design = self.env['sf.technology.design'].sudo().search(
[('routing_tag', '=', 'special'), ('production_id', '=', production_item.id),
('is_auto', '=', False), ('active', 'in', [True, False])])
for special in special_design:
workorders_values = []
if special.active is False:
# 工单采购单外协出入库单皆需取消
domain = [('production_id', '=', special.production_id.id)]
if special.process_parameters_id:
domain += [('surface_technics_parameters_id', '=', special.process_parameters_id.id)]
else:
domain += [('name', '=', special.route_id.name)]
workorder = self.env['mrp.workorder'].search(domain)
if workorder.state != 'cancel':
workorder.write({'state': 'cancel'})
workorder.picking_ids.write({'state': 'cancel'})
workorder.picking_ids.move_ids.write({'state': 'cancel'})
purchase_order = self.env['purchase.order'].search(
[('origin', '=', workorder.production_id.origin)])
for line in purchase_order.order_line:
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id:
purchase_order.write({'state': 'cancel'})
else:
if special.route_id.routing_type == '表面工艺':
display_name = special.process_parameters_id.display_name
else:
display_name = special.route_id.display_name
workorder = self.env['mrp.workorder'].search(
[('name', '=', display_name), ('production_id', '=', special.production_id.id)])
if not workorder:
if special.route_id.routing_type == '表面工艺':
product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
workorders_values.append(
self.env[
'mrp.workorder']._json_workorder_surface_process_str(special.production_id, special,
product_production_process.seller_ids[
0].partner_id.id))
else:
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(special.production_id, special))
special.production_id.write({'workorder_ids': workorders_values})
else:
if len(workorder.blocked_by_workorder_ids) > 1:
if workorder.sequence == 1:
workorder.blocked_by_workorder_ids = None
else:
workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0]
productions._reset_work_order_sequence()
productions.get_subcontract_pick_purchase()
for item in productions:
workorders = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted(
key=lambda a: a.sequence)
workorders[0].state = 'waiting'

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="sf_production_technology_re_adjust_wizard_form_view">
<field name="name">sf.production.technology.re_adjust.wizard.form.view</field>
<field name="model">sf.production.technology.re_adjust.wizard</field>
<field name="arch" type="xml">
<form>
<sheet>
<field name="production_id" invisible="1"/>
<field name="origin" invisible="1"/>
<div>
<field name="is_technology_re_adjust" force_save="1"/>
当前制造订单,同一销售订单相同产品所生成的制造订单是否统一进行退回调整操作
</div>
<footer>
<button string="确认" name="confirm" type="object" class="oe_highlight" confirm="是否确认退回调整"/>
<button string="取消" class="btn btn-secondary" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<record id="action_sf_production_technology_re_adjust_wizard" model="ir.actions.act_window">
<field name="name">工艺退回调整</field>
<field name="res_model">sf.production.technology.re_adjust.wizard</field>
<field name="view_mode">form</field>
<!-- <field name="context">{-->
<!-- 'default_production_id': active_id}-->
<!-- </field>-->
<field name="target">new</field>
</record>
</odoo>

View File

@@ -1,10 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Part of YiZuo. See LICENSE file for full copyright and licensing details. # Part of YiZuo. See LICENSE file for full copyright and licensing details.
import logging import logging
from odoo.exceptions import UserError, ValidationError from itertools import groupby
from collections import defaultdict, namedtuple
from odoo.addons.stock.models.stock_rule import ProcurementException
from datetime import datetime
from odoo import models, api, fields, _ from odoo import models, api, fields, _
@@ -21,5 +18,47 @@ class ProductionTechnologyWizard(models.TransientModel):
domain = [('origin', '=', self.origin)] domain = [('origin', '=', self.origin)]
else: else:
domain = [('id', '=', self.production_id.id)] domain = [('id', '=', self.production_id.id)]
technology_designs = self.production_id.technology_design_ids
productions = self.env['mrp.production'].search(domain) productions = self.env['mrp.production'].search(domain)
productions._create_workorder(self.production_id) for production in productions:
if production != self.production_id:
for td_other in production.technology_design_ids:
if td_other.is_auto is False:
td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id)
if not td_del or td_del.active is False:
td_other.write({'active': False})
for td_main in technology_designs:
route_other = production.technology_design_ids.filtered(
lambda td: td.route_id.id == td_main.route_id.id)
if not route_other and td_main.active is True:
production.write({'technology_design_ids': [(0, 0, {
'route_id': td_main.route_id.id,
'process_parameters_id': False if td_main.process_parameters_id is False else self.env[
'sf.production.process.parameter'].search(
[('id', '=', td_main.process_parameters_id.id)]).id,
'sequence': td_main.sequence})]})
else:
for ro in route_other:
domain = [('production_id', '=', self.production_id.id),
('active', 'in', [True, False]),
('route_id', '=', ro.route_id.id)]
if ro.route_id.routing_type == '表面工艺':
domain += [('process_parameters_id', '=', ro.process_parameters_id.id)]
elif ro.route_id.routing_tag == 'special' and ro.is_auto is False:
display_name = ro.route_id.display_name
domain += [('name', 'ilike', display_name)]
elif ro.panel is not False:
domain += [('panel', '=', ro.panel)]
td_upd = self.env['sf.technology.design'].sudo().search(domain)
if td_upd:
ro.write({'sequence': td_upd.sequence, 'active': td_upd.active})
# special = production.technology_design_ids.filtered(
# lambda td: td.is_auto is False and td.process_parameters_id is not False)
# # if special:
productions._create_workorder(False)
productions.get_subcontract_pick_purchase()
for item in productions:
workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted(
key=lambda a: a.sequence)
if workorder[0].state in ['pending']:
workorder[0].state = 'waiting'

View File

@@ -28,6 +28,8 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
domain = [('programming_no', '=', ret['programming_no'])] domain = [('programming_no', '=', ret['programming_no'])]
if ret['manufacturing_type'] in ('scrap', 'invalid_tool_rework'): if ret['manufacturing_type'] in ('scrap', 'invalid_tool_rework'):
domain += [('state', 'not in', ['done', 'scrap', 'cancel'])] domain += [('state', 'not in', ['done', 'scrap', 'cancel'])]
else:
domain += [('state', '=', 'confirmed')]
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:
@@ -48,26 +50,21 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no']) res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no'])
return json.JSONEncoder().encode(res) return json.JSONEncoder().encode(res)
for production in productions: for production in productions:
if not production.workorder_ids: for panel in ret['processing_panel'].split(','):
production.product_id.model_processing_panel = ret['processing_panel'] # 查询状态为进行中且工序类型为CNC加工的工单
production._create_workorder(ret) cnc_workorder_has = production.workorder_ids.filtered(
productions.process_range_time() lambda ach: ach.routing_type == 'CNC加工' and ach.state not in ['progress', 'done',
else: 'rework',
for panel in ret['processing_panel'].split(','): 'cancel'] and ach.processing_panel == panel)
# 查询状态为进行中且工序类型为CNC加工的工单 if cnc_workorder_has:
cnc_workorder_has = production.workorder_ids.filtered( if cnc_workorder_has.cnc_ids:
lambda ach: ach.routing_type == 'CNC加工' and ach.state not in ['progress', 'done', cnc_workorder_has.cmm_ids.sudo().unlink()
'rework', cnc_workorder_has.cnc_ids.sudo().unlink()
'cancel'] and ach.processing_panel == panel) # request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
if cnc_workorder_has: # production)
if cnc_workorder_has.cnc_ids: cnc_workorder_has.write(
cnc_workorder_has.cmm_ids.sudo().unlink() {'cnc_ids': cnc_workorder_has.cnc_ids.sudo()._json_cnc_processing(panel, ret),
cnc_workorder_has.cnc_ids.sudo().unlink() 'cmm_ids': cnc_workorder_has.cmm_ids.sudo()._json_cmm_program(panel, ret)})
# request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
# production)
cnc_workorder_has.write(
{'cnc_ids': cnc_workorder_has.cnc_ids.sudo()._json_cnc_processing(panel, ret),
'cmm_ids': cnc_workorder_has.cmm_ids.sudo()._json_cmm_program(panel, ret)})
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(
@@ -77,7 +74,6 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
# 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)
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel) program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
files_panel = os.listdir(program_path_tmp_panel) files_panel = os.listdir(program_path_tmp_panel)
if files_panel: if files_panel:
for file in files_panel: for file in files_panel:
@@ -85,17 +81,13 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
if file_extension.lower() == '.pdf': if file_extension.lower() == '.pdf':
panel_file_path = os.path.join(program_path_tmp_panel, file) panel_file_path = os.path.join(program_path_tmp_panel, file)
logging.info('panel_file_path:%s' % panel_file_path) logging.info('panel_file_path:%s' % panel_file_path)
logging.info('更新工作指令:%s' % cnc_workorder)
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())})
logging.info('更新工作指令完成:%s' % cnc_workorder)
pre_workorder = productions.workorder_ids.filtered( pre_workorder = productions.workorder_ids.filtered(
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', 'rework' 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:
logging.info('更新加工图纸:%s' % 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())})
logging.info('更新加工图纸完成:%s' % pre_workorder)
productions.write({'programming_state': '已编程', 'work_state': '已编程'}) productions.write({'programming_state': '已编程', 'work_state': '已编程'})
logging.info('已更新制造订单编程状态:%s' % productions.ids) logging.info('已更新制造订单编程状态:%s' % productions.ids)
res.update({ res.update({

View File

@@ -244,39 +244,39 @@ class RePurchaseOrder(models.Model):
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 == '外协': server_template = self.env['product.template'].search(
server_template = self.env['product.template'].search( [('server_product_process_parameters_id', '=', pp.surface_technics_parameters_id.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_template.product_variant_id.id),
[('product_id', '=', server_template.product_variant_id.id), ('product_qty', '=', len(production_process))], limit=1, order='id desc')
('product_qty', '=', len(production_process))], limit=1, order='id desc') if not purchase_order_line:
if not purchase_order_line: server_product_process.append((0, 0, {
server_product_process.append((0, 0, { 'product_id': server_template.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_template.uom_id.id
'product_uom': server_template.uom_id.id }))
})) else:
else: for item in purchase_order_line:
for item in purchase_order_line: if production.name in production_process:
if production.name in production_process: purchase_order = self.env['purchase.order'].search(
purchase_order = self.env['purchase.order'].search( [('state', '=', 'draft'), ('origin', '=', ','.join(production_process)),
[('state', '=', 'draft'), ('origin', '=', ','.join(production_process)), ('id', '=', item.order_id.id)])
('id', '=', item.order_id.id)]) if not purchase_order:
if not purchase_order: server_product_process.append((0, 0, {
server_product_process.append((0, 0, { 'product_id': server_template.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_template.uom_id.id
'product_uom': server_template.uom_id.id }))
}))
if server_product_process: if server_product_process:
self.env['purchase.order'].sudo().create({ self.env['purchase.order'].sudo().create({
'partner_id': server_template.seller_ids.partner_id.id, 'partner_id': server_template.seller_ids[0].partner_id.id,
'origin': ','.join(production_process), 'origin': ','.join(production_process),
'state': 'draft', 'state': 'draft',
'purchase_type': 'consignment', 'purchase_type': 'consignment',
'order_line': server_product_process}) 'order_line': server_product_process})
# self.env.cr.commit() # self.env.cr.commit()
@api.onchange('order_line') @api.onchange('order_line')
def _onchange_order_line(self): def _onchange_order_line(self):