04/06 implement creating ticket on behalf of another user for IT staff

This commit is contained in:
2026-04-06 17:13:53 -04:00
parent 3b17705911
commit bc236a3d19
8 changed files with 738 additions and 14 deletions
+103
View File
@@ -188,6 +188,109 @@ def create_ticket():
categories=_categories(), priorities=_priorities())
# ─── Create Ticket on Behalf of Employee (IT Staff Only) ─────────────────────
@tickets_bp.route('/tickets/behalf', methods=['GET', 'POST'])
@login_required
def create_ticket_behalf():
"""Allow IT staff to create a ticket on behalf of an employee.
Use case: an employee calls or emails to report an issue and cannot or
does not create a ticket themselves. IT staff completes the form,
selecting the employee from a searchable dropdown.
Data model
----------
ticket.created_by_id = employee's user ID (ticket shows as theirs)
ticket.created_by_staff_id = IT staff's user ID (audit trail)
The employee sees this ticket in their own dashboard and receives the
same new-ticket confirmation notification they would if self-submitted.
"""
if not current_user.is_it_staff:
abort(403)
employees = User.query.filter(
User.is_active == True,
).order_by(User.full_name).all()
if request.method == 'POST':
employee_id = request.form.get('employee_id', type=int)
title = request.form.get('title', '').strip()
description = request.form.get('description', '').strip()
category = request.form.get('category', TicketCategory.OTHER)
priority = request.form.get('priority', TicketPriority.MEDIUM)
location = request.form.get('location', '').strip()
asset_tag = request.form.get('asset_tag', '').strip()
# Validate employee selection
employee = db.session.get(User, employee_id) if employee_id else None
if not employee or not employee.is_active:
flash('Please select a valid active employee.', 'danger')
return render_template('tickets/create_behalf.html',
employees=employees,
categories=_categories(),
priorities=_priorities())
if not title or not description:
flash('Title and description are required.', 'danger')
return render_template('tickets/create_behalf.html',
employees=employees,
categories=_categories(),
priorities=_priorities(),
selected_employee_id=employee_id)
ticket = Ticket(
title = title,
description = description,
category = category,
priority = priority,
location = location,
asset_tag = asset_tag,
created_by_id = employee.id, # ticket belongs to the employee
created_by_staff_id = current_user.id, # IT staff who filed it
status = TicketStatus.OPEN,
)
ticket.ticket_number = ticket.generate_ticket_number()
db.session.add(ticket)
db.session.flush() # get ticket.id before attachments
# Handle file uploads
for f in request.files.getlist('attachments'):
if f and f.filename:
file_error = validate_file(f, ALLOWED_EXT)
if file_error:
logger.warning(
f'[BEHALF UPLOAD REJECTED] {file_error} '
f'filename="{f.filename}" staff_id={current_user.id}'
)
continue
save_attachment(f, ticket_id=ticket.id, uploader_id=current_user.id)
log_action(
current_user.id, 'ticket_create_behalf', 'ticket', ticket.id,
f'ticket_number={ticket.ticket_number} on_behalf_of=user_id:{employee.id} '
f'({employee.full_name}) priority={priority} category={category}'
)
db.session.commit()
logger.info(
f'[TICKET CREATE BEHALF] ticket_id={ticket.id} '
f'number={ticket.ticket_number} '
f'employee_id={employee.id} staff_id={current_user.id}'
)
notify_new_ticket(ticket)
flash(
f'Ticket {ticket.ticket_number} created on behalf of {employee.full_name}.',
'success'
)
return redirect(url_for('tickets.ticket_detail', ticket_id=ticket.id))
return render_template('tickets/create_behalf.html',
employees=employees,
categories=_categories(),
priorities=_priorities())
# ─── Ticket List ──────────────────────────────────────────────────────────────
@tickets_bp.route('/tickets')