- 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:
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user