Skip to content

Commit

Permalink
fix: add CCPOA 2024_10 campaign (#2686)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanfallon authored Nov 13, 2024
1 parent 3674475 commit f3e8675
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 3 deletions.
1 change: 1 addition & 0 deletions api/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const description = `
<div _ngcontent-pmm-c231="" id="summary" class="campaignSummaryText-content-text">
<p>
Campagne d'incitation au covoiturage du <b> 15 octobre 2024 au 14 octobre 2025</b>,
toute la semaine
</p>
<p>Cette campagne est limitée à <b>15 000,00 €</b>.</p>
<p>
Les <b> conducteurs </b> effectuant un trajet en covoiturage d'au moins 5 km
sont incités selon les règles suivantes de façon non cumulative :
</p>
<ul>
<li><b>De 5 à 20 km : 1,50 € par trajet et par passager transporté</b></li>
<li><b>De 20 à 30 km : 0,10 € par trajet et par passager transporté</b></li>
<li><b>De 30 à 80 km : 2,50 € 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>100,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>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 { 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 "./20241015_CCPOA_orthe_et_arrigans_2024.html.ts";

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

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

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

constructor(public max_amount: number) {
super();
this.limits = [
[
"9ea04dd8-2044-41ba-98fe-668bce5c3b81",
max_amount,
watchForGlobalMaxAmount,
],
[
"bf7e8a51-e663-4e15-896f-717fb34fd9e2",
6,
watchForPersonMaxTripByDay,
LimitTargetEnum.Driver,
],
[
"3b5ed8ab-fe9f-4032-9953-48bc58e3a00f",
100_00,
watchForPersonMaxAmountByMonth,
LimitTargetEnum.Driver,
],
];
}

protected processExclusion(ctx: StatelessContextInterface) {
isOperatorOrThrow(ctx, getOperatorsAt(this.operators, ctx.carpool.datetime));
onDistanceRangeOrThrow(ctx, { min: 5_000, max: 80_000 });
isOperatorClassOrThrow(ctx, ["C"]);
startsOrEndsAtOrThrow(ctx, { epci: ["200069417"] });
}

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,149 @@
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 { CCPOA202410 as Handler } from "./20241015_CCPOA_orthe_et_arrigans_2024.ts";

const defaultPosition = {
arr: "40231",
com: "40231",
aom: "200053759",
epci: "200069417",
dep: "40",
reg: "75",
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.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: 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: 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" },
],
meta: [],
},
{
incentive: [150, 300, 200, 400],
meta: [
{
key: "max_amount_restriction.global.campaign.global",
value: 1050,
},
{
key: "max_amount_restriction.0-one.month.10-2024",
value: 450,
},
{
key: "max_amount_restriction.0-two.month.10-2024",
value: 600,
},
],
},
));

it("should work with global limits", async () =>
await process(
{
policy: { handler: Handler.id, max_amount: 15_000_00 },
carpool: [{ distance: 59_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: 250,
},
],
},
));

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 much
],
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,
},
],
},
));
8 changes: 5 additions & 3 deletions api/src/pdc/services/policy/engine/policies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { LannionTregor2024 } from "@/pdc/services/policy/engine/policies/2024040
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 { CCPOA202410 } from "@/pdc/services/policy/engine/policies/20241015_CCPOA_orthe_et_arrigans_2024.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";
Expand All @@ -41,6 +42,8 @@ export const policies: Map<string, PolicyHandlerStaticInterface> = new Map(
[
ATMB202305,
Cannes2024,
CCPOA202410,
CCVMM202405,
Cotentin2023,
GrandChatellerault2024,
GrandPoitiers,
Expand All @@ -59,22 +62,21 @@ export const policies: Map<string, PolicyHandlerStaticInterface> = new Map(
PaysDeLaLoire2021,
PaysDeLaLoire2023,
PaysDeLaLoire2024,
PetrLunevilloisS12023,
PetrLunevillois092024032025,
PetrLunevilloisS12023,
PMGF2022,
PMGF2023,
PMGFOctobre2023,
PMGFxATMB2024,
PolicyTemplateOne,
PolicyTemplateThree,
PolicyTemplateTwo,
SiouleLimagne,
SMT2022,
SMT2023,
SMTC2024Driver,
SMTC2024Passenger,
TerresTouloises2024,
Vitre2023,
CCVMM202405,
SiouleLimagne,
].map((h) => [h.id, h]),
);

0 comments on commit f3e8675

Please sign in to comment.