Skip to content

Commit

Permalink
feat(Appendix2MultiSelect) : group packagings by volume and aggregate…
Browse files Browse the repository at this point in the history
… identification numbers
  • Loading branch information
benoitguigal committed Feb 10, 2025
1 parent a23133a commit 02feef9
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export function getBsddPackagingInfosSummary(packagingInfos: PackagingInfo[]) {
(acc, packagingInfo) => acc + packagingInfo.quantity,
0
);

const packages = [...packagingInfos]
.sort((p1, p2) => p1.type.localeCompare(p2.type))
.map(packagingInfo => {
Expand Down
17 changes: 13 additions & 4 deletions front/src/Apps/common/utils/packagingsBsddSummary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export function getPackagingInfosSummary(packagingInfos: PackagingInfo[]) {
(acc, packagingInfo) => acc + packagingInfo.quantity,
0
);

if (total === 0) {
return "";
}

const packages = [...packagingInfos]
.sort((p1, p2) => p1.type.localeCompare(p2.type))
.map(packagingInfo => {
Expand Down Expand Up @@ -51,13 +56,17 @@ export function getPackagingInfosSummary(packagingInfos: PackagingInfo[]) {
})
.join(", ");

return formTransportIsPipeline({
const isPipeline = formTransportIsPipeline({
wasteDetails: {
packagingInfos
}
})
? `${packages}`
: `${total} colis : ${packages}`;
});

if (isPipeline) {
return packages;
}

return `${total} colis : ${packages}`;
}

export const formTransportIsPipeline = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ import {
GET_FORM,
UPDATE_FORM
} from "../../../../../Apps/common/queries/bsdd/queries";
import {
cleanPackagings,
emptyPackaging
} from "../../../../../form/bsdd/components/packagings/helpers";
import { cleanPackagings } from "../../../../../form/bsdd/components/packagings/helpers";

const validationSchema = yup.object({
takenOverAt: yup.date().required("La date de prise en charge est requise"),
Expand Down
28 changes: 15 additions & 13 deletions front/src/form/bsdd/WasteInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,19 +183,21 @@ export default function WasteInfo({ disabled }) {
</>
)}

<div className="form__row" style={{ flexDirection: "row" }}>
<Switch
label="Le déchet est conditionné pour pipeline"
disabled={disabled}
checked={isPipeline}
onChange={checked => {
const updatedPackagings = checked
? [{ type: Packagings.Pipeline, quantity: 1 }]
: [emptyPackaging];
setFieldValue("wasteDetails.packagingInfos", updatedPackagings);
}}
/>
</div>
{values.emitter?.type !== "APPENDIX1" && (
<div className="form__row" style={{ flexDirection: "row" }}>
<Switch
label="Le déchet est conditionné pour pipeline"
disabled={disabled}
checked={isPipeline}
onChange={checked => {
const updatedPackagings = checked
? [{ type: Packagings.Pipeline, quantity: 1 }]
: [emptyPackaging];
setFieldValue("wasteDetails.packagingInfos", updatedPackagings);
}}
/>
</div>
)}

{values.emitter?.type !== "APPENDIX1" && !isPipeline && (
<>
Expand Down
54 changes: 4 additions & 50 deletions front/src/form/bsdd/components/appendix/Appendix2MultiSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
Form,
InitialForm,
InitialFormFraction,
Packagings
PackagingInfo
} from "@td/codegen-ui";
import {
FieldArray,
Expand All @@ -20,6 +20,7 @@ import Checkbox from "@codegouvfr/react-dsfr/Checkbox";
import NonScrollableInput from "../../../../Apps/common/Components/NonScrollableInput/NonScrollableInput";
import Accordion from "@codegouvfr/react-dsfr/Accordion";
import Button from "@codegouvfr/react-dsfr/Button";
import { totalPackagings } from "./helpers";

type Appendix2MultiSelectProps = {
// Résultat de la query `appendixForms` executé
Expand All @@ -30,13 +31,7 @@ type Appendix2MultiSelectProps = {
updateTotalQuantity: (totalQuantity: number) => void;
// callback permettant de mettre à jour la liste de contenants
// du bordereau en fonction des annexes 2 sélectionnées
updatePackagings: (
packagings: {
type: string;
other: string;
quantity: any;
}[]
) => void;
updatePackagings: (packagings: PackagingInfo[]) => void;
};

// Limite le nombre de bordereaux que l'on peut afficher dans le tableau
Expand Down Expand Up @@ -186,49 +181,8 @@ export default function Appendix2MultiSelect({
}, new Decimal(0))
.toNumber();

// Auto-complète les contenants à partir des annexes 2 sélectionnés
const totalPackagings = (() => {
const quantityByType = currentlyAnnexedForms.reduce(
(acc1, { form, quantity }) => {
if (!form.wasteDetails?.packagingInfos || !quantity) {
return acc1;
}

return form.wasteDetails.packagingInfos.reduce(
(acc2, packagingInfo) => {
if (!acc2[packagingInfo.type]) {
return {
...acc2,
[packagingInfo.type]: packagingInfo.quantity
};
}
return {
...acc2,
[packagingInfo.type]: [
Packagings.Benne,
Packagings.Citerne
].includes(packagingInfo.type)
? Math.min(
packagingInfo.quantity + acc2[packagingInfo.type],
2
)
: packagingInfo.quantity + acc2[packagingInfo.type]
};
},
acc1
);
},
{}
);
return Object.keys(quantityByType).map(type => ({
type,
other: "",
quantity: quantityByType[type]
}));
})();

updateTotalQuantity(totalQuantity);
updatePackagings(totalPackagings);
updatePackagings(totalPackagings(currentlyAnnexedForms));
}, [currentlyAnnexedForms, updateTotalQuantity, updatePackagings]);

// Auto-complète la quantité totale à partir des annexes 2 sélectionnées
Expand Down
133 changes: 133 additions & 0 deletions front/src/form/bsdd/components/appendix/__tests__/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { totalPackagings } from "../helpers";
import { InitialForm, InitialFormFraction, Packagings } from "@td/codegen-ui";

describe("totalPackagings", () => {
it("should group packagings by type, volume, and other", () => {
const annexedForms: InitialFormFraction[] = [
{
form: {
wasteDetails: {
packagingInfos: [
{
type: Packagings.Fut,
volume: 20,
other: null,
quantity: 2,
identificationNumbers: ["A", "B"]
},
{
type: Packagings.Fut,
volume: 30,
other: null,
quantity: 1,
identificationNumbers: ["C"]
}
]
}
} as InitialForm,
quantity: 1
},
{
form: {
wasteDetails: {
packagingInfos: [
{
type: Packagings.Grv,
volume: 30,
other: null,
quantity: 1,
identificationNumbers: ["D"]
},
{
type: Packagings.Fut,
volume: 20,
other: null,
quantity: 3,
identificationNumbers: ["E", "F", "G"]
},
{
type: Packagings.Autre,
volume: 20,
other: "Boite carton",
quantity: 1,
identificationNumbers: ["H"]
}
]
}
} as InitialForm,
quantity: 1
},
{
form: {
wasteDetails: {
packagingInfos: [
{
type: Packagings.Autre,
volume: 20,
other: "Boite carton",
quantity: 1,
identificationNumbers: ["I"]
}
]
}
} as InitialForm,
quantity: 1
},
{
form: {
wasteDetails: {
packagingInfos: [
{
type: Packagings.Autre,
volume: 20,
other: "Boite métallique",
quantity: 1,
identificationNumbers: ["J"]
}
]
}
} as InitialForm,
quantity: 1
}
];

const result = totalPackagings(annexedForms);
expect(result).toEqual([
{
type: "FUT",
volume: 20,
other: null,
quantity: 5,
identificationNumbers: ["A", "B", "E", "F", "G"]
},
{
type: "FUT",
volume: 30,
other: null,
quantity: 1,
identificationNumbers: ["C"]
},
{
type: "GRV",
volume: 30,
other: null,
quantity: 1,
identificationNumbers: ["D"]
},
{
type: "AUTRE",
volume: 20,
other: "Boite carton",
quantity: 2,
identificationNumbers: ["H", "I"]
},
{
type: "AUTRE",
volume: 20,
other: "Boite métallique",
quantity: 1,
identificationNumbers: ["J"]
}
]);
});
});
43 changes: 43 additions & 0 deletions front/src/form/bsdd/components/appendix/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { InitialFormFraction, PackagingInfo } from "@td/codegen-ui";

// Permet de regrouper les conditionnements présents sur les annexes 2 par type, volume et other.
// Exemple avec les annexes 2 et les conditionnements suivants :
// - Première annexe : 2 fûts de 20L (n° A, B) et 1 fût de 30L (n° C)
// - Deuxième annexe : 1 GRV de 30L (n°D) et 3 fûts de 20L (n°E, F, G)
// On veut renvoyer 5 fûts de 20L (n°A, B, E, F, G), 1 fût de 30L (n°C) et 1 GRV de 30L (n°D)
// avec les quantités et les numéros d'identifications qui ont été regroupés par type et par volume
export function totalPackagings(
annexedForms: InitialFormFraction[]
): PackagingInfo[] {
const packagingMap: { [key: string]: PackagingInfo } = {};

for (const { form, quantity } of annexedForms) {
if (form.wasteDetails?.packagingInfos?.length && quantity) {
for (const packagingInfo of form.wasteDetails.packagingInfos) {
const { type, volume, other, quantity, identificationNumbers } =
packagingInfo;

const mapKey = `${type}-${volume ?? "0"}-${other ?? ""}`;

const existingValue = packagingMap[mapKey];

if (existingValue) {
packagingMap[mapKey].quantity += quantity;
packagingMap[mapKey].identificationNumbers.push(
...identificationNumbers
);
} else {
packagingMap[mapKey] = {
type,
volume,
other,
quantity,
identificationNumbers: [...identificationNumbers]
};
}
}
}
}

return Object.values(packagingMap);
}

0 comments on commit 02feef9

Please sign in to comment.