From 443a21a0cc000341a17192007880948a4bb915b4 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Fri, 25 Apr 2025 11:46:05 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E5=A4=96=E5=8D=8F?= =?UTF-8?q?=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rchase_request_line_make_purchase_order.py | 3 + sf_manufacturing/models/mrp_production.py | 3 +- sf_manufacturing/models/mrp_workorder.py | 11 +- sf_manufacturing/models/purchase_order.py | 112 +++++++++++++----- sf_sale/models/sale_order.py | 1 + 5 files changed, 90 insertions(+), 40 deletions(-) diff --git a/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py index 83bf1f39..16248b7b 100644 --- a/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py +++ b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py @@ -32,6 +32,7 @@ class PurchaseRequestLineMakePurchaseOrder(models.TransientModel): line.company_id, line.request_id.origin, ) + # po_data.update({'related_product':line.related_product.id}) purchase = purchase_obj.create(po_data) # Look for any other PO line in the selected PO with same @@ -63,6 +64,8 @@ class PurchaseRequestLineMakePurchaseOrder(models.TransientModel): po_line_data = self._prepare_purchase_order_line(purchase, item) if item.keep_description: po_line_data["name"] = item.name + if line.related_product: + po_line_data.update({'related_product': line.related_product.id}) po_line = po_line_obj.create(po_line_data) po_line_product_uom_qty = po_line.product_uom._compute_quantity( po_line.product_uom_qty, alloc_uom diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index e82b1b40..c051126c 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -934,6 +934,7 @@ class MrpProduction(models.Model): cur_request_line.pop('group_id', None) cur_request_line.pop('production_name', None) self.env["purchase.request.line"].create(cur_request_line) + pr.button_approved() # 外协出入库单处理 def get_subcontract_pick_purchase(self): @@ -961,7 +962,7 @@ class MrpProduction(models.Model): if not sorted_workorders: return for workorders in reversed(sorted_workorders): - self.env['stock.picking'].create_outcontract_picking(workorders, production, sorted_workorders) + # self.env['stock.picking'].create_outcontract_picking(workorders, production, sorted_workorders) # self.env['purchase.order'].get_purchase_order(workorders, production, product_id_to_production_names) purchase_request_line = purchase_request_line + self.env['purchase.order'].get_purchase_request( workorders, production) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index a36e4b9d..036cfdae 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1243,7 +1243,8 @@ class ResMrpWorkOrder(models.Model): return workorders_values_str def _process_compute_state(self): - for workorder in self: + sorted_workorders = sorted(self, key=lambda x: x.sequence) + for workorder in sorted_workorders: # 如果工单的工序没有进行排序则跳出循环 if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0): continue @@ -1302,13 +1303,6 @@ class ResMrpWorkOrder(models.Model): workorder.state = 'ready' elif workorder.state != 'waiting': workorder.state = 'waiting' - # =========== 特殊工艺工单处理 =================== - # if workorder.routing_type == '表面工艺' and workorder.is_subcontrac: - # purchase_order = self.env['purchase.order'].search( - # [('origin', 'ilike', workorder.production_id.name)]) - # if purchase_order.picking_ids.filtered(lambda p: p.state in ['waiting', 'confirmed', 'assigned']): - # workorder.state = 'waiting' - # continue if workorder.technology_design_id.routing_tag == 'special': if workorder.is_subcontract is False: workorder.state = 'ready' @@ -1330,6 +1324,7 @@ class ResMrpWorkOrder(models.Model): else: workorder.state = 'waiting' + @api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state', 'production_id.tool_state', 'production_id.schedule_state', 'sequence', 'production_id.programming_state') diff --git a/sf_manufacturing/models/purchase_order.py b/sf_manufacturing/models/purchase_order.py index a919b3be..833f9fb8 100644 --- a/sf_manufacturing/models/purchase_order.py +++ b/sf_manufacturing/models/purchase_order.py @@ -59,6 +59,86 @@ class PurchaseOrder(models.Model): production_id = self.env['mrp.production'].search([('origin', 'in', origins)]) purchase.production_count = len(production_id) + def process_replenish(self,production,total_qty): + record = self + bom_line_id = production.bom_id.bom_line_ids + replenish = self.env['stock.warehouse.orderpoint'].search([ + ('product_id', '=', bom_line_id.product_id.id), + ( + 'location_id', '=', self.env.ref('sf_stock.stock_location_outsourcing_material_receiving_area').id), + # ('state', 'in', ['draft', 'confirmed']) + ], limit=1) + if not replenish: + replenish_model = self.env['stock.warehouse.orderpoint'] + replenish = replenish_model.create({ + 'product_id': bom_line_id.product_id.id, + 'location_id': self.env.ref( + 'sf_stock.stock_location_outsourcing_material_receiving_area').id, + 'route_id': self.env.ref('sf_stock.stock_route_process_outsourcing').id, + 'group_id': record.group_id.id, + 'qty_to_order': total_qty, + 'origin': record.name, + }) + else: + replenish.write({ + 'product_id': bom_line_id.product_id.id, + 'location_id': self.env.ref( + 'sf_stock.stock_location_outsourcing_material_receiving_area').id, + 'route_id': self.env.ref('sf_stock.stock_route_process_outsourcing').id, + 'group_id': record.group_id.id, + 'qty_to_order': total_qty + replenish.qty_to_order, + 'origin': record.name + ',' + replenish.origin, + }) + replenish.action_replenish() + + def outsourcing_service_replenishment(self): + record = self + if record.purchase_type != 'consignment': + return + grouped_lines = {} + for line in record.order_line: + if line.related_product.id not in grouped_lines: + grouped_lines[line.related_product.id] = [] + grouped_lines[line.related_product.id].append(line) + for product_id,lines in grouped_lines.items(): + production = self.env['mrp.production'].search([('product_id', '=', product_id)], limit=1) + if not production: + continue + total_qty = sum(line.product_qty for line in lines) + record.process_replenish(production,total_qty) + for product_id,lines in grouped_lines.items(): + productions = self.env['mrp.production'].search([('product_id', '=', product_id)], limit=1) + if not productions: + continue + # production.bom_id.bom_line_ids.product_id + location_id = self.env['stock.location'].search([('name', '=', '制造前')]) + quants = self.env['stock.quant'].search([ + ('product_id', '=', product_id), + ('location_id', '=', location_id.id) + ]) + total_qty = sum(quants.mapped('quantity')) # 计算该位置的总库存量 + is_available = total_qty > 0 + if not is_available: + continue + for production_id in productions: + work_ids = production_id.workorder_ids.filtered( + lambda wk: wk.state not in ['done', 'rework', 'cancel']) + if not work_ids: + continue + min_sequence_wk = min(work_ids, key=lambda wk: wk.sequence) + if min_sequence_wk.is_subcontract: + picking_id = production_id.picking_ids.filtered( + lambda wk: wk.location_id.name == '制造前' and wk.location_dest_id.name == '外协加工区') + move_out = picking_id.move_id + for mo in move_out: + if mo.state != 'done': + mo.write({'state': 'assigned', 'production_id': False}) + if not mo.move_line_ids: + self.env['stock.move.line'].create( + mo.get_move_line(production_id, min_sequence_wk)) + # product = self.env['mrp.production'].search([('product_id', '=', product_id)], limit=1) + # match = re.search(r'(S\d{5}-\d)',product.name) + # pass def button_confirm(self): for record in self: for line in record.order_line: @@ -66,37 +146,7 @@ class PurchaseOrder(models.Model): raise UserError('请对【产品】中的【数量】进行输入') if line.price_unit <= 0: raise UserError('请对【产品】中的【单价】进行输入') - if record.purchase_type == 'consignment': - bom_line_id = record.order_line[0].purchase_request_lines.request_id.bom_id.bom_line_ids - replenish = self.env['stock.warehouse.orderpoint'].search([ - ('product_id', '=', bom_line_id.product_id.id), - ( - 'location_id', '=', self.env.ref('sf_stock.stock_location_outsourcing_material_receiving_area').id), - # ('state', 'in', ['draft', 'confirmed']) - ], limit=1) - if not replenish: - replenish_model = self.env['stock.warehouse.orderpoint'] - replenish = replenish_model.create({ - 'product_id': bom_line_id.product_id.id, - 'location_id': self.env.ref( - 'sf_stock.stock_location_outsourcing_material_receiving_area').id, - 'route_id': self.env.ref('sf_stock.stock_route_process_outsourcing').id, - 'group_id': record.group_id.id, - 'qty_to_order': 1, - 'origin': record.name, - }) - else: - replenish.write({ - 'product_id': bom_line_id.product_id.id, - 'location_id': self.env.ref( - 'sf_stock.stock_location_outsourcing_material_receiving_area').id, - 'route_id': self.env.ref('sf_stock.stock_route_process_outsourcing').id, - 'group_id': record.group_id.id, - 'qty_to_order': 1 + replenish.qty_to_order, - 'origin': record.name + ',' + replenish.origin, - }) - replenish.action_replenish() - + record.outsourcing_service_replenishment() return super(PurchaseOrder, self).button_confirm() diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 279ac895..ccb25258 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -390,6 +390,7 @@ class RePurchaseOrder(models.Model): # route_ids result.append({ "product_id": server_template.product_variant_id.id, + 'related_product':production.product_id.id, "name": production.procurement_group_id.name, "date_required": fields.Datetime.now(), "product_uom_id":server_template.uom_id.id, From df53989f22365585be2e49cf9b0d3fba0bb192e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Fri, 25 Apr 2025 14:04:48 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BC=A0=E8=BE=93?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=97=E8=A1=A8=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_printing/models/maintenance_printing.py | 2 +- jikimo_work_reporting_api/controllers/main.py | 11 +++++------ sf_machine_connect/models/ftp_operate.py | 8 ++++---- sf_maintenance/models/sf_maintenance.py | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/jikimo_printing/models/maintenance_printing.py b/jikimo_printing/models/maintenance_printing.py index 641c0af4..6a69662f 100644 --- a/jikimo_printing/models/maintenance_printing.py +++ b/jikimo_printing/models/maintenance_printing.py @@ -22,7 +22,7 @@ class MaintenancePrinting(models.Model): # 切换成A4打印机 try: - self.env['jikimo.printing'].print_qr_code(self.id) + self.env['jikimo.printing'].print_qr_code(self.MTcode) except Exception as e: raise UserError(f"打印失败: {str(e)}") diff --git a/jikimo_work_reporting_api/controllers/main.py b/jikimo_work_reporting_api/controllers/main.py index 9bafb01c..c3ea7daa 100644 --- a/jikimo_work_reporting_api/controllers/main.py +++ b/jikimo_work_reporting_api/controllers/main.py @@ -1,7 +1,7 @@ import json from odoo import http from odoo.http import request -from odoo.addons.sf_machine_connect.models.ftp_operate import transfer_nc_files +from odoo.addons.sf_machine_connect.models.ftp_operate import transfer_files from odoo.addons.sf_base.decorators.api_log import api_log class MainController(http.Controller): @@ -18,12 +18,11 @@ class MainController(http.Controller): if not maintenance_equipment_id or not model_id: return {'code': 400, 'message': '参数错误'} try: - maintenance_equipment_id = int(maintenance_equipment_id) model_id = int(model_id) except Exception as e: return {'code': 400, 'message': '参数类型错误'} maintenance_equipment = request.env['maintenance.equipment'].sudo().search( - [('id', '=', maintenance_equipment_id), ('category_id.equipment_type', '=', '机床')], + [('MTcode', '=', maintenance_equipment_id), ('category_id.equipment_type', '=', '机床')], limit=1 ) if not maintenance_equipment: @@ -55,15 +54,15 @@ class MainController(http.Controller): } # 传输nc文件 try: - result = transfer_nc_files( + result = transfer_files( source_ftp_info, target_ftp_info, '/' + str(model_id), '/', match_str=r'^\d*_\d*-' + tool_groups_id.name + r'-\w{2}-all\.nc$' ) - if result: - return {'code': 200, 'message': 'success'} + if len(result) > 0: + return {'code': 200, 'message': '传输成功', 'file_list': result} else: return {'code': 404, 'message': '未找到编程文件'} except Exception as e: diff --git a/sf_machine_connect/models/ftp_operate.py b/sf_machine_connect/models/ftp_operate.py index 8bd5cf52..e8134ab2 100644 --- a/sf_machine_connect/models/ftp_operate.py +++ b/sf_machine_connect/models/ftp_operate.py @@ -133,7 +133,7 @@ class FtpController: -def transfer_nc_files( +def transfer_files( source_ftp_info, target_ftp_info, source_dir, @@ -151,7 +151,7 @@ def transfer_nc_files( target_dir: str, 目标FTP上的目标目录 keep_dir: bool, 是否保持目录结构,默认False """ - trans_status = [False] + transfered_file_list = [] try: # 连接源FTP source_ftp = FtpController( @@ -217,7 +217,7 @@ def transfer_nc_files( with open(temp_path, 'rb') as f: target_ftp.ftp.storbinary(f'STOR {target_path}', f) - trans_status[0] = True + transfered_file_list.append(item) # 删除临时文件 os.remove(temp_path) logging.info(f"已传输文件: {item}") @@ -259,7 +259,7 @@ def transfer_nc_files( traverse_dir(source_dir) logging.info("所有文件传输完成") - return trans_status[0] + return transfered_file_list except Exception as e: logging.error(f"传输过程出错: {str(e)}") diff --git a/sf_maintenance/models/sf_maintenance.py b/sf_maintenance/models/sf_maintenance.py index 1fdd4e3e..2838a0d0 100644 --- a/sf_maintenance/models/sf_maintenance.py +++ b/sf_maintenance/models/sf_maintenance.py @@ -845,7 +845,7 @@ class SfMaintenanceEquipment(models.Model): box_size=10, border=4, ) - qr.add_data(record.id) + qr.add_data(record.MTcode) qr.make(fit=True) qr_image = qr.make_image(fill_color="black", back_color="white") From d2daae1a8f260029948fb2004b0cfd95ad4d5081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Fri, 25 Apr 2025 14:09:13 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=8E=88=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_work_reporting_api/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_work_reporting_api/controllers/main.py b/jikimo_work_reporting_api/controllers/main.py index c3ea7daa..54cd4cc6 100644 --- a/jikimo_work_reporting_api/controllers/main.py +++ b/jikimo_work_reporting_api/controllers/main.py @@ -6,7 +6,7 @@ from odoo.addons.sf_base.decorators.api_log import api_log class MainController(http.Controller): - @http.route('/api/manual_download_program', type='json', methods=['POST'], auth='public', cors='*') + @http.route('/api/manual_download_program', type='json', methods=['POST'], auth='wechat_token', cors='*') @api_log('人工线下加工编程文件传输', requester='报工系统') def manual_download_program(self): """ From 10a1d43a17a380635b0087f13bbc2fe67705ca17 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Fri, 25 Apr 2025 14:39:58 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E6=8E=92=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_plan/models/custom_plan.py | 4 ++-- sf_plan/wizard/action_plan_some.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py index 20ae4967..af5b387f 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -224,11 +224,11 @@ class sf_production_plan(models.Model): return num - def do_production_schedule(self,date_planned_start): + def do_production_schedule(self): """ 排程方法 """ - self.deal_processing_schedule(date_planned_start) + self.deal_processing_schedule(self.date_planned_start) for record in self: if not record.production_line_id: raise ValidationError("未选择生产线") diff --git a/sf_plan/wizard/action_plan_some.py b/sf_plan/wizard/action_plan_some.py index 1145af9f..78726c4d 100644 --- a/sf_plan/wizard/action_plan_some.py +++ b/sf_plan/wizard/action_plan_some.py @@ -40,5 +40,5 @@ class Action_Plan_All_Wizard(models.TransientModel): self.plan_ids.date_planned_start = self.date_planned_start # 在这里添加您的逻辑来处理这些ID # 判断能否排成 - self.plan_ids.do_production_schedule(self.date_planned_start) + self.plan_ids.do_production_schedule() _logger.info('处理计划: %s 完成', self.plan_ids.ids) From 128bebf338d7dd36bf072551bd71c5e4cc5a3d42 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Fri, 25 Apr 2025 14:57:56 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E7=B4=A7=E6=80=A5=E9=87=87=E8=B4=AD?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E4=B8=BA=E6=98=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 1c8480dd..d985fdf7 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -323,7 +323,7 @@ class RePurchaseOrder(models.Model): contract_summary = fields.Text(string='合同概况') # 选择是否为紧急采购 - urgent_purchase = fields.Selection([('no', '否'), ('yes', '是')], string='紧急采购', default='no') + urgent_purchase = fields.Selection([('no', '否'), ('yes', '是')], string='紧急采购', default='yes') @api.depends('origin') def _compute_purchase_type(self): From 0777e63bc7832a94ff3d18bf64d81ed3d4fd6137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Fri, 25 Apr 2025 15:49:41 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E9=9B=86=E5=87=BA=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_machine_connect/controllers/controllers.py | 17 +++--- sf_machine_connect/models/ftp_operate.py | 53 +++++++++++++++++-- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/sf_machine_connect/controllers/controllers.py b/sf_machine_connect/controllers/controllers.py index 92dc99c7..cefa4ba8 100644 --- a/sf_machine_connect/controllers/controllers.py +++ b/sf_machine_connect/controllers/controllers.py @@ -1298,10 +1298,7 @@ class Sf_Dashboard_Connect(http.Controller): conn = psycopg2.connect(**db_config) # 获取请求的机床数据 machine_list = ast.literal_eval(kw['machine_list']) - time_threshold = datetime.now() - timedelta(days=1) - - alarm_last_24_time = 0.0 - alarm_all_time = 0.0 + time_threshold = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) def fetch_result_as_dict(cursor): """辅助函数:将查询结果转为字典""" @@ -1311,6 +1308,9 @@ class Sf_Dashboard_Connect(http.Controller): # 获取当前时间的时间戳 current_timestamp = datetime.now().timestamp() for item in machine_list: + alarm_last_24_time = 0.0 + alarm_all_time = 0.0 + euipment_obj = request.env['maintenance.equipment'].sudo().search([('code', '=', item)]) # 机床上线时间段 first_online_duration = current_timestamp - euipment_obj.first_online_time.timestamp() @@ -1327,8 +1327,8 @@ class Sf_Dashboard_Connect(http.Controller): cur.execute(""" SELECT * FROM device_data WHERE device_name = %s - AND device_state in ('待机', '警告', '运行中') AND time >= %s AND process_time IS NOT NULL - ORDER BY time ASC + AND device_state in ('待机', '警告', '运行中') AND time <= %s AND process_time IS NOT NULL + ORDER BY time DESC LIMIT 1; """, (item, time_threshold)) last_24_time = fetch_result_as_dict(cur) @@ -1348,12 +1348,13 @@ class Sf_Dashboard_Connect(http.Controller): alarm_last_24_nums = [] with conn.cursor() as cur: cur.execute(""" - SELECT DISTINCT ON (alarm_start_time) alarm_time, alarm_start_time + SELECT DISTINCT ON (alarm_start_time, alarm_time) alarm_time, alarm_start_time FROM device_data WHERE device_name = %s - AND alarm_start_time IS NOT NULL AND time >= %s; + AND alarm_start_time IS NOT NULL AND alarm_start_time::timestamp >= %s; """, (item, time_threshold)) results = cur.fetchall() + logging.info("results============:%s" % results) for result in results: alarm_last_24_nums.append(result[1]) if result[0]: diff --git a/sf_machine_connect/models/ftp_operate.py b/sf_machine_connect/models/ftp_operate.py index e8134ab2..8265b351 100644 --- a/sf_machine_connect/models/ftp_operate.py +++ b/sf_machine_connect/models/ftp_operate.py @@ -9,9 +9,13 @@ _logger = logging.getLogger(__name__) class FTP_P(FTP): """ - 重写FTP类,重写dirs方法 + 重写FTP类,重写dirs方法,增加编码处理 """ - + def __init__(self, host='', user='', passwd='', acct='', timeout=None, encoding='gbk'): + """初始化时指定编码方式""" + super().__init__(host, user, passwd, acct, timeout) + self.encoding = encoding + def dirs(self, *args): """List a directory in long form. By default list current directory to stdout. @@ -32,7 +36,50 @@ class FTP_P(FTP): tempdic['name'] = [file for file in r_files if file != "." and file != ".."] # 去除. .. return tempdic - # return [file for file in r_files if file != "." and file != ".."] + + def nlst(self, *args): + """Get a list of files in a directory.""" + files = [] + def append(line): + try: + if isinstance(line, bytes): + files.append(line.decode(self.encoding)) + else: + files.append(line) + except UnicodeDecodeError: + files.append(line.decode('utf-8', errors='replace')) + cmd = 'NLST' + if args: + cmd = cmd + ' ' + args[0] + self.retrlines(cmd, append) + return files + + def cwd(self, dirname): + """Change to a directory.""" + try: + if isinstance(dirname, bytes): + dirname = dirname.decode(self.encoding) + return super().cwd(dirname) + except UnicodeEncodeError: + return super().cwd(dirname.encode(self.encoding).decode('utf-8')) + + def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None): + """Store a file in binary mode.""" + try: + if isinstance(cmd, bytes): + cmd = cmd.decode(self.encoding) + return super().storbinary(cmd, fp, blocksize, callback, rest) + except UnicodeEncodeError: + return super().storbinary(cmd.encode(self.encoding).decode('utf-8'), fp, blocksize, callback, rest) + + def retrbinary(self, cmd, callback, blocksize=8192, rest=None): + """Retrieve a file in binary mode.""" + try: + if isinstance(cmd, bytes): + cmd = cmd.decode(self.encoding) + return super().retrbinary(cmd, callback, blocksize, rest) + except UnicodeEncodeError: + return super().retrbinary(cmd.encode(self.encoding).decode('utf-8'), callback, blocksize, rest) # FTP接口类 From ca9a91e30a2e3cdfe83d933c03c9d3f1c86bca69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Fri, 25 Apr 2025 16:07:34 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=8D=95=E4=BA=8C=E7=BB=B4=E7=A0=81=E4=B8=8B=E6=96=B9=E6=96=87?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_machine_connect/controllers/controllers.py | 4 ++-- sf_mrs_connect/controllers/controllers.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_machine_connect/controllers/controllers.py b/sf_machine_connect/controllers/controllers.py index 692fa10b..cefa4ba8 100644 --- a/sf_machine_connect/controllers/controllers.py +++ b/sf_machine_connect/controllers/controllers.py @@ -1360,9 +1360,9 @@ class Sf_Dashboard_Connect(http.Controller): if result[0]: if float(result[0]) >= 28800: continue - alarm_last_24_time = float(result[0]) + alarm_last_24_time += float(result[0]) else: - alarm_last_24_time = 0.0 + alarm_last_24_time += 0.0 alarm_all_nums = [] with conn.cursor() as cur: diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index c30d3d53..a5d8d7c7 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -95,7 +95,7 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController): logging.info('panel_file_path:%s' % panel_file_path) # 向编程单中添加二维码 - request.env['printing.utils'].add_qr_code_to_pdf(panel_file_path, model_id, "扫码获取工单") + request.env['printing.utils'].add_qr_code_to_pdf(panel_file_path, model_id, "模型ID:%s" % model_id) cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())}) pre_workorder = productions.workorder_ids.filtered( lambda ap: ap.routing_type in ['装夹预调', '人工线下加工'] and ap.state not in ['done', 'rework' From a7ab8679f4caf517f7af98871faaf67cb8034fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Fri, 25 Apr 2025 16:39:51 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=AD=97=E4=BD=93?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/commons/common.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_base/commons/common.py b/sf_base/commons/common.py index 27b56038..30c06b6d 100644 --- a/sf_base/commons/common.py +++ b/sf_base/commons/common.py @@ -167,10 +167,10 @@ class PrintingUtils(models.AbstractModel): # 设置字体 if font_found: - c.setFont('SimSun', 14) # 增大字体大小到14pt + c.setFont('SimSun', 10) # 增大字体大小到14pt else: # 如果没有找到中文字体,使用默认字体 - c.setFont('Helvetica', 14) + c.setFont('Helvetica', 10) logging.warning("未找到中文字体,将使用默认字体") # 在右下角绘制二维码,预留边距 @@ -182,7 +182,7 @@ class PrintingUtils(models.AbstractModel): if buttom_text: # 在二维码下方绘制文字 text = buttom_text - text_width = c.stringWidth(text, "SimSun" if font_found else "Helvetica", 14) # 准确计算文字宽度 + text_width = c.stringWidth(text, "SimSun" if font_found else "Helvetica", 10) # 准确计算文字宽度 text_x = page_width - qr_size - margin + (qr_size - text_width) / 2 # 文字居中对齐 text_y = margin + 20 # 文字位置靠近底部 c.drawString(text_x, text_y, text)