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/jikimo_work_reporting_api/controllers/main.py b/jikimo_work_reporting_api/controllers/main.py index de57fcda..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): @@ -54,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_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) diff --git a/sf_machine_connect/controllers/controllers.py b/sf_machine_connect/controllers/controllers.py index a6eb4100..cefa4ba8 100644 --- a/sf_machine_connect/controllers/controllers.py +++ b/sf_machine_connect/controllers/controllers.py @@ -1300,9 +1300,6 @@ class Sf_Dashboard_Connect(http.Controller): machine_list = ast.literal_eval(kw['machine_list']) time_threshold = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) - alarm_last_24_time = 0.0 - alarm_all_time = 0.0 - def fetch_result_as_dict(cursor): """辅助函数:将查询结果转为字典""" columns = [desc[0] for desc in cursor.description] @@ -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() @@ -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_machine_connect/models/ftp_operate.py b/sf_machine_connect/models/ftp_operate.py index 8bd5cf52..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接口类 @@ -133,7 +180,7 @@ class FtpController: -def transfer_nc_files( +def transfer_files( source_ftp_info, target_ftp_info, source_dir, @@ -151,7 +198,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 +264,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 +306,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_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 740b50d4..60d17052 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1245,7 +1245,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 @@ -1304,13 +1305,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' @@ -1332,6 +1326,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_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' 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) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index fb28c0fc..ea02f9ce 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):