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
2 changes: 1 addition & 1 deletion .env.kesaseteli.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ APPLY_MIGRATIONS=1
CREATE_SUPERUSER=1
COMPILE_TRANSLATIONS=1
CORS_ALLOW_ALL_ORIGINS=1
CSRF_TRUSTED_ORIGINS="https://localhost:3000,https://localhost:3100,https://localhost:3200"
CSRF_TRUSTED_ORIGINS="https://localhost:3000,https://localhost:3100,https://localhost:3200,https://localhost:8000"
EMPLOYER_URL=https://localhost:3000
# test env EMPLOYER_URL: https://yjdh-kesaseteli-ui-test.agw.arodevtest.hel.fi
# staging env EMPLOYER_URL: https://yjdh-kesaseteli-ui-stg.apps.platta.hel.fi
Expand Down
2 changes: 1 addition & 1 deletion backend/kesaseteli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Creates a new `SummerVoucherConfiguration` for the specified year.
* `--voucher-value`: Voucher value in euros (default: 350)
* `--min-work-compensation`: Minimum work compensation in euros (default: 500)
* `--min-work-hours`: Minimum work hours (default: 60)
* `--target-groups`: List of target group identifiers (default: all)
* `--target-groups`: List of target group identifiers (default: "primary_target_group,secondary_target_group")
* `--force`: Force creation by overwriting existing configuration if it exists

**Docker Entrypoint:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ def add_arguments(self, parser):
parser.add_argument(
"--target-groups",
nargs="+",
default=None,
default=settings.SUMMER_VOUCHER_DEFAULT_TARGET_GROUPS,
help=(
"List of target group identifiers. The options are: "
f"{', '.join(AVAILABLE_TARGET_GROUPS)} (default: all)"
"(default: all)"
f"{', '.join(AVAILABLE_TARGET_GROUPS)} "
f"(default: {settings.SUMMER_VOUCHER_DEFAULT_TARGET_GROUPS}). "
"Use 'all' to select all target groups."
),
)
parser.add_argument(
Expand All @@ -67,7 +68,7 @@ def handle(self, *args, **options):
force = options["force"]

target_groups = options["target_groups"]
if target_groups is None:
if "all" in target_groups:
target_groups = AVAILABLE_TARGET_GROUPS

voucher_value = options["voucher_value"]
Expand Down
26 changes: 26 additions & 0 deletions backend/kesaseteli/applications/target_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ def get_target_group_choices() -> List[Tuple[str, str]]:
]


class EighthGraderTargetGroup(AbstractTargetGroup):
name = _("8. luokkalainen")
identifier = "hki_15"
description = _("8th graders: 15 years old, MUST live in Helsinki.")

def is_valid(self, application: "YouthApplication") -> bool:
"""
8th graders: 15 years old, MUST live in Helsinki.
"""
# 15 years old and lives in Helsinki
return self.get_age_by_year(application) == 15 and application.is_helsinkian


class NinthGraderTargetGroup(AbstractTargetGroup):
name = _("9. luokkalainen")
identifier = "primary_target_group"
Expand Down Expand Up @@ -121,6 +134,19 @@ def is_valid(self, application: "YouthApplication") -> bool:
return self.get_age_by_year(application) == 17 and application.is_helsinkian


class UpperSecondarySecondYearTargetGroup(AbstractTargetGroup):
name = _("Toisen asteen toisen vuoden opiskelija")
identifier = "hki_18"
description = _("Upper secondary 2nd year: 18 years old, MUST live in Helsinki.")

def is_valid(self, application: "YouthApplication") -> bool:
"""
Upper secondary 2nd year: 18 years old, MUST live in Helsinki.
"""
# 18 years old and lives in Helsinki
return self.get_age_by_year(application) == 18 and application.is_helsinkian


def get_target_group_class(identifier: str) -> type[AbstractTargetGroup] | None:
"""
Returns the target group class associated with the given identifier.
Expand Down
7 changes: 3 additions & 4 deletions backend/kesaseteli/applications/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from langdetect import DetectorFactory

from applications.services import EmailTemplateService
from applications.target_groups import get_target_group_choices
from applications.tests.factories import SummerVoucherConfigurationFactory
from common.tests.conftest import * # noqa

Expand Down Expand Up @@ -54,13 +53,13 @@ def enable_admin_urls(settings):


@pytest.fixture(autouse=True)
def seed_default_configuration_for_tests(db):
target_groups = [identifier for identifier, _ in get_target_group_choices()]
def seed_default_configuration_for_tests(db, settings):
default_target_groups = settings.SUMMER_VOUCHER_DEFAULT_TARGET_GROUPS
# Create config for years 2021-2027 to cover most test cases
for year in range(2021, 2028):
SummerVoucherConfigurationFactory(
year=year,
target_group=target_groups,
target_group=default_target_groups,
voucher_value_in_euros=325 if year < 2024 else 350,
min_work_compensation_in_euros=400 if year < 2024 else 500,
min_work_hours=60,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,78 @@ def test_create_summervoucher_configuration_defaults():
assert len(config.target_group) > 0


@pytest.mark.django_db
@pytest.mark.parametrize(
"voucher_value_in_euros,min_work_compensation_in_euros,min_work_hours",
[
(375, 550, 70),
(500, 825, 100),
],
)
def test_create_summervoucher_configuration_numeric_defaults_are_from_settings(
voucher_value_in_euros, min_work_compensation_in_euros, min_work_hours, settings
):
"""
Test that the defaults for the numeric voucher value, minimum work compensation
and minimum work hours are taken from the following settings when creating the
configuration:
- SUMMER_VOUCHER_DEFAULT_VOUCHER_VALUE
- SUMMER_VOUCHER_DEFAULT_MIN_WORK_COMPENSATION
- SUMMER_VOUCHER_DEFAULT_MIN_WORK_HOURS
"""
settings.SUMMER_VOUCHER_DEFAULT_VOUCHER_VALUE = voucher_value_in_euros
settings.SUMMER_VOUCHER_DEFAULT_MIN_WORK_COMPENSATION = (
min_work_compensation_in_euros
)
settings.SUMMER_VOUCHER_DEFAULT_MIN_WORK_HOURS = min_work_hours

# Remove seeded configuration
SummerVoucherConfiguration.objects.filter(year=2024).delete()

out = StringIO()
call_command("create_summervoucher_configuration", "--year", "2024", stdout=out)

config = SummerVoucherConfiguration.objects.get(year=2024)
assert config.voucher_value_in_euros == voucher_value_in_euros
assert config.min_work_compensation_in_euros == min_work_compensation_in_euros
assert config.min_work_hours == min_work_hours


@pytest.mark.django_db
@pytest.mark.parametrize(
"target_groups,expected_result",
[
(["all"], [choice[0] for choice in get_target_group_choices()]),
(
["hki_15", "all", "hki_18"],
[choice[0] for choice in get_target_group_choices()],
),
(["primary_target_group"], ["primary_target_group"]),
(
["hki_15", "primary_target_group", "hki_18"],
["hki_15", "primary_target_group", "hki_18"],
),
],
)
def test_create_summervoucher_configuration_target_group_default_is_from_settings(
target_groups, expected_result, settings
):
"""
Test that the default target groups are parsed from
SUMMER_VOUCHER_DEFAULT_TARGET_GROUPS settings
"""
settings.SUMMER_VOUCHER_DEFAULT_TARGET_GROUPS = target_groups

# Remove seeded configuration
SummerVoucherConfiguration.objects.filter(year=2024).delete()

out = StringIO()
call_command("create_summervoucher_configuration", "--year", "2024", stdout=out)

config = SummerVoucherConfiguration.objects.get(year=2024)
assert config.target_group == expected_result


@pytest.mark.django_db
def test_create_summervoucher_configuration_custom_args():
# Remove seeded configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,6 @@ def test_youth_applications_activate_unexpired_inactive_with_rejection(
def test_youth_applications_activate_unexpired_inactive__vtj_enabled(
api_client,
make_youth_application_activation_link_unexpired,
settings,
application_year,
applicant_age,
is_helsinkian,
Expand Down
8 changes: 8 additions & 0 deletions backend/kesaseteli/kesaseteli/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
from saml2.sigver import get_xmlsec_binary
from sentry_sdk.integrations.django import DjangoIntegration

from applications.target_groups import (
NinthGraderTargetGroup,
UpperSecondaryFirstYearTargetGroup,
)
from common.backward_compatibility import convert_to_django_4_2_csrf_trusted_origins
from shared.suomi_fi.utils import get_contact_person_configuration

Expand Down Expand Up @@ -702,6 +706,10 @@


# Summer Voucher default / fallback configurations
SUMMER_VOUCHER_DEFAULT_TARGET_GROUPS = [
NinthGraderTargetGroup.identifier,
UpperSecondaryFirstYearTargetGroup.identifier,
]
SUMMER_VOUCHER_DEFAULT_VOUCHER_VALUE = 350
SUMMER_VOUCHER_DEFAULT_MIN_WORK_COMPENSATION = 500
SUMMER_VOUCHER_DEFAULT_MIN_WORK_HOURS = 60
Loading