diff --git a/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx b/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx index 00ee3bb..bf11f61 100644 --- a/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx +++ b/frontend/app/src/domains/production/components/PackageLotConfigurator.tsx @@ -10,17 +10,18 @@ import { FormContainer, TextFieldElement, TextareaAutosizeElement, useForm } fro * @returns */ export default function PackageLotConfigurator({ - packageLot: packageLot, - changeCallback: changeCallback, - disabled: disabled = false }) { - const [quantity, setQuantity] = useState(packageLot.quantity) + lot: lot, + disabled: disabled = false, + changeQuantitySoldCallback: changeQuantitySoldCallback }) { + + const [quantity, setQuantity] = useState(lot.quantity) const [editionPopinOpen, setEditionPopinOpen] = useState(false) const form = useForm({ defaultValues: { - label: packageLot.label, - description: packageLot.description, - netWeight: packageLot.netWeight, - unitPrice: packageLot.unitPrice + label: lot.label, + description: lot.description, + netWeight: lot.netWeight, + unitPrice: lot.unitPrice } }) @@ -28,19 +29,19 @@ export default function PackageLotConfigurator({
- {packageLot.label} + {lot.label} {displayEditionButton()}
-
{packageLot.description}
-
{packageLot.netWeight} kg
-
{packageLot.unitPrice} € TTC/kg
+
{lot.description}
+
{lot.netWeight} kg
+
{lot.unitPrice} € TTC/kg
{displayRemovePackagesButtons()}
-
{quantity}
+
{lot.quantity}
colis mis en vente
-
{quantity * packageLot.netWeight} kg
-
{quantity * packageLot.netWeight * packageLot.unitPrice} € TTC
+
{lot.quantity * lot.netWeight} kg
+
{lot.quantity * lot.netWeight * lot.unitPrice} € TTC
{displayAddPackagesButtons()}
@@ -124,18 +125,18 @@ export default function PackageLotConfigurator({ * @param {number} quantity */ function addPackages(quantity) { - packageLot.quantity += quantity - setQuantity(packageLot.quantity) - changeCallback(packageLot) + lot.quantity += quantity + changeQuantitySoldCallback() + setQuantity(lot.quantity) } /** * @param {number} quantity */ function removePackages(quantity) { - packageLot.quantity -= Math.min(quantity, packageLot.quantity) - setQuantity(packageLot.quantity) - changeCallback(packageLot) + lot.quantity -= Math.min(quantity, lot.quantity) + changeQuantitySoldCallback() + setQuantity(lot.quantity) } function openEditionPopin() { @@ -148,20 +149,19 @@ export default function PackageLotConfigurator({ function cancelForm(formData) { form.reset({ - label: packageLot.label, - description: packageLot.description, - netWeight: packageLot.netWeight, - unitPrice: packageLot.unitPrice + label: lot.label, + description: lot.description, + netWeight: lot.netWeight, + unitPrice: lot.unitPrice }) closeEditionPopin() } function validForm(formData) { - packageLot.label = formData.label - packageLot.description = formData.description - packageLot.unitPrice = formData.unitPrice - packageLot.netWeight = formData.netWeight - changeCallback(packageLot) + lot.label = formData.label + lot.description = formData.description + lot.unitPrice = formData.unitPrice + lot.netWeight = formData.netWeight closeEditionPopin() } diff --git a/frontend/app/src/domains/production/views/PackageLotsCreator.tsx b/frontend/app/src/domains/production/views/PackageLotsCreator.tsx index 868dc07..144d07f 100644 --- a/frontend/app/src/domains/production/views/PackageLotsCreator.tsx +++ b/frontend/app/src/domains/production/views/PackageLotsCreator.tsx @@ -1,55 +1,36 @@ -import React from 'react' -import { useEffect, useState } from "react" -import { useKeycloak } from '@react-keycloak/web' -import { ApiBuilder } from '../../../api/ApiBuilder.ts' -import PackageLot from "viandeendirect_eu/dist/model/PackageLot" +import React, { useState } from 'react' import PackageLotConfigurator from "../components/PackageLotConfigurator.tsx" +import { BeefProductionService } from '../service/BeefProductionService.ts' +import { Alert } from '@mui/material' -export default function PackageLotsCreator({ - production: production, - changeProductionCallback: changeProductionCallback, - disabled: disabled = false }) { +export default function PackageLotsCreator({ + production: production, + disabled: disabled = false, + changeQuantitiesCompliancyCallback: changeQuantitiesCompliancyCallback = (isCompliant) => {}}) { - const { keycloak } = useKeycloak() - const apiBuilder = new ApiBuilder() + return <> + {displayAlerts()} + {production.lots?.map(lot => )} + - useEffect(() => { - if (!production.lots) { - apiBuilder.getAuthenticatedApi(keycloak).then(api => { - apiBuilder.invokeAuthenticatedApi(() => { - api.getPackageTemplates((error, data, response) => { - if (error) { - console.error(error); - } else { - console.log('api.getPackageTemplates called successfully. Returned data: ' + data); - const lots = [] - data.map(template => { - let lot = new PackageLot() - lot.label = template.label - lot.description = template.description - lot.unitPrice = template.unitPrice - lot.netWeight = template.netWeight - lot.quantity = 0 - lot.quantitySold = 0 - lots.push(lot) - }) - changeProductionCallback({ ...production, lots: lots }) - } - }) - }, keycloak) - }) + function displayAlerts() { + const totalQuantitySold = production.lots?.map(lot => lot.netWeight * lot.quantity).reduce((total, added) => total + added) || 0 + if (!isTotalQuantitySoldLowerThanMeatWeight(totalQuantitySold)) { + const meatQuantity = BeefProductionService.getMeatWeight(production.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. } - }, [keycloak]) + } - return <> - {production.lots?.map(lot => )} - + function isTotalQuantitySoldLowerThanMeatWeight(totalQuantitySoldUpdated) { + return totalQuantitySoldUpdated < BeefProductionService.getMeatWeight(production.warmCarcassWeight) + } - function changeLotConfiguration() { - changeProductionCallback({ ...production }) + function changeQuantitySold() { + const totalQuantitySold = production.lots?.map(lot => lot.netWeight * lot.quantity).reduce((total, added) => total + added) || 0 + changeQuantitiesCompliancyCallback(isTotalQuantitySoldLowerThanMeatWeight(totalQuantitySold)) } } diff --git a/frontend/app/src/domains/production/views/beefProduction/BeefProductionCreator.tsx b/frontend/app/src/domains/production/views/beefProduction/BeefProductionCreator.tsx index b0bfb5d..eae0d8b 100644 --- a/frontend/app/src/domains/production/views/beefProduction/BeefProductionCreator.tsx +++ b/frontend/app/src/domains/production/views/beefProduction/BeefProductionCreator.tsx @@ -1,22 +1,19 @@ -import React from "react" +import React, { useEffect } from "react" import { useState } from "react" - -import { Button, ButtonGroup, Typography, Stepper, Step, StepContent, StepButton, Alert } from "@mui/material" - +import { useForm } from "react-hook-form" +import dayjs from "dayjs" import 'dayjs/locale/fr' - -import BeefProduction from "viandeendirect_eu/dist/model/BeefProduction.js" - -import { ApiBuilder } from '../../../../api/ApiBuilder.ts' import { useKeycloak } from '@react-keycloak/web' +import { Button, ButtonGroup, Typography, Stepper, Step, StepContent, StepButton, Alert } from "@mui/material" +import { ApiBuilder } from '../../../../api/ApiBuilder.ts' import PackageLotsCreator from "../PackageLotsCreator.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" +import BeefProduction from "viandeendirect_eu/dist/model/BeefProduction.js" +import PackageLot from "viandeendirect_eu/dist/model/PackageLot.js" export default function BeefProductionCreator({ callback }) { @@ -28,9 +25,34 @@ export default function BeefProductionCreator({ callback }) { const { keycloak } = useKeycloak() const [ activeStep, setActiveStep ] = useState(BREEDING_PROPERTIES_STEP) const [ beefProduction, setBeefProduction] = useState({ productionType: "BeefProduction"}) - const [completedSteps, setCompletedSteps] = useState>([]) + const [ completedSteps, setCompletedSteps] = useState>([]) const apiBuilder = new ApiBuilder() + useEffect(() => { + if (! beefProduction.lots) { + apiBuilder.getAuthenticatedApi(keycloak).then(api => { + apiBuilder.invokeAuthenticatedApi(() => { + api.getPackageTemplates((error, data, response) => { + if (error) { + console.error(error); + } else { + console.log('api.getPackageTemplates called successfully. Returned data: ' + data); + const lots: Array = [] + data.map(template => { + lots.push({ + ...template, + quantity: 0, + quantitySold: 0 + }) + }) + setBeefProduction({...beefProduction, lots: lots}) + } + }) + }, keycloak) + }) + } + }, [keycloak]) + const breedingPropertiesForm = useForm({defaultValues: { ...beefProduction, birthDate: beefProduction.birthDate ? dayjs(beefProduction.birthDate) : undefined @@ -95,9 +117,8 @@ export default function BeefProductionCreator({ callback }) { setActiveStep(PRODUCTS_STEP)}>Produits préparés
- {displayAlerts()}
- +
@@ -129,12 +150,6 @@ export default function BeefProductionCreator({ callback }) { setActiveStep(PRODUCTS_STEP) } - function displayAlerts() { - if(!isTotalQuantitySoldLowerThanMeatWeight()) { - 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. - } - } function isTotalQuantitySoldLowerThanMeatWeight() { return getTotalQuantitySold() < BeefProductionService.getMeatWeight(beefProduction.warmCarcassWeight) diff --git a/frontend/app/src/domains/production/views/beefProduction/BeefProductionView.tsx b/frontend/app/src/domains/production/views/beefProduction/BeefProductionView.tsx index df27340..c47dfb7 100644 --- a/frontend/app/src/domains/production/views/beefProduction/BeefProductionView.tsx +++ b/frontend/app/src/domains/production/views/beefProduction/BeefProductionView.tsx @@ -1,11 +1,11 @@ -import { Typography, ButtonGroup, Button, Tab, Tabs } from '@mui/material' import React from 'react' import { useState } from 'react' +import { useForm } from 'react-hook-form' +import { Typography, ButtonGroup, Button, Tab, Tabs } from '@mui/material' +import dayjs from 'dayjs' 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" import PackageLotsCreator from '../PackageLotsCreator.tsx' @@ -16,9 +16,13 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac const CUTTING_PROPERTIES_TAB = 2 const PRODUCTS_TAB = 3 - const [currentTab, setCurrentTab] = useState(BREEDING_PROPERTIES_TAB); + const [currentTab, setCurrentTab] = useState(BREEDING_PROPERTIES_TAB) const [readOnly, setReadOnly] = useState(true) - const [production, setProduction] = useState(beefProduction) + const [production, setProduction] = useState( + {...beefProduction, + lots: beefProduction.lots ? beefProduction.lots.map((lot) => {return {...lot}}) : undefined + }) + const [saveEnabled, setSaveEnabled] = useState(true) const changeTab = (event: React.SyntheticEvent, newValue: number) => { setCurrentTab(newValue); @@ -26,17 +30,17 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac const breedingPropertiesForm = useForm({defaultValues: { ...beefProduction, - birthDate: beefProduction.birthDate ? dayjs(beefProduction.birthDate) : undefined + birthDate: production.birthDate ? dayjs(production.birthDate) : undefined }}) const slaughterPropertiesForm = useForm({defaultValues: { - ...beefProduction, - slaughterDate: beefProduction.slaughterDate ? dayjs(beefProduction.slaughterDate) : undefined + ...production, + slaughterDate: production.slaughterDate ? dayjs(production.slaughterDate) : undefined }}) const cuttingPropertiesForm = useForm({defaultValues: { - ...beefProduction, - cuttingDate: beefProduction.cuttingDate ? dayjs(beefProduction.cuttingDate) : undefined + ...production, + cuttingDate: production.cuttingDate ? dayjs(production.cuttingDate) : undefined }}) return <> @@ -69,12 +73,11 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac
{getButtons()} @@ -87,7 +90,7 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac } return - + } @@ -112,7 +115,6 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac case PRODUCTS_TAB: return () => { setReadOnly(true) - //setProduction() } } } @@ -126,15 +128,23 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac }) case SLAUGHTER_PROPERTIES_TAB: return slaughterPropertiesForm.reset(() => { - setProduction(beefProduction) + setProduction({...beefProduction, + lots: beefProduction.lots ? beefProduction.lots.map((lot) => {return {...lot}}) : undefined + }) setReadOnly(true) }) case CUTTING_PROPERTIES_TAB: return cuttingPropertiesForm.reset(() => { - setProduction(beefProduction) + setProduction({...beefProduction, + lots: beefProduction.lots ? beefProduction.lots.map((lot) => {return {...lot}}) : undefined + }) setReadOnly(true) }) case PRODUCTS_TAB: + setProduction({...beefProduction, + lots: beefProduction.lots ? beefProduction.lots.map((lot) => {return {...lot}}) : undefined + }) + setSaveEnabled(true) setReadOnly(true) } }