Skip to content

Commit

Permalink
Merge pull request #499 from MTES-MCT/master
Browse files Browse the repository at this point in the history
Release 11/02/2025
  • Loading branch information
tristan-gueguen authored Feb 11, 2025
2 parents 305286a + 863cb94 commit a4d6121
Show file tree
Hide file tree
Showing 15 changed files with 441 additions and 47 deletions.
10 changes: 10 additions & 0 deletions app/domain/regulations_helper.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
DEFAULT_KEY = "default"


def resolve_variables(dict_var, business):
res_dict = {}
for key, val in dict_var.items():
Expand All @@ -6,10 +9,17 @@ def resolve_variables(dict_var, business):
if transport_type != business.transport_type.name:
continue
if isinstance(val2, dict):
default_value = None
for business_type, val3 in val2.items():
if business_type == DEFAULT_KEY:
default_value = val3
continue
if business_type != business.business_type.name:
continue
res_dict[key] = val3
break
if key not in res_dict and default_value:
res_dict[key] = default_value
else:
res_dict[key] = val2
else:
Expand Down
23 changes: 22 additions & 1 deletion app/domain/regulations_per_day.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,34 @@ def check_max_work_day_time(activity_groups, regulation_check, business):
MAXIMUM_DURATION_OF_DAY_WORK_IN_HOURS = dict_variables[
"MAXIMUM_DURATION_OF_DAY_WORK_IN_HOURS"
]
AMPLITUDE_TRIGGER_IN_HOURS = dict_variables.get(
"AMPLITUDE_TRIGGER_IN_HOURS", None
)
MAXIMUM_DURATION_OF_DAY_WORK_IF_HIGH_AMPLITUDE_IN_HOURS = (
dict_variables.get(
"MAXIMUM_DURATION_OF_DAY_WORK_IF_HIGH_AMPLITUDE_IN_HOURS", None
)
)
extra = None
for group in activity_groups:
max_work_day_time_in_hours = MAXIMUM_DURATION_OF_DAY_WORK_IN_HOURS

# For some TRV businesses, max work day time is different if amplitude is above a particular value
if (
AMPLITUDE_TRIGGER_IN_HOURS
and MAXIMUM_DURATION_OF_DAY_WORK_IF_HIGH_AMPLITUDE_IN_HOURS
):
amplitude = group.service_duration
if amplitude > AMPLITUDE_TRIGGER_IN_HOURS * HOUR:
max_work_day_time_in_hours = (
MAXIMUM_DURATION_OF_DAY_WORK_IF_HIGH_AMPLITUDE_IN_HOURS
)

night_work = group.total_night_work_legislation_duration > 0
max_time_in_hours = (
MAXIMUM_DURATION_OF_NIGHT_WORK_IN_HOURS
if night_work
else MAXIMUM_DURATION_OF_DAY_WORK_IN_HOURS
else max_work_day_time_in_hours
)
worked_time_in_seconds = group.total_work_duration
extra = dict(
Expand Down
20 changes: 20 additions & 0 deletions app/services/get_businesses.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,24 @@ def get_businesses():
transport_type=TransportType.TRV,
business_type=BusinessType.INFREQUENT,
),
BusinessData(
id=6,
transport_type=TransportType.TRV,
business_type=BusinessType.TAXI_GENERAL,
),
BusinessData(
id=7,
transport_type=TransportType.TRV,
business_type=BusinessType.TAXI_REGULATED,
),
BusinessData(
id=8,
transport_type=TransportType.TRV,
business_type=BusinessType.VTC,
),
BusinessData(
id=9,
transport_type=TransportType.TRV,
business_type=BusinessType.LOTI,
),
]
48 changes: 44 additions & 4 deletions app/services/get_regulation_checks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import json

import sqlalchemy as sa
from dataclasses import dataclass
from datetime import date, datetime
from typing import Optional

from app.domain.regulations_helper import DEFAULT_KEY
from app.models.business import TransportType, BusinessType
from app.models.regulation_check import (
RegulationCheckType,
Expand All @@ -22,6 +26,10 @@ class RegulationCheckData:
date_application_end: Optional[date] = None


DESCRIPTION_MAX_WORK_TRV_FREQUENT = "La durée du travail quotidien est limitée à 10h si l’amplitude de la journée est inférieure à 13h, et à 9h si l’amplitude est supérieure à 13h (article D. 3312-6 du Code des transports). Attention, les dérogations ne sont pas intégrées dans Mobilic."
DESCRIPTION_MAX_WORK_TRV_INFREQUENT = "La durée du travail quotidien est limitée à 10h (article D. 3312-6 du Code des transports). Attention, les dérogations ne sont pas intégrées dans Mobilic."
DESCRIPTION_MAX_WORK_TRV_OTHERS = "La durée du travail quotidien est limitée à 10h si l’amplitude de la journée est inférieure à 12h, et à 9h si l’amplitude est supérieure à 12h (article D. 3312-6 du Code des transports). Attention, les dérogations ne sont pas intégrées dans Mobilic."

REGULATION_CHECK_MAXIMUM_WORK_IN_CALENDAR_WEEK = RegulationCheckData(
id=6,
type=RegulationCheckType.MAXIMUM_WORK_IN_CALENDAR_WEEK,
Expand Down Expand Up @@ -81,13 +89,24 @@ def get_regulation_checks():
str(TransportType.TRM.name): 12,
str(TransportType.TRV.name): 10,
},
AMPLITUDE_TRIGGER_IN_HOURS={
str(TransportType.TRM.name): None,
str(TransportType.TRV.name): {
BusinessType.FREQUENT.name: 13,
BusinessType.INFREQUENT.name: None,
DEFAULT_KEY: 12,
},
},
MAXIMUM_DURATION_OF_DAY_WORK_IF_HIGH_AMPLITUDE_IN_HOURS=9,
DESCRIPTION={
str(
TransportType.TRM.name
): "La durée du travail quotidien est limitée à 12h (article R. 3312-a51 du Code des transports).",
str(
TransportType.TRV.name
): "La durée du travail quotidien est limitée à 10h (article D. 3312-6 du Code des transports). Attention, les dérogations ne sont pas intégrées dans Mobilic.",
str(TransportType.TRV.name): {
BusinessType.FREQUENT.name: DESCRIPTION_MAX_WORK_TRV_FREQUENT,
BusinessType.INFREQUENT.name: DESCRIPTION_MAX_WORK_TRV_INFREQUENT,
DEFAULT_KEY: DESCRIPTION_MAX_WORK_TRV_OTHERS,
},
},
NIGHT_WORK_DESCRIPTION={
str(
Expand Down Expand Up @@ -145,8 +164,29 @@ def get_regulation_checks():
label="Absence de livret individuel de contrôle à bord",
regulation_rule=None,
variables=dict(
DESCRIPTION="Défaut de documents nécessaires au décompte de la durée du travail (L. 3121-67 du Code du travail et R. 3312-58 du Code des transports + arrêté du 20 juillet 1998)."
DESCRIPTION={
str(
TransportType.TRM.name
): "Défaut de documents nécessaires au décompte de la durée du travail (L. 3121-67 du Code du travail et R. 3312-58 du Code des transports + arrêté du 20 juillet 1998).",
str(
TransportType.TRV.name
): "Défaut de documents nécessaires au décompte de la durée du travail (L. 3121-67 du Code du travail et R. 3312-19 du Code des transports + arrêté du 20 juillet 1998).",
}
),
unit=UnitType.DAY,
),
]


def update_regulation_check_variables(session):
regulation_check_data = get_regulation_checks()
for r in regulation_check_data:
session.execute(
sa.text(
"UPDATE regulation_check SET variables = :variables WHERE type = :type;"
),
dict(
variables=json.dumps(r.variables),
type=r.type,
),
)
2 changes: 1 addition & 1 deletion app/templates/cgu_employee_rejected.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
<p>Nous vous informons que votre salarié <b>{{employee_full_name }}</b> (identifiant Mobilic : <b>{{employee_id }}</b>) n’a pas accepté nos nouvelles conditions générales d’utilisation adressées le {{release_date | full_format_day}}.</p>
<p>En cas d'erreur, <b>votre salarié peut modifier son choix</b> pendant 10 jours. Pour cela, il doit se connecter sur Mobilic et accepter les CGU.</p>
<p>S’il ne le fait pas, son compte restera bloqué et sera supprimé. Il ne pourra plus saisir de temps de travail via Mobilic pour votre entreprise. Pour être en règle en cas de contrôle, il doit, dès maintenant, utiliser le livret individuel de contrôle (articles R3312-19 et R3312-58 du Code des transports).</p>
<p>Si la période de 10 jours est déjà passée, votre salarié peut nous contacter à l’adresse suivante : <a href="mailto:assistance@mobilic.beta.gouv.fr">assistance@mobilic.beta.gouv.fr</a>. Nous pourrons ainsi réactiver son compte.</p>
<p>Si la période de 10 jours est déjà passée, votre salarié peut nous contacter à l’adresse suivante : <a href="mailto:contact@mobilic.beta.gouv.fr">contact@mobilic.beta.gouv.fr</a>. Nous pourrons ainsi réactiver son compte.</p>
<p>Cordialement,</p>
{% endblock %}
2 changes: 1 addition & 1 deletion app/templates/cgu_suspended_company.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
<p>Nous vous avons adressé la mise à jour de nos conditions générales d’utilisation en date du {{release_date | full_format_day}}. En l’absence d’acceptation de ces conditions générales d’utilisation dans le délai de 10 jours ouvrés, nous avons été dans l’obligation de suspendre votre compte.</p>
<p>Nous souhaiterions indiquer que vos salariés ont accepté les conditions mais ne peuvent continuer à utiliser l’application Mobilic en l’absence de gestionnaire désigné sur votre entreprise.</p>
<p>L'équipe Mobilic tient à vous rappeler que, conformément aux articles R3312-19 et R3312-58 du Code des transports, le suivi du temps de travail de vos salariés doit s’effectuer soit par le livret individuel de contrôle au format papier, soit au format numérique par Mobilic.</p>
<p>Si vous souhaitez conserver le format numérique assurant une fiabilité et la facilité de saisie pour vos salariés, nous vous invitons à écrire à l’adresse <a href="mailto:assistance@mobilic.beta.gouv.fr">assistance@mobilic.beta.gouv.fr</a>.</p>
<p>Si vous souhaitez conserver le format numérique assurant une fiabilité et la facilité de saisie pour vos salariés, nous vous invitons à écrire à l’adresse <a href="mailto:contact@mobilic.beta.gouv.fr">contact@mobilic.beta.gouv.fr</a>.</p>
<p>Au plaisir de vous retrouver !</p>
{% endblock %}
2 changes: 1 addition & 1 deletion app/templates/companies_about_to_lose_certificate.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<p>Cependant, nous avons pu constater que, depuis cette date, vous n’aviez pas respecté certains critères indispensables à son obtention. Vous trouverez la liste de ces critères dans l'onglet "Certificat" de votre interface Mobilic.</p>
<p>Ainsi, pour que nous puissions renouveler votre certificat à la fin de sa période de validité, veillez à y remédier dans les trois mois à venir.</p>
<p>Vous trouverez sur ce lien le détail des critères à respecter : <a href="https://faq.mobilic.beta.gouv.fr/usages-et-fonctionnement-de-mobilic-gestionnaire/comment-obtenir-le-certificat-mobilic">Comment obtenir le certificat Mobilic ?</a></p>
<p>N’hésitez pas à nous écrire pour toute question à ce sujet sur : <a href="mailto:assistance@mobilic.beta.gouv.fr">assistance@mobilic.beta.gouv.fr</a>.</p>
<p>N’hésitez pas à nous écrire pour toute question à ce sujet sur : <a href="mailto:contact@mobilic.beta.gouv.fr">contact@mobilic.beta.gouv.fr</a>.</p>
<p>A bientôt sur Mobilic !</p>
{% endblock %}
2 changes: 1 addition & 1 deletion app/templates/transactional_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@
<td class="content-block" style="color: white; background-color: #3184FF; padding-top: 24px; padding-bottom: 24px;">
Mobilic est un service numérique de l'Etat incubé à la Fabrique numérique du ministère de la Transition écologique,
membre du réseau d’incubateurs beta.gouv. Pour contacter l’équipe, veuillez écrire à
<a style="color: white" href="mailto:assistance@mobilic.beta.gouv.fr" target="_blank" rel="noopener">assistance@mobilic.beta.gouv.fr</a>.<br/>
<a style="color: white" href="mailto:contact@mobilic.beta.gouv.fr" target="_blank" rel="noopener">contact@mobilic.beta.gouv.fr</a>.<br/>
<a style="color: white" href="https://mobilic.beta.gouv.fr" target="_blank" rel="noopener">Accéder au site</a>
</td>
</tr>
Expand Down
20 changes: 11 additions & 9 deletions app/tests/regulations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,18 @@ def _log_and_validate_mission(
)
return mission

def convert_employee_to_trv(self):
trv_business = Business.query.filter(
Business.business_type == BusinessType.FREQUENT.value
def _convert_employee_to_business(self, business_type):
business = Business.query.filter(
Business.business_type == business_type.value
).one_or_none()
self.employee.employments[0].business = trv_business
self.employee.employments[0].business = business
db.session.commit()

def convert_employee_to_vtc(self):
self._convert_employee_to_business(BusinessType.VTC)

def convert_employee_to_trv(self):
self._convert_employee_to_business(BusinessType.FREQUENT)

def convert_employee_to_trm_short_distance(self):
trm_short_distance_business = Business.query.filter(
Business.business_type == BusinessType.SHORT_DISTANCE.value
).one_or_none()
self.employee.employments[0].business = trm_short_distance_business
db.session.commit()
self._convert_employee_to_business(BusinessType.SHORT_DISTANCE)
Loading

0 comments on commit a4d6121

Please sign in to comment.