-
Notifications
You must be signed in to change notification settings - Fork 10
Configure yearly summer voucher parameters and email templates from admin site #3834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
3b00129
refactor(kesaseteli): move filter_by_voucher_and_fuzzy_name to manager
nikomakela 3e1494d
test(kesaseteli): remove duplicated test
nikomakela 0c2f2c5
refactor(kesaseteli): add error logging
nikomakela 135b29e
feat(kesaseteli,admin): more features in school admin page
nikomakela ac00bc9
chore: add antigravity editor's files to gitignore
nikomakela 6849fdf
fix(kesaseteli): add fixture to enable admin site on every unit test
nikomakela b91aad0
feat(kesaseteli): summer voucher configuration
nikomakela 80baa48
feat(kesaseteli): add API endpoint for summer voucher configuration
nikomakela 147440c
feat(kesaseteli): add API endpoint to list available target groups
nikomakela 9168668
feat(kesaseteli): models and base files for email templates
nikomakela 7a10ac5
docs(kesaseteli): yearly configuration and email templates management
nikomakela 073c313
feat(kesaseteli): reject appl. if no summer voucher config for year
nikomakela 41cfb1f
refactor(kesaseteli): use staticmethods in target group service
nikomakela c71e963
feat(kesaseteli): add description property to target group
nikomakela 587b550
feat(kesaseteli,admin): add custom admin site for context management
nikomakela 702802f
feat(shared,admin): login form can be hidden if context disables it
nikomakela b9b96d6
feat(kesaseteli): mngmt.cmd. to create summer voucher config instance
nikomakela cb4753d
feat(kesaseteli): docker-entrypoint to create summer voucher config
nikomakela 8d5f829
docs(kesaseteli): management command documentation
nikomakela File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| <!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
| <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
| **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* | ||
|
|
||
| - [Applications Module](#applications-module) | ||
| - [Summer Voucher Configuration](#summer-voucher-configuration) | ||
| - [Target Groups Management](#target-groups-management) | ||
| - [Adding a New Target Group](#adding-a-new-target-group) | ||
| - [Email Template Handling](#email-template-handling) | ||
| - [File-Based Initialization](#file-based-initialization) | ||
| - [Restoration and Synchronization](#restoration-and-synchronization) | ||
| - [1. Management Command](#1-management-command) | ||
| - [2. Admin Interface Action](#2-admin-interface-action) | ||
| - [3. Reinitialize Selected Templates](#3-reinitialize-selected-templates) | ||
| - [School Management](#school-management) | ||
| - [API Endpoint](#api-endpoint) | ||
|
|
||
| <!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
|
|
||
| # Applications Module | ||
|
|
||
| This module handles the core logic for youth and employer applications, including configuration and email communication. | ||
|
|
||
| ## Summer Voucher Configuration | ||
|
|
||
| The `SummerVoucherConfiguration` model stores annual configuration settings for the Summer Voucher application process. Key settings include: | ||
|
|
||
| - **Year**: The applicable year for the configuration. | ||
| - **Voucher Value**: The monetary value of the voucher. | ||
| - **Minimum Work Requirements**: Minimum hours and compensation required. | ||
| - **Target Groups**: Defines which youth target groups are active for the year (e.g., specific age ranges or schools). | ||
|
|
||
| This configuration is managed via the Django Admin interface and is used to validate incoming applications. | ||
|
|
||
|
|
||
| ### Target Groups Management | ||
|
|
||
| The system supports defining different groups of applicants eligible for the voucher (e.g., specific age groups or student statuses). The logic for these groups is consolidated in [`target_groups.py`](target_groups.py). | ||
|
|
||
| #### Adding a New Target Group | ||
|
|
||
| 1. Open `applications/target_groups.py`. | ||
| 2. Create a new class that inherits from `AbstractTargetGroup`. | ||
| 3. Define the required properties: | ||
| * `name`: The localized user-facing name. | ||
| * `identifier`: A unique string identifier (e.g., `"new_student_group"`). | ||
| 4. Implement the `is_valid` method to define the eligibility logic (e.g., age checks, residency). | ||
|
|
||
| **Example:** | ||
| ```python | ||
| class VocationalStudentTargetGroup(AbstractTargetGroup): | ||
| name = _("Vocational Student") | ||
| identifier = "vocational_student" | ||
|
|
||
| def is_valid(self, application): | ||
| return application.age == 18 and application.is_helsinkian | ||
| ``` | ||
|
|
||
| > [!WARNING] | ||
| > The `identifier` string is stored directly in the database to link vouchers to their target group. **Changing an existing class's identifier will break data integrity** for historical records. If you need to rename an identifier, a database migration is required. | ||
|
|
||
|
|
||
| ## Email Template Handling | ||
|
|
||
| The system uses the `EmailTemplate` model to manage localized email content sent to applicants and employers. | ||
|
|
||
| ### File-Based Initialization | ||
|
|
||
| Templates are initially defined as HTML files in `applications/templates/email/`. Each template corresponds to a type (e.g., `activation`, `processing`) and a language (`fi`, `sv`, `en`). | ||
|
|
||
| ### Restoration and Synchronization | ||
|
|
||
| Because templates are stored in the database but sourced from files, a restoration mechanism is available to ensure the database matches the file system. | ||
|
|
||
| #### 1. Management Command | ||
| Use the following command to create missing templates and populate them with content from the corresponding files: | ||
|
|
||
| ```bash | ||
| python manage.py ensure_email_templates | ||
| ``` | ||
|
|
||
| #### 2. Admin Interface Action | ||
| Administrators can trigger the restoration process directly from the Django Admin: | ||
| 1. Navigate to **Applications** > **Email Templates**. | ||
| 2. Click the **"Reproduce Missing Templates"** button at the top of the list. | ||
|
|
||
| Both methods use the `EmailTemplateService.ensure_templates_exist()` method to scan for all supported type/language combinations and create any that are missing. | ||
|
|
||
| #### 3. Reinitialize Selected Templates | ||
|
|
||
| To update existing templates with the latest content from the file system (e.g., after a code deployment): | ||
| 1. Navigate to **Applications** > **Email Templates**. | ||
| 2. Select the templates you wish to update using the checkboxes. | ||
| 3. Choose **"Reinitialize selected templates from file"** from the **Action** dropdown menu. | ||
| 4. Click **Go**. | ||
|
|
||
| ### Validation and Preview | ||
|
|
||
| To ensure email quality and prevent errors: | ||
|
|
||
| 1. **Syntax Validation**: The system validates template syntax (Jinja2/Django) whenever an Email Template is saved. If the syntax is invalid (e.g., unclosed tags), the save is blocked and an error is displayed. | ||
| 2. **Preview Feature**: A **"Preview"** button is available on the Email Template change form. Clicking this opens a new window showing the rendered email populated with realistic mock data (e.g., test names, dates, links), allowing administrators to verify the layout and variable usage. | ||
| 3. **Send Test Email**: An admin action **"Send selected email templates to me"** is available in the Email Template list view. This allows administrators to verify the final email delivery by sending the rendered template (with mock data) to their own email address. | ||
|
|
||
| ## School Management | ||
|
|
||
| The `School` model stores the list of schools available for selection in youth applications. The **School Admin** interface allows administrators to: | ||
|
|
||
| - View the list of schools. | ||
| - Search schools by name. | ||
| - Filter schools by creation and modification dates. | ||
| - Add or remove schools as needed. | ||
|
|
||
| ### API Endpoint | ||
|
|
||
| Frontend clients can retrieve the list of available schools using the following endpoint: | ||
|
|
||
| - **URL**: `/v1/schools/` | ||
| - **Method**: `GET` | ||
| - **Description**: Returns a list of all schools, sorted by name using Finnish collation rules. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.