06/09 Allow customer to reply admin answer
This commit is contained in:
+54
-1
@@ -182,7 +182,7 @@ def my_tickets():
|
||||
|
||||
# ── Customer: ticket detail ───────────────────────────────────────────────────
|
||||
|
||||
@bp.route('/my-tickets/<int:ticket_id>')
|
||||
@bp.route('/my-tickets/<int:ticket_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def my_ticket_detail(ticket_id):
|
||||
if current_user.role != 'customer':
|
||||
@@ -192,6 +192,36 @@ def my_ticket_detail(ticket_id):
|
||||
if ticket is None or ticket.customer_id != current_user.id:
|
||||
abort(404)
|
||||
|
||||
if request.method == 'POST':
|
||||
if ticket.status == 'closed':
|
||||
flash('This ticket is closed and cannot receive new replies.', 'warning')
|
||||
return redirect(url_for('support.my_ticket_detail', ticket_id=ticket_id))
|
||||
|
||||
body = request.form.get('body', '').strip()
|
||||
if not body:
|
||||
flash('Reply cannot be empty.', 'warning')
|
||||
return redirect(url_for('support.my_ticket_detail', ticket_id=ticket_id))
|
||||
|
||||
reply = SupportTicketReply(
|
||||
ticket_id = ticket.id,
|
||||
user_id = current_user.id,
|
||||
body = body,
|
||||
created_at = now_eastern(),
|
||||
)
|
||||
db.session.add(reply)
|
||||
# Reopen if it was answered so admin sees there's a follow-up
|
||||
if ticket.status == 'answered':
|
||||
ticket.status = 'open'
|
||||
db.session.commit()
|
||||
|
||||
log_action(ACTION_CREATE, 'SupportTicketReply', reply.id,
|
||||
f'ticket #{ticket.id}',
|
||||
f'customer reply by {current_user.username}')
|
||||
|
||||
_notify_admins_customer_reply(ticket, reply)
|
||||
flash('Your reply has been sent.', 'success')
|
||||
return redirect(url_for('support.my_ticket_detail', ticket_id=ticket_id))
|
||||
|
||||
replies = ticket.replies.order_by(SupportTicketReply.created_at.asc()).all()
|
||||
return render_template('support/my_ticket_detail.html',
|
||||
ticket=ticket, replies=replies)
|
||||
@@ -316,3 +346,26 @@ def _notify_customer_reply(ticket, reply):
|
||||
send_email = True,
|
||||
)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def _notify_admins_customer_reply(ticket, reply):
|
||||
"""Notify admins when a customer adds a follow-up reply to their ticket."""
|
||||
admins = User.query.filter_by(role='admin', active=True).all()
|
||||
if not admins:
|
||||
return
|
||||
|
||||
customer_label = ticket.customer.display_name if ticket.customer else 'Unknown'
|
||||
link = url_for('support.admin_ticket_detail', ticket_id=ticket.id)
|
||||
title = f'Customer reply on ticket #{ticket.id} from {customer_label}'
|
||||
body = (f'Re: {ticket.subject}\n\n'
|
||||
f'{reply.body[:400]}{"…" if len(reply.body) > 400 else ""}')
|
||||
|
||||
for admin in admins:
|
||||
notify(
|
||||
recipient = admin,
|
||||
title = title,
|
||||
body = body,
|
||||
link = link,
|
||||
send_email = True,
|
||||
)
|
||||
db.session.commit()
|
||||
|
||||
@@ -60,7 +60,30 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="text-center mt-2">
|
||||
{% if ticket.status != 'closed' %}
|
||||
<div class="card shadow-sm mt-3">
|
||||
<div class="card-header"><i class="bi bi-reply me-2"></i>Add a Follow-up</div>
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<div class="mb-3">
|
||||
<textarea name="body" class="form-control" rows="4" required
|
||||
placeholder="Type your follow-up message…"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i class="bi bi-send me-1"></i>Send Reply
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-secondary mt-3">
|
||||
<i class="bi bi-lock me-2"></i>This request is closed.
|
||||
<a href="{{ url_for('support.chat') }}">Start a new chat</a> if you need further help.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<a href="{{ url_for('support.chat') }}" class="btn btn-outline-primary btn-sm">
|
||||
<i class="bi bi-chat-dots me-1"></i>Ask another question
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user