diff --git a/frontend/app/src/domains/production/ProductionController.tsx b/frontend/app/src/domains/production/ProductionController.tsx index c7da641..15d5cc3 100644 --- a/frontend/app/src/domains/production/ProductionController.tsx +++ b/frontend/app/src/domains/production/ProductionController.tsx @@ -1,9 +1,9 @@ import React from 'react' import { useState } from 'react' -import BeefProductionCreator from './views/beefProductionCreator/BeefProductionCreator.tsx' +import BeefProductionCreator from './views/beefProduction/BeefProductionCreator.tsx' import PackageLotsCreator from './views/PackageLotsCreator.tsx' import ProductionsList from './views/ProductionsList.tsx' -import BeefProductionView from './views/BeefProductionView.tsx' +import BeefProductionView from './views/beefProduction/BeefProductionView.tsx' export default function ProductionController() { diff --git a/frontend/app/src/domains/production/components/BeefProductionCard.tsx b/frontend/app/src/domains/production/components/BeefProductionCard.tsx index 19d803a..b1ae780 100644 --- a/frontend/app/src/domains/production/components/BeefProductionCard.tsx +++ b/frontend/app/src/domains/production/components/BeefProductionCard.tsx @@ -52,8 +52,6 @@ export default function BeefProductionCard({ if (showActions) { return - - } } diff --git a/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx b/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx index f87f7ca..ffad0a3 100644 --- a/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx +++ b/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx @@ -74,6 +74,7 @@ export default function PackageLotConfigurator({ packageLot: packageLot, changeC fullWidth variant="standard" margin="normal" + type="number" /> diff --git a/frontend/app/src/domains/production/views/BeefProductionView.tsx b/frontend/app/src/domains/production/views/BeefProductionView.tsx deleted file mode 100644 index a5a1c8d..0000000 --- a/frontend/app/src/domains/production/views/BeefProductionView.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Typography, ButtonGroup, Button, Tab, Tabs } from '@mui/material' -import React from 'react' -import { useEffect, useState } from 'react' -import { useKeycloak } from '@react-keycloak/web' -import { ApiBuilder } from '../../../api/ApiBuilder.ts' -import BreedingPropertiesForm from './beefProductionCreator/forms/BreedingPropertiesForm.tsx' -import SlaughterPropertiesForm from './beefProductionCreator/forms/SlaughterPropertiesForm.tsx' -import CuttingPropertiesForm from './beefProductionCreator/forms/CuttingPropertiesForm.tsx' -import TabContext from '@mui/lab/TabContext'; -import TabList from '@mui/lab/TabList'; -import TabPanel from '@mui/lab/TabPanel'; - - -export default function BeefProductionView({ beefProduction: beefProduction, backCallback: backCallback }) { - - const [currentTab, setCurrentTab] = React.useState(0); - - const changeTab = (event: React.SyntheticEvent, newValue: number) => { - setCurrentTab(newValue); - }; - - - return <> - Abattage bovin - - - - - - - - - - - -
- - - - - -
- -} \ No newline at end of file diff --git a/frontend/app/src/domains/production/views/beefProductionCreator/BeefProductionCreator.tsx b/frontend/app/src/domains/production/views/beefProduction/BeefProductionCreator.tsx similarity index 66% rename from frontend/app/src/domains/production/views/beefProductionCreator/BeefProductionCreator.tsx rename to frontend/app/src/domains/production/views/beefProduction/BeefProductionCreator.tsx index 5933971..902ed01 100644 --- a/frontend/app/src/domains/production/views/beefProductionCreator/BeefProductionCreator.tsx +++ b/frontend/app/src/domains/production/views/beefProduction/BeefProductionCreator.tsx @@ -11,10 +11,12 @@ import { ApiBuilder } from '../../../../api/ApiBuilder.ts' import { useKeycloak } from '@react-keycloak/web' import PackageLotsCreator from "../PackageLotsCreator.tsx" -import BreedingPropertiesForm from "./forms/BreedingPropertiesForm.tsx" -import SlaughterPropertiesForm from "./forms/SlaughterPropertiesForm.tsx" -import CuttingPropertiesForm from "./forms/CuttingPropertiesForm.tsx" +import {BreedingPropertiesForm, mapBreedingFormDataToBeefProduction as mapBreedingFormDataToBeefProduction} from "./forms/BreedingPropertiesForm.tsx" +import SlaughterPropertiesForm, { mapSlaughterFormDataToBeefProduction } from "./forms/SlaughterPropertiesForm.tsx" +import CuttingPropertiesForm, { mapCuttingFormDataToBeefProduction } from "./forms/CuttingPropertiesForm.tsx" import { BeefProductionService } from "../../service/BeefProductionService.ts" +import { useForm } from "react-hook-form" +import dayjs from "dayjs" export default function BeefProductionCreator({ callback }) { @@ -29,6 +31,21 @@ export default function BeefProductionCreator({ callback }) { const [completedSteps, setCompletedSteps] = useState>([]) const apiBuilder = new ApiBuilder() + const breedingPropertiesForm = useForm({defaultValues: { + ...beefProduction, + birthDate: beefProduction.birthDate ? dayjs(beefProduction.birthDate) : undefined + }}) + + const slaughterPropertiesForm = useForm({defaultValues: { + ...beefProduction, + slaughterDate: beefProduction.slaughterDate ? dayjs(beefProduction.slaughterDate) : undefined + }}) + + const cuttingPropertiesForm = useForm({defaultValues: { + ...beefProduction, + cuttingDate: beefProduction.cuttingDate ? dayjs(beefProduction.cuttingDate) : undefined + }}) + return <> Nouvel abattage bovin @@ -38,7 +55,11 @@ export default function BeefProductionCreator({ callback }) { completed={completedSteps?.includes(BREEDING_PROPERTIES_STEP)}> setActiveStep(BREEDING_PROPERTIES_STEP)}>Informations sur l'élevage - cancel()}/> + + + + + setActiveStep(SLAUGHTER_PROPERTIES_STEP)}>Informations sur l'abattage - cancel()}/> + + + + + setActiveStep(CUTTING_PROPERTIES_STEP)}>Information sur la découpe setActiveStep(CUTTING_PROPERTIES_STEP)}> - cancel()}/> + + + + + + function validateBreedingProperties(breedingFormData) { - const beefProductionUpdated = { - ...beefProduction, - birthDate: breedingFormData.birthDate, - birthFarm: breedingFormData.birthFarm, - birthPlace: breedingFormData.birthPlace, - animalIdentifier: breedingFormData.animalIdentifier, - animalType: breedingFormData.animalType, - cattleBreed: breedingFormData.cattleBreed, - labelRougeCertified: breedingFormData.labelRougeCertified - } - const updateCompletedSteps = [...completedSteps, BREEDING_PROPERTIES_STEP] - setBeefProduction(beefProductionUpdated) - setCompletedSteps(updateCompletedSteps) - console.debug(beefProductionUpdated) - console.debug(updateCompletedSteps) + setBeefProduction(mapBreedingFormDataToBeefProduction(breedingFormData, beefProduction)) + setCompletedSteps([...completedSteps, BREEDING_PROPERTIES_STEP]) setActiveStep(SLAUGHTER_PROPERTIES_STEP) } function validateSlaughterProperties(slaughterFormData) { - const beefProductionUpdated = { - ...beefProduction, - slaughterDate: slaughterFormData.slaughterDate, - slaughterHouse: slaughterFormData.slaughterHouse, - slaughterPlace: slaughterFormData.slaughterPlace, - warmCarcassWeight: slaughterFormData.warmCarcassWeight - } - setBeefProduction(beefProductionUpdated) - console.debug(beefProductionUpdated) + setBeefProduction(mapSlaughterFormDataToBeefProduction(slaughterFormData, beefProduction)) setCompletedSteps([...completedSteps, SLAUGHTER_PROPERTIES_STEP]) setActiveStep(CUTTING_PROPERTIES_STEP) } function validateCuttingProperties(cuttingFormData) { - const beefProductionUpdated = { - ...beefProduction, - cuttingDate: cuttingFormData.cuttingDate, - cuttingPlace: cuttingFormData.cuttingPlace, - cuttingButcher: cuttingFormData.cuttingButcher - } - setBeefProduction(beefProductionUpdated) - console.debug(beefProductionUpdated) + setBeefProduction(mapCuttingFormDataToBeefProduction(cuttingFormData, beefProduction)) setCompletedSteps([...completedSteps, CUTTING_PROPERTIES_STEP]) setActiveStep(PRODUCTS_STEP) } function displayAlerts() { if(!isTotalQuantitySoldLowerThanMeatWeight()) { - return Le poids total des produits préparés ne doit pas dépasser la quantité de viande de l'animal. + const meatQuantity = BeefProductionService.getMeatWeight(beefProduction.warmCarcassWeight) + return Le poids total des produits préparés ne doit pas dépasser la quantité de viande de l'animal estimée à {meatQuantity} kg. } } diff --git a/frontend/app/src/domains/production/views/beefProduction/BeefProductionView.tsx b/frontend/app/src/domains/production/views/beefProduction/BeefProductionView.tsx new file mode 100644 index 0000000..6c9c168 --- /dev/null +++ b/frontend/app/src/domains/production/views/beefProduction/BeefProductionView.tsx @@ -0,0 +1,126 @@ +import { Typography, ButtonGroup, Button, Tab, Tabs } from '@mui/material' +import React from 'react' +import { useState } from 'react' +import BreedingPropertiesForm, { mapBreedingFormDataToBeefProduction } from './forms/BreedingPropertiesForm.tsx' +import SlaughterPropertiesForm, { mapSlaughterFormDataToBeefProduction } from './forms/SlaughterPropertiesForm.tsx' +import CuttingPropertiesForm, { mapCuttingFormDataToBeefProduction } from './forms/CuttingPropertiesForm.tsx' +import { useForm } from 'react-hook-form' +import dayjs from 'dayjs' +import BeefProduction from "viandeendirect_eu/dist/model/BeefProduction.js" + +export default function BeefProductionView({ beefProduction: beefProduction, backCallback: backCallback }) { + + const BREEDING_PROPERTIES_TAB = 0 + const SLAUGHTER_PROPERTIES_TAB = 1 + const CUTTING_PROPERTIES_TAB = 2 + const PRODUCTS_TAB = 3 + + const [currentTab, setCurrentTab] = useState(BREEDING_PROPERTIES_TAB); + const [readOnly, setReadOnly] = useState(true) + const [production, setProduction] = useState(beefProduction) + + const changeTab = (event: React.SyntheticEvent, newValue: number) => { + setCurrentTab(newValue); + }; + + const breedingPropertiesForm = useForm({defaultValues: { + ...beefProduction, + birthDate: beefProduction.birthDate ? dayjs(beefProduction.birthDate) : undefined + }}) + + const slaughterPropertiesForm = useForm({defaultValues: { + ...beefProduction, + slaughterDate: beefProduction.slaughterDate ? dayjs(beefProduction.slaughterDate) : undefined + }}) + + const cuttingPropertiesForm = useForm({defaultValues: { + ...beefProduction, + cuttingDate: beefProduction.cuttingDate ? dayjs(beefProduction.cuttingDate) : undefined + }}) + + return <> + Abattage bovin + + + + + + + + + + + {getButtons()} + + + function getButtons() { + if (readOnly) { + return + + + + } + return + + + + } + + function saveUpdate() { + switch (currentTab) { + case BREEDING_PROPERTIES_TAB: + return breedingPropertiesForm.handleSubmit((breedingFormData) => { + setProduction(mapBreedingFormDataToBeefProduction(breedingFormData, production)) + setReadOnly(true) + }) + case SLAUGHTER_PROPERTIES_TAB: + return slaughterPropertiesForm.handleSubmit((slaughterFormData) => { + setProduction(mapSlaughterFormDataToBeefProduction(slaughterFormData, production)) + setReadOnly(true) + }) + case CUTTING_PROPERTIES_TAB: + return cuttingPropertiesForm.handleSubmit((cuttingFormData) => { + setProduction(mapCuttingFormDataToBeefProduction(cuttingFormData, production)) + setReadOnly(true) + }) + } + } + + function cancelUpdate() { + switch (currentTab) { + case BREEDING_PROPERTIES_TAB: + return breedingPropertiesForm.reset(() => { + setProduction(beefProduction) + setReadOnly(true) + }) + case SLAUGHTER_PROPERTIES_TAB: + return slaughterPropertiesForm.reset(() => { + setProduction(beefProduction) + setReadOnly(true) + }) + case CUTTING_PROPERTIES_TAB: + return cuttingPropertiesForm.reset(() => { + setProduction(beefProduction) + setReadOnly(true) + }) + } + } +} \ No newline at end of file diff --git a/frontend/app/src/domains/production/views/beefProductionCreator/forms/BreedingPropertiesForm.tsx b/frontend/app/src/domains/production/views/beefProduction/forms/BreedingPropertiesForm.tsx similarity index 64% rename from frontend/app/src/domains/production/views/beefProductionCreator/forms/BreedingPropertiesForm.tsx rename to frontend/app/src/domains/production/views/beefProduction/forms/BreedingPropertiesForm.tsx index 4822949..f399b99 100644 --- a/frontend/app/src/domains/production/views/beefProductionCreator/forms/BreedingPropertiesForm.tsx +++ b/frontend/app/src/domains/production/views/beefProduction/forms/BreedingPropertiesForm.tsx @@ -6,10 +6,10 @@ import { CheckboxElement, DatePickerElement, FormContainer, SelectElement, Submi import BeefProduction from "viandeendirect_eu/dist/model/BeefProduction" import dayjs from "dayjs" -export default function BreedingPropertiesForm({ - beefProduction: beefProduction, - validFormCallback: validFormCallback, - cancelFormCallback: cancelFormCallback }) { +export function BreedingPropertiesForm({ + form: form, + disabled: disabled = false, + maxBirthDate: maxBirthDate = undefined}) { const animalTypeList = [ { id: 'BEEF_COW', label: 'vache' }, @@ -23,43 +23,41 @@ export default function BreedingPropertiesForm({ { id: 'CHAROLAISE', label: 'charolaise' } ] - const form = useForm({defaultValues: { - ...beefProduction, - birthDate: dayjs(beefProduction.birthDate), - slaughterDate: dayjs(beefProduction.slaughterDate), - cuttingDate: dayjs(beefProduction.cuttingDate) - }}) - return <> -
+ label="Date de naissance" + disabled={disabled} + maxDate={maxBirthDate ? dayjs(maxBirthDate) : undefined} + disableFuture={true}/>
+ variant="standard" + disabled={disabled}/>
+ variant="standard" + disabled={disabled}/>
+ variant="standard" + disabled={disabled}/>
+ options={animalTypeList} + disabled={disabled}/>
+ options={cattleBreedList} + disabled={disabled}/>
+ label="Label rouge" + disabled={disabled}/>
-
- - - - -
-} \ No newline at end of file +} + +export function mapBreedingFormDataToBeefProduction(breedingFormData, beefProduction) { + return { + ...beefProduction, + birthDate: breedingFormData.birthDate, + birthFarm: breedingFormData.birthFarm, + birthPlace: breedingFormData.birthPlace, + animalIdentifier: breedingFormData.animalIdentifier, + animalType: breedingFormData.animalType, + cattleBreed: breedingFormData.cattleBreed, + labelRougeCertified: breedingFormData.labelRougeCertified + } +} + +export default BreedingPropertiesForm \ No newline at end of file diff --git a/frontend/app/src/domains/production/views/beefProductionCreator/forms/CuttingPropertiesForm.tsx b/frontend/app/src/domains/production/views/beefProduction/forms/CuttingPropertiesForm.tsx similarity index 53% rename from frontend/app/src/domains/production/views/beefProductionCreator/forms/CuttingPropertiesForm.tsx rename to frontend/app/src/domains/production/views/beefProduction/forms/CuttingPropertiesForm.tsx index 5925cc9..1fbf508 100644 --- a/frontend/app/src/domains/production/views/beefProductionCreator/forms/CuttingPropertiesForm.tsx +++ b/frontend/app/src/domains/production/views/beefProduction/forms/CuttingPropertiesForm.tsx @@ -5,47 +5,48 @@ import { FormContainer, DatePickerElement, TextFieldElement, useForm } from 'rea import BeefProduction from "viandeendirect_eu/dist/model/BeefProduction" import dayjs from 'dayjs' -export default function CuttingPropertiesForm({ - beefProduction: beefProduction, - validFormCallback: validFormCallback, - cancelFormCallback: cancelFormCallback}) { - - const form = useForm({defaultValues: { - ...beefProduction, - birthDate: dayjs(beefProduction.birthDate), - slaughterDate: dayjs(beefProduction.slaughterDate), - cuttingDate: dayjs(beefProduction.cuttingDate) - }}) +export function CuttingPropertiesForm({ + form: form, + disabled: disabled = false, + minCuttingDate: minCuttingDate = undefined}) { - return + return
+ minDate={minCuttingDate ? dayjs(minCuttingDate) : undefined} + disabled={disabled}/>
+ variant="standard" + disabled={disabled}/>
-
-
- - - - + variant="standard" + disabled={disabled}/>
-} \ No newline at end of file +} + +export function mapCuttingFormDataToBeefProduction(cuttingFormData, beefProduction) { + return { + ...beefProduction, + cuttingDate: cuttingFormData.cuttingDate, + cuttingPlace: cuttingFormData.cuttingPlace, + cuttingButcher: cuttingFormData.cuttingButcher + } +} + +export default CuttingPropertiesForm \ No newline at end of file diff --git a/frontend/app/src/domains/production/views/beefProductionCreator/forms/SlaughterPropertiesForm.tsx b/frontend/app/src/domains/production/views/beefProduction/forms/SlaughterPropertiesForm.tsx similarity index 53% rename from frontend/app/src/domains/production/views/beefProductionCreator/forms/SlaughterPropertiesForm.tsx rename to frontend/app/src/domains/production/views/beefProduction/forms/SlaughterPropertiesForm.tsx index 67e76dd..237e524 100644 --- a/frontend/app/src/domains/production/views/beefProductionCreator/forms/SlaughterPropertiesForm.tsx +++ b/frontend/app/src/domains/production/views/beefProduction/forms/SlaughterPropertiesForm.tsx @@ -1,73 +1,75 @@ import React from 'react' -import { ButtonGroup, Button } from '@mui/material' -import { DatePickerElement, FormContainer, SliderElement, TextFieldElement, useForm } from 'react-hook-form-mui' +import { DatePickerElement, FormContainer, SliderElement, TextFieldElement } from 'react-hook-form-mui' -import BeefProduction from "viandeendirect_eu/dist/model/BeefProduction" import { BeefProductionService } from '../../../service/BeefProductionService.ts' import dayjs from 'dayjs' -export default function SlaughterPropertiesForm({ - beefProduction: beefProduction, - validFormCallback: validFormCallback, - cancelFormCallback: cancelFormCallback }) { - - const form = useForm({defaultValues: { - ...beefProduction, - birthDate: dayjs(beefProduction.birthDate), - slaughterDate: dayjs(beefProduction.slaughterDate), - cuttingDate: dayjs(beefProduction.cuttingDate) - }}) +export function SlaughterPropertiesForm({ + form: form, + disabled: disabled = false, + minSlaughterDate: minSlaughterDate = undefined, + maxSlaughterDate: maxSlaughterDate = undefined, + initialWarmCarcassWeight: initialWarmCarcassWeight = 0}) { const warmCarcassWeight = form.watch('warmCarcassWeight') - - return + return
+ minDate={minSlaughterDate ? dayjs(minSlaughterDate) : undefined} + maxDate={maxSlaughterDate ? dayjs(maxSlaughterDate) : undefined} + disabled={disabled}/>
+ variant="standard" + disabled={disabled}/>
+ variant="standard" + disabled={disabled}/>
+ step={10} + disabled={disabled}/>
- Poids de l'animal vivant : {BeefProductionService.getLiveWeight(warmCarcassWeight)} kg + Poids de l'animal vivant : {BeefProductionService.getLiveWeight(warmCarcassWeight || initialWarmCarcassWeight)} kg
- Poids de carcasse chaude : {warmCarcassWeight || 0} kg + Poids de carcasse chaude : {warmCarcassWeight || initialWarmCarcassWeight} kg
- Quantité de viande : {BeefProductionService.getMeatWeight(warmCarcassWeight)} kg + Quantité de viande : {BeefProductionService.getMeatWeight(warmCarcassWeight || initialWarmCarcassWeight)} kg
-
- - - - -
-} \ No newline at end of file +} + +export function mapSlaughterFormDataToBeefProduction(slaughterFormData, beefProduction) { + return { + ...beefProduction, + slaughterDate: slaughterFormData.slaughterDate, + slaughterHouse: slaughterFormData.slaughterHouse, + slaughterPlace: slaughterFormData.slaughterPlace, + warmCarcassWeight: slaughterFormData.warmCarcassWeight + } +} + +export default SlaughterPropertiesForm \ No newline at end of file