fix(reports): refine financial export summaries
Some checks failed
Backend CI/CD / test (push) Has been cancelled
Backend CI/CD / deploy (push) Has been cancelled

This commit is contained in:
2026-05-23 20:13:35 +03:30
parent 59cf62bc73
commit 22e08a099c
3 changed files with 260 additions and 111 deletions

View File

@@ -4,7 +4,12 @@ from django.test import TestCase
from openpyxl import load_workbook
from apps.reports.services.export_i18n import build_export_locale
from apps.reports.services.exporters import build_excel_report, build_pdf_report
from apps.reports.services.exporters import (
_pdf_summary_rate_label,
_rate_label,
build_excel_report,
build_pdf_report,
)
def make_report_data(*, user_name="Owner User", mobile="09129990001", hourly_rate=None):
@@ -74,14 +79,67 @@ def make_user_summary(*, name: str, mobile: str):
}
def make_variable_user_summary(*, name: str, mobile: str):
summary = make_user_summary(name=name, mobile=mobile)
summary["hourly_rates"] = [
{"amount": "15.00", "currency": "USD"},
{"amount": "18.00", "currency": "USD"},
]
summary["rate_periods"] = [
{
"amount": "15.00",
"currency": "USD",
"from_date": "2026-04-01",
"to_date": "2026-04-14",
},
{
"amount": "18.00",
"currency": "USD",
"from_date": "2026-04-15",
"to_date": "2026-04-30",
},
]
return summary
class ReportExporterTests(TestCase):
def test_export_rate_labels_trim_rial_and_toman_decimals(self):
locale = build_export_locale("en")
self.assertEqual(
_rate_label(locale, {"amount": "1250.75", "currency": "USD"}),
"1,250.75 USD",
)
self.assertEqual(
_rate_label(locale, {"amount": "1250.75", "currency": "IRR"}),
"1,250 IRR",
)
self.assertEqual(
_rate_label(locale, {"amount": "9800.50", "currency": "IRT"}),
"9,800 IRT",
)
def test_pdf_summary_uses_multiple_rates_label(self):
locale = build_export_locale("en")
self.assertEqual(
_pdf_summary_rate_label(
locale,
[
{"amount": "15.00", "currency": "USD"},
{"amount": "18.00", "currency": "USD"},
],
),
"Variable rate",
)
def test_excel_export_adds_per_user_sheets_and_daily_rate_column(self):
locale = build_export_locale("en")
report_data = make_report_data(
hourly_rate={"amount": "15.00", "currency": "USD"},
)
report_data["user_summaries"] = [
make_user_summary(name="Owner User", mobile="09129990001"),
make_variable_user_summary(name="Owner User", mobile="09129990001"),
make_user_summary(name="Team Mate", mobile="09129990002"),
]
per_user_reports = [
@@ -91,7 +149,7 @@ class ReportExporterTests(TestCase):
mobile="09129990001",
hourly_rate={"amount": "15.00", "currency": "USD"},
),
"user_summary": make_user_summary(name="Owner User", mobile="09129990001"),
"user_summary": make_variable_user_summary(name="Owner User", mobile="09129990001"),
},
{
**make_report_data(
@@ -123,14 +181,13 @@ class ReportExporterTests(TestCase):
self.assertEqual(summary_sheet["A1"].value, "Workspace Report")
self.assertEqual(summary_sheet["B1"].value, "Exports")
self.assertEqual(summary_sheet["A15"].value, "Users Summary")
self.assertIn("A15:P15", {str(item) for item in summary_sheet.merged_cells.ranges})
self.assertIn("A15:O15", {str(item) for item in summary_sheet.merged_cells.ranges})
self.assertEqual(
tuple(summary_sheet.iter_rows(min_row=16, max_row=16, values_only=True))[0][:16],
tuple(summary_sheet.iter_rows(min_row=16, max_row=16, values_only=True))[0][:15],
(
"Name",
"Mobile",
"Working hours",
"Non-working hours",
"Hourly rate",
"Period",
"Income",
@@ -147,6 +204,7 @@ class ReportExporterTests(TestCase):
)
self.assertTrue(any(row and "Owner User" in row for row in summary_values))
self.assertTrue(any(row and "09129990001" in row for row in summary_values))
self.assertTrue(any(row and "Variable rate" in row for row in summary_values))
user_sheet = workbook[workbook.sheetnames[1]]
user_values = list(user_sheet.iter_rows(values_only=True))
@@ -169,13 +227,11 @@ class ReportExporterTests(TestCase):
breakdown_header = next(row[:7] for row in user_values if row and row[0] == "Name" and row[2] == "Hour %")
self.assertEqual(
breakdown_header,
breakdown_header[:5],
(
"Name",
"Billable hours",
"Hour %",
"Non-billable hours",
"Total hours",
"Income",
"Income %",
),