Skip to content

Commit bbe3ce4

Browse files
authored
fix(prélèvements): corrige les champs type de production et type de culture pour la campagne 2026 (#559)
1 parent 4fcfa46 commit bbe3ce4

File tree

11 files changed

+98
-74
lines changed

11 files changed

+98
-74
lines changed

frontend/src/components/Sample/SampleProcedure/SampleProcedure.tsx

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ interface Props {
1313
}
1414

1515
const SampleProcedure = ({ partialSample }: Props) => {
16-
if (partialSample.specificData.programmingPlanKind === 'PPV') {
17-
return <></>;
18-
}
19-
2016
return (
2117
<div
2218
className={clsx(
@@ -36,47 +32,65 @@ const SampleProcedure = ({ partialSample }: Props) => {
3632
></span>
3733
Modalités d'échantillonnage
3834
</h6>
39-
<div className={cx('fr-grid-row', 'fr-grid-row--gutters')}>
40-
<div className={cx('fr-col-12', 'fr-col-md-6')}>
41-
<div className={cx('fr-my-1v')}>
42-
<b>Contenant en plastique</b>
43-
</div>
44-
<div className={cx('fr-my-1v')}>
45-
Température : <b>-18° </b>
46-
</div>
47-
<div className={cx('fr-my-1v')}>
48-
Délais max. avant analyse : <b>30 jours</b>
35+
{partialSample.specificData.programmingPlanKind !== 'PPV' && (
36+
<>
37+
<div className={cx('fr-grid-row', 'fr-grid-row--gutters')}>
38+
<div className={cx('fr-col-12', 'fr-col-md-6')}>
39+
<div className={cx('fr-my-1v')}>
40+
<b>Contenant en plastique</b>
41+
</div>
42+
<div className={cx('fr-my-1v')}>
43+
Température : <b>-18° </b>
44+
</div>
45+
<div className={cx('fr-my-1v')}>
46+
Délais max. avant analyse : <b>30 jours</b>
47+
</div>
48+
</div>
49+
<div
50+
className={clsx(cx('fr-col-12', 'fr-col-md-6'), 'border-left')}
51+
>
52+
<div className={cx('fr-my-1v')}>
53+
Matière prélevée :{' '}
54+
<b>
55+
{partialSample.specificData.programmingPlanKind ===
56+
'DAOA_SLAUGHTER'
57+
? 'Foie de bovin'
58+
: 'Muscle de volaille'}
59+
</b>
60+
</div>
61+
<div className={cx('fr-my-1v')}>
62+
Quantité par échantillon : <b>200 grammes</b>
63+
</div>
64+
</div>
4965
</div>
50-
</div>
51-
<div className={clsx(cx('fr-col-12', 'fr-col-md-6'), 'border-left')}>
52-
<div className={cx('fr-my-1v')}>
53-
Matière prélevée :{' '}
54-
<b>
55-
{partialSample.specificData.programmingPlanKind ===
56-
'DAOA_SLAUGHTER'
57-
? 'Foie de bovin'
58-
: 'Muscle de volaille'}
59-
</b>
60-
</div>
61-
<div className={cx('fr-my-1v')}>
62-
Quantité par échantillon : <b>200 grammes</b>
66+
<hr className={cx('fr-my-3w')} />
67+
<div>
68+
<span className={cx('fr-mr-1w')}>Analyses prévues</span>
69+
<Tag className={cx('fr-mx-1w')}>Mono-résidus</Tag>
70+
<Tag className={cx('fr-mx-1w')}>Multi-résidus</Tag>
71+
<Tag className={cx('fr-mx-1w')}>Cuivre</Tag>
6372
</div>
64-
</div>
65-
</div>
66-
<hr className={cx('fr-my-3w')} />
67-
<div>
68-
<span className={cx('fr-mr-1w')}>Analyses prévues</span>
69-
<Tag className={cx('fr-mx-1w')}>Mono-résidus</Tag>
70-
<Tag className={cx('fr-mx-1w')}>Multi-résidus</Tag>
71-
<Tag className={cx('fr-mx-1w')}>Cuivre</Tag>
72-
</div>
73+
</>
74+
)}
7375
<div className={cx('fr-mt-3v')}>
7476
<span className={cx('fr-mr-1w')}>Réglementation</span>
7577
<DocumentLink
7678
documentId={config.documents.regulation201862}
7779
iconId="fr-icon-external-link-line"
7880
/>
7981
</div>
82+
{partialSample.specificData.programmingPlanKind === 'PPV' && (
83+
<div>
84+
<hr className={cx('fr-my-3w')} />
85+
<span className={cx('fr-mr-1w')}>Analyses prévues</span>
86+
{partialSample.monoSubstances && (
87+
<Tag className={cx('fr-mx-1w')}>Mono-résidus</Tag>
88+
)}
89+
{partialSample.multiSubstances && (
90+
<Tag className={cx('fr-mx-1w')}>Multi-résidus</Tag>
91+
)}
92+
</div>
93+
)}
8094
</div>
8195
);
8296
};

server/services/csvService/csvService.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const data: AnalysisRequestData = {
5454
specificData: {
5555
programmingPlanKind: 'PPV',
5656
matrixPart: 'PART1',
57+
productionKind: 'PD07A',
5758
cultureKind: 'PD05A',
5859
matrixDetails: ''
5960
},
@@ -89,6 +90,7 @@ test('génère un CSV', async () => {
8990
Matrice;;A031K
9091
LMR/ Partie du végétal concernée;
9192
Détails de la matrice;
93+
Type de production;
9294
Type de culture;
9395
Stade de prélèvement;
9496
@@ -132,6 +134,7 @@ test('génère un CSV avec le BOM pour Girpa', async () => {
132134
Matrice;;A031K
133135
LMR/ Partie du végétal concernée;
134136
Détails de la matrice;
137+
Type de production;
135138
Type de culture;
136139
Stade de prélèvement;
137140

server/services/csvService/csvService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const generateAnalysisRequestCsv = async (data: AnalysisRequestData) => {
3535
? data.specificData?.matrixDetails
3636
: undefined
3737
)}`,
38+
`Type de production;${escapeCsvValue(data.productionKind)}`,
3839
`Type de culture;${escapeCsvValue(data.cultureKind)}`,
3940
`Stade de prélèvement;${escapeCsvValue(data.stage)}`,
4041
`${data.specificData?.programmingPlanKind === 'PPV' && data.specificData?.releaseControl ? 'Type de contrôle;Contrôle libératoire' : ''}`,

shared/referential/CultureKind.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,20 @@
11
import { z } from 'zod';
22
import { PartialSample } from '../schema/Sample/Sample';
3-
const CultureKindDeprecated = z.enum([
4-
'Z0211',
5-
'PD06A',
6-
'PD08A',
7-
'Z0216',
8-
'Z0153',
9-
'PD05A'
10-
]);
11-
const CultureKindEffective = z.enum(['PD07A', 'PD09A', 'Z0215']);
123
export const CultureKind = z.enum(
13-
[...CultureKindDeprecated.options, ...CultureKindEffective.options],
4+
['Z0211', 'PD06A', 'PD08A', 'Z0215', 'Z0153', 'PD05A'],
145
{
156
error: () => 'Veuillez renseigner le type de culture.'
167
}
178
);
189

1910
export type CultureKind = z.infer<typeof CultureKind>;
2011

21-
export const CultureKindList: CultureKind[] = CultureKindEffective.options;
12+
export const CultureKindList: CultureKind[] = CultureKind.options;
2213

2314
export const CultureKindLabels: Record<CultureKind, string> = {
2415
Z0211: 'Sous serre/conditions de croissance protégées',
2516
PD06A: 'Production traditionnelle',
2617
PD08A: 'Production industrielle intensive',
27-
PD07A: 'Production biologique',
28-
Z0216: 'Autre méthode de production',
29-
PD09A: 'Production non biologique',
3018
Z0215: 'Méthode inconnue',
3119
Z0153: 'Sauvages ou cueillis',
3220
PD05A: 'Production en plein air'
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import { z } from 'zod';
22

3-
export const ProductionKind = z.enum(['PROD_1', 'PROD_2', 'PROD_3', 'PROD_4'], {
4-
error: () => 'Veuillez renseigner le type de production.'
5-
});
3+
export const ProductionKind = z.enum(
4+
['PROD_1', 'PROD_2', 'PROD_3', 'PROD_4', 'PD07A', 'Z0216', 'PD09A'],
5+
{
6+
error: () => 'Veuillez renseigner le type de production.'
7+
}
8+
);
69

710
export type ProductionKind = z.infer<typeof ProductionKind>;
811

912
export const ProductionKindLabels: Record<ProductionKind, string> = {
1013
PROD_1: 'Allaitant',
1114
PROD_2: 'Laitier',
1215
PROD_3: 'Inconnu',
13-
PROD_4: 'Boucherie'
16+
PROD_4: 'Boucherie',
17+
PD07A: 'Production biologique',
18+
Z0216: 'Autre méthode de production',
19+
PD09A: 'Production non biologique'
1420
};

shared/schema/Analysis/AnalysisRequestData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const AnalysisRequestData = z.object({
2727
matrixLabel: z.string(),
2828
matrixPart: z.string(),
2929
quantityUnit: z.string(),
30+
productionKind: z.string().nullish(),
3031
cultureKind: z.string().nullish(),
3132
compliance200263: z.string(),
3233
establishment: z.object({

shared/schema/Analysis/Residue/Residue.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ test('sampleResidueLmrIsValid', () => {
77
stage: 'STADE1',
88
reference: 'RF-0847-001-PPP',
99
specificData: {
10-
cultureKind: 'PD06A',
10+
productionKind: 'PD07A',
1111
programmingPlanKind: 'PPV',
1212
matrixPart: 'PART1'
1313
},
@@ -20,7 +20,7 @@ test('sampleResidueLmrIsValid', () => {
2020
stage: 'STADE1',
2121
reference: 'RF-0847-001-PPP',
2222
specificData: {
23-
cultureKind: 'PD06A',
23+
productionKind: 'PD07A',
2424
programmingPlanKind: 'PPV',
2525
matrixPart: 'PART1'
2626
},
@@ -33,7 +33,7 @@ test('sampleResidueLmrIsValid', () => {
3333
stage: 'STADE1',
3434
reference: 'RF-0847-001-PPP',
3535
specificData: {
36-
cultureKind: 'PD06A',
36+
productionKind: 'PD07A',
3737
programmingPlanKind: 'PPV',
3838
matrixPart: 'PART1'
3939
},
@@ -46,7 +46,7 @@ test('sampleResidueLmrIsValid', () => {
4646
stage: 'STADE1',
4747
reference: 'RF-0847-001-PPP',
4848
specificData: {
49-
cultureKind: 'PD06A',
49+
productionKind: 'PD07A',
5050
programmingPlanKind: 'PPV',
5151
matrixPart: 'PART1'
5252
},
@@ -59,7 +59,7 @@ test('sampleResidueLmrIsValid', () => {
5959
stage: 'STADE2',
6060
reference: 'RF-0847-001-PPP',
6161
specificData: {
62-
cultureKind: 'PD06A',
62+
productionKind: 'PD07A',
6363
programmingPlanKind: 'PPV',
6464
matrixPart: 'PART1'
6565
},
@@ -72,7 +72,7 @@ test('sampleResidueLmrIsValid', () => {
7272
stage: 'STADE2',
7373
reference: 'RF-0847-001-PPP',
7474
specificData: {
75-
cultureKind: 'PD06A',
75+
productionKind: 'PD07A',
7676
programmingPlanKind: 'PPV',
7777
matrixPart: 'PART1'
7878
},
@@ -85,7 +85,7 @@ test('sampleResidueLmrIsValid', () => {
8585
stage: 'STADE2',
8686
reference: 'RF-0847-001-PPP',
8787
specificData: {
88-
cultureKind: 'PD06A',
88+
productionKind: 'PD07A',
8989
programmingPlanKind: 'PPV',
9090
matrixPart: 'PART1'
9191
},
@@ -98,7 +98,7 @@ test('sampleResidueLmrIsValid', () => {
9898
stage: 'STADE1',
9999
reference: 'RF-0847-001-PPP',
100100
specificData: {
101-
cultureKind: 'PD06A',
101+
productionKind: 'PD07A',
102102
programmingPlanKind: 'PPV',
103103
matrixPart: 'PART2'
104104
},
@@ -111,7 +111,7 @@ test('sampleResidueLmrIsValid', () => {
111111
stage: 'STADE1',
112112
reference: 'RF-0847-001-PPP',
113113
specificData: {
114-
cultureKind: 'PD06A',
114+
productionKind: 'PD07A',
115115
programmingPlanKind: 'PPV',
116116
matrixPart: 'PART2'
117117
},
@@ -124,7 +124,7 @@ test('sampleResidueLmrIsValid', () => {
124124
stage: 'STADE1',
125125
reference: 'RF-0847-001-PPP',
126126
specificData: {
127-
cultureKind: 'PD06A',
127+
productionKind: 'PD07A',
128128
programmingPlanKind: 'PPV',
129129
matrixPart: 'PART2'
130130
},
@@ -137,7 +137,7 @@ test('sampleResidueLmrIsValid', () => {
137137
stage: 'STADE2',
138138
reference: 'RF-0847-001-PPP',
139139
specificData: {
140-
cultureKind: 'PD06A',
140+
productionKind: 'PD07A',
141141
programmingPlanKind: 'PPV',
142142
matrixPart: 'PART2'
143143
},
@@ -150,7 +150,7 @@ test('sampleResidueLmrIsValid', () => {
150150
stage: 'STADE2',
151151
reference: 'RF-0847-001-PPP',
152152
specificData: {
153-
cultureKind: 'PD06A',
153+
productionKind: 'PD07A',
154154
programmingPlanKind: 'PPV',
155155
matrixPart: 'PART2'
156156
},
@@ -163,7 +163,7 @@ test('sampleResidueLmrIsValid', () => {
163163
stage: 'STADE2',
164164
reference: 'RF-0847-001-PPP',
165165
specificData: {
166-
cultureKind: 'PD06A',
166+
productionKind: 'PD07A',
167167
programmingPlanKind: 'PPV',
168168
matrixPart: 'PART2'
169169
},
@@ -177,7 +177,7 @@ test('lmr can be optional for some reference', () => {
177177
const sampleWithRequiredLmr = {
178178
stage: 'STADE1',
179179
specificData: {
180-
cultureKind: 'PD06A',
180+
productionKind: 'PD07A',
181181
programmingPlanKind: 'PPV',
182182
matrixPart: 'PART1'
183183
},

shared/schema/MatrixSpecificData/MatrixSpecificDataForm.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const MatrixSpecificDataForm: {
2424
PPV: {
2525
matrixDetails: { classes: { container: ['fr-col-sm-12', 'fr-pt-3w'] } },
2626
cultureKind: {},
27+
productionKind: {},
2728
matrixPart: {},
2829
releaseControl: {}
2930
},

shared/schema/Sample/SampleMatrixSpecificData.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, test } from 'vitest';
2-
import { CultureKind } from '../../referential/CultureKind';
2+
import { CultureKindList } from '../../referential/CultureKind';
33
import { ProgrammingPlanKind } from '../ProgrammingPlan/ProgrammingPlanKind';
44
import { getSampleMatrixSpecificDataAttributeValues } from './SampleMatrixSpecificData';
55

@@ -9,7 +9,7 @@ describe('getSampleMatrixSpecificDataAttributeValues', () => {
99
ProgrammingPlanKind.enum.PPV,
1010
'cultureKind'
1111
);
12-
expect(result).toBe(CultureKind.options);
12+
expect(result).toBe(CultureKindList);
1313
});
1414

1515
test('returns null for matrixDetails (string field without options)', () => {

shared/schema/Sample/SampleMatrixSpecificData.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { z, ZodType } from 'zod';
33
import { AnimalKind } from '../../referential/AnimalKind';
44
import { AnimalSex } from '../../referential/AnimalSex';
55
import { BreedingMethod } from '../../referential/BreedingMethod';
6-
import { CultureKind } from '../../referential/CultureKind';
6+
import { CultureKind, CultureKindList } from '../../referential/CultureKind';
77
import { MatrixPart } from '../../referential/Matrix/MatrixPart';
88
import { OutdoorAccess } from '../../referential/OutdoorAccess';
99
import { ProductionKind } from '../../referential/ProductionKind';
@@ -47,7 +47,8 @@ const AnimalAgeInMonths = z.coerce
4747
const SampleMatrixSpecificDataPPV = z.object({
4848
programmingPlanKind: z.literal(ProgrammingPlanKind.enum.PPV),
4949
matrixDetails: z.string().nullish(),
50-
cultureKind: CultureKind,
50+
cultureKind: CultureKind.nullish(),
51+
productionKind: ProductionKind.extract(['PD07A', 'PD09A', 'Z0216']),
5152
matrixPart: MatrixPart,
5253
releaseControl: z.boolean().nullish()
5354
});
@@ -153,6 +154,10 @@ export const getSampleMatrixSpecificDataAttributeValues = (
153154
return [];
154155
}
155156

157+
if (attributeName === 'cultureKind') {
158+
return CultureKindList;
159+
}
160+
156161
if ('options' in fieldSchema && Array.isArray(fieldSchema.options)) {
157162
return fieldSchema.options;
158163
}

0 commit comments

Comments
 (0)