voip announcement
This commit is contained in:
1 parent
38b1cf06df
commit
c7993aae44
18 files changed
+679
-151
No files matched your search
@@ -7,7 +7,7 @@ from apps.attachments.services import save_attachments
|
||||
from apps.core.persian_text import normalize_persian_text
|
||||
from apps.messaging.models import Message,MessageMention
|
||||
from apps.notifications.models import NotificationJob
|
||||
from apps.notifications.services import cancel_staff_reply_sms,enqueue,enqueue_unit_supervisor_ticket_sms,schedule_customer_reply_bale,schedule_staff_reply_sms
|
||||
from apps.notifications.services import cancel_staff_reply_sms,enqueue,enqueue_unit_supervisor_ticket_sms,schedule_announcement,schedule_customer_reply_bale,schedule_staff_reply_sms
|
||||
from .models import GroupDispatch,SLAConfig,Ticket,TicketAccessGrant,TicketEvent
|
||||
from .policies import DispatchPolicy, TicketPolicy
|
||||
|
||||
@@ -37,6 +37,7 @@ def create_ticket(*,customer,category,subject,selected_expert=None,body="",files
|
||||
ticket.full_clean(); ticket.save(); ticket.tags.set(tags); message=Message.objects.create(ticket=ticket,author=actor,body=body); save_attachments(message,files,actor); TicketEvent.objects.create(ticket=ticket,event_type=TicketEvent.Type.CREATED,actor=actor,metadata={"staff_initiated":staff_initiated,"group_dispatch_id":group_dispatch.pk if group_dispatch else None,"unit_id":owning_unit.pk if owning_unit else None})
|
||||
if staff_initiated:
|
||||
enqueue(NotificationJob.Channel.SMS,"STAFF_TICKET_CREATED",ticket,f"ticket:{ticket.pk}:staff-created",customer=customer)
|
||||
schedule_announcement(message)
|
||||
else:
|
||||
enqueue(NotificationJob.Channel.SMS,"CUSTOMER_TICKET_CREATED",ticket,f"ticket:{ticket.pk}:customer-created",customer=customer)
|
||||
if owning_unit and owning_unit.bale_chat_id:
|
||||
@@ -214,6 +215,7 @@ def reply_ticket(*,ticket_id,user,body="",files=(),internal=False,mentioned_user
|
||||
ticket.last_staff_message_at=now; ticket.status=Ticket.Status.WAITING_CUSTOMER
|
||||
if not ticket.first_response_at: ticket.first_response_at=now
|
||||
schedule_staff_reply_sms(ticket,msg)
|
||||
schedule_announcement(msg)
|
||||
ticket.save(); return msg
|
||||
|
||||
@transaction.atomic
|
||||
|
||||
@@ -23,7 +23,7 @@ from apps.accounts.models import TicketMagicLink, User, normalize_mobile
|
||||
from apps.accounts.magic_access import get_ticket_magic_access
|
||||
from apps.customers.models import ContactGroup, CustomerProfile
|
||||
from apps.messaging.models import Message,MessageReadReceipt
|
||||
from apps.notifications.models import NotificationJob, SMSTemplate
|
||||
from apps.notifications.models import AnnouncementJob, NotificationJob, SMSTemplate
|
||||
from apps.core.iran_locations import location_data
|
||||
from apps.core.persian_text import normalize_persian_text
|
||||
from apps.integrations.voip import place_voip_call
|
||||
@@ -444,6 +444,7 @@ def staff_detail(request,public_id):
|
||||
last=conversation[-1] if conversation else None; TicketReadState.objects.update_or_create(ticket=ticket,user=request.user,defaults={"last_read_at":timezone.now(),"last_read_message":last})
|
||||
history=Ticket.objects.filter(customer=ticket.customer).exclude(pk=ticket.pk).select_related("owner__staff_profile","selected_expert__staff_profile").order_by("-last_activity_at")[:5]
|
||||
sms_jobs=list(ticket.notificationjob_set.filter(channel=NotificationJob.Channel.SMS).exclude(event_type="UNIT_SUPERVISOR_NEW_TICKET").order_by("-created_at"))
|
||||
announcement_jobs=list(AnnouncementJob.objects.filter(message__ticket=ticket).select_related("message").order_by("-message__created_at", "-pk"))
|
||||
can_retry_sms=TicketPolicy.can_reply(request.user,ticket)
|
||||
for sms_job in sms_jobs:
|
||||
sms_job.sms_retryable=can_retry_sms and _sms_job_is_retryable(sms_job)
|
||||
@@ -451,7 +452,7 @@ def staff_detail(request,public_id):
|
||||
group_dispatch = ticket.group_dispatch
|
||||
can_resolve_dispatch = bool(group_dispatch and DispatchPolicy.can_view(request.user, group_dispatch) and (request.user.has_perm("tickets.change_ticket") or TicketPolicy.has_unit_permission(request.user, group_dispatch.unit, "tickets.change_ticket")))
|
||||
group_open_count = group_dispatch.tickets.exclude(status__in=(Ticket.Status.RESOLVED, Ticket.Status.CLOSED)).count() if group_dispatch else 0
|
||||
return render(request,"tickets/staff_detail.html",{"ticket":ticket,"conversation":conversation,"has_older":has_older,"older_cursor":older_cursor,"form":StaffReplyForm(),"transfer_form":TransferForm(),"share_form":ShareForm(),"can_claim":TicketPolicy.can_claim(request.user,ticket),"can_transfer":TicketPolicy.can_transfer(request.user,ticket),"can_share":TicketPolicy.can_share(request.user,ticket),"can_delete":TicketPolicy.can_delete(request.user,ticket),"can_resolve_dispatch":can_resolve_dispatch,"group_open_count":group_open_count,"statuses":Ticket.Status.choices,"priorities":Ticket.Priority.choices,"grants":ticket.access_grants.filter(revoked_at__isnull=True).select_related("user__staff_profile"),"customer_history":history,"sms_jobs":sms_jobs,"viewer_user":request.user,"voip_call_methods":_voip_call_methods(request.user),"poll_version":conversation_version(ticket,latest),"poll_cursor":latest.public_id if latest else ""})
|
||||
return render(request,"tickets/staff_detail.html",{"ticket":ticket,"conversation":conversation,"has_older":has_older,"older_cursor":older_cursor,"form":StaffReplyForm(),"transfer_form":TransferForm(),"share_form":ShareForm(),"can_claim":TicketPolicy.can_claim(request.user,ticket),"can_transfer":TicketPolicy.can_transfer(request.user,ticket),"can_share":TicketPolicy.can_share(request.user,ticket),"can_delete":TicketPolicy.can_delete(request.user,ticket),"can_resolve_dispatch":can_resolve_dispatch,"group_open_count":group_open_count,"statuses":Ticket.Status.choices,"priorities":Ticket.Priority.choices,"grants":ticket.access_grants.filter(revoked_at__isnull=True).select_related("user__staff_profile"),"customer_history":history,"sms_jobs":sms_jobs,"announcement_jobs":announcement_jobs,"viewer_user":request.user,"voip_call_methods":_voip_call_methods(request.user),"poll_version":conversation_version(ticket,latest),"poll_cursor":latest.public_id if latest else ""})
|
||||
@staff_required
|
||||
@require_POST
|
||||
def staff_sms_retry(request,public_id,job_id):
|
||||
|
||||
Reference in new issue
Block a user