231 lines
7.8 KiB
Python
231 lines
7.8 KiB
Python
from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify, g
|
|
from models import db, User, Team, Role, Company
|
|
from routes.auth import login_required, admin_required, company_required
|
|
from sqlalchemy import or_
|
|
|
|
# Create the blueprint
|
|
organization_bp = Blueprint('organization', __name__)
|
|
|
|
@organization_bp.route('/admin/organization')
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def admin_organization():
|
|
"""Comprehensive organization management interface"""
|
|
company = g.user.company
|
|
|
|
# Get all teams and users for the company
|
|
teams = Team.query.filter_by(company_id=company.id).order_by(Team.name).all()
|
|
users = User.query.filter_by(company_id=company.id).order_by(User.username).all()
|
|
|
|
return render_template('admin_organization.html',
|
|
title='Organization Management',
|
|
teams=teams,
|
|
users=users,
|
|
Role=Role)
|
|
|
|
@organization_bp.route('/api/organization/teams/<int:team_id>', methods=['GET', 'PUT', 'DELETE'])
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def api_team(team_id):
|
|
"""API endpoint for team operations"""
|
|
team = Team.query.filter_by(id=team_id, company_id=g.user.company_id).first_or_404()
|
|
|
|
if request.method == 'GET':
|
|
return jsonify({
|
|
'id': team.id,
|
|
'name': team.name,
|
|
'description': team.description,
|
|
'members': [{'id': u.id, 'username': u.username} for u in team.users]
|
|
})
|
|
|
|
elif request.method == 'PUT':
|
|
data = request.get_json()
|
|
team.name = data.get('name', team.name)
|
|
team.description = data.get('description', team.description)
|
|
|
|
try:
|
|
db.session.commit()
|
|
return jsonify({'success': True, 'message': 'Team updated successfully'})
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return jsonify({'success': False, 'message': str(e)}), 400
|
|
|
|
elif request.method == 'DELETE':
|
|
# Unassign all users from the team
|
|
for user in team.users:
|
|
user.team_id = None
|
|
|
|
db.session.delete(team)
|
|
db.session.commit()
|
|
return jsonify({'success': True, 'message': 'Team deleted successfully'})
|
|
|
|
@organization_bp.route('/api/organization/teams', methods=['POST'])
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def api_create_team():
|
|
"""API endpoint to create a new team"""
|
|
data = request.get_json()
|
|
|
|
team = Team(
|
|
name=data.get('name'),
|
|
description=data.get('description'),
|
|
company_id=g.user.company_id
|
|
)
|
|
|
|
try:
|
|
db.session.add(team)
|
|
db.session.commit()
|
|
return jsonify({'success': True, 'message': 'Team created successfully', 'team_id': team.id})
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return jsonify({'success': False, 'message': str(e)}), 400
|
|
|
|
@organization_bp.route('/api/organization/users/<int:user_id>', methods=['GET', 'PUT', 'DELETE'])
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def api_user(user_id):
|
|
"""API endpoint for user operations"""
|
|
user = User.query.filter_by(id=user_id, company_id=g.user.company_id).first_or_404()
|
|
|
|
if request.method == 'GET':
|
|
return jsonify({
|
|
'id': user.id,
|
|
'username': user.username,
|
|
'email': user.email,
|
|
'role': user.role.name if user.role else 'TEAM_MEMBER',
|
|
'team_id': user.team_id,
|
|
'is_blocked': user.is_blocked
|
|
})
|
|
|
|
elif request.method == 'PUT':
|
|
data = request.get_json()
|
|
|
|
# Update user fields
|
|
if 'email' in data:
|
|
user.email = data['email']
|
|
if 'role' in data:
|
|
user.role = Role[data['role']]
|
|
if 'team_id' in data:
|
|
user.team_id = data['team_id'] if data['team_id'] else None
|
|
if 'is_blocked' in data:
|
|
user.is_blocked = data['is_blocked']
|
|
if 'password' in data and data['password']:
|
|
user.set_password(data['password'])
|
|
|
|
try:
|
|
db.session.commit()
|
|
return jsonify({'success': True, 'message': 'User updated successfully'})
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return jsonify({'success': False, 'message': str(e)}), 400
|
|
|
|
elif request.method == 'DELETE':
|
|
if user.id == g.user.id:
|
|
return jsonify({'success': False, 'message': 'Cannot delete your own account'}), 400
|
|
|
|
db.session.delete(user)
|
|
db.session.commit()
|
|
return jsonify({'success': True, 'message': 'User deleted successfully'})
|
|
|
|
@organization_bp.route('/api/organization/users', methods=['POST'])
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def api_create_user():
|
|
"""API endpoint to create a new user"""
|
|
data = request.get_json()
|
|
|
|
# Check if username already exists
|
|
if User.query.filter_by(username=data.get('username')).first():
|
|
return jsonify({'success': False, 'message': 'Username already exists'}), 400
|
|
|
|
user = User(
|
|
username=data.get('username'),
|
|
email=data.get('email'),
|
|
company_id=g.user.company_id,
|
|
role=Role[data.get('role', 'TEAM_MEMBER')],
|
|
team_id=data.get('team_id') if data.get('team_id') else None
|
|
)
|
|
user.set_password(data.get('password'))
|
|
|
|
try:
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
return jsonify({'success': True, 'message': 'User created successfully', 'user_id': user.id})
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return jsonify({'success': False, 'message': str(e)}), 400
|
|
|
|
@organization_bp.route('/api/organization/users/<int:user_id>/toggle-status', methods=['POST'])
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def api_toggle_user_status(user_id):
|
|
"""Toggle user active/blocked status"""
|
|
user = User.query.filter_by(id=user_id, company_id=g.user.company_id).first_or_404()
|
|
|
|
if user.id == g.user.id:
|
|
return jsonify({'success': False, 'message': 'Cannot block your own account'}), 400
|
|
|
|
user.is_blocked = not user.is_blocked
|
|
db.session.commit()
|
|
|
|
status = 'blocked' if user.is_blocked else 'unblocked'
|
|
return jsonify({'success': True, 'message': f'User {status} successfully'})
|
|
|
|
@organization_bp.route('/api/organization/users/<int:user_id>/assign-team', methods=['POST'])
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def api_assign_team(user_id):
|
|
"""Assign user to a team"""
|
|
user = User.query.filter_by(id=user_id, company_id=g.user.company_id).first_or_404()
|
|
data = request.get_json()
|
|
|
|
team_id = data.get('team_id')
|
|
if team_id:
|
|
team = Team.query.filter_by(id=team_id, company_id=g.user.company_id).first_or_404()
|
|
user.team_id = team.id
|
|
else:
|
|
user.team_id = None
|
|
|
|
db.session.commit()
|
|
return jsonify({'success': True, 'message': 'Team assignment updated'})
|
|
|
|
@organization_bp.route('/api/organization/search', methods=['GET'])
|
|
@login_required
|
|
@company_required
|
|
@admin_required
|
|
def api_organization_search():
|
|
"""Search users and teams"""
|
|
query = request.args.get('q', '').lower()
|
|
|
|
if not query:
|
|
return jsonify({'users': [], 'teams': []})
|
|
|
|
# Search users
|
|
users = User.query.filter(
|
|
User.company_id == g.user.company_id,
|
|
or_(
|
|
User.username.ilike(f'%{query}%'),
|
|
User.email.ilike(f'%{query}%')
|
|
)
|
|
).limit(10).all()
|
|
|
|
# Search teams
|
|
teams = Team.query.filter(
|
|
Team.company_id == g.user.company_id,
|
|
or_(
|
|
Team.name.ilike(f'%{query}%'),
|
|
Team.description.ilike(f'%{query}%')
|
|
)
|
|
).limit(10).all()
|
|
|
|
return jsonify({
|
|
'users': [{'id': u.id, 'username': u.username, 'email': u.email} for u in users],
|
|
'teams': [{'id': t.id, 'name': t.name, 'description': t.description} for t in teams]
|
|
}) |