From 86b6eb9acf66cf96f60c9bef67c8ab2e7dd37cf0 Mon Sep 17 00:00:00 2001 From: Julien Seren-Rosso Date: Thu, 16 May 2024 17:02:50 +0200 Subject: [PATCH 1/2] Fixes companies verification button (#3333) --- front/src/Apps/Companies/CompanyInfo/CompanyInfo.tsx | 12 ++++++++++++ .../Companies/CompanyInfo/CompanyProfileForm.tsx | 11 ----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/front/src/Apps/Companies/CompanyInfo/CompanyInfo.tsx b/front/src/Apps/Companies/CompanyInfo/CompanyInfo.tsx index 3692efdae4..94ef24374d 100644 --- a/front/src/Apps/Companies/CompanyInfo/CompanyInfo.tsx +++ b/front/src/Apps/Companies/CompanyInfo/CompanyInfo.tsx @@ -2,19 +2,31 @@ import { CompanyPrivate } from "@td/codegen-ui"; import React from "react"; import CompanyIdentificationForm from "./CompanyIdentificationForm"; import CompanyProfileForm from "./CompanyProfileForm"; +import AccountFieldCompanyVerificationStatus from "../../Account/fields/AccountFieldCompanyVerificationStatus"; +import { PROFESSIONALS } from "@td/constants"; + import "./companyInfo.scss"; +const { VITE_VERIFY_COMPANY } = import.meta.env; + interface CompanyInfoProps { company: CompanyPrivate; } const CompanyInfo = ({ company }: CompanyInfoProps) => { + const isWasteProfessional = company.companyTypes.some(ct => + PROFESSIONALS.includes(ct) + ); + return (


+ {isWasteProfessional && VITE_VERIFY_COMPANY === "true" && ( + + )}
); }; diff --git a/front/src/Apps/Companies/CompanyInfo/CompanyProfileForm.tsx b/front/src/Apps/Companies/CompanyInfo/CompanyProfileForm.tsx index 305619eb9e..f2e0287469 100644 --- a/front/src/Apps/Companies/CompanyInfo/CompanyProfileForm.tsx +++ b/front/src/Apps/Companies/CompanyInfo/CompanyProfileForm.tsx @@ -42,12 +42,8 @@ import { gql, useMutation } from "@apollo/client"; import { Loader } from "../../common/Components"; import CompanyProfileSubForm from "./CompanyProfileSubForm"; import { NotificationError } from "../../common/Components/Error/Error"; -import AccountFieldCompanyVerificationStatus from "../../Account/fields/AccountFieldCompanyVerificationStatus"; -import { PROFESSIONALS } from "@td/constants"; import CompanyProfileInformation from "./CompanyProfileInformation"; -const { VITE_VERIFY_COMPANY } = import.meta.env; - interface CompanyProfileFormProps { company: CompanyPrivate; } @@ -660,10 +656,6 @@ const CompanyProfileForm = ({ company }: CompanyProfileFormProps) => { updateCompanyWorkerCertifError || deleteErrorWorkerCertif; - const isWasteProfessional = company.companyTypes.some(ct => - PROFESSIONALS.includes(ct) - ); - return ( { ); })} - {isWasteProfessional && VITE_VERIFY_COMPANY === "true" && ( - - )} {loading && } {error && } From 2dce15de1fbc420394855bbafcb8179b38fe697e Mon Sep 17 00:00:00 2001 From: Laurent Paoletti Date: Mon, 20 May 2024 11:06:52 +0200 Subject: [PATCH 2/2] Fix annexe2 grouping issues (#3335) --- .../repository/form/updateAppendix2Forms.ts | 9 +- .../__tests__/markAsProcessed.integration.ts | 94 +++++++++++++++--- .../__tests__/markAsSealed.integration.ts | 95 +++++++++++++++++++ 3 files changed, 184 insertions(+), 14 deletions(-) diff --git a/back/src/forms/repository/form/updateAppendix2Forms.ts b/back/src/forms/repository/form/updateAppendix2Forms.ts index 6ddd3e6cc9..b93a14cda9 100644 --- a/back/src/forms/repository/form/updateAppendix2Forms.ts +++ b/back/src/forms/repository/form/updateAppendix2Forms.ts @@ -11,6 +11,8 @@ type FormForUpdateAppendix2Forms = Form & FormWithForwardedIn; export const FormForUpdateAppendix2FormsInclude = FormWithForwardedInInclude; +const DECIMAL_WEIGHT_PRECISION = 6; // gramme + export type UpdateAppendix2Forms = ( forms: FormForUpdateAppendix2Forms[] ) => Promise; @@ -46,7 +48,7 @@ const buildUpdateAppendix2Forms: ( .filter(grp => grp.initialFormId === form.id) .map(grp => grp.quantity) .reduce((prev, cur) => prev + cur, 0) ?? 0 - ).toDecimalPlaces(6); // set precision to gramme + ).toDecimalPlaces(DECIMAL_WEIGHT_PRECISION); // set precision to gramme quantitGroupedByFormId[form.id] = quantityGrouped.toNumber(); @@ -54,9 +56,12 @@ const buildUpdateAppendix2Forms: ( .filter(grp => grp.initialFormId === form.id) .map(g => g.nextForm); + // on a quelques quantityReceived avec des décimales au delà du gramme const groupedInTotality = quantityReceived && - quantityGrouped.greaterThanOrEqualTo(quantityReceived); // case > should not happen + quantityGrouped.greaterThanOrEqualTo( + new Decimal(quantityReceived).toDecimalPlaces(DECIMAL_WEIGHT_PRECISION) // limit precision to circumvent rogue decimal digits + ); // case > should not happen const allSealed = groupementForms.length && diff --git a/back/src/forms/resolvers/mutations/__tests__/markAsProcessed.integration.ts b/back/src/forms/resolvers/mutations/__tests__/markAsProcessed.integration.ts index 056668bc98..3c2660c620 100644 --- a/back/src/forms/resolvers/mutations/__tests__/markAsProcessed.integration.ts +++ b/back/src/forms/resolvers/mutations/__tests__/markAsProcessed.integration.ts @@ -869,28 +869,44 @@ describe("mutation.markAsProcessed", () => { }); expect(updatedGroupedForm2.status).toEqual("PROCESSED"); }); - - it("should not mark appendix2 forms as processed if they are partially grouped", async () => { + it("should mark appendix2 forms as processed despite rogue decimal digits", async () => { const { user, company } = await userWithCompanyFactory("ADMIN"); - const appendix2 = await formFactory({ + const groupedForm1 = await formFactory({ ownerId: user.id, opt: { - status: "AWAITING_GROUP", - quantityReceived: 1 + status: "GROUPED", + quantityReceived: 1.000000000000001 // decimal digits after 6th place + } + }); + + // it should also work for BSD with temporary storage + const groupedForm2 = await formWithTempStorageFactory({ + ownerId: user.id, + opt: { + status: "GROUPED", + quantityReceived: 0.02 } }); + const form = await formFactory({ ownerId: user.id, opt: { status: "ACCEPTED", + emitterType: "APPENDIX2", recipientCompanyName: company.name, recipientCompanySiret: company.siret, grouping: { - create: { - initialFormId: appendix2.id, - quantity: 0.1 - } + create: [ + { + initialFormId: groupedForm1.id, + quantity: 1 + }, + { + initialFormId: groupedForm2.id, + quantity: groupedForm2.forwardedIn!.quantityReceived!.toNumber() + } + ] } } }); @@ -910,12 +926,66 @@ describe("mutation.markAsProcessed", () => { } }); - const appendix2grouped = await prisma.form.findUniqueOrThrow({ - where: { id: appendix2.id } + const updatedGroupedForm1 = await prisma.form.findUniqueOrThrow({ + where: { id: groupedForm1.id } }); - expect(appendix2grouped.status).toEqual("AWAITING_GROUP"); + expect(updatedGroupedForm1.status).toEqual("PROCESSED"); + + const updatedGroupedForm2 = await prisma.form.findUniqueOrThrow({ + where: { id: groupedForm2.id } + }); + expect(updatedGroupedForm2.status).toEqual("PROCESSED"); }); + it.each([0.1, 1])( + "should not mark appendix2 forms as processed if they are partially grouped - quantity grouped: %p", + async quantityGrouped => { + const { user, company } = await userWithCompanyFactory("ADMIN"); + + const appendix2 = await formFactory({ + ownerId: user.id, + opt: { + status: "AWAITING_GROUP", + quantityReceived: 1.0000001 + } + }); + const form = await formFactory({ + ownerId: user.id, + opt: { + status: "ACCEPTED", + recipientCompanyName: company.name, + recipientCompanySiret: company.siret, + grouping: { + create: { + initialFormId: appendix2.id, + quantity: quantityGrouped + } + } + } + }); + + const { mutate } = makeClient(user); + + await mutate(MARK_AS_PROCESSED, { + variables: { + id: form.id, + processedInfo: { + processingOperationDescription: "Une description", + processingOperationDone: "D 1", + destinationOperationMode: OperationMode.ELIMINATION, + processedBy: "A simple bot", + processedAt: "2018-12-11T00:00:00.000Z" + } + } + }); + + const appendix2grouped = await prisma.form.findUniqueOrThrow({ + where: { id: appendix2.id } + }); + expect(appendix2grouped.status).toEqual("AWAITING_GROUP"); + } + ); + test.each(allowedFormats)("%p is a valid format for processedAt", async f => { const { user, company } = await userWithCompanyFactory("ADMIN"); const form = await formFactory({ diff --git a/back/src/forms/resolvers/mutations/__tests__/markAsSealed.integration.ts b/back/src/forms/resolvers/mutations/__tests__/markAsSealed.integration.ts index 59be553e8c..c5dc903292 100644 --- a/back/src/forms/resolvers/mutations/__tests__/markAsSealed.integration.ts +++ b/back/src/forms/resolvers/mutations/__tests__/markAsSealed.integration.ts @@ -727,6 +727,101 @@ describe("Mutation.markAsSealed", () => { expect(updatedGroupedForm2.status).toEqual("GROUPED"); }); + it("should mark appendix2 forms as grouped despite rogue decimal digits", async () => { + const { user, company } = await userWithCompanyFactory("MEMBER"); + const destination = await destinationFactory(); + const groupedForm1 = await formFactory({ + ownerId: user.id, + opt: { status: "AWAITING_GROUP", quantityReceived: 1.000000000000001 } + }); + + const groupedForm2 = await formWithTempStorageFactory({ + ownerId: user.id, + opt: { + status: "GROUPED", + quantityReceived: 0.02 + } + }); + + const form = await formFactory({ + ownerId: user.id, + opt: { + status: "DRAFT", + emitterType: "APPENDIX2", + emitterCompanySiret: company.siret, + recipientCompanySiret: destination.siret, + grouping: { + create: [ + { + initialFormId: groupedForm1.id, + quantity: 1 + }, + { + initialFormId: groupedForm2.id, + quantity: groupedForm2.forwardedIn!.quantityReceived! + } + ] + } + } + }); + + const { mutate } = makeClient(user); + + await mutate(MARK_AS_SEALED, { + variables: { id: form.id } + }); + + const updatedGroupedForm1 = await prisma.form.findUniqueOrThrow({ + where: { id: groupedForm1.id } + }); + expect(updatedGroupedForm1.status).toEqual("GROUPED"); + const updatedGroupedForm2 = await prisma.form.findUniqueOrThrow({ + where: { id: groupedForm2.id } + }); + expect(updatedGroupedForm2.status).toEqual("GROUPED"); + }); + + it.each([0.1, 1])( + "should not mark appendix2 forms as grouped if they are partially grouped - quantity grouped: %p", + async () => { + const { user, company } = await userWithCompanyFactory("MEMBER"); + const destination = await destinationFactory(); + const groupedForm1 = await formFactory({ + ownerId: user.id, + opt: { status: "AWAITING_GROUP", quantityReceived: 1.000001 } + }); + + const form = await formFactory({ + ownerId: user.id, + opt: { + status: "DRAFT", + emitterType: "APPENDIX2", + emitterCompanySiret: company.siret, + recipientCompanySiret: destination.siret, + grouping: { + create: [ + { + initialFormId: groupedForm1.id, + quantity: 0.2 + } + ] + } + } + }); + + const { mutate } = makeClient(user); + + await mutate(MARK_AS_SEALED, { + variables: { id: form.id } + }); + + const updatedGroupedForm1 = await prisma.form.findUniqueOrThrow({ + where: { id: groupedForm1.id } + }); + expect(updatedGroupedForm1.status).toEqual("AWAITING_GROUP"); + } + ); + it("should throw an error if destination is not registered in TD", async () => { const { user, company: emitterCompany } = await userWithCompanyFactory( "MEMBER"