Skip to content

Commit

Permalink
Corrections cahier de recette Annexe 2 et entreposage provisoire (#4014)
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitguigal authored Mar 7, 2025
2 parents 4201dde + 121bb58 commit 691d068
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 76 deletions.
3 changes: 2 additions & 1 deletion back/src/forms/__tests__/form-converter.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ describe("expandFormFromDb", () => {
wasteAcceptationStatus: null,
wasteRefusalReason: null,
receivedAt: null,
receivedBy: null
receivedBy: null,
signedAt: null
},
destination: {
cap: "CAP",
Expand Down
3 changes: 2 additions & 1 deletion back/src/forms/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,8 @@ export function expandFormFromDb(
wasteAcceptationStatus: form.wasteAcceptationStatus,
wasteRefusalReason: form.wasteRefusalReason,
receivedAt: processDate(form.receivedAt),
receivedBy: form.receivedBy
receivedBy: form.receivedBy,
signedAt: form.signedAt
},
transporter: forwardedInTransporter
? expandTransporterFromDb(forwardedInTransporter)
Expand Down
4 changes: 3 additions & 1 deletion back/src/forms/pdf/components/BsddPdf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,9 @@ export function BsddPdf({
</p>
<AcceptationFields
{...form.temporaryStorageDetail?.temporaryStorer}
signedAt={form.signedAt} //check this
signedAt={
form.temporaryStorageDetail?.temporaryStorer?.signedAt
}
/>
<p>
Nom :{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ describe("signTransportForm", () => {
it("should sign transport from temporary storage", async () => {
const temporaryStorage = await userWithCompanyFactory("ADMIN");
const transporter = await userWithCompanyFactory("ADMIN");
await transporterReceiptFactory({ company: transporter.company });
const emittedAt = new Date("2018-12-11T00:00:00.000Z");
const takenOverAt = new Date("2018-12-12T00:00:00.000Z");

Expand Down Expand Up @@ -499,6 +500,7 @@ describe("signTransportForm", () => {
it("should sign transport from temporary storage when plates are valid", async () => {
const temporaryStorage = await userWithCompanyFactory("ADMIN");
const transporter = await userWithCompanyFactory("ADMIN");
await transporterReceiptFactory({ company: transporter.company });
const emittedAt = new Date("2018-12-11T00:00:00.000Z");
const takenOverAt = new Date("2018-12-12T00:00:00.000Z");

Expand Down Expand Up @@ -555,6 +557,7 @@ describe("signTransportForm", () => {
it("should throw an error when signing transport from temporary storage and plates are invalid", async () => {
const temporaryStorage = await userWithCompanyFactory("ADMIN");
const transporter = await userWithCompanyFactory("ADMIN");
await transporterReceiptFactory({ company: transporter.company });
const emittedAt = new Date("2018-12-11T00:00:00.000Z");
const takenOverAt = new Date("2018-12-12T00:00:00.000Z");

Expand Down Expand Up @@ -604,6 +607,7 @@ describe("signTransportForm", () => {
it("should sign transport from temporary storage with security code", async () => {
const temporaryStorage = await userWithCompanyFactory("ADMIN");
const transporter = await userWithCompanyFactory("ADMIN");
await transporterReceiptFactory({ company: transporter.company });
const emittedAt = new Date("2018-12-11T00:00:00.000Z");
const takenOverAt = new Date("2018-12-12T00:00:00.000Z");

Expand Down Expand Up @@ -701,6 +705,115 @@ describe("signTransportForm", () => {
expect(errors).not.toBeUndefined();
});

it("should throw an error when signing transport from temporary storage if plates are not provided and mode is ROAD", async () => {
const temporaryStorage = await userWithCompanyFactory("ADMIN");
const transporter = await userWithCompanyFactory("ADMIN");
await transporterReceiptFactory({ company: transporter.company });
const emittedAt = new Date("2018-12-11T00:00:00.000Z");
const takenOverAt = new Date("2018-12-12T00:00:00.000Z");
const form = await formWithTempStorageFactory({
ownerId: temporaryStorage.user.id,
opt: {
status: "SIGNED_BY_TEMP_STORER",
recipientCompanySiret: temporaryStorage.company.siret,
recipientCompanyName: temporaryStorage.company.name
},
forwardedInOpts: {
emittedAt: emittedAt,
emittedBy: temporaryStorage.user.name,
transporters: {
create: {
transporterCompanySiret: transporter.company.siret,
transporterCompanyName: transporter.company.name,
transporterTransportMode: "ROAD",
transporterNumberPlate: null,
number: 1
}
}
}
});

const { mutate } = makeClient(transporter.user);
const { errors } = await mutate<
Pick<Mutation, "signTransportForm">,
MutationSignTransportFormArgs
>(SIGN_TRANSPORT_FORM, {
variables: {
id: form.id,
input: {
takenOverAt: takenOverAt.toISOString() as unknown as Date,
takenOverBy: transporter.user.name,
transporterNumberPlate: null
}
}
});

expect(errors).toEqual([
expect.objectContaining({
message: "La plaque d'immatriculation est requise"
})
]);
});

it("should sign transport from temporary storage if plates are not provided and mode is not ROAD", async () => {
const temporaryStorage = await userWithCompanyFactory("ADMIN");
const transporter = await userWithCompanyFactory("ADMIN");
await transporterReceiptFactory({ company: transporter.company });
const emittedAt = new Date("2018-12-11T00:00:00.000Z");
const takenOverAt = new Date("2018-12-12T00:00:00.000Z");
const form = await formWithTempStorageFactory({
ownerId: temporaryStorage.user.id,
opt: {
status: "SIGNED_BY_TEMP_STORER",
recipientCompanySiret: temporaryStorage.company.siret,
recipientCompanyName: temporaryStorage.company.name
},
forwardedInOpts: {
emittedAt: emittedAt,
emittedBy: temporaryStorage.user.name,
transporters: {
create: {
transporterCompanySiret: transporter.company.siret,
transporterCompanyName: transporter.company.name,
transporterTransportMode: "SEA",
transporterNumberPlate: null,
number: 1
}
}
}
});

const { mutate } = makeClient(transporter.user);
const { data, errors } = await mutate<
Pick<Mutation, "signTransportForm">,
MutationSignTransportFormArgs
>(SIGN_TRANSPORT_FORM, {
variables: {
id: form.id,
input: {
takenOverAt: takenOverAt.toISOString() as unknown as Date,
takenOverBy: transporter.user.name,
transporterNumberPlate: null
}
}
});

expect(errors).toBeUndefined();

expect(data.signTransportForm).toEqual(
expect.objectContaining({
status: "RESENT",
temporaryStorageDetail: expect.objectContaining({
signedAt: takenOverAt.toISOString(),
signedBy: temporaryStorage.user.name,

takenOverAt: takenOverAt.toISOString(),
takenOverBy: transporter.user.name
})
})
);
});

it("should throw an error if signed by an intermediary", async () => {
const intermediary = await userWithCompanyFactory("ADMIN");
const emitter = await userWithCompanyFactory("ADMIN");
Expand Down
39 changes: 23 additions & 16 deletions back/src/forms/resolvers/mutations/signTransportForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { getFormRepository } from "../../repository";
import { getTransporterCompanyOrgId } from "@td/constants";
import { runInTransaction } from "../../../common/repository/helper";
import { sumPackagingInfos } from "../../repository/helper";
import { validateBeforeTransport, plateSchemaFn } from "../../validation";
import { validateBeforeTransport, transporterSchemaFn } from "../../validation";
import { Permission } from "../../../permissions";
import { enqueueUpdatedBsdToIndex } from "../../../queue/producers/elastic";
import { recipifyFormInput } from "../../recipify";
Expand Down Expand Up @@ -333,12 +333,30 @@ const signatures: Partial<
const existingFullForm = await getFullForm(existingForm);

const transporter = getFirstTransporterSync(existingFullForm.forwardedIn!);
const signingTransporterOrgId = getTransporterCompanyOrgId(transporter)!;
await checkCanSignFor(
getTransporterCompanyOrgId(transporter)!,
signingTransporterOrgId,
user,
Permission.BsdCanSignTransport,
args.securityCode
);
const transporterNumberPlate =
args.input.transporterNumberPlate ?? transporter?.transporterNumberPlate;

const transporterTransportMode =
args.input.transporterTransportMode ??
transporter?.transporterTransportMode;

const transporterSchema = transporterSchemaFn({ signingTransporterOrgId });

const receiptFields = await getFormReceiptField(transporter);

await transporterSchema.validate({
...transporter,
transporterNumberPlate,
transporterTransportMode,
...receiptFields
});

const formUpdateInput: Prisma.FormUpdateInput = {
forwardedIn: {
Expand All @@ -349,9 +367,9 @@ const signatures: Partial<
transporters: {
updateMany: {
data: {
transporterNumberPlate:
args.input.transporterNumberPlate ??
transporter?.transporterNumberPlate
transporterNumberPlate,
transporterTransportMode,
...receiptFields
},
where: { number: 1 }
}
Expand All @@ -365,17 +383,6 @@ const signatures: Partial<
}
};

await plateSchemaFn().validate(
{
transporterNumberPlate:
args.input.transporterNumberPlate ??
transporter?.transporterNumberPlate
},
{
abortEarly: false
}
);

const updatedForm = await getFormRepository(user).update(
{ id: existingFullForm.id, status: existingFullForm.status },
{
Expand Down
3 changes: 2 additions & 1 deletion back/src/forms/typeDefs/bsdd.objects.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,10 @@ type TemporaryStorer {
quantityAccepted: Float
wasteAcceptationStatus: WasteAcceptationStatus
wasteRefusalReason: String

receivedAt: DateTime
receivedBy: String
"Date à laquelle le déchet a été accepté ou refusé (case 13)"
signedAt: DateTime
}

"Destination finale après entreposage provisoire ou reconditionement"
Expand Down
13 changes: 0 additions & 13 deletions back/src/forms/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1113,19 +1113,6 @@ export const validatePlates = (transporterNumberPlate: string) => {
return true;
};

// Schema dedicated to validate plates on signTransportForm SIGNED_BY_TEMP_STORER
export const plateSchemaFn = () =>
yup.object({
transporterNumberPlate: yup
.string()
.nullable()
.test(transporterNumberPlate => {
return transporterNumberPlate
? validatePlates(transporterNumberPlate)
: true;
})
});

export const transporterSchemaFn: FactorySchemaOf<
Pick<FormValidationContext, "signingTransporterOrgId">,
Transporter
Expand Down
2 changes: 1 addition & 1 deletion front/src/Apps/Dashboard/dashboardServices.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ describe("dashboardServices", () => {
}
},
permissions,
"actTab"
"toCollectTab"
);
expect(result).toEqual(SIGNER);
});
Expand Down
2 changes: 1 addition & 1 deletion front/src/Apps/Dashboard/dashboardServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ export const getSignByProducerBtnLabel = (
isSameSiretTransporter(currentSiret, bsd) &&
permissions.includes(UserPermission.BsdCanSignTransport)
) {
if (isBsdd(bsd.type)) {
if (isBsdd(bsd.type) && isToCollectTab) {
return SIGNER;
}
if (isBsdasri(bsd.type)) {
Expand Down
13 changes: 10 additions & 3 deletions front/src/Apps/Forms/Components/PackagingList/PackagingForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,16 @@ function PackagingForm({
packagingsLength > 1
? // Un conditionnement en citerne ou benne exclut le mélange avec
// tout autre type de conditionnement
packagingTypeOptions.filter(
o => o.value !== Packagings.Citerne && o.value !== Packagings.Benne
)
packagingTypeOptions.filter(o => {
return (
// tra-16064 - cas particulier si les conditionnements ont été calculés
// automatiquement à partir de la liste des annexes 2, on peut se retrouver
// avec des conditionnements incohérents et on veut quand même pouvoir afficher
// Citerne ou Benne dans la liste des options disponibles.
o.value === packaging.type ||
(o.value !== Packagings.Citerne && o.value !== Packagings.Benne)
);
})
: packagingTypeOptions;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ export function FormJourneySummary({ form }: FormJourneySummaryProps) {
variant={
form.temporaryStorageDetail.emittedAt
? "complete"
: (form.transporters ?? []).every(t => Boolean(t.takenOverAt))
: (form.isDirectSupply && form.emittedAt) ||
(!form.isDirectSupply &&
(form.transporters ?? []).every(t =>
Boolean(t.takenOverAt)
))
? // Actif si tous les transporteurs ont signé, sinon en attente
"active"
: "incomplete"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ export function FormWasteEmissionSummary({
.filter((name, index, fields) => fields.indexOf(name) === index)
);

// On ne doit pas pouvoir éditer la liste des contenants ou la plaque immat
// lors d'un acheminement direct par pipeline ou convoyeur sauf s'il s'agit
// de la signature du TTR après entreposage provisoire
const isDirectSupply =
form.temporaryStorageDetail && form.emittedAt ? false : form.isDirectSupply;

return (
<>
<DataList>
Expand Down Expand Up @@ -104,7 +110,7 @@ export function FormWasteEmissionSummary({
</button>
</DataListDescription>
</DataListItem>
{!form.isDirectSupply && (
{!isDirectSupply && (
<DataListItem>
<DataListTerm>Contenant(s)</DataListTerm>
<DataListDescription>
Expand Down Expand Up @@ -157,22 +163,23 @@ export function FormWasteEmissionSummary({
</DataListDescription>
</DataListItem>
)}
{form.emitter?.type !== EmitterType.Appendix1Producer && (
<DataListItem>
<DataListTerm>Plaque d'immatriculation</DataListTerm>
<DataListDescription>
{values.transporterNumberPlate}
{form.emitter?.type !== EmitterType.Appendix1Producer &&
!isDirectSupply && (
<DataListItem>
<DataListTerm>Plaque d'immatriculation</DataListTerm>
<DataListDescription>
{values.transporterNumberPlate}

<button
type="button"
onClick={() => addField("transporterNumberPlate")}
className="tw-ml-2"
>
<IconPaperWrite color="blue" />
</button>
</DataListDescription>
</DataListItem>
)}
<button
type="button"
onClick={() => addField("transporterNumberPlate")}
className="tw-ml-2"
>
<IconPaperWrite color="blue" />
</button>
</DataListDescription>
</DataListItem>
)}
</DataList>
{fields.length > 0 && (
<div className="tw-mb-4">
Expand Down
Loading

0 comments on commit 691d068

Please sign in to comment.