Skip to content

Commit

Permalink
fix: add PETR Lunevillois 2024/2025 (#2659)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanfallon committed Oct 16, 2024
1 parent 0f31cbf commit c5e47f2
Show file tree
Hide file tree
Showing 4 changed files with 340 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const description = `
<div _ngcontent-pmm-c231="" id="summary" class="campaignSummaryText-content-text">
<p>
Campagne d'incitation au covoiturage du <b> 2 septembre 2024 au 28 février 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
sont incités selon les règles suivantes :
</p>
<ul>
<li><b>De 2 à 60 km : 0,07 € par km et par trajet par passager transporté</b></li>
</ul>
<p>Les restrictions suivantes seront appliquées :</p>
<ul>
<li><b>2 trajets maximum pour le conducteur par jour.</b></li>
</ul>
<p>
La campagne est limitée à l'opérateur Mobicoop proposant des preuves de classe <b>C</b>.
</p>
</div>`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
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,
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 { startsAndEndsAtOrThrow } from "@/pdc/services/policy/engine/helpers/startsAndEndsAtOrThrow.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";
import { description } from "./20240108_PetrLunevillois.html.ts";

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

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

// 7 cts per km per passenger
protected slices: RunnableSlices = [
{
start: 2_000,
end: 60_000,
fn: (ctx: StatelessContextInterface) =>
perSeat(ctx, perKm(ctx, { amount: 7, offset: 2_000, limit: 60_000 })),
},
];

constructor(public max_amount: number) {
super();
this.limits = [
[
"d5895fd5-05db-4680-85e1-ef0d95e01441",
max_amount,
watchForGlobalMaxAmount,
],
[
"95ae2e57-6e3d-4de3-aef2-96610be9e1da",
2,
watchForPersonMaxTripByDay,
LimitTargetEnum.Driver,
],
];
}

protected processExclusion(ctx: StatelessContextInterface) {
isOperatorOrThrow(
ctx,
getOperatorsAt(this.operators, ctx.carpool.datetime),
);
onDistanceRangeOrThrow(ctx, { min: 2_000, max: 60_000 });
isOperatorClassOrThrow(ctx, ["C"]);
startsAndEndsAtOrThrow(ctx, { aom: ["200051134"] });
}

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,201 @@
import { it } from "@/dev_deps.ts";
import { v4 as uuidV4 } from "@/lib/uuid/index.ts";
import { OperatorsEnum } from "../../interfaces/index.ts";
import { makeProcessHelper } from "../tests/macro.ts";
import { PetrLunevillois092024032025 as Handler } from "./20240902_PetrLunevillois.ts";

const defaultPosition = {
arr: "54233",
com: "54233",
aom: "200051134",
epci: "200069433",
dep: "54",
reg: "44",
country: "XXXXX",
reseau: "269",
};
const defaultLat = 48.5905360901711;
const defaultLon = 6.499392987670189;

const defaultCarpool = {
_id: 1,
operator_trip_id: uuidV4(),
passenger_identity_key: uuidV4(),
driver_identity_key: uuidV4(),
operator_uuid: OperatorsEnum.MOBICOOP,
operator_class: "C",
passenger_is_over_18: true,
passenger_has_travel_pass: true,
driver_has_travel_pass: true,
datetime: new Date("2024-09-08"),
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: 48.58685290576798,
end_lon: 6.483696700766759,
};

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: 60_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" },
],
meta: [],
},
{
incentive: [21, 42, 161, 322],
meta: [
{
key: "max_amount_restriction.global.campaign.global",
value: 546,
},
],
},
));

it("should work basic with start or end outside aom", async () =>
await process(
{
policy: { handler: Handler.id },
carpool: [
// start
{
distance: 5_000,
driver_identity_key: "one",
start: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 5_000,
seats: 2,
driver_identity_key: "one",
start: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 25_000,
driver_identity_key: "two",
start: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 25_000,
seats: 2,
driver_identity_key: "two",
start: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 55_000,
driver_identity_key: "two",
start: { ...defaultPosition, aom: "not_in_aom" },
},

// end
{
distance: 5_000,
driver_identity_key: "one",
end: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 5_000,
seats: 2,
driver_identity_key: "one",
end: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 25_000,
driver_identity_key: "two",
end: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 25_000,
seats: 2,
driver_identity_key: "two",
end: { ...defaultPosition, aom: "not_in_aom" },
},
{
distance: 55_000,
driver_identity_key: "two",
end: { ...defaultPosition, aom: "not_in_aom" },
},
],
meta: [],
},
{
incentive: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
meta: [],
},
));

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

it("should work with 2 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" },
],
meta: [],
},
{
incentive: [21, 21, 0, 0],
meta: [
{
key: "max_amount_restriction.global.campaign.global",
value: 42,
},
],
},
));
6 changes: 2 additions & 4 deletions api/src/pdc/services/policy/engine/policies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@ import { TerresTouloises2024 } from "@/pdc/services/policy/engine/policies/20240
import { LannionTregor2024 } from "@/pdc/services/policy/engine/policies/20240401_LannionTregor.ts";
import { PMGFxATMB2024 } from "@/pdc/services/policy/engine/policies/20240401_PMGFxATMB.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 { 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 { CCVMM202405 } from "./20240805_CCVMM_2024_05.ts";

export const policies: Map<string, PolicyHandlerStaticInterface> = new Map(
// disable prettier to avoid having it reformat to a single line
// this helps with git conflicts when modifying the list.
/* eslint-disable prettier/prettier */
[
ATMB202305,
Cannes2024,
Expand All @@ -62,6 +60,7 @@ export const policies: Map<string, PolicyHandlerStaticInterface> = new Map(
PaysDeLaLoire2023,
PaysDeLaLoire2024,
PetrLunevilloisS12023,
PetrLunevillois092024032025,
PMGF2022,
PMGF2023,
PMGFOctobre2023,
Expand All @@ -78,5 +77,4 @@ export const policies: Map<string, PolicyHandlerStaticInterface> = new Map(
CCVMM202405,
SiouleLimagne,
].map((h) => [h.id, h]),
/* eslint-enable prettier/prettier */
);

0 comments on commit c5e47f2

Please sign in to comment.