feat: added promocode activation

also code reformatting and bug fixes
This commit is contained in:
ITQ
2025-01-26 11:33:03 +03:00
parent 43baa2af5c
commit 545201e4dd
11 changed files with 218 additions and 99 deletions
+3 -1
View File
@@ -70,7 +70,9 @@ class CreatePromocodeOut(Schema):
class PromocodeListFilters(Schema):
limit: int = Field(10, gt=0, description="Limit must be greater than 0")
limit: int = Field(
10, ge=0, description="Limit must be greater than or equal 0"
)
offset: int = Field(
0, ge=0, description="Offset must be greater than or equal to 0"
)
+6 -6
View File
@@ -172,8 +172,8 @@ def list_promocode(
promocodes = promocodes.order_by("-created_at")
promocodes = promocodes.prefetch_related("activations", "likes").annotate(
used_count=Count("activations"),
like_count=Count("likes"),
used_count=Count("activations", distinct=True),
like_count=Count("likes", distinct=True),
)
promocodes = promocodes[filters.offset : filters.offset + filters.limit]
@@ -213,8 +213,8 @@ def get_promocode(
promocodes.select_related("target")
.prefetch_related("activations", "likes")
.annotate(
used_count=Count("activations"),
like_count=Count("likes"),
used_count=Count("activations", distinct=True),
like_count=Count("likes", distinct=True),
)
)
@@ -255,8 +255,8 @@ def patch_promocode(
promocodes.select_related("target")
.prefetch_related("activations", "likes")
.annotate(
used_count=Count("activations"),
like_count=Count("likes"),
used_count=Count("activations", distinct=True),
like_count=Count("likes", distinct=True),
)
)
+11 -5
View File
@@ -71,7 +71,9 @@ class PatchUserIn(Schema):
class PromocodeFeedFilters(Schema):
limit: int = Field(10, gt=0, description="Limit must be greater than 0")
limit: int = Field(
10, ge=0, description="Limit must be greater than or equal 0"
)
offset: int = Field(
0, ge=0, description="Offset must be greater than or equal to 0"
)
@@ -101,7 +103,9 @@ class PromocodeRemoveLikeOut(Schema):
class PromocodeCommentsFilters(Schema):
limit: int = Field(10, gt=0, description="Limit must be greater than 0")
limit: int = Field(
10, ge=0, description="Limit must be greater than or equal 0"
)
offset: int = Field(
0, ge=0, description="Offset must be greater than or equal to 0"
)
@@ -110,9 +114,7 @@ class PromocodeCommentsFilters(Schema):
class CommentIn(ModelSchema):
class Meta:
model = PromocodeComment
fields: ClassVar[list[str]] = [
PromocodeComment.text.field.name
]
fields: ClassVar[list[str]] = [PromocodeComment.text.field.name]
class CommentAuthor(Schema):
@@ -130,3 +132,7 @@ class CommentOut(Schema):
class CommentDeletedOut(Schema):
status: str = "ok"
class PromocodeActivateOut(Schema):
promo: str
+2 -2
View File
@@ -39,6 +39,6 @@ def map_comment_to_schema(comment: PromocodeComment) -> schemas.CommentOut:
author=schemas.CommentAuthor(
name=comment.author.name,
surname=comment.author.surname,
avatar_url=comment.author.avatar_url
)
avatar_url=comment.author.avatar_url,
),
)
+61 -10
View File
@@ -17,6 +17,7 @@ from apps.promo.models import (
)
from apps.user.models import User
from config.errors import UniqueConstraintError
from config.integrations.antifraud.interactor import AntifraudServiceInteractor
router = Router(tags=["user"])
@@ -146,8 +147,8 @@ def feed(
)
promocodes = promocodes.prefetch_related("likes", "comments").annotate(
like_count=Count("likes"),
comment_count=Count("comments"),
like_count=Count("likes", distinct=True),
comment_count=Count("comments", distinct=True),
is_liked_by_user=Exists(
PromocodeLike.objects.filter(promocode=OuterRef("pk"), user=user)
),
@@ -203,8 +204,8 @@ def get_promocode(
promocodes.select_related("business")
.prefetch_related("likes", "comments")
.annotate(
like_count=Count("likes"),
comment_count=Count("comments"),
like_count=Count("likes", distinct=True),
comment_count=Count("comments", distinct=True),
is_liked_by_user=Exists(
PromocodeLike.objects.filter(
promocode=OuterRef("pk"), user=user
@@ -234,7 +235,7 @@ def get_promocode(
)
def add_like(
request: HttpRequest, promocode_id: str
) -> tuple[status.OK, schemas.PromocodeViewOut]:
) -> tuple[status.OK, schemas.PromocodeLikeOut]:
user: User = request.auth
promocodes = Promocode.objects.filter(id=promocode_id)
@@ -259,7 +260,7 @@ def add_like(
)
def delete_like(
request: HttpRequest, promocode_id: str
) -> tuple[status.OK, schemas.PromocodeViewOut]:
) -> tuple[status.OK, schemas.PromocodeRemoveLikeOut]:
user: User = request.auth
promocodes = Promocode.objects.filter(id=promocode_id)
@@ -272,7 +273,7 @@ def delete_like(
promocode=promocodes.first(), user=user
).delete()
return status.OK, schemas.PromocodeLikeOut()
return status.OK, schemas.PromocodeRemoveLikeOut()
@router.post(
@@ -315,8 +316,8 @@ def list_comments(
request: HttpRequest,
filters: Query[schemas.PromocodeCommentsFilters],
promocode_id: str,
response: HttpResponse
) -> tuple[int, schemas.CommentOut]:
response: HttpResponse,
) -> tuple[int, list[schemas.CommentOut]]:
promocodes = Promocode.objects.filter(id=promocode_id)
if not promocodes.exists():
@@ -412,7 +413,7 @@ def delete_comment(
request: HttpRequest,
promocode_id: str,
comment_id: str,
) -> tuple[int, schemas.CommentOut]:
) -> tuple[int, schemas.CommentDeletedOut]:
user: User = request.auth
commnets = PromocodeComment.objects.filter(
@@ -432,3 +433,53 @@ def delete_comment(
comment_obj.delete()
return status.OK, schemas.CommentDeletedOut()
@router.post(
"/promo/{promocode_id}/activate",
auth=UserAuth(),
response={
status.OK: schemas.PromocodeActivateOut,
status.BAD_REQUEST: global_schemas.BadRequestError,
status.NOT_FOUND: global_schemas.NotFoundError,
},
)
def activate_promocode(
request: HttpRequest,
promocode_id: str,
) -> tuple[int, schemas.PromocodeActivateOut]:
user: User = request.auth
promocodes = Promocode.objects.filter(id=promocode_id)
if not promocodes.exists():
raise HttpError(status.NOT_FOUND, status.NOT_FOUND.phrase)
promocodes = promocodes.select_related("target").filter(
Q(
Q(target__age_from__isnull=True)
| Q(target__age_from__lte=user.age),
Q(target__age_until__isnull=True)
| Q(target__age_until__gte=user.age),
Q(target__country__isnull=True) | Q(target__country=user.country),
)
)
if not promocodes.exists():
raise HttpError(status.FORBIDDEN, status.FORBIDDEN.phrase)
promocode = promocodes.first()
if not promocode.active:
raise HttpError(status.FORBIDDEN, status.FORBIDDEN.phrase)
antifraud_result = AntifraudServiceInteractor().validate(
user_email=user.email, promo_id=str(promocode.id)
)
if not antifraud_result["ok"]:
raise HttpError(status.FORBIDDEN, status.FORBIDDEN.phrase)
promo = promocode.activate_promocode(user)
return status.OK, schemas.PromocodeActivateOut(promo=promo)