Skip to content

Commit

Permalink
Refactor the code.
Browse files Browse the repository at this point in the history
  • Loading branch information
platsajacki committed Apr 6, 2024
1 parent 14de900 commit 792627d
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 37 deletions.
7 changes: 3 additions & 4 deletions src/companies/api/viewsets/point.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet

from django.db.models import QuerySet

Expand Down Expand Up @@ -42,13 +42,12 @@ def add_employees(self, *args: Any, **kwargs: Any) -> Response:
return Response(EmployeeSerializer(employee).data)


class MaterialsStatisticViewSet(ModelViewSet):
http_method_names = ["get"]
class MaterialsStatisticViewSet(ReadOnlyModelViewSet):
serializer_class = MaterialsStatisticSerializer
permission_classes = [IsCompanyOwner]

def get_queryset(self) -> QuerySet[Material]:
DateValidatorService(self.request)()
DateValidatorService(self.request.query_params)()
return Material.objects.statistic(
self.kwargs["point_pk"],
self.request.query_params.get("date_from"),
Expand Down
7 changes: 3 additions & 4 deletions src/companies/models/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@ class Meta:
class MaterialQuerySet(QuerySet):
def statistic(self, point_id: int, date_from: str | None = None, date_to: str | None = None) -> Self:
now = timezone.now().date()
q_date_from = Q(date__gte=date_from) if date_from else Q(date__gte=(now - timedelta(days=30)))
q_date_to = Q(date__lte=date_to) if date_to else Q(date__lte=now)
date_filter = Q(date__gte=date_from or (now - timedelta(days=30))) & Q(date__lte=date_to or now)
stock_queryset = (
StockMaterial.objects.select_related("stock__date")
.filter(stock__point__id=point_id)
.annotate(date=F("stock__date"))
.filter(q_date_from & q_date_to)
.filter(date_filter)
)
stocks = (
stock_queryset.filter(material_id=OuterRef("id"))
Expand All @@ -54,7 +53,7 @@ def statistic(self, point_id: int, date_from: str | None = None, date_to: str |
.filter(material__stock__point_id=point_id)
.select_related("material__material_id")
.annotate(date=TruncDate("modified"))
.filter(q_date_from & q_date_to)
.filter(date_filter)
)
usage = (
usage_queryset.filter(material__material_id=OuterRef("id"))
Expand Down
12 changes: 6 additions & 6 deletions src/companies/services/materials_statistic/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
from typing import Callable

from rest_framework.exceptions import ValidationError
from rest_framework.request import Request

from django.http.request import QueryDict

from app.services import BaseService


@dataclass
class DateValidatorService(BaseService):
request: Request
query_params: QueryDict | None

def valide_date_query_params(self) -> None:
query_params = self.request.query_params
if not query_params:
if not self.query_params:
return
try:
date_format = "%Y-%m-%d"
date_from_str = query_params.get("date_from")
date_to_str = query_params.get("date_to")
date_from_str = self.query_params.get("date_from")
date_to_str = self.query_params.get("date_to")
if date_from_str:
date_from = datetime.strptime(date_from_str, date_format).date()
if date_to_str:
Expand Down
32 changes: 19 additions & 13 deletions tests/apps/companies/services/test_materials_statistic_validator.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
import pytest

from rest_framework.exceptions import ValidationError
from rest_framework.request import Request

from django.http.request import QueryDict

from companies.services import DateValidatorService


def test_valid_date_params(mock_request: Request, material_date_query_params: dict[str, str]):
mock_request.query_params = material_date_query_params # type: ignore
def test_valid_date_params(material_date_query_params: dict[str, str]):
query_params = QueryDict(mutable=True)
query_params.update(**material_date_query_params)

assert DateValidatorService(mock_request)() is True
assert DateValidatorService(query_params)() is True


def test_only_date_from_param(mock_request: Request, material_date_query_params: dict[str, str]):
def test_only_date_from_param(material_date_query_params: dict[str, str]):
del material_date_query_params["date_to"]
mock_request.query_params = material_date_query_params # type: ignore
query_params = QueryDict(mutable=True)
query_params.update(**material_date_query_params)

assert DateValidatorService(mock_request)() is True
assert DateValidatorService(query_params)() is True


def test_only_date_to_param(mock_request: Request, material_date_query_params: dict[str, str]):
def test_only_date_to_param(material_date_query_params: dict[str, str]):
del material_date_query_params["date_from"]
mock_request.query_params = material_date_query_params # type: ignore
query_params = QueryDict(mutable=True)
query_params.update(**material_date_query_params)

assert DateValidatorService(query_params)() is True

assert DateValidatorService(mock_request)() is True

def test_invalid_date_params(invalide_material_date_query_params: dict[str, str]):
query_params = QueryDict(mutable=True)
query_params.update(**invalide_material_date_query_params)

def test_invalid_date_params(mock_request: Request, invalide_material_date_query_params: dict[str, str]):
mock_request.query_params = invalide_material_date_query_params # type: ignore
with pytest.raises(ValidationError):
DateValidatorService(mock_request)()
DateValidatorService(query_params)()
3 changes: 1 addition & 2 deletions tests/fixtures/apps/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from tests.fixtures.apps.app.api import as_anon, as_superuser, as_user, mock_request
from tests.fixtures.apps.app.api import as_anon, as_superuser, as_user
from tests.fixtures.apps.app.factory import factory

__all__ = [
"as_anon",
"as_superuser",
"as_user",
"factory",
"mock_request",
]
8 changes: 0 additions & 8 deletions tests/fixtures/apps/app/api.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import pytest

from pytest_mock import MockerFixture
from rest_framework.request import Request

from app.testing import ApiClient
from users.models import User

Expand All @@ -20,8 +17,3 @@ def as_user(user: User) -> ApiClient:
@pytest.fixture
def as_superuser(superuser: User) -> ApiClient:
return ApiClient(user=superuser)


@pytest.fixture
def mock_request(mocker: MockerFixture) -> Request:
return mocker.MagicMock(spec=Request)

0 comments on commit 792627d

Please sign in to comment.