diff --git a/apps/reports/services/aggregation.py b/apps/reports/services/aggregation.py index 0fc5b7f..096683f 100644 --- a/apps/reports/services/aggregation.py +++ b/apps/reports/services/aggregation.py @@ -53,9 +53,9 @@ UNCATEGORIZED_LABELS = { "tags": "No tag", }, "fa": { - "clients": "\u0628\u062f\u0648\u0646 \u0645\u0634\u062a\u0631\u06cc", - "projects": "\u0628\u062f\u0648\u0646 \u067e\u0631\u0648\u0698\u0647", - "tags": "\u0628\u062f\u0648\u0646 \u062a\u06af", + "clients": "بدون مشتری", + "projects": "بدون پروژه", + "tags": "بدون تگ", }, } diff --git a/apps/reports/services/export_i18n.py b/apps/reports/services/export_i18n.py index 5528576..be428c5 100644 --- a/apps/reports/services/export_i18n.py +++ b/apps/reports/services/export_i18n.py @@ -10,7 +10,7 @@ import jdatetime from arabic_reshaper import reshape from bidi.algorithm import get_display -PERSIAN_DIGITS = str.maketrans("0123456789", "\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9") +PERSIAN_DIGITS = str.maketrans("0123456789", "۰۱۲۳۴۵۶۷۸۹") ARABIC_RANGES = ( (0x0600, 0x06FF), (0x0750, 0x077F), @@ -70,52 +70,52 @@ TRANSLATIONS = { "uncategorized_tag": "No tag", }, "fa": { - "report_title": "\u06af\u0632\u0627\u0631\u0634 \u0641\u0636\u0627\u06cc \u06a9\u0627\u0631\u06cc", - "overall_sheet": "\u06af\u0632\u0627\u0631\u0634 \u06a9\u0644\u06cc", - "users_summary_sheet": "\u062e\u0644\u0627\u0635\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646", - "workspace": "\u0641\u0636\u0627\u06cc \u06a9\u0627\u0631\u06cc", - "period": "\u0628\u0627\u0632\u0647", - "from_date": "\u0627\u0632 \u062a\u0627\u0631\u06cc\u062e", - "to_date": "\u062a\u0627 \u062a\u0627\u0631\u06cc\u062e", - "user": "\u06a9\u0627\u0631\u0628\u0631", - "mobile": "\u0645\u0648\u0628\u0627\u06cc\u0644", - "all_users": "\u0647\u0645\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646", - "generated_at": "\u062a\u0627\u0631\u06cc\u062e \u062a\u0648\u0644\u06cc\u062f", - "summary": "\u062e\u0644\u0627\u0635\u0647", - "total_hours": "\u06a9\u0644 \u0633\u0627\u0639\u0627\u062a", - "billable_hours": "\u0633\u0627\u0639\u0627\u062a \u06a9\u0627\u0631\u06cc", - "non_billable_hours": "\u0633\u0627\u0639\u0627\u062a \u063a\u06cc\u0631 \u06a9\u0627\u0631\u06cc", - "hourly_rate": "\u0646\u0631\u062e \u0633\u0627\u0639\u062a\u06cc", - "income": "\u06a9\u0627\u0631\u06a9\u0631\u062f", - "working_hours": "\u0633\u0627\u0639\u0627\u062a \u06a9\u0627\u0631\u06cc", - "non_working_hours": "\u0633\u0627\u0639\u0627\u062a \u063a\u06cc\u0631\u06a9\u0627\u0631\u06cc", - "hourly_rates": "\u0646\u0631\u062e\u200c\u0647\u0627\u06cc \u0633\u0627\u0639\u062a\u06cc", - "project_percentages": "\u062f\u0631\u0635\u062f \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627", - "client_percentages": "\u062f\u0631\u0635\u062f \u0645\u0634\u062a\u0631\u06cc\u200c\u0647\u0627", - "tag_percentages": "\u062f\u0631\u0635\u062f \u062a\u06af\u200c\u0647\u0627", - "summary_by_user": "\u062e\u0644\u0627\u0635\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646", - "rate_history": "\u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0646\u0631\u062e \u0633\u0627\u0639\u062a\u06cc", - "from": "\u0627\u0632", - "to": "\u062a\u0627", - "now": "\u062d\u0627\u0644", - "project": "\u067e\u0631\u0648\u0698\u0647", - "percentage": "\u062f\u0631\u0635\u062f", - "hour_percentage": "\u062f\u0631\u0635\u062f \u0633\u0627\u0639\u062a", - "income_percentage": "\u062f\u0631\u0635\u062f \u06a9\u0627\u0631\u06a9\u0631\u062f", - "multiple_rates": "\u0686\u0646\u062f \u0646\u0631\u062e - \u062c\u0632\u0626\u06cc\u0627\u062a \u062f\u0631 \u06af\u0632\u0627\u0631\u0634 \u06a9\u0627\u0631\u0628\u0631", - "variable_rate": "\u0646\u0631\u062e \u0645\u062a\u063a\u06cc\u0631", - "none": "\u0628\u062f\u0648\u0646 \u0645\u0648\u0631\u062f", - "daily_summary": "\u062e\u0644\u0627\u0635\u0647 \u0631\u0648\u0632\u0627\u0646\u0647", - "clients": "\u0645\u0634\u062a\u0631\u06cc\u0627\u0646", - "projects": "\u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627", - "tags": "\u062a\u06af\u200c\u0647\u0627", - "date": "\u062a\u0627\u0631\u06cc\u062e", - "name": "\u0646\u0627\u0645", - "total": "\u062c\u0645\u0639", - "no_data": "\u0628\u062f\u0648\u0646 \u062f\u0627\u062f\u0647", - "uncategorized_client": "\u0628\u062f\u0648\u0646 \u0645\u0634\u062a\u0631\u06cc", - "uncategorized_project": "\u0628\u062f\u0648\u0646 \u067e\u0631\u0648\u0698\u0647", - "uncategorized_tag": "\u0628\u062f\u0648\u0646 \u062a\u06af", + "report_title": "گزارش فضای کاری", + "overall_sheet": "گزارش کلی", + "users_summary_sheet": "خلاصه کاربران", + "workspace": "فضای کاری", + "period": "بازه", + "from_date": "از تاریخ", + "to_date": "تا تاریخ", + "user": "کاربر", + "mobile": "موبایل", + "all_users": "همه کاربران", + "generated_at": "تاریخ تولید", + "summary": "خلاصه", + "total_hours": "کل ساعات", + "billable_hours": "ساعات کاری", + "non_billable_hours": "ساعات غیر کاری", + "hourly_rate": "نرخ ساعتی", + "income": "کارکرد", + "working_hours": "ساعات کاری", + "non_working_hours": "ساعات غیرکاری", + "hourly_rates": "نرخ‌های ساعتی", + "project_percentages": "درصد پروژه‌ها", + "client_percentages": "درصد مشتری‌ها", + "tag_percentages": "درصد تگ‌ها", + "summary_by_user": "خلاصه کاربران", + "rate_history": "تاریخچه نرخ ساعتی", + "from": "از", + "to": "تا", + "now": "حال", + "project": "پروژه", + "percentage": "درصد", + "hour_percentage": "درصد ساعت", + "income_percentage": "درصد کارکرد", + "multiple_rates": "چند نرخ - جزئیات در گزارش کاربر", + "variable_rate": "نرخ متغیر", + "none": "بدون مورد", + "daily_summary": "خلاصه روزانه", + "clients": "مشتریان", + "projects": "پروژه‌ها", + "tags": "تگ‌ها", + "date": "تاریخ", + "name": "نام", + "total": "جمع", + "no_data": "بدون داده", + "uncategorized_client": "بدون مشتری", + "uncategorized_project": "بدون پروژه", + "uncategorized_tag": "بدون تگ", }, } @@ -129,23 +129,23 @@ PERIOD_LABELS = { "period": "Custom period", }, "fa": { - "this_week": "\u0627\u06cc\u0646 \u0647\u0641\u062a\u0647", - "this_month": "\u0627\u06cc\u0646 \u0645\u0627\u0647", - "this_year": "\u0627\u0645\u0633\u0627\u0644", - "half_year_first": "\u0646\u06cc\u0645\u0647 \u0627\u0648\u0644 \u0633\u0627\u0644", - "half_year_second": "\u0646\u06cc\u0645\u0647 \u062f\u0648\u0645 \u0633\u0627\u0644", - "period": "\u0628\u0627\u0632\u0647 \u062f\u0644\u062e\u0648\u0627\u0647", + "this_week": "این هفته", + "this_month": "این ماه", + "this_year": "امسال", + "half_year_first": "نیمه اول سال", + "half_year_second": "نیمه دوم سال", + "period": "بازه دلخواه", }, } CURRENCY_LABELS = { - "USD": {"en": "USD", "fa": "\u062f\u0644\u0627\u0631 \u0622\u0645\u0631\u06cc\u06a9\u0627"}, - "EUR": {"en": "EUR", "fa": "\u06cc\u0648\u0631\u0648"}, - "GBP": {"en": "GBP", "fa": "\u067e\u0648\u0646\u062f"}, - "IRR": {"en": "IRR", "fa": "\u0631\u06cc\u0627\u0644"}, - "IRT": {"en": "IRT", "fa": "\u062a\u0648\u0645\u0627\u0646"}, - "AED": {"en": "AED", "fa": "\u062f\u0631\u0647\u0645"}, - "TRY": {"en": "TRY", "fa": "\u0644\u06cc\u0631"}, + "USD": {"en": "USD", "fa": "دلار آمریکا"}, + "EUR": {"en": "EUR", "fa": "یورو"}, + "GBP": {"en": "GBP", "fa": "پوند"}, + "IRR": {"en": "IRR", "fa": "ریال"}, + "IRT": {"en": "IRT", "fa": "تومان"}, + "AED": {"en": "AED", "fa": "درهم"}, + "TRY": {"en": "TRY", "fa": "لیر"}, } DECIMAL_TRIM_CURRENCIES = {"IRR", "IRT"} diff --git a/apps/reports/services/exporters.py b/apps/reports/services/exporters.py index 244bda0..0bf5c8a 100644 --- a/apps/reports/services/exporters.py +++ b/apps/reports/services/exporters.py @@ -71,7 +71,7 @@ def _money_label(locale: ExportLocale, income_totals: list[dict]) -> str: def _money_label_excel(locale: ExportLocale, income_totals: list[dict]) -> str: value = locale.format_money_label(income_totals, ascii_digits=True) - return f"\u202B{value}\u202C" if locale.is_rtl else value + return f"\u202B{value}\u202C" if locale.is_rtl else value # Unicode bidi control characters def _rates_label(locale: ExportLocale, rates: list[dict], *, ascii_digits: bool = False) -> str: @@ -114,7 +114,7 @@ def _rate_label_excel(locale: ExportLocale, rate: dict | None) -> str: f"{locale.format_amount_for_currency(rate['amount'], rate['currency'], ascii_digits=True)} " f"{locale.currency_label(rate['currency'])}" ) - return f"\u202B{value}\u202C" if locale.is_rtl else value + return f"\u202B{value}\u202C" if locale.is_rtl else value # Unicode bidi control characters def _pdf_summary_rate_label(locale: ExportLocale, rates: list[dict]) -> str: @@ -227,7 +227,7 @@ def _percentage_display(locale: ExportLocale, rows: list[dict], row_data: dict, def _percentage_value(locale: ExportLocale, percentage: str, *, ascii_digits: bool = False) -> str: value = f"{locale.format_amount(percentage, ascii_digits=ascii_digits)}%" - return f"\u202B{value}\u202C" if locale.is_rtl and ascii_digits else value + return f"\u202B{value}\u202C" if locale.is_rtl and ascii_digits else value # Unicode bidi control characters def _summary_breakdown_rows(