diff --git a/sf_hr/__manifest__.py b/sf_hr/__manifest__.py index aaf9cfc7..c0bd63ef 100644 --- a/sf_hr/__manifest__.py +++ b/sf_hr/__manifest__.py @@ -10,6 +10,8 @@ 'depends': ['hr'], 'data': [ 'views/hr_employee.xml', + 'views/res_config_settings_views.xml', + 'data/cron_data.xml', ], 'demo': [ ], diff --git a/sf_hr/data/cron_data.xml b/sf_hr/data/cron_data.xml new file mode 100644 index 00000000..4757b5c2 --- /dev/null +++ b/sf_hr/data/cron_data.xml @@ -0,0 +1,15 @@ + + + + 员工企微id同步 + + code + model._employee_info_sync() + 1 + days + -1 + + + + + \ No newline at end of file diff --git a/sf_hr/models/__init__.py b/sf_hr/models/__init__.py index 633f8661..ffe76391 100644 --- a/sf_hr/models/__init__.py +++ b/sf_hr/models/__init__.py @@ -1,2 +1,4 @@ # -*- coding: utf-8 -*- +from . import hr_employee +from . import res_config_setting diff --git a/sf_hr/models/hr_employee.py b/sf_hr/models/hr_employee.py new file mode 100644 index 00000000..8cf5595d --- /dev/null +++ b/sf_hr/models/hr_employee.py @@ -0,0 +1,26 @@ +import logging +import requests +from odoo import models, fields, api, _ + +_logger = logging.getLogger(__name__) + + +class JkmPracticeEmployee(models.Model): + _inherit = 'hr.employee' + _description = '员工信息' + + we_id = fields.Char(string='企微ID', index=True) + + def _employee_info_sync(self): + url = '/api/get/organization' + config = self.env['res.config.settings'].get_values() + ret = requests.post((config['ims_url'] + url), json={}, data={}) + result = ret.json()['result'] + if result['code'] == 200: + if result['employee_list']: + for employee_info in result['employee_list']: + if employee_info['work_email']: + self.sudo().search([('work_email', '=', employee_info['work_email'])]).write( + {'we_id': employee_info['we_id']}) + else: + logging.info('_employee_info_sync error:%s' % result['message']) diff --git a/sf_hr/models/res_config_setting.py b/sf_hr/models/res_config_setting.py new file mode 100644 index 00000000..f0d6dae4 --- /dev/null +++ b/sf_hr/models/res_config_setting.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +import logging +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class ResIMSConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + ims_url = fields.Char('综合管理系统访问地址') + + @api.model + def get_values(self): + """ + 重载获取参数的方法,参数都存在系统参数中 + :return: + """ + values = super(ResIMSConfigSettings, self).get_values() + config = self.env['ir.config_parameter'].sudo() + ims_url = config.get_param('ims_url', default='') + values.update( + ims_url=ims_url, + ) + return values + + def set_values(self): + super(ResIMSConfigSettings, self).set_values() + ir_config = self.env['ir.config_parameter'].sudo() + ir_config.set_param("ims_url", self.ims_url or "") diff --git a/sf_hr/views/hr_employee.xml b/sf_hr/views/hr_employee.xml index a3db9076..c2b39112 100644 --- a/sf_hr/views/hr_employee.xml +++ b/sf_hr/views/hr_employee.xml @@ -7,7 +7,16 @@ - 1 + 1 + + + + + + + + + diff --git a/sf_hr/views/res_config_settings_views.xml b/sf_hr/views/res_config_settings_views.xml new file mode 100644 index 00000000..75ee6551 --- /dev/null +++ b/sf_hr/views/res_config_settings_views.xml @@ -0,0 +1,28 @@ + + + + + res.config.settings.finance.view.form.extend + res.config.settings + + + +
+

综合管理系统接口配置

+
+
+
+
+
+
+
+
+
+
+ + + + + diff --git a/sf_machine_connect/views/res_config_settings_views.xml b/sf_machine_connect/views/res_config_settings_views.xml index fa3ba59c..b8a681a2 100644 --- a/sf_machine_connect/views/res_config_settings_views.xml +++ b/sf_machine_connect/views/res_config_settings_views.xml @@ -24,7 +24,7 @@

获取检测报告服务配置

-
+
@@ -38,6 +38,18 @@
+ +
+
+ +
+
+
+
+
+
+
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 23fd8c79..5de5e780 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -144,6 +144,8 @@ class ResMrpWorkOrder(models.Model): # 是否绑定托盘 is_trayed = fields.Boolean(string='是否绑定托盘', default=False) + tag_type = fields.Selection([("重新加工", "重新加工")], string="标签", tracking=True) + @api.depends('name', 'production_id.name') def _compute_surface_technics_picking_ids(self): for workorder in self: @@ -426,7 +428,8 @@ class ResMrpWorkOrder(models.Model): logging.info('local_file_path:%s' % local_file_path) remote_path = '/home/ftp/ftp_root/ThreeTest/XT/Before/' + local_filename logging.info('remote_path:%s' % remote_path) - if not ftp.file_exists(remote_path): + is_get_detection_file = self.env['ir.config_parameter'].sudo().get_param('is_get_detection_file') + if not is_get_detection_file: paload_data = { "filename": local_filename } @@ -603,6 +606,8 @@ class ResMrpWorkOrder(models.Model): print("(%.2f,%.2f)" % (x, y)) self.material_center_point = ("(%.2f,%.2f,%.2f)" % (x, y, z)) self.X_deviation_angle = jdz + logging.info("坯料中心点坐标:(%.2f,%.2f)" % (x, y)) + logging.info("X轴偏差度数:%.2f" % jdz) # 将补偿值写入CNC加工工单 workorder = self.env['mrp.workorder'].browse(self.ids) work = workorder.production_id.workorder_ids @@ -705,6 +710,7 @@ class ResMrpWorkOrder(models.Model): 'date_planned_finished': datetime.now() + timedelta(days=1), 'duration_expected': duration_expected, 'duration': 0, + 'tag_type': '重新加工' if item is False else False, 'cnc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cnc.processing']._json_cnc_processing( k, item), 'cmm_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k, @@ -1183,8 +1189,10 @@ class ResMrpWorkOrder(models.Model): if not record.rfid_code and record.is_rework is False: raise UserError("请扫RFID码进行绑定") if record.is_rework is False: - if not record.material_center_point or record.X_deviation_angle <= 0: - raise UserError("坯料中心点为空或X偏差角度小于等于0") + if not record.material_center_point: + raise UserError("坯料中心点为空,请检查") + if record.X_deviation_angle <= 0: + raise UserError("X偏差角度小于等于0,请检查!本次计算的X偏差角度为:%s" % record.X_deviation_angle) record.process_state = '待加工' # record.write({'process_state': '待加工'}) record.production_id.process_state = '待加工' @@ -1565,6 +1573,8 @@ class SfWorkOrderBarcodes(models.Model): def on_barcode_scanned(self, barcode): logging.info('Rfid:%s' % barcode) + if 'O-CMD' in barcode: + return None workorder = self.env['mrp.workorder'].browse(self.ids) # workorder_preset = self.env['mrp.workorder'].search( # [('routing_type', '=', '装夹预调'), ('rfid_code', '=', barcode)]) diff --git a/sf_manufacturing/models/res_config_setting.py b/sf_manufacturing/models/res_config_setting.py index f3a87ca4..984ba223 100644 --- a/sf_manufacturing/models/res_config_setting.py +++ b/sf_manufacturing/models/res_config_setting.py @@ -4,11 +4,15 @@ from odoo import models, fields, api class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - is_agv_task_dispatch = fields.Boolean('是否下发AGV任务', default=False) - wbcode = fields.Char('地码') - agv_code = fields.Char(string='agv编号') agv_rcs_url = fields.Char(string='avg_rcs访问地址', default='http://172.16.10.114:8182/rcms/services/rest/hikRpcService/genAgvSchedulingTask') + wbcode = fields.Char('地码') + agv_code = fields.Char(string='agv编号') + task_type_no = fields.Char('任务单类型编号') + + is_agv_task_dispatch = fields.Boolean('是否下发AGV任务', default=False) + # 是否重新获取检测文件 + is_get_detection_file = fields.Boolean(string='重新获取检测文件', default=False) @api.model def get_values(self): @@ -18,19 +22,21 @@ class ResConfigSettings(models.TransientModel): wbcode = config.get_param('wbcode', default='') agv_code = config.get_param('agv_code', default='') is_agv_task_dispatch = config.get_param('is_agv_task_dispatch') - + is_get_detection_file = config.get_param('is_get_detection_file') values.update( - is_agv_task_dispatch=is_agv_task_dispatch, - agv_code=agv_code, agv_rcs_url=agv_rcs_url, wbcode=wbcode, + agv_code=agv_code, + is_agv_task_dispatch=is_agv_task_dispatch, + is_get_detection_file=is_get_detection_file ) return values def set_values(self): super(ResConfigSettings, self).set_values() config = self.env['ir.config_parameter'].sudo() - config.set_param("is_agv_task_dispatch", self.is_agv_task_dispatch or False) config.set_param("agv_rcs_url", self.agv_rcs_url or "") config.set_param("wbcode", self.wbcode or "") config.set_param("agv_code", self.agv_code or "") + config.set_param("is_agv_task_dispatch", self.is_agv_task_dispatch or False) + config.set_param("is_get_detection_file", self.is_get_detection_file or False) diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index bb451f51..e38f502f 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -32,6 +32,8 @@ + @@ -43,11 +45,11 @@ - - - - - + + + + + {'invisible': ['|', '|', '|','|','|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), @@ -165,8 +167,8 @@ - - + +
@@ -514,8 +519,8 @@ -
-
-
- - -
diff --git a/sf_manufacturing/wizard/workpiece_delivery_wizard.py b/sf_manufacturing/wizard/workpiece_delivery_wizard.py index 472910f9..10171806 100644 --- a/sf_manufacturing/wizard/workpiece_delivery_wizard.py +++ b/sf_manufacturing/wizard/workpiece_delivery_wizard.py @@ -184,7 +184,8 @@ class WorkpieceDeliveryWizard(models.TransientModel): if not barcode.isdigit(): # 判断是否是AGV接驳站名称 agv_site = self.env['sf.agv.site'].search([('name', '=', barcode)]) - self.feeder_station_start_id = agv_site.id # 修正:移除 .id + if agv_site: + self.feeder_station_start_id = agv_site.id # 修正:移除 .id return if delivery_type == '上产线': @@ -206,6 +207,9 @@ class WorkpieceDeliveryWizard(models.TransientModel): workorder.production_line_id.id != self.production_ids[0].production_line_id.id): raise UserError(f'该rfid对应的制造订单号为{workorder.production_id.name}的目的生产线不一致') + # 调用打印成品条码方法 + workorder.print_method() + # 将对象添加到对应的同模型且是多对多类型里 self.production_ids |= workorder.production_id self.workorder_ids |= workorder diff --git a/sf_message/models/sf_message_sale.py b/sf_message/models/sf_message_sale.py index 2f9a9c01..d8d3bd21 100644 --- a/sf_message/models/sf_message_sale.py +++ b/sf_message/models/sf_message_sale.py @@ -4,3 +4,8 @@ from odoo import models, fields, api, _ class SFMessageSale(models.Model): _name = 'sale.order' _inherit = ['sale.order', 'sf.message.template'] + + # def create(self): + # res = super(SFMessageSale, self).create() + # if res is True: + diff --git a/sf_message/models/sf_message_template.py b/sf_message/models/sf_message_template.py index 5f695a52..ea6e4222 100644 --- a/sf_message/models/sf_message_template.py +++ b/sf_message/models/sf_message_template.py @@ -8,30 +8,6 @@ class SfMessageTemplate(models.Model): _description = u'消息模板' name = fields.Char(string=u"名称", required=True) - # type = fields.Selection([ - # ('待接单', '待接单'), - # ('待排程', '待排程'), - # ('坯料采购', '坯料采购'), - # ('坯料发料', '坯料发料'), - # ('待编程', '待编程'), - # ('调拨入库', '调拨入库'), - # ('功能刀具组装', '功能刀具组装'), - # ('功能刀具寿命到期', '功能刀具寿命到期'), - # ('程序用刀计划异常', '程序用刀计划异常'), - # ('工单无CNC程序', '工单无CNC程序'), - # ('生产线无功能刀具', '生产线无功能刀具'), - # ('工单无定位数据', '工单无定位数据'), - # ('工单FTP无文件', '工单FTP无文件'), - # ('工单加工失败', '工单加工失败'), - # ('设备故障及异常', '设备故障及异常'), - # ('工单逾期预警', '工单逾期预警'), - # ('工单已逾期', '工单已逾期'), - # ('销售订单逾期', '销售订单逾期'), - # ('销售订单已逾期', '销售订单已逾期'), - # ('待质量判定', '待质量判定'), - # ('生产完工待入库', '生产完工待入库'), - # ('订单发货', '订单发货') - # ], string='类型', required=True) description = fields.Char(string=u"描述") content = fields.Html(string=u"内容", render_engine='qweb', translate=True, prefetch=True, sanitize=False) msgtype = fields.Selection( @@ -41,6 +17,9 @@ class SfMessageTemplate(models.Model): notification_employee_ids = fields.Many2many('hr.employee', string=u'员工', domain="[('department_id', '=',notification_department_id)]", required=True) + is_send_time = fields.Boolean(string=u"定时发送", default=False) + send_time_1 = fields.Integer('发送时间点1') + send_time_2 = fields.Integer('发送时间点2') active = fields.Boolean(string=u"是否有效", default=True) @api.onchange('notification_department_id') diff --git a/sf_message/views/sf_message_template_view.xml b/sf_message/views/sf_message_template_view.xml index 9680507a..ff1bb74e 100644 --- a/sf_message/views/sf_message_template_view.xml +++ b/sf_message/views/sf_message_template_view.xml @@ -18,11 +18,14 @@ - + + + + @@ -37,9 +40,12 @@ - + + + + diff --git a/sf_mrs_connect/models/res_config_setting.py b/sf_mrs_connect/models/res_config_setting.py index ca7c667e..72b04e92 100644 --- a/sf_mrs_connect/models/res_config_setting.py +++ b/sf_mrs_connect/models/res_config_setting.py @@ -113,9 +113,7 @@ class ResConfigSettings(models.TransientModel): token=token, sf_secret_key=sf_secret_key, sf_url=sf_url, - agv_rcs_url=agv_rcs_url, - wbcode=wbcode, - agv_code=agv_code, + center_control_url=center_control_url, center_control_Authorization=center_control_Authorization, ftp_host=ftp_host, @@ -132,6 +130,7 @@ class ResConfigSettings(models.TransientModel): ir_config.set_param("token", self.token or "") ir_config.set_param("sf_secret_key", self.sf_secret_key or "") ir_config.set_param("sf_url", self.sf_url or "") + ir_config.set_param("center_control_url", self.center_control_url or "") ir_config.set_param("center_control_Authorization", self.center_control_Authorization or "") ir_config.set_param("ftp_host", self.ftp_host or "") diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index d3f9c585..97ef47e5 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -931,13 +931,6 @@ class SfStockMoveLine(models.Model): if not record.destination_location_id.product_id: record.destination_location_id.product_id = record.product_id.id - @api.model_create_multi - def create(self, vals_list): - - records = super(SfStockMoveLine, self).create(vals_list) - self.put_shelf_location(records) - return records - class SfStockPicking(models.Model): _inherit = 'stock.picking' @@ -1122,6 +1115,12 @@ class SfPickingType(models.Model): 'sf_warehouse.group_sf_stock_manager' ) + def _get_action(self, action_xmlid): + action = super(SfPickingType, self)._get_action(action_xmlid) + if not self.env.user.has_group('base.group_system'): + action['context']['create'] = False + return action + class CustomStockMove(models.Model): _name = 'stock.move' diff --git a/sf_warehouse/views/view.xml b/sf_warehouse/views/view.xml index fadaa58f..10be546c 100644 --- a/sf_warehouse/views/view.xml +++ b/sf_warehouse/views/view.xml @@ -4,6 +4,7 @@ {'search_default_groupby_code':1} + [('name', '!=', '制造')] diff --git a/sf_warehouse/wizard/wizard.py b/sf_warehouse/wizard/wizard.py index 62ed5771..a6fd68d4 100644 --- a/sf_warehouse/wizard/wizard.py +++ b/sf_warehouse/wizard/wizard.py @@ -77,18 +77,20 @@ class ShelfLocationWizard(models.TransientModel): def confirm_the_change(self): if self.destination_barcode_id: + stocks = [] if self.lot_id: self.current_barcode_id.product_sn_id = False self.destination_barcode_id.product_sn_id = self.lot_id.id - self.create_stock_moves(self.lot_id, 1) + stocks = self.create_stock_moves(self.lot_id, 1) elif self.current_product_sn_ids: for current_product_sn_id in self.current_product_sn_ids: - self.create_stock_moves(current_product_sn_id.lot_id, current_product_sn_id.qty_num) + stocks = self.create_stock_moves(current_product_sn_id.lot_id, current_product_sn_id.qty_num) current_product_sn_id.write({ 'qty_num': 0 }) else: raise ValidationError('没有需要变更的批次/序列号!') + self.env['stock.move.line'].sudo().put_shelf_location(stocks[-1]) else: raise ValidationError('请选择目标货位编码!')