Skip to content

Commit

Permalink
Refund throtling and logging (#2017)
Browse files Browse the repository at this point in the history
* Throttling and logging for refunds
  • Loading branch information
nkiryanov authored Oct 2, 2023
1 parent 20b053c commit bde0512
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/app/conf/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"notion-materials": "100/hour",
"promocode": "100/hour",
"purchase": "100/hour",
"order-refund": "5/day",
},
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
Expand Down
32 changes: 24 additions & 8 deletions src/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-25 17:58+0300\n"
"POT-Creation-Date: 2023-10-02 20:01+0300\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
Expand All @@ -31,6 +31,10 @@ msgstr "Да"
msgid "No"
msgstr "Нет"

#: banking/base.py:23
msgid "—"
msgstr ""

#: banking/models.py:10
msgid "Atol"
msgstr "Атол"
Expand Down Expand Up @@ -362,31 +366,43 @@ msgstr "Файл"
msgid "Material files"
msgstr "Файлы"

#: orders/admin/orders/actions.py:14
#: orders/admin/orders/actions.py:21
msgid "Set paid"
msgstr "Пометить оплаченным"

#: orders/admin/orders/actions.py:22
#: orders/admin/orders/actions.py:29
msgid "Refund"
msgstr "Вернуть"

#: orders/admin/orders/actions.py:30
#: orders/admin/orders/actions.py:45
#, python-brace-format
msgid "Orders {refunded_orders_as_message} refunded."
msgstr "Заказы {refunded_orders_as_message} возвращены."

#: orders/admin/orders/actions.py:51
#, python-brace-format
msgid "Orders {non_refunded_orders_as_message} have not been refunded. Up to 5 "
"refunds per day are allowed. Please come back tomorrow."
msgstr "Заказы {non_refunded_orders_as_message} не были возвращены. "
"Разрешено до 5 возвратов в день, попробуйте снова завтра."

#: orders/admin/orders/actions.py:56
msgid "Ship without payments"
msgstr "Допустить до уроков без оплаты"

#: orders/admin/orders/actions.py:41
#: orders/admin/orders/actions.py:67
msgid "Ship again if paid"
msgstr "Ещё раз выполнить (если заказ не оплачен — не выполнится)"

#: orders/admin/orders/actions.py:54 products/admin/courses/actions.py:40
#: orders/admin/orders/actions.py:80 products/admin/courses/actions.py:40
msgid "Generate diplomas"
msgstr "Сгенерировать дипломы"

#: orders/admin/orders/actions.py:64
#: orders/admin/orders/actions.py:90
msgid "Accept homework"
msgstr "Засчитать домашку"

#: orders/admin/orders/actions.py:73
#: orders/admin/orders/actions.py:99
msgid "Disaccept homework"
msgstr "Не засчитать домашку"

Expand Down
32 changes: 29 additions & 3 deletions src/orders/admin/orders/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@

from celery import group

from django.contrib import messages
from django.db.models import QuerySet
from django.http.request import HttpRequest
from django.utils.translation import gettext as _

from app.admin import admin
from orders import tasks
from orders.admin.orders.throttling import OrderRefundActionThrottle
from orders.models import Order
from studying.models import Study


def format_orders_for_message(orders: list[Order]) -> str:
return ", ".join(str(order.id) for order in orders)


@admin.action(description=_("Set paid"), permissions=["pay"])
def set_paid(modeladmin: Any, request: HttpRequest, queryset: QuerySet) -> None:
for order in queryset.iterator():
Expand All @@ -21,10 +28,29 @@ def set_paid(modeladmin: Any, request: HttpRequest, queryset: QuerySet) -> None:

@admin.action(description=_("Refund"), permissions=["unpay"])
def refund(modeladmin: Any, request: HttpRequest, queryset: QuerySet) -> None:
for order in queryset.iterator():
order.refund()
throttle = OrderRefundActionThrottle()
refunded_orders = []
non_refunded_orders = []

modeladmin.message_user(request, f"{queryset.count()} orders refunded")
for order in queryset.iterator():
if throttle.allow_request(request, view=modeladmin):
order.refund()
modeladmin.log_change(request, order, "Order refunded")
refunded_orders.append(order)
else:
non_refunded_orders.append(order)

if refunded_orders:
refunded_orders_as_message = format_orders_for_message(refunded_orders)
modeladmin.message_user(request, _(f"Orders {refunded_orders_as_message} refunded."))

if non_refunded_orders:
non_refunded_orders_as_message = format_orders_for_message(non_refunded_orders)
modeladmin.message_user(
request,
_(f"Orders {non_refunded_orders_as_message} have not been refunded. Up to 5 refunds per day are allowed. Please come back tomorrow."),
level=messages.ERROR,
)


@admin.action(description=_("Ship without payments"), permissions=["pay"])
Expand Down
9 changes: 9 additions & 0 deletions src/orders/admin/orders/throttling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework.throttling import UserRateThrottle

from app.throttling import ConfigurableThrottlingMixin


class OrderRefundActionThrottle(ConfigurableThrottlingMixin, UserRateThrottle): # type: ignore
"""Throttle for order's admin action `refund`."""

scope = "order-refund"

0 comments on commit bde0512

Please sign in to comment.