- Introduction of PARTNER_RAG retriever, PARTNER_RAG_SPECIALIST and linked Agent and Task, to support documentation inquiries in the management app (eveai_app)

- Addition of a tenant_partner_services view to show partner services from the viewpoint of a tenant
- Addition of domain model diagrams
- Addition of license_periods views and form
This commit is contained in:
Josako
2025-07-16 21:24:08 +02:00
parent 000636a229
commit f3a243698c
30 changed files with 1566 additions and 356 deletions

View File

@@ -13,11 +13,11 @@ from common.services.user import PartnerServices
from common.services.user import UserServices
from common.utils.eveai_exceptions import EveAIException
from common.utils.security_utils import current_user_has_role
from .entitlements_forms import LicenseTierForm, LicenseForm
from .entitlements_forms import LicenseTierForm, LicenseForm, EditPeriodForm
from common.utils.view_assistants import prepare_table_for_macro, form_validation_failed
from common.utils.nginx_utils import prefixed_url_for
from common.utils.document_utils import set_logging_information, update_logging_information
from .list_views.entitlement_list_views import get_license_tiers_list_view, get_license_list_view
from .list_views.entitlement_list_views import get_license_tiers_list_view, get_license_list_view, get_license_periods_list_view
from .list_views.list_view_utils import render_list_view
entitlements_bp = Blueprint('entitlements_bp', __name__, url_prefix='/entitlements')
@@ -255,14 +255,14 @@ def handle_license_selection():
case 'edit_license':
return redirect(prefixed_url_for('entitlements_bp.edit_license', license_id=license_id))
case 'view_periods':
return redirect(prefixed_url_for('entitlements_bp.view_license_periods', license_id=license_id))
return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
case _:
return redirect(prefixed_url_for('entitlements_bp.licenses'))
@entitlements_bp.route('/license/<int:license_id>/periods')
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
def view_license_periods(license_id):
def license_periods(license_id):
license = License.query.get_or_404(license_id)
# Verify user can access this license
@@ -272,48 +272,77 @@ def view_license_periods(license_id):
flash('Access denied to this license', 'danger')
return redirect(prefixed_url_for('entitlements_bp.licenses'))
# Get all periods for this license
periods = (LicensePeriod.query
.filter_by(license_id=license_id)
.order_by(LicensePeriod.period_number)
.all())
config = get_license_periods_list_view(license_id)
# Group related data for easy template access
usage_by_period = {}
payments_by_period = {}
invoices_by_period = {}
# Check if there was an error in getting the configuration
if config.get('error'):
return render_template("index.html")
for period in periods:
usage_by_period[period.id] = period.license_usage
payments_by_period[period.id] = list(period.payments)
invoices_by_period[period.id] = list(period.invoices)
return render_template('entitlements/license_periods.html',
license=license,
periods=periods,
usage_by_period=usage_by_period,
payments_by_period=payments_by_period,
invoices_by_period=invoices_by_period)
return render_list_view('list_view.html', **config)
@entitlements_bp.route('/license/<int:license_id>/periods/<int:period_id>/transition', methods=['POST'])
@roles_accepted('Super User', 'Partner Admin')
def transition_period_status(license_id, period_id):
@entitlements_bp.route('/license_period/<int:period_id>', methods=['GET', 'POST'])
@roles_accepted('Super User')
def edit_license_period(period_id):
"""Handle status transitions for license periods"""
period = LicensePeriod.query.get_or_404(period_id)
new_status = request.form.get('new_status')
form = EditPeriodForm(obj=period)
try:
period.transition_status(PeriodStatus[new_status], current_user.id)
db.session.commit()
flash(f'Period {period.period_number} status updated to {new_status}', 'success')
except ValueError as e:
flash(f'Invalid status transition: {str(e)}', 'danger')
except Exception as e:
db.session.rollback()
flash(f'Error updating status: {str(e)}', 'danger')
if request.method == 'POST' and form.validate_on_submit():
form.populate_obj(period)
update_logging_information(period, dt.now(tz.utc))
match form.status.data:
case 'UPCOMING':
period.upcoming_at = dt.now(tz.utc)
case 'PENDING':
period.pending_at = dt.now(tz.utc)
case 'ACTIVE':
period.active_at = dt.now(tz.utc)
case 'COMPLETED':
period.completed_at = dt.now(tz.utc)
case 'INVOICED':
period.invoiced_at = dt.now(tz.utc)
case 'CLOSED':
period.closed_at = dt.now(tz.utc)
return redirect(prefixed_url_for('entitlements_bp.view_license_periods', license_id=license_id))
try:
db.session.add(period)
db.session.commit()
flash('Period updated successfully.', 'success')
current_app.logger.info(f"Successfully updated period {period_id}")
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Error updating status: {str(e)}', 'danger')
current_app.logger.error(f"Error updating period {period_id}: {str(e)}")
return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=period.license_id))
return render_template('entitlements/edit_license_period.html', form=form)
@entitlements_bp.route('/license/<int:license_id>/handle_period_selection', methods=['POST'])
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
def handle_license_period_selection(license_id):
"""Handle actions for license periods"""
action = request.form['action']
# For actions that don't require a selection
if 'selected_row' not in request.form:
return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
period_identification = request.form['selected_row']
period_id = ast.literal_eval(period_identification).get('value')
match action:
case 'view_period_details':
# TODO: Implement period details view if needed
flash('Period details view not yet implemented', 'info')
return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
case 'edit_license_period':
# Display a form to choose the new status
return redirect(prefixed_url_for('entitlements_bp.edit_license_period', period_id=period_id))
case _:
return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
@entitlements_bp.route('/view_licenses')