Skip to content

Commit

Permalink
frontend : fix problems for product setup
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminpochat committed Feb 24, 2024
1 parent a9a4be8 commit a883f19
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,38 @@ import { FormContainer, TextFieldElement, TextareaAutosizeElement, useForm } fro
* @returns
*/
export default function PackageLotConfigurator({
packageLot: packageLot,
changeCallback: changeCallback,
disabled: disabled = false }) {
const [quantity, setQuantity] = useState<number>(packageLot.quantity)
lot: lot,
disabled: disabled = false,
changeQuantitySoldCallback: changeQuantitySoldCallback }) {

const [quantity, setQuantity] = useState<number>(lot.quantity)
const [editionPopinOpen, setEditionPopinOpen] = useState<boolean>(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
}
})

return <div>
<div className="lot">
<div className="lot__package">
<div className="lot__package__name">
<span>{packageLot.label}</span>
<span>{lot.label}</span>
{displayEditionButton()}
</div>
<div className="lot__package__description">{packageLot.description}</div>
<div className="lot__package__net-weight">{packageLot.netWeight} kg</div>
<div className="lot__package__unit-price">{packageLot.unitPrice}<sup>TTC</sup>/kg</div>
<div className="lot__package__description">{lot.description}</div>
<div className="lot__package__net-weight">{lot.netWeight} kg</div>
<div className="lot__package__unit-price">{lot.unitPrice}<sup>TTC</sup>/kg</div>
</div>
{displayRemovePackagesButtons()}
<div className="lot__summary">
<div className="lot__summary__package-number">{quantity}</div>
<div className="lot__summary__package-number">{lot.quantity}</div>
<div className="lot__summary__label">colis mis en vente</div>
<div className="lot__summary__total-quantity">{quantity * packageLot.netWeight} kg</div>
<div className="lot__summary__total-price">{quantity * packageLot.netWeight * packageLot.unitPrice}<sup>TTC</sup></div>
<div className="lot__summary__total-quantity">{lot.quantity * lot.netWeight} kg</div>
<div className="lot__summary__total-price">{lot.quantity * lot.netWeight * lot.unitPrice}<sup>TTC</sup></div>
</div>
{displayAddPackagesButtons()}
</div>
Expand Down Expand Up @@ -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() {
Expand All @@ -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()
}

Expand Down
71 changes: 26 additions & 45 deletions frontend/app/src/domains/production/views/PackageLotsCreator.tsx
Original file line number Diff line number Diff line change
@@ -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 => <PackageLotConfigurator
lot={lot}
disabled={disabled}
changeQuantitySoldCallback={changeQuantitySold} />)}
</>

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 <Alert severity="error">Le poids total des produits préparés ne doit pas dépasser la quantité de viande de l'animal estimée à {meatQuantity} kg.</Alert>
}
}, [keycloak])
}

return <>
{production.lots?.map(lot => <PackageLotConfigurator
packageLot={lot}
changeCallback={changeLotConfiguration}
disabled={disabled}/>)}
</>
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))
}
}
Original file line number Diff line number Diff line change
@@ -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 }) {

Expand All @@ -28,9 +25,34 @@ export default function BeefProductionCreator({ callback }) {
const { keycloak } = useKeycloak()
const [ activeStep, setActiveStep ] = useState<number>(BREEDING_PROPERTIES_STEP)
const [ beefProduction, setBeefProduction] = useState<BeefProduction>({ productionType: "BeefProduction"})
const [completedSteps, setCompletedSteps] = useState<Array<number>>([])
const [ completedSteps, setCompletedSteps] = useState<Array<number>>([])
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<PackageLot> = []
data.map(template => {
lots.push({
...template,
quantity: 0,
quantitySold: 0
})
})
setBeefProduction({...beefProduction, lots: lots})
}
})
}, keycloak)
})
}
}, [keycloak])

const breedingPropertiesForm = useForm<BeefProduction>({defaultValues: {
...beefProduction,
birthDate: beefProduction.birthDate ? dayjs(beefProduction.birthDate) : undefined
Expand Down Expand Up @@ -95,9 +117,8 @@ export default function BeefProductionCreator({ callback }) {
<StepButton onClick={() => setActiveStep(PRODUCTS_STEP)}>Produits préparés</StepButton>
<StepContent>
<div className="form">
{displayAlerts()}
<div>
<PackageLotsCreator production={beefProduction} changeProductionCallback={setBeefProduction}></PackageLotsCreator>
<PackageLotsCreator production={beefProduction}></PackageLotsCreator>
</div>
<div>
<ButtonGroup>
Expand Down Expand Up @@ -129,12 +150,6 @@ export default function BeefProductionCreator({ callback }) {
setActiveStep(PRODUCTS_STEP)
}

function displayAlerts() {
if(!isTotalQuantitySoldLowerThanMeatWeight()) {
const meatQuantity = BeefProductionService.getMeatWeight(beefProduction.warmCarcassWeight)
return <Alert severity="error">Le poids total des produits préparés ne doit pas dépasser la quantité de viande de l'animal estimée à {meatQuantity} kg.</Alert>
}
}

function isTotalQuantitySoldLowerThanMeatWeight() {
return getTotalQuantitySold() < BeefProductionService.getMeatWeight(beefProduction.warmCarcassWeight)
Expand Down
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -16,27 +16,31 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac
const CUTTING_PROPERTIES_TAB = 2
const PRODUCTS_TAB = 3

const [currentTab, setCurrentTab] = useState<number>(BREEDING_PROPERTIES_TAB);
const [currentTab, setCurrentTab] = useState<number>(BREEDING_PROPERTIES_TAB)
const [readOnly, setReadOnly] = useState<boolean>(true)
const [production, setProduction] = useState<BeefProduction>(beefProduction)
const [production, setProduction] = useState<BeefProduction>(
{...beefProduction,
lots: beefProduction.lots ? beefProduction.lots.map((lot) => {return {...lot}}) : undefined
})
const [saveEnabled, setSaveEnabled] = useState<boolean>(true)

const changeTab = (event: React.SyntheticEvent, newValue: number) => {
setCurrentTab(newValue);
};

const breedingPropertiesForm = useForm<BeefProduction>({defaultValues: {
...beefProduction,
birthDate: beefProduction.birthDate ? dayjs(beefProduction.birthDate) : undefined
birthDate: production.birthDate ? dayjs(production.birthDate) : undefined
}})

const slaughterPropertiesForm = useForm<BeefProduction>({defaultValues: {
...beefProduction,
slaughterDate: beefProduction.slaughterDate ? dayjs(beefProduction.slaughterDate) : undefined
...production,
slaughterDate: production.slaughterDate ? dayjs(production.slaughterDate) : undefined
}})

const cuttingPropertiesForm = useForm<BeefProduction>({defaultValues: {
...beefProduction,
cuttingDate: beefProduction.cuttingDate ? dayjs(beefProduction.cuttingDate) : undefined
...production,
cuttingDate: production.cuttingDate ? dayjs(production.cuttingDate) : undefined
}})

return <>
Expand Down Expand Up @@ -69,12 +73,11 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac
</div>
<div hidden={currentTab !== 3}>
<div>
<PackageLotsCreator
<PackageLotsCreator
production={production}
changeProductionCallback={setProduction}
disabled={readOnly}/>
disabled={readOnly}
changeQuantitiesCompliancyCallback={setSaveEnabled}/>
</div>

</div>
{getButtons()}
</>
Expand All @@ -87,7 +90,7 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac
</ButtonGroup>
}
return <ButtonGroup>
<Button variant="contained" size="small" onClick={saveUpdate()} >Sauvegarder</Button>
<Button variant="contained" size="small" onClick={saveUpdate()} disabled={!saveEnabled}>Sauvegarder</Button>
<Button variant="outlined" size="small" onClick={cancelUpdate} >Abandonner</Button>
</ButtonGroup>
}
Expand All @@ -112,7 +115,6 @@ export default function BeefProductionView({ beefProduction: beefProduction, bac
case PRODUCTS_TAB:
return () => {
setReadOnly(true)
//setProduction()
}
}
}
Expand All @@ -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)
}
}
Expand Down

0 comments on commit a883f19

Please sign in to comment.