59 lines
3.0 KiB
Python
59 lines
3.0 KiB
Python
from datetime import date
|
|
from decimal import Decimal
|
|
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
|
|
from apps.accounts.models import User
|
|
from apps.companies.models import Company
|
|
from apps.projects.models import Project, ProjectMember
|
|
from apps.tasks.models import Task
|
|
|
|
from .services import build_monthly_report
|
|
|
|
|
|
class MonthlyReportTests(TestCase):
|
|
def setUp(self):
|
|
self.user = User.objects.create_user(username="worker", password="password123", must_change_password=False)
|
|
self.company_a = Company.objects.create(name="Клиент A")
|
|
self.company_b = Company.objects.create(name="Клиент B")
|
|
self.project_a = Project.objects.create(company=self.company_a, name="Проект A")
|
|
self.project_b = Project.objects.create(company=self.company_b, name="Проект B")
|
|
for project in (self.project_a, self.project_b):
|
|
ProjectMember.objects.create(project=project, user=self.user, hourly_rate=Decimal("1000.00"))
|
|
self._task(self.project_a, "Выполнена A", Task.Status.COMPLETED, 60)
|
|
self._task(self.project_b, "Выполнена B", Task.Status.COMPLETED, 30)
|
|
self._task(self.project_a, "Отменена", Task.Status.CANCELLED, 120)
|
|
|
|
def _task(self, project, title, status, minutes):
|
|
return Task.objects.create(
|
|
project=project, assignee=self.user, title=title, description="Описание", work_date=date(2026, 7, 10),
|
|
duration_minutes=minutes, hourly_rate=Decimal("1000.00"),
|
|
amount=Task.calculate_amount(minutes, Decimal("1000.00")), status=status, created_by=self.user,
|
|
)
|
|
|
|
def test_internal_report_groups_companies_and_excludes_cancelled(self):
|
|
report = build_monthly_report(self.user, 2026, 7)
|
|
self.assertEqual(len(report["companies"]), 2)
|
|
self.assertEqual(report["total_minutes"], 90)
|
|
self.assertEqual(report["total_amount"], Decimal("1500.00"))
|
|
|
|
def test_client_report_contains_only_selected_company(self):
|
|
report = build_monthly_report(self.user, 2026, 7, company=self.company_a)
|
|
self.assertEqual(len(report["companies"]), 1)
|
|
self.assertEqual(report["companies"][0]["company"], self.company_a)
|
|
self.assertEqual(report["total_minutes"], 60)
|
|
|
|
def test_worker_cannot_request_other_users_report(self):
|
|
other = User.objects.create_user(username="other", password="password123", must_change_password=False)
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("monthly-report"), {"user": other.pk, "year": 2026, "month": 7})
|
|
self.assertEqual(response.context["report"]["user"], self.user)
|
|
|
|
def test_client_pdf_is_generated_for_one_company(self):
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("company-report-pdf", args=(self.company_a.pk,)), {"year": 2026, "month": 7})
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response["Content-Type"], "application/pdf")
|
|
self.assertTrue(response.content.startswith(b"%PDF"))
|