Skip to content

Commit

Permalink
[TRA-15098] - Permettre au transporteur étranger d'avoir les mêmes dr…
Browse files Browse the repository at this point in the history
…oits qu'un transporteur FR concernant la révision sur une Annexe 1 (#3770)
  • Loading branch information
benoitguigal authored Nov 27, 2024
2 parents fecb7b8 + b3fdf6a commit 8b9f4a5
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 29 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ et le projet suit un schéma de versionning inspiré de [Calendar Versioning](ht

# [2024.12.1] 17/12/2024

#### :nail_care: Améliorations

- Permettre au transporteur étranger d'avoir les mêmes droits qu'un transporteur FR concernant la révision sur une Annexe 1 [PR 3770](https://github.com/MTES-MCT/trackdechets/pull/3770)

#### :bug: Corrections de bugs

- Ne pas doubler les quantités restantes à regrouper lorsqu'on modifie un bordereau de groupement [PR 3760](https://github.com/MTES-MCT/trackdechets/pull/3760)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const CREATE_FORM_REVISION_REQUEST = `
wasteDetails { code }
}
authoringCompany {
orgId
siret
}
approvals {
Expand Down Expand Up @@ -624,7 +625,7 @@ describe("Mutation.createFormRevisionRequest", () => {

it(
"should create a revisionRequest and identifying current user" +
" as the requester (transporter when emitterType=APPENIDX_PRODUCER) ",
" as the requester (transporter when emitterType=APPENDIX_PRODUCER) ",
async () => {
const { company: recipientCompany } = await userWithCompanyFactory(
"ADMIN",
Expand Down Expand Up @@ -679,6 +680,75 @@ describe("Mutation.createFormRevisionRequest", () => {
}
);

it(
"should create a revisionRequest and identifying current user" +
" as the requester (foreign transporter when emitterType=APPENDIX_PRODUCER) ",
async () => {
const { company: recipientCompany } = await userWithCompanyFactory(
"ADMIN",
{
companyTypes: [CompanyType.WASTEPROCESSOR],
wasteProcessorTypes: [
WasteProcessorType.DANGEROUS_WASTES_INCINERATION
]
}
);
const { company: emitterCompany } = await userWithCompanyFactory("ADMIN");
const vatNumber = "IT13029381004";
const { user, company: foreignTransporter } =
await userWithCompanyFactory("ADMIN", {
vatNumber,
orgId: vatNumber,
siret: null
});
const bsdd = await formFactory({
ownerId: user.id,
opt: {
emitterType: EmitterType.APPENDIX1_PRODUCER,
emitterCompanySiret: emitterCompany.siret,
recipientCompanySiret: recipientCompany.siret,
transportersSirets: [foreignTransporter.vatNumber!],
wasteDetailsQuantity: 1,
status: "SENT",
takenOverAt: new Date(),
transporters: {
create: {
number: 1,
transporterCompanySiret: null,
transporterCompanyVatNumber: foreignTransporter.vatNumber
}
}
}
});

const { mutate } = makeClient(user);
const { data, errors } = await mutate<
Pick<Mutation, "createFormRevisionRequest">,
MutationCreateFormRevisionRequestArgs
>(CREATE_FORM_REVISION_REQUEST, {
variables: {
input: {
formId: bsdd.id,
content: { wasteDetails: { quantity: 10 } },
comment: "A comment",
authoringCompanySiret: foreignTransporter.vatNumber!
}
}
});

expect(errors).toBeUndefined();

expect(data.createFormRevisionRequest.form.id).toBe(bsdd.id);
expect(data.createFormRevisionRequest.authoringCompany.orgId).toBe(
foreignTransporter.vatNumber
);
// one approval is created
expect(data.createFormRevisionRequest.approvals).toStrictEqual([
{ approverSiret: emitterCompany.siret, status: "PENDING" }
]);
}
);

it("should create a revisionRequest and an approval targetting the company not requesting the revisionRequest", async () => {
const { company: recipientCompany } = await userWithCompanyFactory(
"ADMIN",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,90 @@ describe("Mutation.submitFormRevisionRequestApproval", () => {
expect(updatedBsdd?.nextDestinationProcessingOperation).toBe("");
});

it("should be possible for a foreign transporter to approve a revision on an annexe1", async () => {
const vatNumber = "IT13029381004";
const { user, company: foreignTransporter } = await userWithCompanyFactory(
"ADMIN",
{ siret: null, vatNumber, orgId: vatNumber }
);
const { user: emitter, company: emitterCompany } =
await userWithCompanyFactory();
const { company: collectorCompany } = await userWithCompanyFactory();
const { company: destinationCompany } = await userWithCompanyFactory();

const bsdd = await formFactory({
ownerId: emitter.id,
opt: {
emitterType: "APPENDIX1_PRODUCER",
emitterCompanySiret: emitterCompany.siret,
wasteDetailsQuantity: 1,
transporters: {
create: {
number: 1,
transporterCompanyVatNumber: foreignTransporter.vatNumber,
transporterCompanySiret: null
}
}
}
});

const bsddTourneeDedie = await formFactory({
ownerId: emitter.id,
opt: {
emitterType: "APPENDIX1",
emitterCompanySiret: collectorCompany.siret,
recipientCompanySiret: destinationCompany.siret,
wasteDetailsQuantity: 1,
grouping: { create: { initialFormId: bsdd.id, quantity: 1 } }
}
});

const revisionRequest = await prisma.bsddRevisionRequest.create({
data: {
status: "PENDING",
bsddId: bsdd.id,
authoringCompanyId: emitterCompany.id,
approvals: { create: { approverSiret: foreignTransporter.orgId! } },
wasteDetailsQuantity: 2,
comment: "Yolo"
}
});

const { mutate } = makeClient(user);

const { data, errors } = await mutate<
Pick<Mutation, "submitFormRevisionRequestApproval">
>(SUBMIT_BSDD_REVISION_REQUEST_APPROVAL, {
variables: {
id: revisionRequest.id,
isApproved: true
}
});

expect(data.submitFormRevisionRequestApproval.status).toEqual("ACCEPTED");

expect(errors).toBeUndefined();

const updatedRevisionRequest =
await prisma.bsddRevisionRequest.findUniqueOrThrow({
where: { id: revisionRequest.id }
});

expect(updatedRevisionRequest.status).toEqual("ACCEPTED");

const updatedBsdd = await prisma.form.findUniqueOrThrow({
where: { id: bsdd.id }
});

expect(updatedBsdd.wasteDetailsQuantity?.toNumber()).toEqual(2);

const updatedBsddTourneeDedie = await prisma.form.findUniqueOrThrow({
where: { id: bsddTourneeDedie.id }
});

expect(updatedBsddTourneeDedie.wasteDetailsQuantity?.toNumber()).toEqual(2);
});

describe("wasteAcceptationStatus & quantityRefused", () => {
it("should update the BSDD wasteAcceptationStatus", async () => {
// Given
Expand Down
33 changes: 22 additions & 11 deletions back/src/forms/resolvers/mutations/createFormRevisionRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ import {
} from "../../../generated/graphql/types";
import { GraphQLContext } from "../../../types";
import { getUserCompanies } from "../../../users/database";
import { getFormOrFormNotFound } from "../../database";
import { getFormOrFormNotFound, getTransportersSync } from "../../database";
import {
expandableFormIncludes,
flattenBsddRevisionRequestInput
flattenBsddRevisionRequestInput,
PrismaFormWithForwardedInAndTransporters
} from "../../converter";
import { checkCanRequestRevision } from "../../permissions";
import { getFormRepository } from "../../repository";
Expand Down Expand Up @@ -109,7 +110,12 @@ export default async function createFormRevisionRequest(
{ input }: MutationCreateFormRevisionRequestArgs,
context: GraphQLContext
) {
const { formId, content, comment, authoringCompanySiret } = input;
const {
formId,
content,
comment,
authoringCompanySiret: authoringCompanyOrgId
} = input;

const user = checkIsAuthenticated(context);
const existingBsdd = await getFormOrFormNotFound(
Expand All @@ -127,7 +133,7 @@ export default async function createFormRevisionRequest(
const authoringCompany = await getAuthoringCompany(
user,
existingBsdd,
authoringCompanySiret
authoringCompanyOrgId
);
const approversSirets = await getApproversSirets(
existingBsdd,
Expand All @@ -150,8 +156,8 @@ export default async function createFormRevisionRequest(

async function getAuthoringCompany(
user: Express.User,
bsdd: Form,
authoringCompanySiret: string
bsdd: PrismaFormWithForwardedInAndTransporters,
authoringCompanyOrgId: string
) {
const forwardedIn = await getFormRepository(user).findForwardedInById(
bsdd.id
Expand All @@ -160,28 +166,33 @@ async function getAuthoringCompany(
const transporterCanBeAuthor =
bsdd.emitterType === EmitterType.APPENDIX1_PRODUCER && bsdd.takenOverAt;

const transporterOrgIds = () =>
getTransportersSync(bsdd)
.flatMap(t => [t.transporterCompanySiret, t.transporterCompanyVatNumber])
.filter(Boolean);

const canBeAuthorCompany = [
bsdd.emitterCompanySiret,
bsdd.recipientCompanySiret,
bsdd.ecoOrganismeSiret,
forwardedIn?.recipientCompanySiret,
...(transporterCanBeAuthor ? bsdd.transportersSirets : [])
...(transporterCanBeAuthor ? transporterOrgIds() : [])
].filter(Boolean);

if (!canBeAuthorCompany.includes(authoringCompanySiret)) {
if (!canBeAuthorCompany.includes(authoringCompanyOrgId)) {
throw new UserInputError(
`Le SIRET "${authoringCompanySiret}" ne peut pas être auteur de la révision.`
`Le SIRET "${authoringCompanyOrgId}" ne peut pas être auteur de la révision.`
);
}

const userCompanies = await getUserCompanies(user.id);
const authoringCompany = userCompanies.find(
company => company.siret === authoringCompanySiret
company => company.orgId === authoringCompanyOrgId
);

if (!authoringCompany) {
throw new UserInputError(
`Vous n'avez pas les droits suffisants pour déclarer le SIRET "${authoringCompanySiret}" comme auteur de la révision.`
`Vous n'avez pas les droits suffisants pour déclarer le SIRET "${authoringCompanyOrgId}" comme auteur de la révision.`
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,18 @@ export default async function submitFormRevisionRequestApproval(
);
}

const currentApproverSiret = await getCurrentApproverSiret(
const currentApproverOrgId = await getCurrentApproverOrgId(
user,
revisionRequest
);

const approval = revisionRequest.approvals.find(
approval => approval.approverSiret === currentApproverSiret
approval => approval.approverSiret === currentApproverOrgId
);

if (!approval) {
throw new Error(
`No approval found for current approver siret ${currentApproverSiret}`
`No approval found for current approver siret ${currentApproverOrgId}`
);
}

Expand Down Expand Up @@ -91,7 +92,7 @@ export default async function submitFormRevisionRequestApproval(
return formRepository.getRevisionRequestById(id);
}

async function getCurrentApproverSiret(
async function getCurrentApproverOrgId(
user: User,
revisionRequest: BsddRevisionRequestWithApprovals
) {
Expand All @@ -101,7 +102,7 @@ async function getCurrentApproverSiret(

const userCompanies = await getUserCompanies(user.id);
const approvingCompaniesCandidates = userCompanies.filter(
company => company.siret && remainingApproverSirets.includes(company.siret)
company => company.orgId && remainingApproverSirets.includes(company.orgId)
);

if (approvingCompaniesCandidates.length === 0) {
Expand All @@ -110,5 +111,5 @@ async function getCurrentApproverSiret(
);
}

return approvingCompaniesCandidates[0].siret;
return approvingCompaniesCandidates[0].orgId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,60 @@ describe("Mutation.formRevisionRequests", () => {
expect(data.formRevisionRequests.pageInfo.hasNextPage).toBe(false);
});

it("should return revision request of foreign transporter", async () => {
const vatNumber = "IT13029381004";
const { user, company: foreignTransporter } = await userWithCompanyFactory(
"ADMIN",
{ siret: null, vatNumber, orgId: vatNumber }
);
const { company: emitterCompany } = await userWithCompanyFactory("ADMIN");
const { company: destinationCompany } = await userWithCompanyFactory(
"ADMIN"
);

const { query } = makeClient(user);

const bsdd = await formFactory({
ownerId: user.id,
opt: {
emitterType: "APPENDIX1_PRODUCER",
emitterCompanySiret: emitterCompany.siret,
recipientCompanySiret: destinationCompany.siret,
transporters: {
create: {
number: 1,
transporterCompanySiret: null,
transporterCompanyVatNumber: foreignTransporter.vatNumber
}
}
}
});

await prisma.bsddRevisionRequest.create({
data: {
bsddId: bsdd.id,
authoringCompanyId: foreignTransporter.id,
approvals: {
createMany: {
data: [{ approverSiret: emitterCompany.siret! }]
}
},
comment: ""
}
});

const { data, errors } = await query<Pick<Query, "formRevisionRequests">>(
FORM_REVISION_REQUESTS,
{
variables: { siret: foreignTransporter.vatNumber }
}
);

expect(errors).toBeUndefined();

expect(data.formRevisionRequests.totalCount).toBe(1);
});

it("should list every revisionRequest related to eco-organismes", async () => {
const { user, company } = await userWithCompanyFactory("ADMIN");
const { company: otherCompany } = await userWithCompanyFactory("ADMIN");
Expand Down
Loading

0 comments on commit 8b9f4a5

Please sign in to comment.