diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index 632e9e4c..719ac481 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -477,7 +477,7 @@ class Manufacturing_Connect(http.Controller): logging.info('LocationChange error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def AGVToProduct(self, **kw): """ @@ -549,7 +549,7 @@ class Manufacturing_Connect(http.Controller): logging.info('AGVToProduct error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def AGVDownProduct(self, **kw): """ diff --git a/sf_manufacturing/wizard/rework_wizard.py b/sf_manufacturing/wizard/rework_wizard.py index 53fd2965..4698a994 100644 --- a/sf_manufacturing/wizard/rework_wizard.py +++ b/sf_manufacturing/wizard/rework_wizard.py @@ -25,6 +25,7 @@ class ReworkWizard(models.TransientModel): processing_panel_id = fields.Many2many('sf.processing.panel', string="加工面") is_reprogramming = fields.Boolean(string='申请重新编程', default=False) is_reprogramming_readonly = fields.Boolean(string='申请重新编程(只读)', default=False) + is_clamp_measure = fields.Boolean(string='保留装夹测量数据', default=True) reprogramming_num = fields.Integer('重新编程次数', default=0) programming_state = fields.Selection( [('待编程', '待编程'), ('编程中', '编程中'), ('已编程', '已编程'), ('已编程未下发', '已编程未下发'), @@ -35,6 +36,7 @@ class ReworkWizard(models.TransientModel): def confirm(self): if self.routing_type in ['装夹预调', 'CNC加工']: + self.is_clamp_measure = False self.workorder_id.is_rework = True self.production_id.write({'detection_result_ids': [(0, 0, { 'rework_reason': self.rework_reason, @@ -58,19 +60,15 @@ class ReworkWizard(models.TransientModel): if processing_panels_missing: processing_panels_str = ','.join(processing_panels_missing) raise UserError('您还有待处理的检测结果中为%s的加工面未选择' % processing_panels_str) - # processing_panels = set() - # for handle_item in handle_result: - # for dr_panel in self.processing_panel_id: - # if dr_panel.name == handle_item.processing_panel: - # processing_panels.add(dr_panel.name) - # if len(processing_panels) != len(handle_result): - # processing_panels_str = ','.join(processing_panels) - # return UserError(f'您还有待处理的检测结果中为{processing_panels_str}的加工面未选择') for panel in self.processing_panel_id: panel_workorder = self.production_id.workorder_ids.filtered( lambda ap: ap.processing_panel == panel.name and ap.state != 'rework') if panel_workorder: panel_workorder.write({'state': 'rework'}) + rework_clamp_workorder = max(panel_workorder.filtered( + lambda + rp: rp.processing_panel == panel.name and rp.routing_type == '装夹预调' and rp.state in [ + 'done', 'rework'])) # panel_workorder.filtered( # lambda wo: wo.routing_type == '装夹预调').workpiece_delivery_ids.filtered( # lambda wd: wd.status == '待下发').write({'status': '已取消'}) @@ -93,6 +91,43 @@ class ReworkWizard(models.TransientModel): self.production_id.detection_result_ids.filtered( lambda ap1: ap1.processing_panel == panel.name and ap1.handle_result == '待处理').write( {'handle_result': '已处理'}) + new_pre_workorder = self.production_id.workorder_ids.filtered(lambda + p: p.routing_type == '装夹预调' and p.processing_panel == panel.name and p.state not in ( + 'rework', 'done')) + if new_pre_workorder and rework_clamp_workorder and self.is_clamp_measure is True: + new_pre_workorder.write( + {'X1_axis': rework_clamp_workorder.X1_axis, 'Y1_axis': rework_clamp_workorder.Y1_axis + , 'Z1_axis': rework_clamp_workorder.Z1_axis, + 'X2_axis': rework_clamp_workorder.X2_axis + , 'Y2_axis': rework_clamp_workorder.Y2_axis, + 'Z2_axis': rework_clamp_workorder.Z2_axis + , 'X3_axis': rework_clamp_workorder.X3_axis, + 'Y3_axis': rework_clamp_workorder.Y3_axis + , 'Z3_axis': rework_clamp_workorder.Z3_axis, + 'X4_axis': rework_clamp_workorder.X4_axis + , 'Y4_axis': rework_clamp_workorder.Y4_axis, + 'Z4_axis': rework_clamp_workorder.Z4_axis + , 'X5_axis': rework_clamp_workorder.X5_axis, + 'Y5_axis': rework_clamp_workorder.Y5_axis + , 'Z5_axis': rework_clamp_workorder.Z5_axis, + 'X6_axis': rework_clamp_workorder.X6_axis + , 'Y6_axis': rework_clamp_workorder.Y6_axis, + 'Z6_axis': rework_clamp_workorder.Z6_axis + , 'X7_axis': rework_clamp_workorder.X7_axis, + 'Y7_axis': rework_clamp_workorder.Y7_axis + , 'Z7_axis': rework_clamp_workorder.Z7_axis, + 'X8_axis': rework_clamp_workorder.X8_axis + , 'Y8_axis': rework_clamp_workorder.Y8_axis, + 'Z8_axis': rework_clamp_workorder.Z8_axis + , 'X9_axis': rework_clamp_workorder.X9_axis, + 'Y9_axis': rework_clamp_workorder.Y9_axis + , 'Z9_axis': rework_clamp_workorder.Z9_axis, + 'X10_axis': rework_clamp_workorder.X10_axis + , 'Y10_axis': rework_clamp_workorder.Y10_axis, + 'Z10_axis': rework_clamp_workorder.Z10_axis + , 'X_deviation_angle': rework_clamp_workorder.X_deviation_angle, + 'material_center_point': rework_clamp_workorder.material_center_point + }) if self.is_reprogramming is False: if self.programming_state in ['已编程', '已下发']: if self.reprogramming_num >= 1 and self.programming_state == '已编程': @@ -149,9 +184,7 @@ class ReworkWizard(models.TransientModel): 'cmm_ids': new_cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel.name, ret), 'cnc_worksheet': cnc_rework.cnc_worksheet}) - new_pre_workorder = self.production_id.workorder_ids.filtered(lambda - p: p.routing_type == '装夹预调' and p.processing_panel == panel.name and p.state not in ( - 'rework', 'done')) + if new_pre_workorder: pre_rework = max(self.production_id.workorder_ids.filtered( lambda pr: pr.processing_panel == panel.name and pr.state in ( diff --git a/sf_manufacturing/wizard/rework_wizard_views.xml b/sf_manufacturing/wizard/rework_wizard_views.xml index 8ba3f4dd..d8cf0fb9 100644 --- a/sf_manufacturing/wizard/rework_wizard_views.xml +++ b/sf_manufacturing/wizard/rework_wizard_views.xml @@ -14,17 +14,25 @@ + +
+ 保留装夹测量数据 + + +
- 注意: 该制造订单产品已申请重新编程次数为,且当前编程状态为 - + + 注意: 该制造订单产品已申请重新编程次数为,且当前编程状态为 + +
申请重新编程 diff --git a/sf_stock/__init__.py b/sf_stock/__init__.py new file mode 100644 index 00000000..511a0ca3 --- /dev/null +++ b/sf_stock/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import controllers +from . import models \ No newline at end of file diff --git a/sf_stock/__manifest__.py b/sf_stock/__manifest__.py new file mode 100644 index 00000000..f22004e5 --- /dev/null +++ b/sf_stock/__manifest__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +{ + 'name': "sf_stock", + + 'summary': """ + Short (1 phrase/line) summary of the module's purpose, used as + subtitle on modules listing or apps.openerp.com""", + + 'description': """ + Long description of module's purpose + """, + + 'author': "My Company", + 'website': "https://www.yourcompany.com", + + # Categories can be used to filter modules in modules listing + # Check https://github.com/odoo/odoo/blob/16.0/odoo/addons/base/data/ir_module_category_data.xml + # for the full list + 'category': 'Uncategorized', + 'version': '0.1', + + # any module necessary for this one to work correctly + 'depends': ['sf_sale', 'stock'], + + # always loaded + 'data': [ + # 'security/ir.model.access.csv', + 'views/stock_picking.xml', + ], + # only loaded in demonstration mode + 'demo': [ + 'demo/demo.xml', + ], + 'installable': True, + 'application': True, +} diff --git a/sf_stock/controllers/__init__.py b/sf_stock/controllers/__init__.py new file mode 100644 index 00000000..457bae27 --- /dev/null +++ b/sf_stock/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/sf_stock/controllers/controllers.py b/sf_stock/controllers/controllers.py new file mode 100644 index 00000000..af35ee1d --- /dev/null +++ b/sf_stock/controllers/controllers.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# from odoo import http + + +# class SfStock(http.Controller): +# @http.route('/sf_stock/sf_stock', auth='public') +# def index(self, **kw): +# return "Hello, world" + +# @http.route('/sf_stock/sf_stock/objects', auth='public') +# def list(self, **kw): +# return http.request.render('sf_stock.listing', { +# 'root': '/sf_stock/sf_stock', +# 'objects': http.request.env['sf_stock.sf_stock'].search([]), +# }) + +# @http.route('/sf_stock/sf_stock/objects/', auth='public') +# def object(self, obj, **kw): +# return http.request.render('sf_stock.object', { +# 'object': obj +# }) diff --git a/sf_stock/demo/demo.xml b/sf_stock/demo/demo.xml new file mode 100644 index 00000000..726c51be --- /dev/null +++ b/sf_stock/demo/demo.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/sf_stock/models/__init__.py b/sf_stock/models/__init__.py new file mode 100644 index 00000000..c62a4dff --- /dev/null +++ b/sf_stock/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import stock_picking \ No newline at end of file diff --git a/sf_stock/models/stock_picking.py b/sf_stock/models/stock_picking.py new file mode 100644 index 00000000..82ce7ea5 --- /dev/null +++ b/sf_stock/models/stock_picking.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +import json +import requests +from odoo import models, fields, api + +from odoo.exceptions import UserError +import logging +from odoo.tools import date_utils + +_logger = logging.getLogger(__name__) + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + cancel_backorder_ids = fields.Boolean(default=False, string='是否取消后置单据') + + # 重写验证,下发发货到bfm + def button_validate(self): + info = super(StockPicking, self).button_validate() + if self.picking_type_code == 'outgoing': + self.send_to_bfm() + return info + + def deal_move_ids(self, send_move_ids, send_move_line_ids): + move_ids = [] # 本次发货单 + move_line_ids = [] # 本次发货单行 + if send_move_ids: + for item in send_move_ids: + val = { + 'name': item.product_id.upload_model_file.display_name, + 'quantity_done': item.quantity_done, + 'date': date_utils.json_default(item.date) if item.date else None, + 'description_picking': item.description_picking, + 'date_deadline': date_utils.json_default(item.date_deadline) if item.date_deadline else None, + 'product_uom_qty': item.product_uom_qty, + 'sequence': item.sequence, + 'price_unit': item.price_unit, + 'priority': item.priority, + 'state': item.state, + } + move_ids.append(val) + for item in send_move_line_ids: + val = { + 'qty_done': item.qty_done, + 'reserved_qty': item.reserved_qty, + 'reserved_uom_qty': item.reserved_uom_qty, + 'date': date_utils.json_default(item.date) if item.date else None, + 'description_picking': item.description_picking, + 'state': item.state, + } + move_line_ids.append(val) + return move_ids, move_line_ids + + def deal_send_backorder_id(self, backorder_ids1): + backorder_ids = [] + + if backorder_ids1: + for item in backorder_ids1: + move_ids, move_line_ids = self.deal_move_ids(item.move_ids, item.move_line_ids) + val = { + 'receiverName': item.receiverName, + 'name': item.sale_id.default_code, + 'send_no': item.name, + 'scheduled_date': date_utils.json_default(item.scheduled_date) if item.scheduled_date else None, + 'date': date_utils.json_default(item.date) if item.date else None, + 'date_deadline': date_utils.json_default(item.date_deadline) if item.date_deadline else None, + 'date_done': date_utils.json_default(item.date_done) if item.date_done else None, + 'move_ids': move_ids, + 'move_line_ids': move_line_ids, + 'state': item.state, + 'move_type': item.move_type, + } + backorder_ids.append(val) + return backorder_ids + + def send_to_bfm(self): + skip_backorder = self.env.context.get('skip_backorder') + # 下发发货到bfm + config = self.env['res.config.settings'].get_values() + move_ids, move_line_ids = self.deal_move_ids(self.move_ids, self.move_line_ids) + data = { + 'params': { + 'receiverName': self.receiverName, + 'priority': self.priority, + 'name': self.sale_id.default_code, + 'send_no': self.name, + 'scheduled_date': date_utils.json_default(self.scheduled_date) if self.scheduled_date else None, + 'date': date_utils.json_default(self.date) if self.date else None, + 'date_deadline': date_utils.json_default(self.date_deadline) if self.date_deadline else None, + 'date_done': date_utils.json_default(self.date_done) if self.date_done else None, + 'move_ids': move_ids, + 'move_line_ids': move_line_ids, + 'state': self.state, + 'backorder_id': self.deal_send_backorder_id(self.backorder_id), + 'backorder_ids': self.deal_send_backorder_id(self.backorder_ids), + 'cancel_backorder_ids': skip_backorder, + 'move_type': self.move_type, + }, + } + url1 = config['bfm_url_new'] + '/api/stock/deliver_goods' + json_str = json.dumps(data) + print('json_str', json_str) + r = requests.post(url1, json=data, data=None) + if r.status_code == 200: + result = json.loads(r.json()['result']) + if result['code'] != 200: + raise UserError(result['message'] or '工厂发货下发bfm失败') + else: + raise UserError('工厂发货下发bfm失败') diff --git a/sf_stock/security/ir.model.access.csv b/sf_stock/security/ir.model.access.csv new file mode 100644 index 00000000..af1bcbaf --- /dev/null +++ b/sf_stock/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_sf_stock_sf_stock,sf_stock.sf_stock,model_sf_stock_sf_stock,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/sf_stock/views/stock_picking.xml b/sf_stock/views/stock_picking.xml new file mode 100644 index 00000000..7750ca76 --- /dev/null +++ b/sf_stock/views/stock_picking.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file