diff --git a/sf_machine_connect/views/WorkCenterBarcodes.xml b/sf_machine_connect/views/WorkCenterBarcodes.xml index 0a0cccd6..d44c8a82 100644 --- a/sf_machine_connect/views/WorkCenterBarcodes.xml +++ b/sf_machine_connect/views/WorkCenterBarcodes.xml @@ -10,6 +10,7 @@ + @@ -19,7 +20,11 @@ - + + + + + \ No newline at end of file diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index 58afdc9f..dcfd2791 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -426,18 +426,33 @@ class Manufacturing_Connect(http.Controller): res = {'Succeed': True} datas = request.httprequest.data ret = json.loads(datas) + logging.info('ret:%s' % ret) if 'DeviceId' in ret: logging.info('DeviceId:%s' % ret['DeviceId']) - workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( - [('feeder_station_destination_id.name', '=', ret['DeviceId']), - ('status', '=', '已配送'), ('type', '=', '上产线')], order='id asc') - if workpiece_delivery: - for wd in workpiece_delivery: - logging.info('wd.production_id:%s' % wd.production_id.name) - if wd.workorder_id.state == 'done' and wd.production_id.production_line_state == '待上产线': - logging.info('wd.production_line_state:%s' % wd.production_id.production_line_state) - wd.production_id.write({'production_line_state': '已上产线'}) - wd.write({'production_line_state': '已上产线'}) + for i in range(1, 5): + logging.info('F-RfidCode:%s' % i) + if f'RfidCode{i}' in ret: + rfid_code = ret[f'RfidCode{i}'] + logging.info('RfidCode:%s' % rfid_code) + domain = [ + ('feeder_station_destination_id.name', '=', ret['DeviceId']), + ('workorder_id.rfid_code', '=', rfid_code), + ('status', '=', '已配送'), + ('type', '=', '上产线') + ] + workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(domain, order='id asc') + if workpiece_delivery: + for wd in workpiece_delivery: + logging.info('wd.production_id:%s' % wd.production_id.name) + if wd.workorder_id.state == 'done' and wd.production_id.production_line_state == '待上产线': + logging.info('wd.production_line_state:%s' % wd.production_id.production_line_state) + wd.production_id.write({'production_line_state': '已上产线'}) + next_workpiece = request.env['sf.workpiece.delivery'].sudo().search( + [('workorder_id.rfid_code', '=', rfid_code), ('type', '=', '下产线'), + ('production_id', '=', wd.production_id.id)]) + if next_workpiece: + logging.info('next_workpiece:%s' % next_workpiece.delivery_num) + next_workpiece.write({'status': '待下发', 'task_delivery_time': datetime.now()}) else: res = {'Succeed': False, 'ErrorCode': 203, 'Error': '该DeviceId没有对应的已配送工件数据'} else: @@ -461,31 +476,50 @@ class Manufacturing_Connect(http.Controller): res = {'Succeed': True} datas = request.httprequest.data ret = json.loads(datas) + logging.info('ret:%s' % ret) if 'DeviceId' in ret: logging.info('DeviceId:%s' % ret['DeviceId']) - workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( - [('feeder_station_destination_id.name', '=', ret['DeviceId']), - ('status', '=', '已配送'), ('type', '=', '下产线')], order='id asc') - if workpiece_delivery: - for wd in workpiece_delivery: - logging.info('wd.production_id:%s' % wd.production_id.name) - if wd.workorder_id.state == 'done' and wd.production_id.production_line_state == '已上产线': - logging.info('wd.production_line_state:%s' % wd.production_id.production_line_state) - wd.production_id.write({'production_line_state': '已下产线'}) - logging.info('开始向agv下发下产线任务') - wd._delivery_avg() - logging.info('agv下发下产线任务已配送') - - else: - res = {'Succeed': False, 'ErrorCode': 203, 'Error': '该DeviceId没有对应的工件配送数据'} - else: - res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传DeviceId字段'} + delivery_Arr = [] + for i in range(1, 5): + logging.info('F-RfidCode:%s' % i) + if f'RfidCode{i}' in ret: + rfid_code = ret[f'RfidCode{i}'] + logging.info('RfidCode:%s' % rfid_code) + domain = [ + ('feeder_station_start_id.name', '=', ret['DeviceId']), + ('workorder_id.rfid_code', '=', rfid_code), + ('status', '=', '待下发'), + ('type', '=', '下产线') + ] + workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(domain, order='id asc') + if workpiece_delivery: + for wd in workpiece_delivery: + logging.info('wd.production_id:%s' % wd.production_id.name) + if wd.workorder_id.state == 'done' and wd.production_id.production_line_state == '已上产线': + logging.info('wd.production_line_state:%s' % wd.production_id.production_line_state) + wd.production_id.write({'production_line_state': '已下产线'}) + delivery_Arr.append({wd.id}) + next_workpiece = request.env['sf.workpiece.delivery'].sudo().search( + [('workorder_id.rfid_code', '=', rfid_code), ('type', '=', '运送空料架'), + ('production_id', '=', wd.production_id.id)]) + if next_workpiece: + logging.info('next_workpiece:%s' % next_workpiece.delivery_num) + next_workpiece.write({'status': '待下发', 'task_delivery_time': datetime.now()}) + if delivery_Arr: + logging.info('delivery_Arr:%s' % delivery_Arr) + delivery_workpiece = request.env['sf.workpiece.delivery'].sudo().search( + [('id', 'in', delivery_Arr)]) + if delivery_workpiece: + logging.info('开始向agv下发下产线任务') + delivery_workpiece._delivery_avg() + logging.info('agv下发下产线任务下发完成') except Exception as e: res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} logging.info('AGVDownProduct error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/EquipmentBaseCoordinate', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/EquipmentBaseCoordinate', type='json', auth='sf_token', methods=['GET', 'POST'], + csrf=False, cors="*") def PutEquipmentBaseCoordinate(self, **kw): """ diff --git a/sf_manufacturing/controllers/workpiece.py b/sf_manufacturing/controllers/workpiece.py index 04a4bbab..820e0002 100644 --- a/sf_manufacturing/controllers/workpiece.py +++ b/sf_manufacturing/controllers/workpiece.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import logging import json +from datetime import datetime from odoo import http from odoo.http import request @@ -24,14 +25,16 @@ class Workpiece(http.Controller): if 'reqCode' in ret: if 'method' in ret: if ret['method'] == 'end': - logging.info('backfeed-ret:%s' % ret['reqCode'].rsplit('-', 1)[0]) - workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( - [('production_id.name', '=', ret['reqCode'].rsplit('-', 1)[0]), ('delivery_num', '=', - ret['reqCode'])]) - if workpiece_delivery: - workpiece_delivery.write({'status': '已配送', 'task_completion_time': ret['reqTime']}) - else: - res = {'Succeed': False, 'ErrorCode': 203, 'Error': '该reqCode暂未查到对应的工件配送记录'} + req_codes = ret['reqCode'].split(',') + for req_code in req_codes: + workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( + [('production_id.name', '=', req_code.rsplit('-', 1)[0]), + ('delivery_num', '=', req_code.strip())]) + if workpiece_delivery: + workpiece_delivery.write({'status': '已配送', 'task_completion_time': datetime.now()}) + else: + res = {'Succeed': False, 'ErrorCode': 203, + 'Error': '该reqCode暂未查到对应的工件配送记录'} else: res = {'Succeed': False, 'ErrorCode': 204, 'Error': '未传method字段'} else: diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 082924c5..7ad53612 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -172,6 +172,7 @@ class ResMrpWorkOrder(models.Model): is_delivery = fields.Boolean('是否配送完成', default=False) rfid_code = fields.Char('RFID码') rfid_code_old = fields.Char('RFID码(已解除)') + production_line_id = fields.Many2one('sf.production.line', related='production_id.production_line_id', string='生产线', store=True) production_line_state = fields.Selection(related='production_id.production_line_state', @@ -419,10 +420,8 @@ class ResMrpWorkOrder(models.Model): for item in self.workpiece_delivery_ids: if not item.route_id: raise UserError('【工件配送】明细中请选择【任务路线】') - # if not item.workpiece_code: - # raise UserError('请对【同运工件】进行扫描') else: - if self.cnc_program_down_state == '已下发': + if item.is_cnc_program_down is True: if item.status == '待下发': return { 'name': _('确认'), @@ -773,6 +772,7 @@ class ResMrpWorkOrder(models.Model): raise UserError("请对前置三元检测定位参数进行计算定位") if not self.rfid_code: raise UserError("请扫RFID码进行绑定") + self.workpiece_delivery_ids[0].write({'status': '待下发'}) if self.picking_out_id: picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)]) if picking_out.workorder_out_id: @@ -901,6 +901,11 @@ class CNCprocessing(models.Model): # cnc_workorder.state = 'done' cnc_workorder.work_state = '已编程' cnc_workorder.programming_state = '已编程' + workpiece_delivery = self.env['sf.workpiece.delivery'].search( + [('production_id', '=', cnc_workorder.id)]) + if workpiece_delivery: + for item in workpiece_delivery: + item.is_cnc_program_down = True # cnc_workorder.time_ids.date_end = datetime.now() # cnc_workorder.button_finish() @@ -985,20 +990,11 @@ class SfWorkOrderBarcodes(models.Model): def on_barcode_scanned(self, barcode): workorder = self.env['mrp.workorder'].browse(self.ids) - workorder_preset = self.env['mrp.workorder'].search( - [('routing_type', '=', '装夹预调'), ('rfid_code', '=', barcode)]) - # workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)]) - if len(workorder_preset) <= 4: - workpiece_ids = [] - for item in workorder_preset: - if item.production_line_id.id == workorder.production_line_id.id: - workpiece_ids.append(item.production_id.id) - else: - raise UserError('工件生产线不一致,请重新确认') - if workpiece_ids: - workorder.workpiece_delivery_ids.write({'sametransport_production_ids': [(6, 0, workpiece_ids)]}) - - # raise UserError('该托盘已绑定【%s】制造订单,请先解除绑定!!!' % workorder_old.production_id.name) + # workorder_preset = self.env['mrp.workorder'].search( + # [('routing_type', '=', '装夹预调'), ('rfid_code', '=', barcode)]) + workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)]) + if workorder_old: + raise UserError('该托盘已绑定【%s】制造订单,请先解除绑定!!!' % workorder_old.production_id.name) if workorder: if workorder.routing_type == '装夹预调': if workorder.state in ['done']: @@ -1086,12 +1082,11 @@ class WorkPieceDelivery(models.Model): delivery_num = fields.Char('工件配送编码') workorder_id = fields.Many2one('mrp.workorder', string='工单', readonly=True) - production_id = fields.Many2one('mrp.production', string='制造订单', readonly=True) + production_id = fields.Many2one('mrp.production', string='制造订单号', readonly=True) production_line_id = fields.Many2one('sf.production.line', compute='_compute_production_line_id', string='目的生产线', readonly=True, store=True) plan_start_processing_time = fields.Datetime('计划开始加工时间', readonly=True) - sametransport_production_ids = fields.Many2many('mrp.production', 'rel_workpiece_production', string='同运工件编码') route_id = fields.Many2one('sf.agv.task.route', '任务路线') feeder_station_start_id = fields.Many2one('sf.agv.site', '起点接驳站') @@ -1102,66 +1097,100 @@ class WorkPieceDelivery(models.Model): [('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型') delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration') status = fields.Selection( - [('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', - default='待下发') - production_line_state = fields.Selection( - [('待上产线', '待上产线'), ('已上产线', '已上产线'), ('已下产线', '已下产线')], - string='上/下产线', default='待上产线') - cnc_program_down_state = fields.Selection([('待下发', '待下发'), ('已下发', '已下发')], - string='CNC程序下发状态', default='待下发') + [('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', ) + is_cnc_program_down = fields.Boolean('程序是否下发', default=False) @api.onchange('route_id') - def onchage_route(self): + def onchange_route(self): if self.route_id: - self.feeder_station_start_id = self.route_id.start_site_id - self.feeder_station_destination_id = self.route_id.end_site_id + self.feeder_station_start_id = self.route_id.start_site_id.id + self.feeder_station_destination_id = self.route_id.end_site_id.id # 工件配送 def button_delivery(self): - if self.cnc_program_down_state == '待下发': - if self.route_id: - if self.status == '待下发': - return { - 'name': _('确认'), - 'type': 'ir.actions.act_window', - 'view_mode': 'form', - 'res_model': 'sf.workpiece.delivery.wizard', - 'target': 'new', - 'context': { - 'default_delivery_id': self.id, - }} - else: - raise UserError('状态为【待下发】的工件记录可进行配送') + delivery_ids = [] + is_cnc_down = 0 + is_not_production_line = 0 + is_not_route = 0 + same_production_line_id = None + same_route_id = None + down_status = '待下发' + production_type = '上产线' + num = 0 + for item in self: + num += 1 + if num > 4: + raise UserError('仅限于配送1-4个制造订单,请重新选择') + if item.route_id: + if same_route_id is None: + same_route_id = item.route_id.id + if item.route_id.id != same_route_id: + is_not_route += 1 else: - raise UserError('请选择任务路线再进行配送') - else: - raise UserError(_("该制造订单还未下发CNC程序单,无法进行工件配送")) + raise UserError('请选择【任务路线】再进行配送') + # if production_type != item.type: + # raise UserError('请选择类型为【上产线】的制造订单进行配送') + if down_status != item.status: + raise UserError('请选择状态为【待下发】的制造订单进行配送') + if same_production_line_id is None: + same_production_line_id = item.production_line_id.id + if item.production_line_id.id != same_production_line_id: + is_not_production_line += 1 + if item.is_cnc_program_down is False: + is_cnc_down += 1 + if is_cnc_down == 0 and is_not_production_line == 0 and is_not_route == 0: + delivery_ids.append(item.id) + if is_cnc_down >= 1: + raise UserError('您所选择制造订单的【CNC程序】暂未下发,请在程序下发后再进行配送') + if is_not_production_line >= 1: + raise UserError('您所选择制造订单的【目的生产线】不一致,请重新确认') + if is_not_route >= 1: + raise UserError('您所选择制造订单的【任务路线】不一致,请重新确认') + if delivery_ids: + return { + 'name': _('确认'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'sf.workpiece.delivery.wizard', + 'target': 'new', + 'context': { + 'default_delivery_ids': [(6, 0, delivery_ids)], + }} # 配送至avg小车 def _delivery_avg(self): agv_site = self.env['sf.agv.site'].search([]) - # if agv_site: - # agv_site.update_site_state() + if agv_site: + agv_site.update_site_state() config = self.env['res.config.settings'].get_values() positionCode_Arr = [] - if self.feeder_station_start_id: + delivery_Arr = [] + feeder_station_start = None + feeder_station_destination = None + for item in self: + if feeder_station_start is None: + feeder_station_start = item.feeder_station_start_id.name + if feeder_station_destination is None: + feeder_station_destination = item.feeder_station_destination_id.name + delivery_Arr.append(item.delivery_num) + delivery_str = ', '.join(map(str, delivery_Arr)) + if feeder_station_start is not None: positionCode_Arr.append({ - 'positionCode': self.feeder_station_start_id.name, + 'positionCode': feeder_station_start, 'code': '00' }) - if self.feeder_station_destination_id: + if feeder_station_destination is not None: positionCode_Arr.append({ - 'positionCode': self.feeder_station_destination_id.name, + 'positionCode': feeder_station_destination, 'code': '00' }) - res = {'reqCode': self.delivery_num, 'reqTime': '', 'clientCode': '', 'tokenCode': '', + res = {'reqCode': delivery_str, 'reqTime': '', 'clientCode': '', 'tokenCode': '', 'taskTyp': 'F01', 'ctnrTyp': '', 'ctnrCode': '', 'wbCode': config['wbcode'], 'positionCodePath': positionCode_Arr, 'podCode': '', 'podDir': '', 'materialLot': '', 'priority': '', 'taskCode': '', 'agvCode': '', 'materialLot': '', 'data': ''} try: - # config['agv_rcs_url'] = 'http://172.16.10.114:8182/rcms/services/rest/hikRpcService/genAgvSchedulingTask' logging.info('AGV请求路径:%s' % config['agv_rcs_url']) logging.info('AGV-json:%s' % res) headers = {'Content-Type': 'application/json'} @@ -1169,16 +1198,16 @@ class WorkPieceDelivery(models.Model): ret = ret.json() logging.info('config-ret:%s' % ret) if ret['code'] == 0: - if self.delivery_num == ret['reqCode']: - if self.sametransport_production_ids: - for item in self.sametransport_production_ids: - sametransport_workpiece = self.search( - [('production_id', '=', item.id), ('type', '=', '上产线')]) - if sametransport_workpiece: - sametransport_workpiece.write( - {'task_delivery_time': fields.Datetime.now(), 'status': '待配送'}) - self.write( - {'task_delivery_time': fields.Datetime.now(), 'status': '待配送'}) + req_codes = ret['reqCode'].split(',') + for delivery_item in self: + for req_code in req_codes: + if delivery_item.delivery_num == req_code.strip(): + logging.info('delivery_num:%s' % delivery_item.delivery_num) + delivery_item.write({ + 'task_delivery_time': fields.Datetime.now(), + 'status': '待配送' + }) + delivery_item.workorder_id.write({'is_delivery': True}) else: raise UserError(ret['message']) except Exception as e: diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 94a9d646..df9ed02e 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -269,6 +269,13 @@ class ProductionLot(models.Model): rfid = fields.Char('Rfid', readonly=True) product_specification = fields.Char('规格', compute='_compute_product_specification', store=True) + def search_lot_put_rfid(self): + # 使用SQL将所有刀柄Rfid不满十位的值在前方补零 + self.env.cr.execute( + '''UPDATE stock_lot SET rfid = LPAD(rfid, 10, '0') WHERE rfid IS NOT NULL AND LENGTH(rfid) < 10''' + ) + self.env.cr.commit() + @api.depends('product_id') def _compute_product_specification(self): for stock in self: diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 3d822104..0e1695ef 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -67,6 +67,7 @@ progress,pending_cam,pending_processing,pending_era_cam,completed,done + diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 50566ebd..f381e481 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -23,6 +23,9 @@ + + + @@ -174,6 +177,8 @@ attrs="{'invisible': [('production_state','=', 'draft')], 'readonly': [('is_user_working', '=', True)]}" sum="real duration"/> + - @@ -265,7 +269,7 @@ placeholder="如有预调程序信息请在此处输入....."/> - + @@ -429,14 +433,14 @@ - - + + @@ -532,7 +536,8 @@ - +