"""Business Units API endpoints - Full CRUD.""" from flask import Blueprint, request from flask_jwt_extended import jwt_required from shopdb.extensions import db from shopdb.core.models import BusinessUnit from shopdb.utils.responses import ( success_response, error_response, paginated_response, ErrorCodes ) from shopdb.utils.pagination import get_pagination_params, paginate_query businessunits_bp = Blueprint('businessunits', __name__) @businessunits_bp.route('', methods=['GET']) @jwt_required(optional=True) def list_businessunits(): """List all business units.""" page, per_page = get_pagination_params(request) query = BusinessUnit.query if request.args.get('active', 'true').lower() != 'false': query = query.filter(BusinessUnit.isactive == True) if search := request.args.get('search'): query = query.filter( db.or_( BusinessUnit.businessunit.ilike(f'%{search}%'), BusinessUnit.code.ilike(f'%{search}%') ) ) query = query.order_by(BusinessUnit.businessunit) items, total = paginate_query(query, page, per_page) data = [bu.to_dict() for bu in items] return paginated_response(data, page, per_page, total) @businessunits_bp.route('/', methods=['GET']) @jwt_required(optional=True) def get_businessunit(bu_id: int): """Get a single business unit.""" bu = BusinessUnit.query.get(bu_id) if not bu: return error_response( ErrorCodes.NOT_FOUND, f'Business unit with ID {bu_id} not found', http_code=404 ) data = bu.to_dict() data['parent'] = bu.parent.to_dict() if bu.parent else None data['children'] = [c.to_dict() for c in bu.children] return success_response(data) @businessunits_bp.route('', methods=['POST']) @jwt_required() def create_businessunit(): """Create a new business unit.""" data = request.get_json() if not data or not data.get('businessunit'): return error_response(ErrorCodes.VALIDATION_ERROR, 'businessunit is required') if BusinessUnit.query.filter_by(businessunit=data['businessunit']).first(): return error_response( ErrorCodes.CONFLICT, f"Business unit '{data['businessunit']}' already exists", http_code=409 ) bu = BusinessUnit( businessunit=data['businessunit'], code=data.get('code'), description=data.get('description'), parentid=data.get('parentid') ) db.session.add(bu) db.session.commit() return success_response(bu.to_dict(), message='Business unit created', http_code=201) @businessunits_bp.route('/', methods=['PUT']) @jwt_required() def update_businessunit(bu_id: int): """Update a business unit.""" bu = BusinessUnit.query.get(bu_id) if not bu: return error_response( ErrorCodes.NOT_FOUND, f'Business unit with ID {bu_id} not found', http_code=404 ) data = request.get_json() if not data: return error_response(ErrorCodes.VALIDATION_ERROR, 'No data provided') if 'businessunit' in data and data['businessunit'] != bu.businessunit: if BusinessUnit.query.filter_by(businessunit=data['businessunit']).first(): return error_response( ErrorCodes.CONFLICT, f"Business unit '{data['businessunit']}' already exists", http_code=409 ) for key in ['businessunit', 'code', 'description', 'parentid', 'isactive']: if key in data: setattr(bu, key, data[key]) db.session.commit() return success_response(bu.to_dict(), message='Business unit updated') @businessunits_bp.route('/', methods=['DELETE']) @jwt_required() def delete_businessunit(bu_id: int): """Delete (deactivate) a business unit.""" bu = BusinessUnit.query.get(bu_id) if not bu: return error_response( ErrorCodes.NOT_FOUND, f'Business unit with ID {bu_id} not found', http_code=404 ) bu.isactive = False db.session.commit() return success_response(message='Business unit deleted')