add retry sms manually
This commit is contained in:
1 parent
33930e972c
commit
cb92abbb41
42 files changed
+1628
-1484
No files matched your search
+62
-9
@@ -33,6 +33,53 @@ from .policies import DispatchPolicy, TicketPolicy
|
||||
from .selectors import customer_tickets,dashboard_counts,filter_staff_tickets,staff_ticket_rows
|
||||
from .services import change_priority,change_status,claim_ticket,create_ticket,dispatch_group_tickets,refresh_group_dispatch_status,reply_ticket,resolve_group_dispatch_tickets,revoke_access,share_ticket,transfer_ticket
|
||||
MESSAGE_PAGE_SIZE=50
|
||||
SMS_RETRYABLE_DELIVERY_STATUSES=(
|
||||
NotificationJob.DeliveryStatus.UNDELIVERED,
|
||||
NotificationJob.DeliveryStatus.EXPIRED,
|
||||
NotificationJob.DeliveryStatus.BLOCKED,
|
||||
NotificationJob.DeliveryStatus.UNKNOWN,
|
||||
NotificationJob.DeliveryStatus.ERROR,
|
||||
)
|
||||
|
||||
|
||||
def _retryable_sms_jobs(jobs):
|
||||
return jobs.filter(
|
||||
Q(status=NotificationJob.Status.FAILED)
|
||||
| Q(
|
||||
status=NotificationJob.Status.SENT,
|
||||
delivery_status__in=SMS_RETRYABLE_DELIVERY_STATUSES,
|
||||
delivery_next_check_at__isnull=True,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _sms_job_is_retryable(job):
|
||||
return job.status == NotificationJob.Status.FAILED or (
|
||||
job.status == NotificationJob.Status.SENT
|
||||
and job.delivery_status in SMS_RETRYABLE_DELIVERY_STATUSES
|
||||
and job.delivery_next_check_at is None
|
||||
)
|
||||
|
||||
|
||||
def _requeue_retryable_sms_jobs(jobs):
|
||||
return _retryable_sms_jobs(jobs).update(
|
||||
status=NotificationJob.Status.PENDING,
|
||||
attempts=0,
|
||||
next_attempt_at=timezone.now(),
|
||||
last_error="",
|
||||
provider_message_id="",
|
||||
provider_status_code="",
|
||||
sent_at=None,
|
||||
delivery_status="",
|
||||
delivery_status_code="",
|
||||
delivery_description="",
|
||||
delivery_checked_at=None,
|
||||
delivery_check_attempts=0,
|
||||
delivery_next_check_at=None,
|
||||
delivery_is_final=False,
|
||||
)
|
||||
|
||||
|
||||
def conversation_page(queryset,before=None):
|
||||
queryset=queryset.order_by("-created_at","-id")
|
||||
if before:
|
||||
@@ -395,13 +442,25 @@ def staff_detail(request,public_id):
|
||||
mark_messages_read(conversation,request.user)
|
||||
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=ticket.notificationjob_set.filter(channel=NotificationJob.Channel.SMS).exclude(event_type="UNIT_SUPERVISOR_NEW_TICKET").order_by("-created_at")
|
||||
sms_jobs=list(ticket.notificationjob_set.filter(channel=NotificationJob.Channel.SMS).exclude(event_type="UNIT_SUPERVISOR_NEW_TICKET").order_by("-created_at"))
|
||||
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)
|
||||
latest=conversation[-1] if conversation else None
|
||||
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,"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):
|
||||
ticket=get_object_or_404(Ticket,public_id=public_id)
|
||||
if not TicketPolicy.can_reply(request.user,ticket): raise PermissionDenied
|
||||
jobs=ticket.notificationjob_set.filter(pk=job_id,channel=NotificationJob.Channel.SMS).exclude(event_type="UNIT_SUPERVISOR_NEW_TICKET")
|
||||
count=_requeue_retryable_sms_jobs(jobs)
|
||||
messages.success(request,"پیامک ناموفق دوباره در صف ارسال قرار گرفت." if count else "این پیامک در وضعیت قابل تلاش مجدد نیست.")
|
||||
return redirect("staff_tickets:detail",public_id=public_id)
|
||||
@staff_required
|
||||
def staff_messages(request,public_id):
|
||||
ticket=get_object_or_404(Ticket,public_id=public_id)
|
||||
if not TicketPolicy.can_view(request.user,ticket): raise PermissionDenied
|
||||
@@ -640,20 +699,14 @@ def staff_dispatch_resolve(request, public_id):
|
||||
def staff_dispatch_retry(request, public_id):
|
||||
dispatch=get_object_or_404(GroupDispatch,public_id=public_id)
|
||||
if not DispatchPolicy.can_view(request.user,dispatch) or not DispatchPolicy.can_create(request.user,dispatch.unit,dispatch.operation_type): raise PermissionDenied
|
||||
retryable_delivery = [NotificationJob.DeliveryStatus.UNDELIVERED, NotificationJob.DeliveryStatus.EXPIRED, NotificationJob.DeliveryStatus.BLOCKED, NotificationJob.DeliveryStatus.UNKNOWN, NotificationJob.DeliveryStatus.ERROR]
|
||||
jobs=NotificationJob.objects.filter(ticket__group_dispatch=dispatch,channel=NotificationJob.Channel.SMS,event_type=SMSTemplate.Event.STAFF_TICKET_CREATED).filter(Q(status=NotificationJob.Status.FAILED) | Q(status=NotificationJob.Status.SENT,delivery_status__in=retryable_delivery,delivery_next_check_at__isnull=True))
|
||||
jobs=NotificationJob.objects.filter(ticket__group_dispatch=dispatch,channel=NotificationJob.Channel.SMS,event_type=SMSTemplate.Event.STAFF_TICKET_CREATED)
|
||||
job_id=request.POST.get("job_id","").strip()
|
||||
if job_id:
|
||||
if not job_id.isdigit():
|
||||
messages.error(request,"شناسه پیامک برای تلاش مجدد معتبر نیست.")
|
||||
return redirect("staff_tickets:dispatch_detail",public_id=public_id)
|
||||
jobs=jobs.filter(pk=int(job_id))
|
||||
count=jobs.update(
|
||||
status=NotificationJob.Status.PENDING, attempts=0, next_attempt_at=timezone.now(),
|
||||
last_error="", provider_message_id="", provider_status_code="", sent_at=None,
|
||||
delivery_status="", delivery_status_code="", delivery_description="",
|
||||
delivery_checked_at=None, delivery_check_attempts=0, delivery_next_check_at=None,
|
||||
)
|
||||
count=_requeue_retryable_sms_jobs(jobs)
|
||||
refresh_group_dispatch_status(dispatch.pk)
|
||||
messages.success(request,f"{count} ارسال ناموفق دوباره در صف قرار گرفت." if count else "ارسال ناموفقی برای تلاش مجدد وجود ندارد.")
|
||||
return redirect("staff_tickets:dispatch_detail",public_id=public_id)
|
||||
|
||||
Reference in new issue
Block a user