Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions backend/donations/admin/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class CommonCauseFields:
{"fields": ("ngo",)},
)

flags_fieldset: tuple[str, dict[str, tuple[str]]] = (
flags_fieldset = (
_("Flags"),
{
"fields": (
Expand All @@ -36,7 +36,7 @@ class CommonCauseFields:
},
)

form_data_fieldset: tuple[str, dict[str, tuple[str]]] = (
form_data_fieldset = (
_("Form Data"),
{
"fields": (
Expand All @@ -46,7 +46,7 @@ class CommonCauseFields:
},
)

data_fieldset: tuple[str, dict[str, tuple[str]]] = (
data_fieldset = (
_("Data"),
{
"fields": (
Expand All @@ -58,7 +58,7 @@ class CommonCauseFields:
},
)

dates_fieldset: tuple[str, dict[str, tuple[str]]] = (
dates_fieldset = (
_("Date"),
{
"fields": (
Expand All @@ -70,7 +70,7 @@ class CommonCauseFields:

readonly_fields = ("ngo", "date_created", "date_updated")

def get_readonly_fields(self, _: HttpRequest, obj=None):
def get_readonly_fields(self, request: HttpRequest, obj=None):
if obj and not obj.has_online_tax_account:
return self.readonly_fields + ("allow_online_collection",)

Expand Down
2 changes: 1 addition & 1 deletion backend/donations/admin/donors.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ def run_anonymize_donation_task(selected_donor: Donor) -> dict[str, str]:
},
)

return redirect(reverse_lazy("admin:donations_donor_change", args=[donor.pk]))
# return redirect(reverse_lazy("admin:donations_donor_change", args=[donor.pk]))

@action(description=_("Schedule redirections stats"), url_path="schedule-redirections-stats-generator")
def run_redirections_stats_generator(self, request):
Expand Down
6 changes: 3 additions & 3 deletions backend/donations/admin/ngos.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def has_delete_permission(self, request, obj=...):

class NgoPartnerInline(TabularInline):
# noinspection PyUnresolvedReferences
model = Ngo.partners.through
model = Ngo.partners.through # type: ignore
extra = 1
tab = True

Expand Down Expand Up @@ -515,7 +515,7 @@ def update_from_ngohub_async(self, request: HttpRequest, queryset: QuerySet[Ngo]
def check_cult_registry_sync(self, request: HttpRequest, queryset: QuerySet[Ngo]):
show_errors: bool = True

registration_numbers = queryset.values_list("registration_number", flat=True)
registration_numbers: list[str] = queryset.values_list("registration_number", flat=True) # type: ignore
task_result = cult_registry_check_organizations(registration_numbers, update_method="sync")

message = "ANAF Registry Results: | "
Expand All @@ -533,7 +533,7 @@ def check_cult_registry_sync(self, request: HttpRequest, queryset: QuerySet[Ngo]

@action(description=_("Check in ANAF Cult Registry asynchronously"))
def check_cult_registry_async(self, request, queryset: QuerySet[Ngo]):
registration_numbers = queryset.values_list("registration_number", flat=True)
registration_numbers: list[str] = queryset.values_list("registration_number", flat=True) # type: ignore
cult_registry_check_organizations(registration_numbers, update_method="async")
self.message_user(request, _("NGOs are being searched in ANAF Cult Registry."))

Expand Down
4 changes: 2 additions & 2 deletions backend/donations/forms/ngo_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def save(self, commit=True):
return cause

def clean_slug(self):
slug = self.cleaned_data.get("slug").lower()
slug = self.cleaned_data.get("slug", "").lower()

ngo_slug_validator(slug)

Expand All @@ -155,7 +155,7 @@ def clean_slug(self):
return slug

def clean_description(self):
return self.cleaned_data.get("description").strip()
return self.cleaned_data.get("description", "").strip()

def clean_bank_account(self):
bank_account = self.cleaned_data.get("bank_account")
Expand Down
3 changes: 1 addition & 2 deletions backend/donations/management/commands/generate_orgs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import random
from typing import Any

from django.contrib.auth import get_user_model
from django.core.management import BaseCommand
Expand Down Expand Up @@ -803,7 +802,7 @@ def handle(self, *args, **options):
create_user_only = options.get("user_only", None)
create_ngohub_id = options.get("ngohub", None)

organizations: list[dict[str, Any]] = []
organizations: list[Ngo] = []
generated_organization_names: list[str] = []

user_model = get_user_model()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ def handle(self, *args, **options):
consecutive_identical_names: int = 0
while len(causes) < total_causes:
if target_org:
ngo: Ngo = target_org
ngo: Ngo | None = target_org
else:
ngo: Ngo = Ngo.active.order_by("?").first()
if not ngo.can_create_causes:
ngo: Ngo | None = Ngo.active.order_by("?").first()
if not ngo or not ngo.can_create_causes:
continue

cause_title = MOCK_CAUSE_NAMES["titles"][random.randint(0, len(MOCK_CAUSE_NAMES["titles"]) - 1)]
Expand Down
2 changes: 1 addition & 1 deletion backend/donations/management/commands/generate_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def add_arguments(self, parser):

def handle(self, *args, **options):
statistic_type: str = options["statistic"]
for_date_str: str = options.get("date")
for_date_str: str = options.get("date", "")

if statistic_type == StatsChoices.REDIRECTIONS_PER_DAY and not for_date_str:
self.stderr.write("Error: --date argument is required for REDIRECTIONS_PER_DAY statistic.")
Expand Down
2 changes: 1 addition & 1 deletion backend/donations/models/downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class RedirectionsDownloadJob(AsyncJob):
null=True,
)

class Meta:
class Meta: # type: ignore
verbose_name = _("download job")
verbose_name_plural = _("download jobs")

Expand Down
2 changes: 1 addition & 1 deletion backend/donations/models/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Job(AsyncJob):
def __str__(self):
return f"{self.cause} {self.status}"

class Meta:
class Meta: # type: ignore
verbose_name = _("job")
verbose_name_plural = _("jobs")

Expand Down
27 changes: 22 additions & 5 deletions backend/donations/models/ngos.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import re
from functools import partial
from typing import Any
from typing import TYPE_CHECKING, Any

from auditlog.registry import auditlog
from django.conf import settings
Expand All @@ -25,6 +25,11 @@
ngo_id_number_validator,
)

if TYPE_CHECKING:
from donations.models import Job, RedirectionsDownloadJob
from partners.models import Partner


ALL_NGOS_CACHE_KEY = "ALL_NGOS"
ALL_NGO_IDS_CACHE_KEY = "ALL_NGO_IDS"
FRONTPAGE_NGOS_KEY = "FRONTPAGE_NGOS"
Expand Down Expand Up @@ -280,12 +285,20 @@ class Ngo(CommonFilenameCacheModel):
date_created = models.DateTimeField(verbose_name=_("date created"), db_index=True, auto_now_add=True)
date_updated = models.DateTimeField(verbose_name=_("date updated"), db_index=True, auto_now=True)

# Type hinting for related models
causes: "models.manager.RelatedManager[Cause]"
partners: "models.manager.RelatedManager[Partner]"
jobs: "models.manager.RelatedManager[Job]"
download_jobs: "models.manager.RelatedManager[RedirectionsDownloadJob]"
donor_set: "models.manager.RelatedManager[Donor]"

# Model managers
objects = models.Manager()
active = NgoActiveManager()
ngo_hub = NgoHubManager()
with_forms_this_year = NgoWithFormsThisYearManager()

class Meta:
class Meta: # type: ignore
verbose_name = _("NGO")
verbose_name_plural = _("NGOs")

Expand Down Expand Up @@ -388,7 +401,7 @@ def has_ngo_hub(self):
@classmethod
def mandatory_fields(cls):
# noinspection PyTypeChecker
field_names: list[DeferredAttribute] = [
field_names = [
Ngo.name,
Ngo.registration_number,
]
Expand Down Expand Up @@ -540,7 +553,7 @@ class Cause(CommonFilenameCacheModel):
blank=True,
null=False,
storage=select_public_storage,
upload_to=partial(cause_directory_path, "logos"),
upload_to=partial(cause_directory_path, "logos"), # type: ignore
)

slug = models.SlugField(
Expand Down Expand Up @@ -571,14 +584,18 @@ class Cause(CommonFilenameCacheModel):
date_created = models.DateTimeField(verbose_name=_("date created"), db_index=True, auto_now_add=True)
date_updated = models.DateTimeField(verbose_name=_("date updated"), db_index=True, auto_now=True)

# Type hinting for related models
donor_set: "models.manager.RelatedManager[Donor]"

# Model managers
objects = models.Manager()
active = CauseActiveManager()
main = CauseMainManager()
other = CauseOtherManager()
public_active = CausePublicFormManager()
nonprivate_active = CauseNonPrivateFormManager()

class Meta:
class Meta: # type: ignore
verbose_name = _("Cause")
verbose_name_plural = _("Causes")
constraints = [
Expand Down
15 changes: 9 additions & 6 deletions backend/donations/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

def _format_bank_account(bank_account: str):
# remove spaces from the bank account number
bank_account: str = bank_account.replace(" ", "")
bank_account = bank_account.replace(" ", "")

account: str = ""
for i, letter in enumerate(bank_account):
Expand Down Expand Up @@ -58,7 +58,7 @@ def _add_ngo_data(start_y: int, c: Canvas, cause: Cause | None, ngo: Ngo):
c.setFontSize(11)

# the bank account
bank_account: str = cause.bank_account if cause else ngo.bank_account
bank_account: str = (cause.bank_account if cause else ngo.bank_account) or ""
account: str = _format_bank_account(bank_account)
c.drawString(110, start_ngo_y - 84, account)

Expand Down Expand Up @@ -159,7 +159,7 @@ def _add_donor_data(start_y, c: Canvas, donor: Donor):
cnp: str = donor.get_cnp()
for letter in cnp:
c.drawString(cnp_x, cnp_y, letter)
cnp_x += 18.5
cnp_x += 18

# email
start_email_x: int = donor_block_x + 296
Expand Down Expand Up @@ -189,9 +189,9 @@ def _add_donor_data(start_y, c: Canvas, donor: Donor):
c.drawString(donor_block_x - 39, donor_block_y - 362, "x")


def _add_signature_to_pdf(c: Canvas, signature: str, new_height: int = 30):
def _add_signature_to_pdf(c: Canvas, raw_signature: str, new_height: int = 30):
# Remove the header added by JavaScript
headerless_signature: str = signature.split(",")[1]
headerless_signature: str = raw_signature.split(",")[1]
# Make sure the string has the right padding
signature: str = headerless_signature + "=" * (-len(headerless_signature) % 4)

Expand Down Expand Up @@ -279,7 +279,10 @@ def create_full_pdf(donor: Donor, signature: str | None = None):
# DRAW DONOR DATA
_add_donor_data(start_y, c, donor)

_add_ngo_data(start_y, c, donor.cause, donor.ngo)
if donor.ngo:
_add_ngo_data(start_y, c, donor.cause, donor.ngo)
else:
print("Cannot add NGO data to PDF because there is no NGO")

if signature:
_add_signature_to_pdf(c, signature)
Expand Down
30 changes: 15 additions & 15 deletions backend/donations/tests/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,37 +53,37 @@ def with_all_fields(self) -> "DonorTestBuilder":
.with_misc()
)

def with_first_name(self, first_name: str = None) -> "DonorTestBuilder":
def with_first_name(self, first_name: str | None = None) -> "DonorTestBuilder":
self.donor_data["f_name"] = first_name if first_name else faker.first_name()

return self

def with_last_name(self, last_name: str = None) -> "DonorTestBuilder":
def with_last_name(self, last_name: str | None = None) -> "DonorTestBuilder":
self.donor_data["l_name"] = last_name if last_name else faker.last_name()

return self

def with_initial(self, initial: str = None) -> "DonorTestBuilder":
def with_initial(self, initial: str | None = None) -> "DonorTestBuilder":
self.donor_data["initial"] = initial if initial else faker.random_uppercase_letter()

return self

def with_cnp(self, cnp: str = None) -> "DonorTestBuilder":
def with_cnp(self, cnp: str | None = None) -> "DonorTestBuilder":
self.donor_data["cnp"] = cnp if cnp else faker.ssn()

return self

def with_city(self, city: str = None) -> "DonorTestBuilder":
def with_city(self, city: str | None = None) -> "DonorTestBuilder":
self.donor_data["city"] = city if city else faker.city()

return self

def with_county(self, county: str = None) -> "DonorTestBuilder":
def with_county(self, county: str | None = None) -> "DonorTestBuilder":
self.donor_data["county"] = county if county else faker.state()

return self

def with_address(self, address: dict[str, str] = None) -> "DonorTestBuilder":
def with_address(self, address: dict[str, str] | None = None) -> "DonorTestBuilder":
if address is None:
address = {
"street_name": faker.street_name(),
Expand All @@ -102,17 +102,17 @@ def with_address(self, address: dict[str, str] = None) -> "DonorTestBuilder":

return self

def with_phone(self, phone: str = None) -> "DonorTestBuilder":
def with_phone(self, phone: str | None = None) -> "DonorTestBuilder":
self.donor_data["phone"] = phone if phone else faker.phone_number()

return self

def with_email(self, email: str = None) -> "DonorTestBuilder":
def with_email(self, email: str | None = None) -> "DonorTestBuilder":
self.donor_data["email"] = email if email else faker.email()

return self

def with_geoip(self, geoip: dict[str, Any] = None) -> "DonorTestBuilder":
def with_geoip(self, geoip: dict[str, Any] | None = None) -> "DonorTestBuilder":
if geoip is None:
geoip = {
"ip": faker.ipv4(),
Expand All @@ -129,11 +129,11 @@ def with_geoip(self, geoip: dict[str, Any] = None) -> "DonorTestBuilder":
def with_misc(
self,
*,
is_anonymous: bool = None,
anaf_gdpr: bool = None,
two_years: bool = None,
has_signed: bool = None,
income_type: str = None,
is_anonymous: bool | None = None,
anaf_gdpr: bool | None = None,
two_years: bool | None = None,
has_signed: bool | None = None,
income_type: str | None = None,
):
if is_anonymous is None:
is_anonymous = random.choice([True, False])
Expand Down
6 changes: 3 additions & 3 deletions backend/donations/views/dashboard/admin_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@
ADMIN_DASHBOARD_YEARLY_CACHE_KEY = "ADMIN_DASHBOARD_YEARLY"


def callback(_, context) -> dict:
def callback(request, context) -> dict:
context.update(_get_admin_stats())
return context


def _get_admin_stats() -> dict:
years_range_ascending = get_current_year_range()

header_stats: list[list[dict[str, str | int]]] = _get_header_stats()
header_stats: list[list[dict[str, str | int | datetime]]] = _get_header_stats()

yearly_stats: list[dict] = _get_yearly_stats(years_range_ascending)

Expand All @@ -54,7 +54,7 @@ def _get_header_stats() -> list[list[dict[str, str | int | datetime]]]:
today: datetime = now()

current_year: int = today.year
tz_info: tzinfo = today.tzinfo
tz_info: tzinfo | None = today.tzinfo

current_year_range = get_encoded_current_year_range(current_year, tz_info)

Expand Down
Loading