This commit is contained in:
2026-09-04 13:05:54 +03:30
parent 463b812e3e
commit 17082a5ea9
43 changed files with 5663 additions and 285 deletions
+15
View File
@@ -45,3 +45,18 @@ class BulkMessageSerializer(serializers.ModelSerializer):
def get_needs_manual(self, obj: BulkMessage):
pending = obj.recipients.filter(status=MessageRecipient.Status.NEEDS_MANUAL)
return MessageRecipientSerializer(pending, many=True).data
class ContactMessageHistorySerializer(serializers.ModelSerializer):
"""یک ردیفِ تاریخچه — متنِ واقعیِ فرستاده‌شده، کانال، وضعیت و زمان."""
sent_at = serializers.DateTimeField(source="bulk_message.created_at", read_only=True)
channel_display = serializers.CharField(source="get_channel_display", read_only=True)
status_display = serializers.CharField(source="get_status_display", read_only=True)
class Meta:
model = MessageRecipient
fields = [
"id", "channel", "channel_display", "status", "status_display",
"rendered_body", "error", "sent_at",
]
+38 -1
View File
@@ -10,7 +10,13 @@ from apps.banker.models import ContactGroup
from apps.billing.permissions import HasActiveFeature
from apps.messaging.models import BulkMessage, MessageRecipient
from .serializers import BulkMessageSerializer, SendBulkMessageSerializer
from apps.billing.forms import normalize_iran_phone
from .serializers import (
BulkMessageSerializer,
ContactMessageHistorySerializer,
SendBulkMessageSerializer,
)
from .services import BulkMessageService
@@ -90,3 +96,34 @@ class ConfirmManualSendView(APIView):
except MessageRecipient.DoesNotExist:
raise NotFound("گیرنده یافت نشد.")
return Response({"success": True, "status": recipient.status})
class ContactMessageHistoryView(APIView):
"""تاریخچه‌ی پیام‌های فرستاده‌شده به یک شماره.
چرا بر اساس *شماره* و نه شناسه‌ی مخاطب: صفحه‌ی «مشتریان» و «مخاطبین»
دو موجودیتِ جدا هستند و کاربر انتظار دارد روی پروفایلِ مشتری هم ببیند
چه پیامی برایش رفته. شماره تنها چیزی است که این دو را به هم وصل
می‌کند، پس با شماره‌ی نرمال‌شده جستجو می‌کنیم.
"""
permission_classes = [IsAuthenticated]
def get(self, request):
raw = request.query_params.get("phone", "") or ""
phone = normalize_iran_phone(raw)
if not phone:
raise ValidationError({"phone": "شماره لازم است."})
# ارقامِ ذخیره‌شده ممکن است با ۰ یا +۹۸ باشند؛ روی چند شکل تطبیق
# می‌دهیم تا تاریخچه به‌خاطر تفاوتِ قالبِ شماره گم نشود.
variants = {phone, phone.lstrip("0"), "+98" + phone.lstrip("0"), "98" + phone.lstrip("0")}
rows = (
MessageRecipient.objects.filter(
bulk_message__user=request.user,
contact__phone__in=variants,
)
.select_related("bulk_message")
.order_by("-bulk_message__created_at", "-id")[:100]
)
return Response(ContactMessageHistorySerializer(rows, many=True).data)