Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ff30d24
RGAA compliance (#2050)
alexandre-legal Nov 7, 2025
b1c246b
add pull request event on recette branche
ayoubbouchachia Nov 7, 2025
04cb8f1
fix yaml structure (#2058)
Ayoub-BOUCHACHIA Nov 7, 2025
36b5c64
Avenant for convention mixte latest to recette (#2064)
Ayoub-BOUCHACHIA Nov 17, 2025
b685512
Fix export conventions list btn position (#2065)
Ayoub-BOUCHACHIA Nov 17, 2025
e6edf2e
Désactiver le déclenchement du déploiement lors de la création d’une …
Ayoub-BOUCHACHIA Nov 19, 2025
81f4e20
Ruels avenant convention mixte latest (#2067)
Ayoub-BOUCHACHIA Nov 25, 2025
2193f46
RGAA fichiers qui ne pouvaient pas être merge (#2072)
alexandre-legal Nov 27, 2025
69e3c6d
Masquer la case à cocher permettant de sélectionner les conversations…
Ayoub-BOUCHACHIA Dec 2, 2025
eb92457
Adapter le récapitulatif aux conventions mixte (#2076)
Ayoub-BOUCHACHIA Dec 2, 2025
c6834f9
fix recette deployment (#2080)
Ayoub-BOUCHACHIA Dec 2, 2025
834ebd4
fix deploiment use checkout v4 instead of v5
ayoubbouchachia Dec 2, 2025
c3f8d2b
Traduction des erreurs en français (#2083)
adrien202 Dec 5, 2025
6077a35
correction de l affichage des prets pour convention mixte (#2082)
adrien202 Dec 5, 2025
4f886ea
documentation pour nmp security (#2085)
Ayoub-BOUCHACHIA Dec 8, 2025
d0bc1ef
Ajout des corrections RGAA (sauf composant multiselect) (#2084)
alexandre-legal Dec 8, 2025
8485635
correction de test
Dec 8, 2025
5f438f7
Ajout nouveau component multiselect RGAA (#2086)
alexandre-legal Dec 8, 2025
d922134
clean lot in template (#2087)
adrien202 Dec 9, 2025
5e7e884
Update workflow to trigger only on push to recette
adrien202 Dec 9, 2025
3959fa3
fix export conventions (#2088)
adrien202 Dec 12, 2025
88c3f4a
fix financement multiple lors de l'import de logements via fichier ex…
adrien202 Dec 18, 2025
bf07675
Mise à jour du template de la fiche CAF pour s'adapter aux convention…
adrien202 Jan 5, 2026
dc5d5f8
rebase onto recette
alexandre-legal Dec 5, 2025
57d6c04
tried to fix bug of research that disspears between two pages (unsucc…
alexandre-legal Dec 5, 2025
65374d3
pre commit hooks
alexandre-legal Dec 5, 2025
5d45b9f
temp commit
alexandre-legal Dec 5, 2025
abe7d03
fixed css commented code
alexandre-legal Dec 5, 2025
1f636ab
added pre commit hooks modifications
alexandre-legal Jan 5, 2026
88219c3
merged input_search_select_core and input_search_select_native
alexandre-legal Jan 5, 2026
97c225e
removed unused file from SonarQube detection
alexandre-legal Jan 6, 2026
a0ead41
removed unused files
alexandre-legal Jan 6, 2026
94d0d0a
fully removed virtual select
alexandre-legal Jan 8, 2026
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 .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Deploy Sphinx Documentation to GitHub Pages
on:
push:
branches:
- main # Adjust this to your default branch name, if necessary
- main
- sphynx

jobs:
Expand All @@ -12,7 +12,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4

- uses: actions/setup-python@v6
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/push-branch-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
needs: test
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4
- uses: kolok/deploy-to-scalingo@v1
with:
ssh-private-key: ${{ secrets.SCALINGO_SSH_PRIVATE_KEY }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/push-branch-recette.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ jobs:
test:
uses: ./.github/workflows/run_tests.yml

deploy_to_siap_recette:
deploy_to_siap_recette:
name: "Deploy to Siap Recette"
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4
- uses: kolok/deploy-to-scalingo@v1
with:
ssh-private-key: ${{ secrets.SCALINGO_SSH_PRIVATE_KEY }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/push-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4

- uses: actions/setup-python@v6
with:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/push-version-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
needs: test
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4
- uses: ncipollo/release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -34,7 +34,7 @@ jobs:
needs: test
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4
- uses: kolok/deploy-to-scalingo@v1
with:
ssh-private-key: ${{ secrets.SCALINGO_SSH_PRIVATE_KEY }}
Expand All @@ -47,7 +47,7 @@ jobs:
needs: test
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4
- uses: kolok/deploy-to-scalingo@v1
with:
ssh-private-key: ${{ secrets.SCALINGO_SSH_PRIVATE_KEY }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out the repository
uses: actions/checkout@v5
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v6
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v4

- uses: actions/setup-python@v6
with:
Expand Down
4 changes: 2 additions & 2 deletions conventions/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class ConventionAdmin(ApilosModelAdmin):
"administration",
"bailleur",
"programme",
"lot",
"lots_list",
"numero",
"numero_pour_recherche",
"date_fin_conventionnement",
Expand Down Expand Up @@ -157,7 +157,7 @@ class ConventionAdmin(ApilosModelAdmin):
"numero_pour_recherche",
"cree_par",
"cree_le",
"lot",
"lots_list",
)
autocomplete_fields = (
"programme",
Expand Down
31 changes: 30 additions & 1 deletion conventions/forms/convention_form_annexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
TypologieAnnexe,
TypologieLogementClassique,
)
from programmes.models.choices import Financement


class LotAnnexeForm(forms.Form):
Expand All @@ -20,6 +21,9 @@ class LotAnnexeForm(forms.Form):
"""

uuid = forms.UUIDField(required=False)
financement = forms.TypedChoiceField(
required=False, label="", choices=Financement.choices
)
annexe_caves = forms.BooleanField(
required=False,
label="Caves",
Expand Down Expand Up @@ -92,6 +96,9 @@ class AnnexeForm(forms.Form):
"max_length": "La designation du logement ne doit pas excéder 255 caractères",
},
)
financement = forms.TypedChoiceField(
required=False, label="", choices=Financement.choices
)
logement_typologie = forms.TypedChoiceField(
required=True, label="", choices=TypologieLogementClassique.choices
)
Expand Down Expand Up @@ -123,6 +130,26 @@ class AnnexeForm(forms.Form):
},
)

def clean_financement(self):
"""
Validation du financement
"""
financement = self.cleaned_data.get("financement", None)
financement_exist = False

if financement:
for choices in list(Financement.choices):
if financement in choices:
financement_exist = True
break

if not financement_exist:
raise ValidationError(
"Vérifiez si le financement est pris en charge par Apilos ou s'il s'agit d'une erreur de saisie."
)

return financement

def clean_loyer(self):
"""
Validation du loyer :
Expand Down Expand Up @@ -165,7 +192,7 @@ def manage_logement_exists_validation(self):
- le logement doit exister dans le lot
"""
if self.convention:
lgts = self.convention.lot.logements.all()
lgts = Logement.objects.filter(lot__convention=self.convention)
for form in self.forms:
try:
lgts.get(designation=form.cleaned_data.get("logement_designation"))
Expand All @@ -176,3 +203,5 @@ def manage_logement_exists_validation(self):


AnnexeFormSet = formset_factory(AnnexeForm, formset=BaseAnnexeFormSet, extra=0)

LotAnnexeFormSet = formset_factory(LotAnnexeForm, extra=0)
80 changes: 55 additions & 25 deletions conventions/forms/convention_form_financement.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from conventions.models import Preteur
from programmes.models import TypeOperation
from programmes.models.choices import Financement


class ConventionFinancementForm(forms.Form):
Expand Down Expand Up @@ -61,14 +62,20 @@ def clean(self):
and self.convention is not None
and annee_fin_conventionnement is not None
):
if self.convention.programme.is_outre_mer:
self._outre_mer_end_date_validation(annee_fin_conventionnement)
elif self.convention.is_pls_financement_type:
self._pls_end_date_validation(annee_fin_conventionnement)
elif self.convention.programme.type_operation == TypeOperation.SANSTRAVAUX:
self._sans_travaux_end_date_validation(annee_fin_conventionnement)
else:
if self.convention.is_mixte:
self._other_end_date_validation(annee_fin_conventionnement)
else:
if self.convention.programme.is_outre_mer:
self._outre_mer_end_date_validation(annee_fin_conventionnement)
elif self.convention.is_pls_financement_type:
self._pls_end_date_validation(annee_fin_conventionnement)
elif (
self.convention.programme.type_operation
== TypeOperation.SANSTRAVAUX
):
self._sans_travaux_end_date_validation(annee_fin_conventionnement)
else:
self._other_end_date_validation(annee_fin_conventionnement)

def _outre_mer_end_date_validation(self, annee_fin_conventionnement):
today = datetime.date.today()
Expand Down Expand Up @@ -225,6 +232,9 @@ class PretForm(forms.Form):
"max_length": "Le numero ne doit pas excéder 255 caractères",
},
)
financement = forms.TypedChoiceField(
required=False, label="", choices=Financement.choices
)
preteur = forms.TypedChoiceField(required=False, label="", choices=Preteur.choices)
autre = forms.CharField(
required=False,
Expand Down Expand Up @@ -259,6 +269,11 @@ def clean(self):
- si le prêteur est autre, le champ autre est obligatoire
"""
cleaned_data = super().clean()
if not cleaned_data.get("financement"):
self.add_error(
"financement",
"Le financement doit obligatoirement être fourni",
)
preteur = cleaned_data.get("preteur")

if preteur in ["CDCF", "CDCL"]:
Expand Down Expand Up @@ -298,15 +313,22 @@ def clean(self):
self.manage_cdc_validation()

def validate_initial_numero_unicity(self) -> bool:
is_valid = True
numeros = [form.initial.get("numero") for form in self.forms]
for form in self.forms:
num = form.initial.get("numero")
if numeros.count(num) > 1:
form.errors["numero"] = [
f"Le numéro de financement {num} n'est pas unique."
]
is_valid = False
financements = {form.initial.get("financement") for form in self.forms}
for financement in financements:
is_valid = True
forms_financement = [
form
for form in self.forms
if form.initial.get("financement") == financement
]
numeros = [form.initial.get("numero") for form in forms_financement]
for form in forms_financement:
num = form.initial.get("numero")
if numeros.count(num) > 1:
form.errors["numero"] = [
f"Le numéro de financement {num} n'est pas unique pour le financement {financement}."
]
is_valid = False
return is_valid

def manage_cdc_validation(self):
Expand All @@ -316,17 +338,25 @@ def manage_cdc_validation(self):
"""
if (
self.convention is not None
and not self.convention.is_pls_financement_type
and self.convention.programme.type_operation != TypeOperation.SANSTRAVAUX
):
for form in self.forms:
if form.cleaned_data.get("preteur") in ["CDCF", "CDCL"]:
return
error = ValidationError(
"Au moins un prêt à la Caisee des dépôts et consignations doit-être déclaré "
+ "(CDC foncière, CDC locative)"
)
self._non_form_errors.append(error)
for lot in self.convention.lots.all():
if not lot.is_pls_financement_type:
exist_cdcf_cdcl = False
lot_exist = False
for form in self.forms:
if form.cleaned_data.get("financement") == lot.financement:
lot_exist = True
if form.cleaned_data.get("preteur") in ["CDCF", "CDCL"]:
exist_cdcf_cdcl = True
if exist_cdcf_cdcl or not lot_exist:
continue

error = ValidationError(
"Au moins un prêt à la Caisee des dépôts et consignations doit-être déclaré "
+ f"(CDC foncière, CDC locative) pour le financement {lot.financement}"
)
self._non_form_errors.append(error)


PretFormSet = formset_factory(PretForm, formset=BasePretFormSet, extra=0)
Loading