Skip to content

Commit

Permalink
fix(policy): Haute Correze 2025 (#2757)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanfallon committed Jan 17, 2025
1 parent f011f5f commit f5b122d
Show file tree
Hide file tree
Showing 4 changed files with 333 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const description = `
<div _ngcontent-pmm-c231="" id="summary" class="campaignSummaryText-content-text">
<p>
Campagne d'incitation au covoiturage du <b> 02 septembre 2024 au 01 septembre 2025</b>,
toute la semaine
</p>
<p>Cette campagne est limitée à <b>10 000,00 €</b>.</p>
<p>
Les <b> conducteurs </b> effectuant un trajet en covoiturage d'au moins 2 km
au départ ou à l'arrivée de la CC Haute-Corrèze Communauté
sont incités selon les règles suivantes :
</p>
<ul>
<li><b>De 2 à 15 km : 1,50 € par trajet et par passager transporté</b></li>
<li><b>De 15 à 30 km : 1,50 € + 0,10 € par km supplémentaire par trajet et par passager transporté</b></li>
<li><b>De 30 à 80 km : 3,00 € par trajet et par passager transporté</b></li>
</ul>
<p>Les restrictions suivantes seront appliquées :</p>
<ul>
<li><b>6 trajets maximum pour le conducteur par jour.</b></li>
<li><b>150,00 € maximum pour le conducteur par mois.</b></li>
</ul>
<p>
La campagne est limitée à l'opérateur Blablacar Daily proposant des preuves de classe <b>B</b> ou <b>C</b>.
</p>
</div>`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { getOperatorsAt, TimestampedOperators } from "@/pdc/services/policy/engine/helpers/getOperatorsAt.ts";
import { isOperatorClassOrThrow } from "@/pdc/services/policy/engine/helpers/isOperatorClassOrThrow.ts";
import { isOperatorOrThrow } from "@/pdc/services/policy/engine/helpers/isOperatorOrThrow.ts";
import {
LimitTargetEnum,
watchForGlobalMaxAmount,
watchForPersonMaxAmountByMonth,
watchForPersonMaxTripByDay,
} from "@/pdc/services/policy/engine/helpers/limits.ts";
import { onDistanceRange, onDistanceRangeOrThrow } from "@/pdc/services/policy/engine/helpers/onDistanceRange.ts";
import { perKm, perSeat } from "@/pdc/services/policy/engine/helpers/per.ts";
import { startsOrEndsAtOrThrow } from "@/pdc/services/policy/engine/helpers/startsOrEndsAtOrThrow.ts";
import { description } from "@/pdc/services/policy/engine/policies/20240902_haute_correze_2025.html.ts";
import { AbstractPolicyHandler } from "@/pdc/services/policy/engine/policies/AbstractPolicyHandler.ts";
import { RunnableSlices } from "@/pdc/services/policy/interfaces/engine/PolicyInterface.ts";
import {
OperatorsEnum,
PolicyHandlerInterface,
PolicyHandlerParamsInterface,
PolicyHandlerStaticInterface,
StatelessContextInterface,
} from "@/pdc/services/policy/interfaces/index.ts";

/* eslint-disable-next-line */
export const HauteCorreze2025: PolicyHandlerStaticInterface = class extends AbstractPolicyHandler
implements PolicyHandlerInterface {
static readonly id = "haute_correze_2025";

protected operators: TimestampedOperators = [
{
date: new Date("2024-09-02T00:00:00+0200"),
operators: [OperatorsEnum.BLABLACAR_DAILY],
},
];

// 7 cts per km per passenger
protected slices: RunnableSlices = [
{
start: 2_000,
end: 15_000,
fn: (ctx: StatelessContextInterface) => perSeat(ctx, 1_50),
},
{
start: 15_000,
end: 30_000,
fn: (ctx: StatelessContextInterface) => perSeat(ctx, perKm(ctx, { amount: 10, offset: 15_000, limit: 30_000 })),
},
{
start: 30_000,
end: 80_001,
fn: (_ctx: StatelessContextInterface) => 0,
},
];

constructor(public max_amount: number) {
super();
this.limits = [
[
"17a34876-97dc-409e-a45a-eb1c1a7f9924",
max_amount,
watchForGlobalMaxAmount,
],
[
"23ad0e0c-6805-41ae-915d-bcc566486bb6",
6,
watchForPersonMaxTripByDay,
LimitTargetEnum.Driver,
],
[
"4437e7aa-efe6-4eb8-b844-3139819f8fcf",
150_00,
watchForPersonMaxAmountByMonth,
LimitTargetEnum.Driver,
],
];
}

protected processExclusion(ctx: StatelessContextInterface) {
isOperatorOrThrow(ctx, getOperatorsAt(this.operators, ctx.carpool.datetime));
onDistanceRangeOrThrow(ctx, { min: 2_000, max: 80_001 });
isOperatorClassOrThrow(ctx, ["B", "C"]);
startsOrEndsAtOrThrow(ctx, { aom: ["200066744"] });
}

processStateless(ctx: StatelessContextInterface): void {
this.processExclusion(ctx);
super.processStateless(ctx);

let amount = 0;
for (const { start, fn } of this.slices) {
if (onDistanceRange(ctx, { min: start })) {
amount += fn(ctx);
}
}

ctx.incentive.set(amount);
}

params(): PolicyHandlerParamsInterface {
return {
tz: "Europe/Paris",
slices: this.slices,
operators: getOperatorsAt(this.operators),
limits: {
glob: this.max_amount,
},
};
}

describe(): string {
return description;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { it } from "@/dev_deps.ts";
import { v4 as uuidV4 } from "@/lib/uuid/index.ts";
import { HauteCorreze2025 as Handler } from "@/pdc/services/policy/engine/policies/20240902_haute_correze_2025.ts";
import { makeProcessHelper } from "@/pdc/services/policy/engine/tests/macro.ts";
import { OperatorsEnum } from "@/pdc/services/policy/interfaces/index.ts";

const defaultPosition = {
arr: "19139",
com: "19139",
aom: "200066744",
epci: "200066744",
dep: "19",
reg: "75",
country: "XXXXX",
reseau: "73",
};
const defaultLat = 45.54858380899173;
const defaultLon = 2.3146017323921195;

const defaultCarpool = {
_id: 1,
operator_trip_id: uuidV4(),
passenger_identity_key: uuidV4(),
driver_identity_key: uuidV4(),
operator_uuid: OperatorsEnum.BLABLACAR_DAILY,
operator_class: "C",
passenger_is_over_18: true,
passenger_has_travel_pass: true,
driver_has_travel_pass: true,
datetime: new Date("2024-11-01"),
seats: 1,
distance: 5_000,
operator_journey_id: uuidV4(),
operator_id: 1,
driver_revenue: 20,
passenger_contribution: 20,
start: { ...defaultPosition },
end: { ...defaultPosition },
start_lat: defaultLat,
start_lon: defaultLon,
end_lat: 45.53725299731382,
end_lon: 2.3059201226861297,
};

const process = makeProcessHelper(defaultCarpool);

it("should work with exclusions", async () =>
await process(
{
policy: { handler: Handler.id },
carpool: [
{ operator_uuid: "not in list" },
{ operator_uuid: OperatorsEnum.KLAXIT },
{ distance: 100 },
{ distance: 90_000 },
{ operator_class: "A" },
],
meta: [],
},
{ incentive: [0, 0, 0, 0, 0], meta: [] },
));

it("should work basic with start/end inside aom", async () =>
await process(
{
policy: { handler: Handler.id },
carpool: [
{ distance: 5_000, driver_identity_key: "one" },
{ distance: 5_000, seats: 2, driver_identity_key: "one" },
{ distance: 25_000, driver_identity_key: "two" },
{ distance: 25_000, seats: 2, driver_identity_key: "two" },
{ distance: 80_000, driver_identity_key: "marcel" },
],
meta: [],
},
{
incentive: [150, 300, 250, 500, 300],
meta: [
{
key: "max_amount_restriction.global.campaign.global",
value: 1500,
},
{
key: "max_amount_restriction.0-one.month.10-2024",
value: 450,
},
{
key: "max_amount_restriction.0-two.month.10-2024",
value: 750,
},
{
key: "max_amount_restriction.0-marcel.month.10-2024",
value: 300,
},
],
},
));

it("should work with global limits", async () =>
await process(
{
policy: { handler: Handler.id, max_amount: 15_000_00 },
carpool: [{ distance: 79_000, driver_identity_key: "one" }],
meta: [
{
key: "max_amount_restriction.global.campaign.global",
value: 14_999_99,
},
],
},
{
incentive: [1], // <-- should be 250. capped to 1
meta: [
{
key: "max_amount_restriction.global.campaign.global",
value: 15_000_00,
},
{
key: "max_amount_restriction.0-one.month.10-2024",
value: 300,
},
],
},
));

it("should work with 6 trips per day limit", async () =>
await process(
{
policy: { handler: Handler.id },
carpool: [
{ distance: 5_000, driver_identity_key: "one" },
{ distance: 5_000, driver_identity_key: "one" },
{ distance: 5_000, driver_identity_key: "one" },
{ distance: 5_000, driver_identity_key: "one" },
{ distance: 5_000, driver_identity_key: "one" },
{ distance: 5_000, driver_identity_key: "one" },
{ distance: 5_000, driver_identity_key: "one" }, // too many
],
meta: [],
},
{
incentive: [150, 150, 150, 150, 150, 150, 0],
meta: [
{
key: "max_amount_restriction.global.campaign.global",
value: 900,
},
{
key: "max_amount_restriction.0-one.month.10-2024",
value: 900,
},
],
},
));
62 changes: 32 additions & 30 deletions api/src/pdc/services/policy/engine/policies/index.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
import { PaysDeLaLoire2021 } from "@/pdc/services/policy/engine/policies/20210105_PaysDeLaLoire.ts";
import { ATMB202305 } from "@/pdc/services/policy/engine/policies/20230502_ATMB.ts";
import { Cannes2024 } from "@/pdc/services/policy/engine/policies/20240101_Cannes.ts";
import { CCPOA202410 } from "@/pdc/services/policy/engine/policies/20241015_CCPOA_orthe_et_arrigans_2024.ts";
import { CCVMM202405 } from "@/pdc/services/policy/engine/policies/20240805_CCVMM_2024_05.ts";
import { Cotentin2023 } from "@/pdc/services/policy/engine/policies/20230101_Cotentin.ts";
import { GrandChatellerault2024 } from "@/pdc/services/policy/engine/policies/20240201_GrandChatellerault.ts";
import { GrandPoitiers } from "@/pdc/services/policy/engine/policies/20230927_GrandPoitiers.ts";
import { GrandPoitiers2025 } from "@/pdc/services/policy/engine/policies/20250101_GrandPoitiers2025.ts";
import { HauteCorreze2025 } from "@/pdc/services/policy/engine/policies/20240902_haute_correze_2025.ts";
import { IDFMPeriodeNormale2021 } from "@/pdc/services/policy/engine/policies/20210520_IDFM.ts";
import { NantesMetropoleXPCovoitan2021 } from "@/pdc/services/policy/engine/policies/20211202_NantesMetropoleXP.ts";
import { Lannion202305 } from "@/pdc/services/policy/engine/policies/20230501_Lannion.ts";
import { LannionTregor2024 } from "@/pdc/services/policy/engine/policies/20240401_LannionTregor.ts";
import { LaRochelle20232024 } from "@/pdc/services/policy/engine/policies/20230101_LaRochelle.ts";
import { LaRochelle2024 } from "@/pdc/services/policy/engine/policies/20240101_LaRochelle.ts";
import { LavalAgglo2022 } from "@/pdc/services/policy/engine/policies/20220412_LavalAgglo.ts";
import { SMT2022 } from "@/pdc/services/policy/engine/policies/20220414_SMT.ts";
import { MetropoleRouenNormandie2022 } from "@/pdc/services/policy/engine/policies/20220420_MetropoleRouenNormandie.ts";
import { Occitanie20232024 } from "@/pdc/services/policy/engine/policies/20221024_Occitanie.ts";
import { PMGF2022 } from "@/pdc/services/policy/engine/policies/20221102_PMGF.ts";
import { Montpellier } from "@/pdc/services/policy/engine/policies/20221206_Montpellier.ts";
import { Cotentin2023 } from "@/pdc/services/policy/engine/policies/20230101_Cotentin.ts";
import { LaRochelle20232024 } from "@/pdc/services/policy/engine/policies/20230101_LaRochelle.ts";
import { Vitre2023 } from "@/pdc/services/policy/engine/policies/20230101_Vitre.ts";
import { MetropoleSavoie } from "@/pdc/services/policy/engine/policies/20230124_MetropoleSavoie.ts";
import { SMT2023 } from "@/pdc/services/policy/engine/policies/20230126_SMT.ts";
import { PaysDeLaLoire2023 } from "@/pdc/services/policy/engine/policies/20230201_PaysDeLaLoire.ts";
import { PaysBasque20232024 } from "@/pdc/services/policy/engine/policies/20230401_PaysBasqueAdour.ts";
import { Lannion202305 } from "@/pdc/services/policy/engine/policies/20230501_Lannion.ts";
import { ATMB202305 } from "@/pdc/services/policy/engine/policies/20230502_ATMB.ts";
import { PMGF2023 } from "@/pdc/services/policy/engine/policies/20230502_PMGF.ts";
import { GrandPoitiers } from "@/pdc/services/policy/engine/policies/20230927_GrandPoitiers.ts";
import { PMGFOctobre2023 } from "@/pdc/services/policy/engine/policies/20231001_PMGF.ts";
import { Cannes2024 } from "@/pdc/services/policy/engine/policies/20240101_Cannes.ts";
import { LaRochelle2024 } from "@/pdc/services/policy/engine/policies/20240101_LaRochelle.ts";
import { Montpellier } from "@/pdc/services/policy/engine/policies/20221206_Montpellier.ts";
import { NantesMetropole2024 } from "@/pdc/services/policy/engine/policies/20240101_NantesMetropole.ts";
import { NantesMetropoleXPCovoitan2021 } from "@/pdc/services/policy/engine/policies/20211202_NantesMetropoleXP.ts";
import { Occitanie20232024 } from "@/pdc/services/policy/engine/policies/20221024_Occitanie.ts";
import { PaysBasque20232024 } from "@/pdc/services/policy/engine/policies/20230401_PaysBasqueAdour.ts";
import { PaysDeLaLoire2021 } from "@/pdc/services/policy/engine/policies/20210105_PaysDeLaLoire.ts";
import { PaysDeLaLoire2023 } from "@/pdc/services/policy/engine/policies/20230201_PaysDeLaLoire.ts";
import { PaysDeLaLoire2024 } from "@/pdc/services/policy/engine/policies/20240101_PaysDeLaLoire.ts";
import { SMTC2024Passenger } from "@/pdc/services/policy/engine/policies/20240101_SMTC2024Passenger.ts";
import { SMTC2024Driver } from "@/pdc/services/policy/engine/policies/20240101_SMTCDriver.ts";
import { PetrLunevillois092024032025 } from "@/pdc/services/policy/engine/policies/20240902_PetrLunevillois.ts";
import { PetrLunevilloisS12023 } from "@/pdc/services/policy/engine/policies/20240108_PetrLunevillois.ts";
import { GrandChatellerault2024 } from "@/pdc/services/policy/engine/policies/20240201_GrandChatellerault.ts";
import { TerresTouloises2024 } from "@/pdc/services/policy/engine/policies/20240201_TerresTouloises.ts";
import { LannionTregor2024 } from "@/pdc/services/policy/engine/policies/20240401_LannionTregor.ts";
import { PMGF2022 } from "@/pdc/services/policy/engine/policies/20221102_PMGF.ts";
import { PMGF2023 } from "@/pdc/services/policy/engine/policies/20230502_PMGF.ts";
import { PMGFOctobre2023 } from "@/pdc/services/policy/engine/policies/20231001_PMGF.ts";
import { PMGFxATMB2024 } from "@/pdc/services/policy/engine/policies/20240401_PMGFxATMB.ts";
import { CCVMM202405 } from "@/pdc/services/policy/engine/policies/20240805_CCVMM_2024_05.ts";
import { SiouleLimagne } from "@/pdc/services/policy/engine/policies/20240901_SiouleLimagne_2024_09.ts";
import { PetrLunevillois092024032025 } from "@/pdc/services/policy/engine/policies/20240902_PetrLunevillois.ts";
import { CCPOA202410 } from "@/pdc/services/policy/engine/policies/20241015_CCPOA_orthe_et_arrigans_2024.ts";
import { GrandPoitiers2025 } from "@/pdc/services/policy/engine/policies/20250101_GrandPoitiers2025.ts";
import { PolicyHandlerStaticInterface } from "@/pdc/services/policy/interfaces/index.ts";
import { PolicyTemplateOne } from "@/pdc/services/policy/engine/policies/unbound/PolicyTemplateOne.ts";
import { PolicyTemplateThree } from "@/pdc/services/policy/engine/policies/unbound/PolicyTemplateThree.ts";
import { PolicyTemplateTwo } from "@/pdc/services/policy/engine/policies/unbound/PolicyTemplateTwo.ts";
import { PolicyHandlerStaticInterface } from "@/pdc/services/policy/interfaces/index.ts";
import { SiouleLimagne } from "@/pdc/services/policy/engine/policies/20240901_SiouleLimagne_2024_09.ts";
import { SMT2022 } from "@/pdc/services/policy/engine/policies/20220414_SMT.ts";
import { SMT2023 } from "@/pdc/services/policy/engine/policies/20230126_SMT.ts";
import { SMTC2024Driver } from "@/pdc/services/policy/engine/policies/20240101_SMTCDriver.ts";
import { SMTC2024Passenger } from "@/pdc/services/policy/engine/policies/20240101_SMTC2024Passenger.ts";
import { TerresTouloises2024 } from "@/pdc/services/policy/engine/policies/20240201_TerresTouloises.ts";
import { Vitre2023 } from "@/pdc/services/policy/engine/policies/20230101_Vitre.ts";

export const policies: Map<string, PolicyHandlerStaticInterface> = new Map(
[
Expand All @@ -49,6 +50,7 @@ export const policies: Map<string, PolicyHandlerStaticInterface> = new Map(
Cotentin2023,
GrandChatellerault2024,
GrandPoitiers,
HauteCorreze2025,
GrandPoitiers2025,
IDFMPeriodeNormale2021,
Lannion202305,
Expand Down

0 comments on commit f5b122d

Please sign in to comment.