Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TRA 14872] - Paramètre d'affichage des BSDs DND dans les exports #3988

Merged
merged 3 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ et le projet suit un schéma de versionning inspiré de [Calendar Versioning](ht
#### :rocket: Nouvelles fonctionnalités

- Permet l'ajout du volume et des numéros d'identification sur le BSDD partout où le formulaire de conditionnement apparait (création, modification, bordereau suite, signature émetteur/transporteur, révision) & Passage du formulaire conditionnement au DSFR [PR 3936](https://github.com/MTES-MCT/trackdechets/pull/3936).
- Ajout de l'export du registre sortant V2 [PR 3976](https://github.com/MTES-MCT/trackdechets/pull/3976)
- Ajout d'un paramètre pour les établissements souhaitant pousser automatiquement leurs BSDND dans leurs déclarations [PR3988](https://github.com/MTES-MCT/trackdechets/pull/3988)

#### :nail_care: Améliorations

Expand Down
5 changes: 3 additions & 2 deletions back/src/companies/resolvers/Mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import toggleDormantCompany from "./mutations/toggleDormantCompany";
import { createAdministrativeTransfer } from "./mutations/createAdministrativeTransfer";
import { cancelAdministrativeTransfer } from "./mutations/cancelAdministrativeTransfer";
import { submitAdministrativeTransferApproval } from "./mutations/submitAdministrativeTransferApproval";

import enableRegistryDndFromBsd from "./mutations/enableRegistryDndFromBsd";
const Mutation: MutationResolvers = {
createCompany,
renewSecurityCode,
Expand Down Expand Up @@ -66,7 +66,8 @@ const Mutation: MutationResolvers = {
toggleDormantCompany,
createAdministrativeTransfer,
cancelAdministrativeTransfer,
submitAdministrativeTransferApproval
submitAdministrativeTransferApproval,
enableRegistryDndFromBsd
};

export default Mutation;
39 changes: 39 additions & 0 deletions back/src/companies/resolvers/mutations/enableRegistryDndFromBsd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { MutationResolvers } from "@td/codegen-back";
import { prisma } from "@td/prisma";
import { applyAuthStrategies, AuthType } from "../../../auth";
import { checkIsAuthenticated } from "../../../common/permissions";
import { getCompanyOrCompanyNotFound } from "../../database";
import { checkUserPermissions, Permission } from "../../../permissions";
import {
ForbiddenError,
NotCompanyAdminErrorMsg
} from "../../../common/errors";
import { toGqlCompanyPrivate } from "../../converters";

const enableRegistryDndFromBsdResolver: MutationResolvers["enableRegistryDndFromBsd"] =
async (parent, args, context) => {
const authStrategies = [AuthType.Session];
applyAuthStrategies(context, authStrategies);
const user = checkIsAuthenticated(context);
const existingCompany = await getCompanyOrCompanyNotFound({ id: args.id });
await checkUserPermissions(
user,
existingCompany.orgId,
Permission.CompanyCanUpdate,
NotCompanyAdminErrorMsg(existingCompany.orgId)
);
if (existingCompany.hasEnabledRegistryDndFromBsdSince) {
throw new ForbiddenError(
"Cette entreprise a déjà activé la traçabilité des déchets non dangereux dans le registre."
);
}
const updatedCompany = await prisma.company.update({
where: { id: existingCompany.id },
data: {
hasEnabledRegistryDndFromBsdSince: new Date()
}
});
return toGqlCompanyPrivate(updatedCompany);
};

export default enableRegistryDndFromBsdResolver;
6 changes: 6 additions & 0 deletions back/src/companies/typeDefs/company.mutations.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,10 @@ type Mutation {
createAnonymousCompanyFromPDF(
input: CreateAnonymousCompanyFromPDFInput!
): Boolean

"""
Permet d'activer la prise en compte des BSDs de déchet non dangereux dans les exports de registre
ATTENTION: CETTE ACTION EST NON RÉVERSIBLE
"""
enableRegistryDndFromBsd(id: String!): CompanyPrivate!
}
9 changes: 8 additions & 1 deletion back/src/companies/typeDefs/company.objects.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,18 @@ type CompanyPrivate {
featureFlags: [String]!

"""
Date depuis partir de laquelle l'entreprise est en sommeil sur Trackdéchets.
Date depuis laquelle l'entreprise est en sommeil sur Trackdéchets.
Vide si l'entreprise n'est pas en sommeil.
"""
isDormantSince: DateTime

"""
Date à partir de laquelle l'entreprise a choisi de prendre en compte
ses BSD de déchet non dangereux dans les exports de registres
Vide si l'entreprise n'a pas fait ce choix.
"""
hasEnabledRegistryDndFromBsdSince: DateTime

"""
Liste des transferts administratifs initiés par l'établissement
"""
Expand Down
75 changes: 71 additions & 4 deletions back/src/queue/jobs/processRegistryExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,78 @@ export async function processRegistryExportJob(
});
upload = streamInfos.upload;
const outputStream = streamInfos.s3Stream;

let condition: Prisma.RegistryLookupWhereInput;
// if there is a chance that DND BSDs are in the export
if (
(!registryExport.wasteTypes?.length ||
registryExport.wasteTypes.some(wasteType => wasteType === "DND")) && // the user wants DNDs in the export
registryExport.declarationType !== "REGISTRY" && // the user only wants BSDs in the export
registryExport.registryType !== "SSD" // the user doesn't want a RNDTS declaration only registry
) {
const companies = await prisma.company.findMany({
where: {
orgId: {
in: registryExport.sirets
}
},
select: {
orgId: true,
hasEnabledRegistryDndFromBsdSince: true
}
});
// create a pre-filter that hides DND BSDs pre-hasEnabledRegistryDndFromBsdSince if it's defined for a company
const orCondition = companies.map(company => {
if (company.hasEnabledRegistryDndFromBsdSince) {
return {
siret: company.orgId,
OR: [
{
declarationType: "REGISTRY"
},
{
wasteType: { in: ["DD", "TEXS"] },
declarationType: "BSD"
},
{
wasteType: "DND",
declarationType: "BSD",
date: {
gte: company.hasEnabledRegistryDndFromBsdSince
}
}
]
} as Prisma.RegistryLookupWhereInput;
} else {
// the company has not enabled DND BSDs, so we always hide them
return {
siret: company.orgId,
OR: [
{
declarationType: "REGISTRY"
},
{
wasteType: { in: ["DD", "TEXS"] },
declarationType: "BSD"
}
]
} as Prisma.RegistryLookupWhereInput;
}
});
condition = {
OR: orCondition
};
} else {
// we know this export will not contain DND BSDs, so we don't need a pre-filter
condition = {
siret: {
in: registryExport.sirets
}
};
}
//craft the query
const query: Prisma.RegistryLookupFindManyArgs["where"] = {
siret: {
in: registryExport.sirets
},
const query: Prisma.RegistryLookupWhereInput = {
...condition,
reportAsSiret: registryExport.delegateSiret ?? undefined,
exportRegistryType: registryExport.registryType ?? undefined,
wasteType: registryExport.wasteTypes?.length
Expand Down
2 changes: 2 additions & 0 deletions docs/RegistryExportV2.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ registryLookup --> |includes|registrySsd[(RegistrySsd)]
lookup --> |Returns|inputStream>Input Stream]
subgraph Pipeline
direction LR
companies[(Companies)] --> companyCachedFetcher[companyCachedFetcher]
companyCachedFetcher --> transformStream
inputStream2>Input Stream] --> transformStream>Transform Stream]
transformStream --> uploadStream2>Upload Stream]
uploadStream2 --> file@{ shape: doc, label: "Export file" }
Expand Down
10 changes: 5 additions & 5 deletions front/src/Apps/Companies/CompanyDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import CompanyMembers from "./CompanyMembers/CompanyMembers";
import CompanyDigestSheetForm from "./CompanyDigestSheet/CompanyDigestSheet";
import { Tabs, TabsProps } from "@codegouvfr/react-dsfr/Tabs";
import { FrIconClassName } from "@codegouvfr/react-dsfr";
import { CompanyRegistryDelegation } from "./CompanyRegistryDelegation/CompanyRegistryDelegation";
import { CompanyRegistry } from "./CompanyRegistry/CompanyRegistry";

export type TabContentProps = {
company: CompanyPrivate;
Expand Down Expand Up @@ -78,11 +78,11 @@ const buildTabs = (
};
if (canViewRndtsFeatures) {
tabs.push({
tabId: "delegations",
label: "Délégations",
tabId: "registry",
label: "Registre national",
iconId
});
tabsContent["delegations"] = CompanyRegistryDelegation;
tabsContent["registry"] = CompanyRegistry;
}
if (isAdmin) {
tabs.push({
Expand All @@ -108,7 +108,7 @@ export default function CompanyDetails() {
"membres",
"contact",
"fiche",
"delegations",
"registry",
"avance"
].includes(location.hash.substring(1))
? location.hash.substring(1)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import React from "react";
import "./companyRegistryDelegation.scss";
import "./CompanyRegistry.scss";
import { CompanyPrivate } from "@td/codegen-ui";
import { CompanyRegistryDelegationAsDelegator } from "./CompanyRegistryDelegationAsDelegator";
import { CompanyRegistryDelegationAsDelegate } from "./CompanyRegistryDelegationAsDelegate";
import { CompanyRegistryDndFromBsd } from "./CompanyRegistryDndFromBsd";

interface Props {
company: CompanyPrivate;
}

export const CompanyRegistryDelegation = ({ company }: Props) => {
export const CompanyRegistry = ({ company }: Props) => {
return (
<>
<CompanyRegistryDelegationAsDelegator company={company} />
<CompanyRegistryDelegationAsDelegate company={company} />
<CompanyRegistryDndFromBsd company={company} />
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import "./companyRegistryDelegation.scss";
import "./CompanyRegistry.scss";
import { CompanyPrivate } from "@td/codegen-ui";
import { RegistryDelegationsTable } from "./RegistryDelegationsTable";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from "react";
import "./companyRegistryDelegation.scss";
import "./CompanyRegistry.scss";
import { CompanyPrivate, UserRole } from "@td/codegen-ui";
import Button from "@codegouvfr/react-dsfr/Button";
import { CreateRegistryDelegationModal } from "./CreateRegistryDelegationModal";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.fr-list {
list-style-type: var(--ul-type);
padding-inline-start: var(--ul-start);
}

.dnd-from-bsd-confirmation-modal {
.fr-modal__title {
display: flex;
align-items: center;
gap: 6px;
.fr-icon-warning-line::before {
background-color: var(--text-default-error);
}
}
}

.custom-modal-header {
display: flex;
align-items: center;
gap: 6px;
}

.danger-button {
background-color: var(--text-default-error);
}
Loading