from flask import jsonify, request from models.workflow import Workflow from models.department import Department import logging import os from db import get_gridfs from bson.objectid import ObjectId from datetime import datetime # Configure logging logger = logging.getLogger(__name__) def create_workflow(current_user): """Create a new workflow for a department""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 data = request.get_json() # Check if required fields are present required_fields = ['title', 'description'] for field in required_fields: if field not in data: return jsonify({'message': f'Missing required field: {field}'}), 400 # Get user's department department = Department.find_by_id(current_user.department_id) if not department: return jsonify({'message': 'Department not found'}), 404 # Check if workflow with this title already exists in this department existing_workflow = Workflow.find_by_title(data['title'], current_user.department_id) if existing_workflow: return jsonify({'message': 'Workflow with this title already exists in your department'}), 400 try: # Create new workflow workflow = Workflow( title=data['title'], description=data['description'], department_id=current_user.department_id, data_requirements=data.get('data_requirements', []), form_fields=data.get('form_fields', []) ) if workflow.save(): # Add workflow to department department.add_workflow(workflow._id) return jsonify({ 'message': 'Workflow created successfully', 'workflow': workflow.to_dict() }), 201 else: return jsonify({'message': 'Failed to save workflow'}), 500 except Exception as e: logger.error(f"Error creating workflow: {str(e)}") return jsonify({'message': f'Error creating workflow: {str(e)}'}), 500 def get_workflow(current_user, workflow_id): """Get workflow by ID""" workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 return jsonify({'workflow': workflow.to_dict()}), 200 def update_workflow(current_user, workflow_id): """Update workflow details""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 data = request.get_json() logger.info(f"Update workflow request data keys: {data.keys() if data else 'None'}") if 'markdown_template' in data: template_length = len(data['markdown_template']) if data['markdown_template'] else 0 logger.info(f"Received markdown_template with length: {template_length}") if template_length > 0: logger.info(f"First 100 chars: {data['markdown_template'][:100]}") # Update fields if provided if 'title' in data: # Check if new title already exists in this department if data['title'] != workflow.title: existing_workflow = Workflow.find_by_title(data['title'], current_user.department_id) if existing_workflow: return jsonify({'message': 'Workflow with this title already exists in your department'}), 400 workflow.title = data['title'] if 'description' in data: workflow.description = data['description'] if 'data_requirements' in data: workflow.data_requirements = data['data_requirements'] if 'form_fields' in data: workflow.form_fields = data['form_fields'] if 'markdown_template' in data: workflow.markdown_template = data['markdown_template'] if 'template_name' in data: workflow.template_name = data['template_name'] # Save changes if workflow.save(): return jsonify({ 'message': 'Workflow updated successfully', 'workflow': workflow.to_dict() }), 200 else: return jsonify({'message': 'Failed to update workflow'}), 500 def delete_workflow(current_user, workflow_id): """Delete a workflow""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 # Get department to remove workflow reference department = Department.find_by_id(current_user.department_id) if department: department.remove_workflow(workflow_id) # Delete the workflow if workflow.delete(): return jsonify({'message': 'Workflow deleted successfully'}), 200 else: return jsonify({'message': 'Failed to delete workflow'}), 500 def get_department_workflows(current_user): """Get all workflows for the user's department""" workflows = Workflow.find_by_department(current_user.department_id) return jsonify({'workflows': [workflow.to_dict() for workflow in workflows]}), 200 def add_data_requirement(current_user, workflow_id): """Add a data requirement to a workflow""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 data = request.get_json() # Check if required fields are present if 'field' not in data or 'description' not in data: return jsonify({'message': 'Field and description are required'}), 400 # Add data requirement if workflow.add_data_requirement(data['field'], data['description']): return jsonify({ 'message': 'Data requirement added successfully', 'workflow': workflow.to_dict() }), 200 else: return jsonify({'message': 'Failed to add data requirement'}), 500 def remove_data_requirement(current_user, workflow_id): """Remove a data requirement from a workflow""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 data = request.get_json() # Check if required fields are present if 'index' not in data: return jsonify({'message': 'Index of data requirement to remove is required'}), 400 try: index = int(data['index']) if index < 0 or index >= len(workflow.data_requirements): return jsonify({'message': 'Invalid index'}), 400 # Remove the data requirement at the specified index workflow.data_requirements.pop(index) if workflow.save(): return jsonify({ 'message': 'Data requirement removed successfully', 'workflow': workflow.to_dict() }), 200 else: return jsonify({'message': 'Failed to remove data requirement'}), 500 except ValueError: return jsonify({'message': 'Index must be a valid integer'}), 400 except Exception as e: logger.error(f"Error removing data requirement: {str(e)}") return jsonify({'message': f'Error removing data requirement: {str(e)}'}), 500 def upload_form(current_user, workflow_id): """Upload a markdown form template to a workflow""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 if 'file' not in request.files: return jsonify({'message': 'No file part'}), 400 file = request.files['file'] if file.filename == '': return jsonify({'message': 'No selected file'}), 400 if file and file.filename.endswith('.md'): try: # Read the markdown content markdown_content = file.read().decode('utf-8') # Store directly in the workflow model workflow.markdown_template = markdown_content workflow.template_name = file.filename # Save the workflow if workflow.save(): return jsonify({ 'message': 'Form template uploaded successfully', 'workflow': workflow.to_dict() }), 200 else: return jsonify({'message': 'Failed to save workflow with markdown template'}), 500 except Exception as e: logger.error(f"Error uploading markdown template: {str(e)}") return jsonify({'message': f'Error uploading template: {str(e)}'}), 500 else: return jsonify({'message': 'File must be a markdown (.md) file'}), 400 def remove_form(current_user, workflow_id): """Remove the form template from a workflow""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 # Check if there's a template to remove if not workflow.markdown_template: return jsonify({'message': 'No form template found to remove'}), 404 try: # Clear the template using the model method if workflow.clear_template(): return jsonify({ 'message': 'Form template removed successfully', 'workflow': workflow.to_dict() }), 200 else: return jsonify({'message': 'Failed to remove form template from workflow'}), 500 except Exception as e: logger.error(f"Error removing form template: {str(e)}") return jsonify({'message': f'Error removing form template: {str(e)}'}), 500 def add_form_field(current_user, workflow_id): """Add a form field to a workflow""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 data = request.get_json() # Check if required fields are present if 'position' not in data or 'field_name' not in data: return jsonify({'message': 'Position and field_name are required'}), 400 try: position = data['position'] field_name = data['field_name'] # Add form field if workflow.add_form_field(position, field_name): return jsonify({ 'message': 'Form field added successfully', 'workflow': workflow.to_dict() }), 200 else: return jsonify({'message': 'Failed to add form field'}), 500 except Exception as e: logger.error(f"Error adding form field: {str(e)}") return jsonify({'message': f'Error adding form field: {str(e)}'}), 500 def remove_form_field(current_user, workflow_id): """Remove a form field from a workflow""" # Check if user has admin permissions if current_user.permissions != 'Admin': return jsonify({'message': 'Admin permissions required'}), 403 workflow = Workflow.find_by_id(workflow_id) if not workflow: return jsonify({'message': 'Workflow not found'}), 404 # Check if user belongs to the same department as the workflow if str(workflow.department_id) != str(current_user.department_id): return jsonify({'message': 'Access denied to workflows from other departments'}), 403 data = request.get_json() # Check if required fields are present if 'index' not in data: return jsonify({'message': 'Index of form field to remove is required'}), 400 try: index = int(data['index']) if index < 0 or index >= len(workflow.form_fields): return jsonify({'message': 'Invalid index'}), 400 # Remove the form field at the specified index workflow.form_fields.pop(index) if workflow.save(): return jsonify({ 'message': 'Form field removed successfully', 'workflow': workflow.to_dict() }), 200 else: return jsonify({'message': 'Failed to remove form field'}), 500 except ValueError: return jsonify({'message': 'Index must be a valid integer'}), 400 except Exception as e: logger.error(f"Error removing form field: {str(e)}") return jsonify({'message': f'Error removing form field: {str(e)}'}), 500